001package com.nimbusds.jose;
002
003
004import com.nimbusds.jose.util.ArrayUtils;
005import net.jcip.annotations.Immutable;
006
007
008/**
009 * JSON Web Encryption (JWE) algorithm name, represents the {@code alg} header 
010 * parameter in JWE objects. This class is immutable.
011 *
012 * <p>Includes constants for the following standard JWE algorithm names:
013 *
014 * <ul>
015 *     <li>{@link #RSA1_5}
016 *     <li>{@link #RSA_OAEP RSA-OAEP}
017 *     <li>{@link #RSA_OAEP_256 RSA-OAEP-256}
018 *     <li>{@link #A128KW}
019 *     <li>{@link #A192KW}
020 *     <li>{@link #A256KW}
021 *     <li>{@link #DIR dir}
022 *     <li>{@link #ECDH_ES ECDH-ES}
023 *     <li>{@link #ECDH_ES_A128KW ESDH-ES+A128KW}
024 *     <li>{@link #ECDH_ES_A128KW ESDH-ES+A192KW}
025 *     <li>{@link #ECDH_ES_A256KW ESDH-ES+A256KW}
026 *     <li>{@link #PBES2_HS256_A128KW PBES2-HS256+A128KW}
027 *     <li>{@link #PBES2_HS384_A192KW PBES2-HS256+A192KW}
028 *     <li>{@link #PBES2_HS512_A256KW PBES2-HS256+A256KW}
029 * </ul>
030 *
031 * <p>Additional JWE algorithm names can be defined using the constructors.
032 *
033 * @author Vladimir Dzhuvinov
034 * @version 2016-08-24
035 */
036@Immutable
037public final class JWEAlgorithm extends Algorithm {
038
039
040        private static final long serialVersionUID = 1L;
041
042
043        /**
044         * RSAES-PKCS1-V1_5 (RFC 3447) (required).
045         */
046        public static final JWEAlgorithm RSA1_5 = new JWEAlgorithm("RSA1_5", Requirement.REQUIRED);
047
048
049        /**
050         * RSAES using Optimal Asymmetric Encryption Padding (OAEP) (RFC 3447),
051         * with the default parameters specified by RFC 3447 in section A.2.1
052         * (recommended).
053         */
054        public static final JWEAlgorithm RSA_OAEP = new JWEAlgorithm("RSA-OAEP", Requirement.OPTIONAL);
055
056
057        /**
058         * RSAES using Optimal Asymmetric Encryption Padding (OAEP) (RFC 3447),
059         * with the SHA-256 hash function and the MGF1 with SHA-256 mask
060         * generation function (recommended).
061         */
062        public static final JWEAlgorithm RSA_OAEP_256 = new JWEAlgorithm("RSA-OAEP-256", Requirement.OPTIONAL);
063
064
065        /**
066         * Advanced Encryption Standard (AES) Key Wrap Algorithm (RFC 3394) 
067         * using 128 bit keys (recommended).
068         */
069        public static final JWEAlgorithm A128KW = new JWEAlgorithm("A128KW", Requirement.RECOMMENDED);
070
071
072        /**
073         * Advanced Encryption Standard (AES) Key Wrap Algorithm (RFC 3394)
074         * using 192 bit keys (optional).
075         */
076        public static final JWEAlgorithm A192KW = new JWEAlgorithm("A192KW", Requirement.OPTIONAL);
077
078
079        /**
080         * Advanced Encryption Standard (AES) Key Wrap Algorithm (RFC 3394) 
081         * using 256 bit keys (recommended).
082         */
083        public static final JWEAlgorithm A256KW = new JWEAlgorithm("A256KW", Requirement.RECOMMENDED);
084
085
086        /**
087         * Direct use of a shared symmetric key as the Content Encryption Key 
088         * (CEK) for the block encryption step (rather than using the symmetric
089         * key to wrap the CEK) (recommended).
090         */
091        public static final JWEAlgorithm DIR = new JWEAlgorithm("dir", Requirement.RECOMMENDED);
092
093
094        /**
095         * Elliptic Curve Diffie-Hellman Ephemeral Static (RFC 6090) key 
096         * agreement using the Concat KDF, as defined in section 5.8.1 of
097         * NIST.800-56A, with the agreed-upon key being used directly as the 
098         * Content Encryption Key (CEK) (rather than being used to wrap the 
099         * CEK) (recommended).
100         */
101        public static final JWEAlgorithm ECDH_ES = new JWEAlgorithm("ECDH-ES", Requirement.RECOMMENDED);
102
103
104        /**
105         * Elliptic Curve Diffie-Hellman Ephemeral Static key agreement per
106         * "ECDH-ES", but where the agreed-upon key is used to wrap the Content
107         * Encryption Key (CEK) with the "A128KW" function (rather than being 
108         * used directly as the CEK) (recommended).
109         */
110        public static final JWEAlgorithm ECDH_ES_A128KW = new JWEAlgorithm("ECDH-ES+A128KW", Requirement.RECOMMENDED);
111
112
113        /**
114         * Elliptic Curve Diffie-Hellman Ephemeral Static key agreement per
115         * "ECDH-ES", but where the agreed-upon key is used to wrap the Content
116         * Encryption Key (CEK) with the "A192KW" function (rather than being
117         * used directly as the CEK) (optional).
118         */
119        public static final JWEAlgorithm ECDH_ES_A192KW = new JWEAlgorithm("ECDH-ES+A192KW", Requirement.OPTIONAL);
120
121
122        /**
123         * Elliptic Curve Diffie-Hellman Ephemeral Static key agreement per
124         * "ECDH-ES", but where the agreed-upon key is used to wrap the Content
125         * Encryption Key (CEK) with the "A256KW" function (rather than being 
126         * used directly as the CEK) (recommended).
127         */
128        public static final JWEAlgorithm ECDH_ES_A256KW = new JWEAlgorithm("ECDH-ES+A256KW", Requirement.RECOMMENDED);
129
130
131        /**
132         * AES in Galois/Counter Mode (GCM) (NIST.800-38D) 128 bit keys
133         * (optional).
134         */
135        public static final JWEAlgorithm A128GCMKW = new JWEAlgorithm("A128GCMKW", Requirement.OPTIONAL);
136
137
138        /**
139         * AES in Galois/Counter Mode (GCM) (NIST.800-38D) 192 bit keys
140         * (optional).
141         */
142        public static final JWEAlgorithm A192GCMKW = new JWEAlgorithm("A192GCMKW", Requirement.OPTIONAL);
143
144
145        /**
146         * AES in Galois/Counter Mode (GCM) (NIST.800-38D) 256 bit keys
147         * (optional).
148         */
149        public static final JWEAlgorithm A256GCMKW = new JWEAlgorithm("A256GCMKW", Requirement.OPTIONAL);
150
151
152        /**
153         * PBES2 (RFC 2898) with HMAC SHA-256 as the PRF and AES Key Wrap
154         * (RFC 3394) using 128 bit keys for the encryption scheme (optional).
155         */
156        public static final JWEAlgorithm PBES2_HS256_A128KW = new JWEAlgorithm("PBES2-HS256+A128KW", Requirement.OPTIONAL);
157
158
159        /**
160         * PBES2 (RFC 2898) with HMAC SHA-384 as the PRF and AES Key Wrap
161         * (RFC 3394) using 192 bit keys for the encryption scheme (optional).
162         */
163        public static final JWEAlgorithm PBES2_HS384_A192KW = new JWEAlgorithm("PBES2-HS384+A192KW", Requirement.OPTIONAL);
164
165
166        /**
167         * PBES2 (RFC 2898) with HMAC SHA-512 as the PRF and AES Key Wrap
168         * (RFC 3394) using 256 bit keys for the encryption scheme (optional).
169         */
170        public static final JWEAlgorithm PBES2_HS512_A256KW = new JWEAlgorithm("PBES2-HS512+A256KW", Requirement.OPTIONAL);
171
172
173        /**
174         * JWE algorithm family.
175         */
176        public static final class Family extends AlgorithmFamily<JWEAlgorithm> {
177
178
179                private static final long serialVersionUID = 1L;
180
181
182                /**
183                 * RSA key encryption.
184                 */
185                public static final Family RSA = new Family(RSA1_5, RSA_OAEP, RSA_OAEP_256);
186
187
188                /**
189                 * AES key wrap.
190                 */
191                public static final Family AES_KW = new Family(A128KW, A192KW, A256KW);
192
193
194                /**
195                 * Elliptic Curve Diffie-Hellman Ephemeral Static key
196                 * agreement.
197                 */
198                public static final Family ECDH_ES = new Family(JWEAlgorithm.ECDH_ES, ECDH_ES_A128KW, ECDH_ES_A192KW, ECDH_ES_A256KW);
199
200
201                /**
202                 * AES GCM key wrap.
203                 */
204                public static final Family AES_GCM_KW = new Family(A128GCMKW, A192GCMKW, A256GCMKW);
205
206
207                /**
208                 * Password-Based Cryptography Specification Version 2.0
209                 */
210                public static final Family PBES2 = new Family(PBES2_HS256_A128KW, PBES2_HS384_A192KW, PBES2_HS512_A256KW);
211                
212                
213                /**
214                 * Super family of all asymmetric (public / private key based)
215                 * JWE algorithms.
216                 */
217                public static final Family ASYMMETRIC = new Family(ArrayUtils.concat(
218                        RSA.toArray(new JWEAlgorithm[]{}),
219                        ECDH_ES.toArray(new JWEAlgorithm[]{})));
220                
221                
222                /**
223                 * Super family of all symmetric (shared key based) JWE
224                 * algorithms.
225                 */
226                public static final Family SYMMETRIC = new Family(ArrayUtils.concat(
227                        AES_KW.toArray(new JWEAlgorithm[]{}),
228                        AES_GCM_KW.toArray(new JWEAlgorithm[]{}),
229                        new JWEAlgorithm[]{JWEAlgorithm.DIR}));
230
231
232                /***
233                 * Creates a new JWE algorithm family.
234                 *
235                 * @param algs The JWE algorithms of the family. Must not be
236                 *             {@code null}.
237                 */
238                public Family(final JWEAlgorithm ... algs) {
239                        super(algs);
240                }
241        }
242
243
244        /**
245         * Creates a new JSON Web Encryption (JWE) algorithm.
246         *
247         * @param name The algorithm name. Must not be {@code null}.
248         * @param req  The implementation requirement, {@code null} if not 
249         *             known.
250         */
251        public JWEAlgorithm(final String name, final Requirement req) {
252
253                super(name, req);
254        }
255
256
257        /**
258         * Creates a new JSON Web Encryption (JWE) algorithm.
259         *
260         * @param name The algorithm name. Must not be {@code null}.
261         */
262        public JWEAlgorithm(final String name) {
263
264                super(name, null);
265        }
266
267
268        /**
269         * Parses a JWE algorithm from the specified string.
270         *
271         * @param s The string to parse. Must not be {@code null}.
272         *
273         * @return The JWE algorithm (matching standard algorithm constant, else
274         *         a newly created algorithm).
275         */
276        public static JWEAlgorithm parse(final String s) {
277
278                if (s.equals(RSA1_5.getName())) {
279                        return RSA1_5;
280                } else if (s.equals(RSA_OAEP.getName())) {
281                        return RSA_OAEP;
282                } else if (s.equals(RSA_OAEP_256.getName())) {
283                        return RSA_OAEP_256;
284                } else if (s.equals(A128KW.getName())) {
285                        return A128KW;
286                } else if (s.equals(A192KW.getName())) {
287                        return A192KW;
288                } else if (s.equals(A256KW.getName())) {
289                        return A256KW;
290                } else if (s.equals(DIR.getName())) {
291                        return DIR;
292                } else if (s.equals(ECDH_ES.getName())) {
293                        return ECDH_ES;
294                } else if (s.equals(ECDH_ES_A128KW.getName())) {
295                        return ECDH_ES_A128KW;
296                } else if (s.equals(ECDH_ES_A192KW.getName())) {
297                        return ECDH_ES_A192KW;
298                } else if (s.equals(ECDH_ES_A256KW.getName())) {
299                        return ECDH_ES_A256KW;
300                } else if (s.equals(A128GCMKW.getName())) {
301                        return A128GCMKW;
302                } else if (s.equals(A192GCMKW.getName())) {
303                        return A192GCMKW;
304                } else if (s.equals(A256GCMKW.getName())) {
305                        return A256GCMKW;
306                } else if (s.equals(PBES2_HS256_A128KW.getName())) {
307                        return PBES2_HS256_A128KW;
308                } else if (s.equals(PBES2_HS384_A192KW.getName())) {
309                        return PBES2_HS384_A192KW;
310                } else if (s.equals(PBES2_HS512_A256KW.getName())) {
311                        return PBES2_HS512_A256KW;
312                } else {
313                        return new JWEAlgorithm(s);
314                }
315        }
316}