001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2016, Connect2id Ltd.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.jose;
019
020
021import com.nimbusds.jose.util.ArrayUtils;
022import net.jcip.annotations.Immutable;
023
024
025/**
026 * JSON Web Signature (JWS) algorithm name, represents the {@code alg} header
027 * parameter in JWS objects. Also used to represent integrity algorithm 
028 * ({@code ia}) header parameters in JWE objects. This class is immutable.
029 *
030 * <p>Includes constants for the following standard JWS algorithm names:
031 *
032 * <ul>
033 *     <li>{@link #HS256}
034 *     <li>{@link #HS384}
035 *     <li>{@link #HS512}
036 *     <li>{@link #RS256}
037 *     <li>{@link #RS384}
038 *     <li>{@link #RS512}
039 *     <li>{@link #ES256}
040 *     <li>{@link #ES256K}
041 *     <li>{@link #ES384}
042 *     <li>{@link #ES512}
043 *     <li>{@link #PS256}
044 *     <li>{@link #PS384}
045 *     <li>{@link #PS512}
046 *     <li>{@link #EdDSA}
047 *     <li>{@link #Ed25519}
048 *     <li>{@link #Ed448}
049 * </ul>
050 *
051 * <p>Additional JWS algorithm names can be defined using the constructors.
052 *
053 * @author Vladimir Dzhuvinov
054 * @author Aleksei Doroganov
055 * @version 2024-05-07
056 */
057@Immutable
058public final class JWSAlgorithm extends Algorithm {
059
060
061        private static final long serialVersionUID = 1L;
062
063
064        /**
065         * HMAC using SHA-256 hash algorithm (required).
066         */
067        public static final JWSAlgorithm HS256 = new JWSAlgorithm("HS256", Requirement.REQUIRED);
068
069
070        /**
071         * HMAC using SHA-384 hash algorithm (optional).
072         */
073        public static final JWSAlgorithm HS384 = new JWSAlgorithm("HS384", Requirement.OPTIONAL);
074
075
076        /**
077         * HMAC using SHA-512 hash algorithm (optional).
078         */
079        public static final JWSAlgorithm HS512 = new JWSAlgorithm("HS512", Requirement.OPTIONAL);
080
081
082        /**
083         * RSASSA-PKCS-v1_5 using SHA-256 hash algorithm (recommended).
084         */
085        public static final JWSAlgorithm RS256 = new JWSAlgorithm("RS256", Requirement.RECOMMENDED);
086
087
088        /**
089         * RSASSA-PKCS-v1_5 using SHA-384 hash algorithm (optional).
090         */
091        public static final JWSAlgorithm RS384 = new JWSAlgorithm("RS384", Requirement.OPTIONAL);
092
093
094        /**
095         * RSASSA-PKCS-v1_5 using SHA-512 hash algorithm (optional).
096         */
097        public static final JWSAlgorithm RS512 = new JWSAlgorithm("RS512", Requirement.OPTIONAL);
098
099
100        /**
101         * ECDSA using P-256 (secp256r1) curve and SHA-256 hash algorithm
102         * (recommended).
103         */
104        public static final JWSAlgorithm ES256 = new JWSAlgorithm("ES256", Requirement.RECOMMENDED);
105
106        
107        /**
108         * ECDSA using P-256K (secp256k1) curve and SHA-256 hash algorithm
109         * (optional).
110         */
111        public static final JWSAlgorithm ES256K = new JWSAlgorithm("ES256K", Requirement.OPTIONAL);
112
113
114        /**
115         * ECDSA using P-384 curve and SHA-384 hash algorithm (optional).
116         */
117        public static final JWSAlgorithm ES384 = new JWSAlgorithm("ES384", Requirement.OPTIONAL);
118
119
120        /**
121         * ECDSA using P-521 curve and SHA-512 hash algorithm (optional).
122         */
123        public static final JWSAlgorithm ES512 = new JWSAlgorithm("ES512", Requirement.OPTIONAL);
124
125
126        /**
127         * RSASSA-PSS using SHA-256 hash algorithm and MGF1 mask generation
128         * function with SHA-256 (optional).
129         */
130        public static final JWSAlgorithm PS256 = new JWSAlgorithm("PS256", Requirement.OPTIONAL);
131
132
133        /**
134         * RSASSA-PSS using SHA-384 hash algorithm and MGF1 mask generation
135         * function with SHA-384 (optional).
136         */
137        public static final JWSAlgorithm PS384 = new JWSAlgorithm("PS384", Requirement.OPTIONAL);
138
139
140        /**
141         * RSASSA-PSS using SHA-512 hash algorithm and MGF1 mask generation
142         * function with SHA-512 (optional).
143         */
144        public static final JWSAlgorithm PS512 = new JWSAlgorithm("PS512", Requirement.OPTIONAL);
145        
146        
147        /**
148         * EdDSA signature algorithms (optional).
149         */
150        public static final JWSAlgorithm EdDSA = new JWSAlgorithm("EdDSA", Requirement.OPTIONAL);
151
152
153        /**
154         * EdDSA signature algorithms using Ed25519 curve (optional).
155         */
156        public static final JWSAlgorithm Ed25519 = new JWSAlgorithm("Ed25519", Requirement.OPTIONAL);
157
158
159        /**
160         * EdDSA signature algorithms using Ed448 curve (optional).
161         */
162        public static final JWSAlgorithm Ed448 = new JWSAlgorithm("Ed448", Requirement.OPTIONAL);
163
164
165        /**
166         * JWS algorithm family.
167         */
168        public static final class Family extends AlgorithmFamily<JWSAlgorithm> {
169
170
171                private static final long serialVersionUID = 1L;
172
173
174                /**
175                 * HMAC using a SHA-2 hash.
176                 */
177                public static final Family HMAC_SHA = new Family(HS256, HS384, HS512);
178
179
180                /**
181                 * RSA signature (RSASSA-PKCS-v1_5 or RSASSA-PSS) using a SHA-2
182                 * hash.
183                 */
184                public static final Family RSA = new Family(RS256, RS384, RS512, PS256, PS384, PS512);
185
186
187                /**
188                 * Elliptic Curve signature (ECDSA) using a SHA-2 hash.
189                 */
190                public static final Family EC = new Family(ES256, ES256K, ES384, ES512);
191                
192                
193                /**
194                 * Edwards Curve signature (EdDSA).
195                 */
196                public static final Family ED = new Family(EdDSA, Ed25519, Ed448);
197                
198                
199                /**
200                 * Super family of all digital signature based JWS algorithms.
201                 */
202                public static final Family SIGNATURE = new Family(ArrayUtils
203                        .concat(
204                                RSA.toArray(new JWSAlgorithm[]{}),
205                                EC.toArray(new JWSAlgorithm[]{}),
206                                ED.toArray(new JWSAlgorithm[]{})
207                        )
208                );
209
210
211                /***
212                 * Creates a new JWS algorithm family.
213                 *
214                 * @param algs The JWS algorithms of the family. Must not be
215                 *             {@code null}.
216                 */
217                public Family(final JWSAlgorithm ... algs) {
218                        super(algs);
219                }
220        }
221
222
223        /**
224         * Creates a new JSON Web Signature (JWS) algorithm name.
225         *
226         * @param name The algorithm name. Must not be {@code null}.
227         * @param req  The implementation requirement, {@code null} if not 
228         *             known.
229         */
230        public JWSAlgorithm(final String name, final Requirement req) {
231
232                super(name, req);
233        }
234
235
236        /**
237         * Creates a new JSON Web Signature (JWS) algorithm name.
238         *
239         * @param name The algorithm name. Must not be {@code null}.
240         */
241        public JWSAlgorithm(final String name) {
242
243                super(name, null);
244        }
245
246
247        /**
248         * Parses a JWS algorithm from the specified string.
249         *
250         * @param s The string to parse. Must not be {@code null}.
251         *
252         * @return The JWS algorithm (matching standard algorithm constant, else
253         *         a newly created algorithm).
254         */
255        public static JWSAlgorithm parse(final String s) {
256
257                if (s.equals(HS256.getName())) {
258                        return HS256;
259                } else if (s.equals(HS384.getName())) {
260                        return HS384;
261                } else if (s.equals(HS512.getName())) {
262                        return HS512;
263                } else if (s.equals(RS256.getName())) {
264                        return RS256;
265                } else if (s.equals(RS384.getName())) {
266                        return RS384;
267                } else if (s.equals(RS512.getName())) {
268                        return RS512;
269                } else if (s.equals(ES256.getName())) {
270                        return ES256;
271                } else if (s.equals(ES256K.getName())) {
272                        return ES256K;
273                } else if (s.equals(ES384.getName())) {
274                        return ES384;
275                } else if (s.equals(ES512.getName())) {
276                        return ES512;
277                } else if (s.equals(PS256.getName())) {
278                        return PS256;
279                } else if (s.equals(PS384.getName())) {
280                        return PS384;
281                } else if (s.equals(PS512.getName())) {
282                        return PS512;
283                } else if (s.equals(EdDSA.getName())) {
284                        return EdDSA;
285                } else if (s.equals(Ed25519.getName())) {
286                        return Ed25519;
287                } else if (s.equals(Ed448.getName())) {
288                        return Ed448;
289                } else {
290                        return new JWSAlgorithm(s);
291                }
292        }
293}