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 net.jcip.annotations.Immutable;
022
023
024/**
025 * Encryption method name, represents the {@code enc} header parameter in JSON
026 * Web Encryption (JWE) objects. This class is immutable.
027 *
028 * <p>Includes constants for the following encryption method names:
029 *
030 * <ul>
031 *     <li>{@link #A128CBC_HS256 A128CBC-HS256}
032 *     <li>{@link #A192CBC_HS384 A192CBC-HS384}
033 *     <li>{@link #A256CBC_HS512 A256CBC-HS512}
034 *     <li>{@link #A128GCM}
035 *     <li>{@link #A192GCM}
036 *     <li>{@link #A256GCM}
037 *     <li>{@link #XC20P}
038 *     <li>{@link #A128CBC_HS256_DEPRECATED A128CBC+HS256 (deprecated)}
039 *     <li>{@link #A256CBC_HS512_DEPRECATED A256CBC+HS512 (deprecated)}
040 * </ul>
041 *
042 * <p>Additional encryption method names can be defined using the constructors.
043 *
044 * @author Vladimir Dzhuvinov
045 * @version 2021-08-22
046 */
047@Immutable
048public final class EncryptionMethod extends Algorithm {
049
050
051        private static final long serialVersionUID = 1L;
052
053
054        /**
055         * The Content Encryption Key (CEK) bit length, zero if not specified.
056         */
057        private final int cekBitLength;
058
059
060        /**
061         * AES_128_CBC_HMAC_SHA_256 authenticated encryption using a 256 bit 
062         * key (required).
063         */
064        public static final EncryptionMethod A128CBC_HS256 = 
065                new EncryptionMethod("A128CBC-HS256", Requirement.REQUIRED, 256);
066
067
068        /**
069         * AES_192_CBC_HMAC_SHA_384 authenticated encryption using a 384 bit
070         * key (optional).
071         */
072        public static final EncryptionMethod A192CBC_HS384 =
073                new EncryptionMethod("A192CBC-HS384", Requirement.OPTIONAL, 384);
074
075
076        /**
077         * AES_256_CBC_HMAC_SHA_512 authenticated encryption using a 512 bit
078         * key (required).
079         */
080        public static final EncryptionMethod A256CBC_HS512 = 
081                new EncryptionMethod("A256CBC-HS512", Requirement.REQUIRED, 512);
082
083
084        /**
085         * AES_128_CBC_HMAC_SHA_256 authenticated encryption using a 256 bit
086         * key, deprecated in JOSE draft suite version 09.
087         */
088        public static final EncryptionMethod A128CBC_HS256_DEPRECATED =
089                new EncryptionMethod("A128CBC+HS256", Requirement.OPTIONAL, 256);
090
091
092        /**
093         * AES_256_CBC_HMAC_SHA_512 authenticated encryption using a 512 bit
094         * key, deprecated in JOSE draft suite version 09.
095         */
096        public static final EncryptionMethod A256CBC_HS512_DEPRECATED =
097                new EncryptionMethod("A256CBC+HS512", Requirement.OPTIONAL, 512);
098
099
100        /**
101         * AES in Galois/Counter Mode (GCM) (NIST.800-38D) using a 128 bit key 
102         * (recommended).
103         */
104        public static final EncryptionMethod A128GCM = 
105                new EncryptionMethod("A128GCM", Requirement.RECOMMENDED, 128);
106
107
108        /**
109         * AES in Galois/Counter Mode (GCM) (NIST.800-38D) using a 192 bit key
110         * (optional).
111         */
112        public static final EncryptionMethod A192GCM =
113                new EncryptionMethod("A192GCM", Requirement.OPTIONAL, 192);
114
115
116        /**
117         * AES in Galois/Counter Mode (GCM) (NIST.800-38D) using a 256 bit key 
118         * (recommended).
119         */
120        public static final EncryptionMethod A256GCM = 
121                new EncryptionMethod("A256GCM", Requirement.RECOMMENDED, 256);
122
123
124        /**
125         * XChaCha: eXtended-nonce ChaCha and AEAD_XChaCha20_Poly1305
126         * (optional)
127         */
128        public static final EncryptionMethod XC20P =
129                new EncryptionMethod("XC20P", Requirement.OPTIONAL, 256);
130
131
132        /**
133         * Encryption method family.
134         */
135        public static final class Family extends AlgorithmFamily<EncryptionMethod> {
136
137
138                private static final long serialVersionUID = 1L;
139
140
141                /**
142                 * AES/CBC/HMAC with SHA-2.
143                 */
144                public static final Family AES_CBC_HMAC_SHA = new Family(A128CBC_HS256, A192CBC_HS384, A256CBC_HS512);
145
146
147                /**
148                 * AES/GCM.
149                 */
150                public static final Family AES_GCM = new Family(A128GCM, A192GCM, A256GCM);
151
152
153                /***
154                 * Creates a new encryption method family.
155                 *
156                 * @param encs The encryption methods of the family. Must not
157                 *             be {@code null}.
158                 */
159                public Family(final EncryptionMethod ... encs) {
160                        super(encs);
161                }
162        }
163
164
165        /**
166         * Creates a new encryption method.
167         *
168         * @param name         The encryption method name. Must not be 
169         *                     {@code null}.
170         * @param req          The implementation requirement, {@code null} if 
171         *                     not known.
172         * @param cekBitLength The Content Encryption Key (CEK) bit length, 
173         *                     zero if not specified.
174         */
175        public EncryptionMethod(final String name, final Requirement req, final int cekBitLength) {
176
177                super(name, req);
178
179                this.cekBitLength = cekBitLength;
180        }
181
182
183        /**
184         * Creates a new encryption method. The Content Encryption Key (CEK)
185         * bit length is not specified.
186         *
187         * @param name The encryption method name. Must not be {@code null}.
188         * @param req  The implementation requirement, {@code null} if not 
189         *             known.
190         */
191        public EncryptionMethod(final String name, final Requirement req) {
192
193                this(name, req, 0);
194        }
195
196
197        /**
198         * Creates a new encryption method. The implementation requirement and
199         * the Content Encryption Key (CEK) bit length are not specified.
200         *
201         * @param name The encryption method name. Must not be {@code null}.
202         */
203        public EncryptionMethod(final String name) {
204
205                this(name, null, 0);
206        }
207
208
209        /**
210         * Gets the length of the associated Content Encryption Key (CEK).
211         *
212         * @return The Content Encryption Key (CEK) bit length, zero if not 
213         *         specified.
214         */
215        public int cekBitLength() {
216
217                return cekBitLength;
218        }
219
220
221        /**
222         * Parses an encryption method from the specified string.
223         *
224         * @param s The string to parse. Must not be {@code null}.
225         *
226         * @return The encryption method  (matching standard algorithm
227         *         constant, else a newly created algorithm).
228         */
229        public static EncryptionMethod parse(final String s) {
230
231                if (s.equals(A128CBC_HS256.getName())) {
232
233                        return A128CBC_HS256;
234
235                } else if (s.equals(A192CBC_HS384.getName())) {
236
237                        return A192CBC_HS384;
238
239                } else if (s.equals(A256CBC_HS512.getName())) {
240
241                        return A256CBC_HS512;
242
243                } else if (s.equals(A128GCM.getName())) {
244
245                        return A128GCM;
246
247                } else if (s.equals(A192GCM.getName())) {
248
249                        return A192GCM;
250
251                } else if (s.equals(A256GCM.getName())) {
252
253                        return A256GCM;
254
255                } else if (s.equals(A128CBC_HS256_DEPRECATED.getName())) {
256
257                        return A128CBC_HS256_DEPRECATED;
258
259                } else if (s.equals(A256CBC_HS512_DEPRECATED.getName())) {
260
261                        return A256CBC_HS512_DEPRECATED;
262
263                } else if (s.equals(XC20P.getName())){
264
265                        return XC20P;
266                } else {
267
268                        return new EncryptionMethod(s);
269                }
270        }
271}