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 * </ul>
048 *
049 * <p>Additional JWS algorithm names can be defined using the constructors.
050 *
051 * @author Vladimir Dzhuvinov
052 * @author Aleksei Doroganov
053 * @version 2018-03-28
054 */
055@Immutable
056public final class JWSAlgorithm extends Algorithm {
057
058
059        private static final long serialVersionUID = 1L;
060
061
062        /**
063         * HMAC using SHA-256 hash algorithm (required).
064         */
065        public static final JWSAlgorithm HS256 = new JWSAlgorithm("HS256", Requirement.REQUIRED);
066
067
068        /**
069         * HMAC using SHA-384 hash algorithm (optional).
070         */
071        public static final JWSAlgorithm HS384 = new JWSAlgorithm("HS384", Requirement.OPTIONAL);
072
073
074        /**
075         * HMAC using SHA-512 hash algorithm (optional).
076         */
077        public static final JWSAlgorithm HS512 = new JWSAlgorithm("HS512", Requirement.OPTIONAL);
078
079
080        /**
081         * RSASSA-PKCS-v1_5 using SHA-256 hash algorithm (recommended).
082         */
083        public static final JWSAlgorithm RS256 = new JWSAlgorithm("RS256", Requirement.RECOMMENDED);
084
085
086        /**
087         * RSASSA-PKCS-v1_5 using SHA-384 hash algorithm (optional).
088         */
089        public static final JWSAlgorithm RS384 = new JWSAlgorithm("RS384", Requirement.OPTIONAL);
090
091
092        /**
093         * RSASSA-PKCS-v1_5 using SHA-512 hash algorithm (optional).
094         */
095        public static final JWSAlgorithm RS512 = new JWSAlgorithm("RS512", Requirement.OPTIONAL);
096
097
098        /**
099         * ECDSA using P-256 (secp256r1) curve and SHA-256 hash algorithm
100         * (recommended).
101         */
102        public static final JWSAlgorithm ES256 = new JWSAlgorithm("ES256", Requirement.RECOMMENDED);
103
104        
105        /**
106         * ECDSA using P-256K (secp256k1) curve and SHA-256 hash algorithm
107         * (optional).
108         */
109        public static final JWSAlgorithm ES256K = new JWSAlgorithm("ES256K", Requirement.OPTIONAL);
110
111
112        /**
113         * ECDSA using P-384 curve and SHA-384 hash algorithm (optional).
114         */
115        public static final JWSAlgorithm ES384 = new JWSAlgorithm("ES384", Requirement.OPTIONAL);
116
117
118        /**
119         * ECDSA using P-521 curve and SHA-512 hash algorithm (optional).
120         */
121        public static final JWSAlgorithm ES512 = new JWSAlgorithm("ES512", Requirement.OPTIONAL);
122
123
124        /**
125         * RSASSA-PSS using SHA-256 hash algorithm and MGF1 mask generation
126         * function with SHA-256 (optional).
127         */
128        public static final JWSAlgorithm PS256 = new JWSAlgorithm("PS256", Requirement.OPTIONAL);
129
130
131        /**
132         * RSASSA-PSS using SHA-384 hash algorithm and MGF1 mask generation
133         * function with SHA-384 (optional).
134         */
135        public static final JWSAlgorithm PS384 = new JWSAlgorithm("PS384", Requirement.OPTIONAL);
136
137
138        /**
139         * RSASSA-PSS using SHA-512 hash algorithm and MGF1 mask generation
140         * function with SHA-512 (optional).
141         */
142        public static final JWSAlgorithm PS512 = new JWSAlgorithm("PS512", Requirement.OPTIONAL);
143        
144        
145        /**
146         * EdDSA signature algorithms (optional).
147         */
148        public static final JWSAlgorithm EdDSA = new JWSAlgorithm("EdDSA", Requirement.OPTIONAL);
149
150
151        /**
152         * JWS algorithm family.
153         */
154        public static final class Family extends AlgorithmFamily<JWSAlgorithm> {
155
156
157                private static final long serialVersionUID = 1L;
158
159
160                /**
161                 * HMAC using a SHA-2 hash.
162                 */
163                public static final Family HMAC_SHA = new Family(HS256, HS384, HS512);
164
165
166                /**
167                 * RSA signature (RSASSA-PKCS-v1_5 or RSASSA-PSS) using a SHA-2
168                 * hash.
169                 */
170                public static final Family RSA = new Family(RS256, RS384, RS512, PS256, PS384, PS512);
171
172
173                /**
174                 * Elliptic Curve signature (ECDSA) using a SHA-2 hash.
175                 */
176                public static final Family EC = new Family(ES256, ES256K, ES384, ES512);
177                
178                
179                /**
180                 * Edwards Curve signature (EdDSA).
181                 */
182                public static final Family ED = new Family(EdDSA);
183                
184                
185                /**
186                 * Super family of all digital signature based JWS algorithms.
187                 */
188                public static final Family SIGNATURE = new Family(ArrayUtils
189                        .concat(
190                                RSA.toArray(new JWSAlgorithm[]{}),
191                                EC.toArray(new JWSAlgorithm[]{}),
192                                ED.toArray(new JWSAlgorithm[]{})
193                        )
194                );
195
196
197                /***
198                 * Creates a new JWS algorithm family.
199                 *
200                 * @param algs The JWS algorithms of the family. Must not be
201                 *             {@code null}.
202                 */
203                public Family(final JWSAlgorithm ... algs) {
204                        super(algs);
205                }
206        }
207
208
209        /**
210         * Creates a new JSON Web Signature (JWS) algorithm name.
211         *
212         * @param name The algorithm name. Must not be {@code null}.
213         * @param req  The implementation requirement, {@code null} if not 
214         *             known.
215         */
216        public JWSAlgorithm(final String name, final Requirement req) {
217
218                super(name, req);
219        }
220
221
222        /**
223         * Creates a new JSON Web Signature (JWS) algorithm name.
224         *
225         * @param name The algorithm name. Must not be {@code null}.
226         */
227        public JWSAlgorithm(final String name) {
228
229                super(name, null);
230        }
231
232
233        /**
234         * Parses a JWS algorithm from the specified string.
235         *
236         * @param s The string to parse. Must not be {@code null}.
237         *
238         * @return The JWS algorithm (matching standard algorithm constant, else
239         *         a newly created algorithm).
240         */
241        public static JWSAlgorithm parse(final String s) {
242
243                if (s.equals(HS256.getName())) {
244                        return HS256;
245                } else if (s.equals(HS384.getName())) {
246                        return HS384;
247                } else if (s.equals(HS512.getName())) {
248                        return HS512;
249                } else if (s.equals(RS256.getName())) {
250                        return RS256;
251                } else if (s.equals(RS384.getName())) {
252                        return RS384;
253                } else if (s.equals(RS512.getName())) {
254                        return RS512;
255                } else if (s.equals(ES256.getName())) {
256                        return ES256;
257                } else if (s.equals(ES256K.getName())) {
258                        return ES256K;
259                } else if (s.equals(ES384.getName())) {
260                        return ES384;
261                } else if (s.equals(ES512.getName())) {
262                        return ES512;
263                } else if (s.equals(PS256.getName())) {
264                        return PS256;
265                } else if (s.equals(PS384.getName())) {
266                        return PS384;
267                } else if (s.equals(PS512.getName())) {
268                        return PS512;
269                } else if (s.equals(EdDSA.getName())) {
270                        return EdDSA;
271                } else {
272                        return new JWSAlgorithm(s);
273                }
274        }
275}