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 Encryption (JWE) algorithm name, represents the {@code alg} header 
027 * parameter in JWE objects. This class is immutable.
028 *
029 * <p>Includes constants for the following JWE algorithm names:
030 *
031 * <ul>
032 *     <li>{@link #RSA_OAEP_256 RSA-OAEP-256}
033 *     <li>{@link #RSA_OAEP_512 RSA-OAEP-512}
034 *     <li>{@link #RSA_OAEP RSA-OAEP} (deprecated)
035 *     <li>{@link #RSA1_5} (deprecated)
036 *     <li>{@link #A128KW}
037 *     <li>{@link #A192KW}
038 *     <li>{@link #A256KW}
039 *     <li>{@link #DIR dir}
040 *     <li>{@link #ECDH_ES ECDH-ES}
041 *     <li>{@link #ECDH_ES_A128KW ESDH-ES+A128KW}
042 *     <li>{@link #ECDH_ES_A128KW ESDH-ES+A192KW}
043 *     <li>{@link #ECDH_ES_A256KW ESDH-ES+A256KW}
044 *     <li>{@link #ECDH_1PU ECDH-1PU}
045 *     <li>{@link #ECDH_1PU_A128KW ESDH-1PU+A128KW}
046 *     <li>{@link #ECDH_1PU_A128KW ESDH-1PU+A192KW}
047 *     <li>{@link #ECDH_1PU_A256KW ESDH-1PU+A256KW}
048 *     <li>{@link #PBES2_HS256_A128KW PBES2-HS256+A128KW}
049 *     <li>{@link #PBES2_HS384_A192KW PBES2-HS256+A192KW}
050 *     <li>{@link #PBES2_HS512_A256KW PBES2-HS256+A256KW}
051 * </ul>
052 *
053 * <p>Additional JWE algorithm names can be defined using the constructors.
054 *
055 * @author Vladimir Dzhuvinov
056 * @version 2021-09-24
057 */
058@Immutable
059public final class JWEAlgorithm extends Algorithm {
060
061
062        private static final long serialVersionUID = 1L;
063
064
065        /**
066         * RSAES-PKCS1-V1_5 (RFC 3447). Use of this RSA encryption algorithm is
067         * no longer recommended, use {@link #RSA_OAEP_256} instead.
068         */
069        @Deprecated
070        public static final JWEAlgorithm RSA1_5 = new JWEAlgorithm("RSA1_5", Requirement.REQUIRED);
071
072
073        /**
074         * RSAES using Optimal Asymmetric Encryption Padding (OAEP) (RFC 3447),
075         * with the default parameters specified by RFC 3447 in section A.2.1.
076         * Use of this encryption algorithm is no longer recommended, use
077         * {@link #RSA_OAEP_256} instead.
078         */
079        @Deprecated
080        public static final JWEAlgorithm RSA_OAEP = new JWEAlgorithm("RSA-OAEP", Requirement.OPTIONAL);
081
082
083        /**
084         * RSAES using Optimal Asymmetric Encryption Padding (OAEP) (RFC 3447),
085         * with the SHA-256 hash function and the MGF1 with SHA-256 mask
086         * generation function.
087         */
088        public static final JWEAlgorithm RSA_OAEP_256 = new JWEAlgorithm("RSA-OAEP-256", Requirement.OPTIONAL);
089        
090        
091        /**
092         * RSAES using Optimal Asymmetric Encryption Padding (OAEP) (RFC 3447),
093         * with the SHA-512 hash function and the MGF1 with SHA-384 mask
094         * generation function.
095         */
096        public static final JWEAlgorithm RSA_OAEP_384 = new JWEAlgorithm("RSA-OAEP-384", Requirement.OPTIONAL);
097        
098        
099        /**
100         * RSAES using Optimal Asymmetric Encryption Padding (OAEP) (RFC 3447),
101         * with the SHA-512 hash function and the MGF1 with SHA-512 mask
102         * generation function.
103         */
104        public static final JWEAlgorithm RSA_OAEP_512 = new JWEAlgorithm("RSA-OAEP-512", Requirement.OPTIONAL);
105
106
107        /**
108         * Advanced Encryption Standard (AES) Key Wrap Algorithm (RFC 3394) 
109         * using 128 bit keys.
110         */
111        public static final JWEAlgorithm A128KW = new JWEAlgorithm("A128KW", Requirement.RECOMMENDED);
112
113
114        /**
115         * Advanced Encryption Standard (AES) Key Wrap Algorithm (RFC 3394)
116         * using 192 bit keys.
117         */
118        public static final JWEAlgorithm A192KW = new JWEAlgorithm("A192KW", Requirement.OPTIONAL);
119
120
121        /**
122         * Advanced Encryption Standard (AES) Key Wrap Algorithm (RFC 3394) 
123         * using 256 bit keys.
124         */
125        public static final JWEAlgorithm A256KW = new JWEAlgorithm("A256KW", Requirement.RECOMMENDED);
126
127
128        /**
129         * Direct use of a shared symmetric key as the Content Encryption Key 
130         * (CEK) for the block encryption step (rather than using the symmetric
131         * key to wrap the CEK).
132         */
133        public static final JWEAlgorithm DIR = new JWEAlgorithm("dir", Requirement.RECOMMENDED);
134
135
136        /**
137         * Elliptic Curve Diffie-Hellman Ephemeral Static (RFC 6090) key 
138         * agreement using the Concat KDF, as defined in section 5.8.1 of
139         * NIST.800-56A, with the agreed-upon key being used directly as the 
140         * Content Encryption Key (CEK) (rather than being used to wrap the 
141         * CEK).
142         */
143        public static final JWEAlgorithm ECDH_ES = new JWEAlgorithm("ECDH-ES", Requirement.RECOMMENDED);
144
145
146        /**
147         * Elliptic Curve Diffie-Hellman Ephemeral Static key agreement per
148         * "ECDH-ES", but where the agreed-upon key is used to wrap the Content
149         * Encryption Key (CEK) with the "A128KW" function (rather than being 
150         * used directly as the CEK).
151         */
152        public static final JWEAlgorithm ECDH_ES_A128KW = new JWEAlgorithm("ECDH-ES+A128KW", Requirement.RECOMMENDED);
153
154
155        /**
156         * Elliptic Curve Diffie-Hellman Ephemeral Static key agreement per
157         * "ECDH-ES", but where the agreed-upon key is used to wrap the Content
158         * Encryption Key (CEK) with the "A192KW" function (rather than being
159         * used directly as the CEK).
160         */
161        public static final JWEAlgorithm ECDH_ES_A192KW = new JWEAlgorithm("ECDH-ES+A192KW", Requirement.OPTIONAL);
162
163
164        /**
165         * Elliptic Curve Diffie-Hellman Ephemeral Static key agreement per
166         * "ECDH-ES", but where the agreed-upon key is used to wrap the Content
167         * Encryption Key (CEK) with the "A256KW" function (rather than being 
168         * used directly as the CEK).
169         */
170        public static final JWEAlgorithm ECDH_ES_A256KW = new JWEAlgorithm("ECDH-ES+A256KW", Requirement.RECOMMENDED);
171
172
173        /**
174         * Elliptic Curve Diffie-Hellman One-Pass Unified Model key
175         * agreement using the Concat KDF, as defined in section 5.8.1 of
176         * NIST.800-56A, with the agreed-upon key being used directly as the
177         * Content Encryption Key (CEK) (rather than being used to wrap the
178         * CEK).
179         */
180        public static final JWEAlgorithm ECDH_1PU = new JWEAlgorithm("ECDH-1PU", Requirement.OPTIONAL);
181
182
183        /**
184         * Elliptic Curve Diffie-Hellman One-Pass Unified Model key agreement
185         * per "ECDH-1PU", but where the agreed-upon key is used to wrap the
186         * Content Encryption Key (CEK) with the "A128KW" function (rather than
187         * being used directly as the CEK).
188         */
189        public static final JWEAlgorithm ECDH_1PU_A128KW = new JWEAlgorithm("ECDH-1PU+A128KW", Requirement.OPTIONAL);
190
191
192        /**
193         * Elliptic Curve Diffie-Hellman One-Pass Unified Model key agreement
194         * per "ECDH-1PU", but where the agreed-upon key is used to wrap the
195         * Content Encryption Key (CEK) with the "A192KW" function (rather than
196         * being used directly as the CEK).
197         */
198        public static final JWEAlgorithm ECDH_1PU_A192KW = new JWEAlgorithm("ECDH-1PU+A192KW", Requirement.OPTIONAL);
199
200
201        /**
202         * Elliptic Curve Diffie-Hellman One-Pass Unified Model key agreement
203         * per "ECDH-1PU", but where the agreed-upon key is used to wrap the
204         * Content Encryption Key (CEK) with the "A256KW" function (rather than
205         * being used directly as the CEK).
206         */
207        public static final JWEAlgorithm ECDH_1PU_A256KW = new JWEAlgorithm("ECDH-1PU+A256KW", Requirement.OPTIONAL);
208
209        
210        /**
211         * AES in Galois/Counter Mode (GCM) (NIST.800-38D) 128 bit keys.
212         */
213        public static final JWEAlgorithm A128GCMKW = new JWEAlgorithm("A128GCMKW", Requirement.OPTIONAL);
214
215
216        /**
217         * AES in Galois/Counter Mode (GCM) (NIST.800-38D) 192 bit keys.
218         */
219        public static final JWEAlgorithm A192GCMKW = new JWEAlgorithm("A192GCMKW", Requirement.OPTIONAL);
220
221
222        /**
223         * AES in Galois/Counter Mode (GCM) (NIST.800-38D) 256 bit keys.
224         */
225        public static final JWEAlgorithm A256GCMKW = new JWEAlgorithm("A256GCMKW", Requirement.OPTIONAL);
226
227
228        /**
229         * PBES2 (RFC 2898) with HMAC SHA-256 as the PRF and AES Key Wrap
230         * (RFC 3394) using 128 bit keys for the encryption scheme.
231         */
232        public static final JWEAlgorithm PBES2_HS256_A128KW = new JWEAlgorithm("PBES2-HS256+A128KW", Requirement.OPTIONAL);
233
234
235        /**
236         * PBES2 (RFC 2898) with HMAC SHA-384 as the PRF and AES Key Wrap
237         * (RFC 3394) using 192 bit keys for the encryption scheme.
238         */
239        public static final JWEAlgorithm PBES2_HS384_A192KW = new JWEAlgorithm("PBES2-HS384+A192KW", Requirement.OPTIONAL);
240
241
242        /**
243         * PBES2 (RFC 2898) with HMAC SHA-512 as the PRF and AES Key Wrap
244         * (RFC 3394) using 256 bit keys for the encryption scheme.
245         */
246        public static final JWEAlgorithm PBES2_HS512_A256KW = new JWEAlgorithm("PBES2-HS512+A256KW", Requirement.OPTIONAL);
247
248
249        /**
250         * JWE algorithm family.
251         */
252        public static final class Family extends AlgorithmFamily<JWEAlgorithm> {
253
254
255                private static final long serialVersionUID = 1L;
256
257
258                /**
259                 * RSA key encryption.
260                 */
261                public static final Family RSA = new Family(RSA1_5, RSA_OAEP, RSA_OAEP_256, RSA_OAEP_384, RSA_OAEP_512);
262
263
264                /**
265                 * AES key wrap.
266                 */
267                public static final Family AES_KW = new Family(A128KW, A192KW, A256KW);
268
269
270                /**
271                 * Elliptic Curve Diffie-Hellman Ephemeral Static key
272                 * agreement.
273                 */
274                public static final Family ECDH_ES = new Family(JWEAlgorithm.ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW);
275
276                
277                /**
278                 * Public key authenticated encryption with ECDH-1PU.
279                 */
280                public static final Family ECDH_1PU = new Family(JWEAlgorithm.ECDH_1PU, ECDH_1PU_A128KW, ECDH_1PU_A192KW, ECDH_1PU_A256KW);
281
282
283                /**
284                 * AES GCM key wrap.
285                 */
286                public static final Family AES_GCM_KW = new Family(A128GCMKW, A192GCMKW, A256GCMKW);
287
288
289                /**
290                 * Password-Based Cryptography Specification Version 2.0
291                 */
292                public static final Family PBES2 = new Family(PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW);
293                
294                
295                /**
296                 * Super family of all asymmetric (public / private key based)
297                 * JWE algorithms.
298                 */
299                public static final Family ASYMMETRIC = new Family(ArrayUtils.concat(
300                        RSA.toArray(new JWEAlgorithm[]{}),
301                        ECDH_ES.toArray(new JWEAlgorithm[]{})));
302                
303                
304                /**
305                 * Super family of all symmetric (shared key based) JWE
306                 * algorithms.
307                 */
308                public static final Family SYMMETRIC = new Family(ArrayUtils.concat(
309                        AES_KW.toArray(new JWEAlgorithm[]{}),
310                        AES_GCM_KW.toArray(new JWEAlgorithm[]{}),
311                        new JWEAlgorithm[]{JWEAlgorithm.DIR}));
312
313
314                /***
315                 * Creates a new JWE algorithm family.
316                 *
317                 * @param algs The JWE algorithms of the family. Must not be
318                 *             {@code null}.
319                 */
320                public Family(final JWEAlgorithm ... algs) {
321                        super(algs);
322                }
323        }
324
325
326        /**
327         * Creates a new JSON Web Encryption (JWE) algorithm.
328         *
329         * @param name The algorithm name. Must not be {@code null}.
330         * @param req  The implementation requirement, {@code null} if not 
331         *             known.
332         */
333        public JWEAlgorithm(final String name, final Requirement req) {
334
335                super(name, req);
336        }
337
338
339        /**
340         * Creates a new JSON Web Encryption (JWE) algorithm.
341         *
342         * @param name The algorithm name. Must not be {@code null}.
343         */
344        public JWEAlgorithm(final String name) {
345
346                super(name, null);
347        }
348
349
350        /**
351         * Parses a JWE algorithm from the specified string.
352         *
353         * @param s The string to parse. Must not be {@code null}.
354         *
355         * @return The JWE algorithm (matching standard algorithm constant, else
356         *         a newly created algorithm).
357         */
358        public static JWEAlgorithm parse(final String s) {
359
360                if (s.equals(RSA1_5.getName())) {
361                        return RSA1_5;
362                } else if (s.equals(RSA_OAEP.getName())) {
363                        return RSA_OAEP;
364                } else if (s.equals(RSA_OAEP_256.getName())) {
365                        return RSA_OAEP_256;
366                } else if (s.equals(RSA_OAEP_384.getName())) {
367                        return RSA_OAEP_384;
368                } else if (s.equals(RSA_OAEP_512.getName())) {
369                        return RSA_OAEP_512;
370                } else if (s.equals(A128KW.getName())) {
371                        return A128KW;
372                } else if (s.equals(A192KW.getName())) {
373                        return A192KW;
374                } else if (s.equals(A256KW.getName())) {
375                        return A256KW;
376                } else if (s.equals(DIR.getName())) {
377                        return DIR;
378                } else if (s.equals(ECDH_ES.getName())) {
379                        return ECDH_ES;
380                } else if (s.equals(ECDH_ES_A128KW.getName())) {
381                        return ECDH_ES_A128KW;
382                } else if (s.equals(ECDH_ES_A192KW.getName())) {
383                        return ECDH_ES_A192KW;
384                } else if (s.equals(ECDH_ES_A256KW.getName())) {
385                        return ECDH_ES_A256KW;
386                } else if (s.equals(ECDH_1PU.getName())) {
387                        return ECDH_1PU;
388                } else if (s.equals(ECDH_1PU_A128KW.getName())) {
389                        return ECDH_1PU_A128KW;
390                } else if (s.equals(ECDH_1PU_A192KW.getName())) {
391                        return ECDH_1PU_A192KW;
392                } else if (s.equals(ECDH_1PU_A256KW.getName())) {
393                        return ECDH_1PU_A256KW;
394                } else if (s.equals(A128GCMKW.getName())) {
395                        return A128GCMKW;
396                } else if (s.equals(A192GCMKW.getName())) {
397                        return A192GCMKW;
398                } else if (s.equals(A256GCMKW.getName())) {
399                        return A256GCMKW;
400                } else if (s.equals(PBES2_HS256_A128KW.getName())) {
401                        return PBES2_HS256_A128KW;
402                } else if (s.equals(PBES2_HS384_A192KW.getName())) {
403                        return PBES2_HS384_A192KW;
404                } else if (s.equals(PBES2_HS512_A256KW.getName())) {
405                        return PBES2_HS512_A256KW;
406                } else {
407                        return new JWEAlgorithm(s);
408                }
409        }
410}