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