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