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