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