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