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