001    package com.nimbusds.jose;
002    
003    
004    import 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 #A256CBC_HS512 A256CBC+HS512}
016     *     <li>{@link #A128GCM}
017     *     <li>{@link #A256GCM}
018     * </ul>
019     *
020     * <p>Additional encryption method names can be defined using the constructors.
021     *
022     * @author Vladimir Dzhuvinov
023     * @version $version$ (2013-04-15)
024     */
025    @Immutable
026    public final class EncryptionMethod extends Algorithm {
027    
028    
029            /**
030             * The Content Master Key (CMK) bit length, zero if not specified.
031             */
032            private final int cmkBitLength;
033    
034    
035            /**
036             * Composite Authenticated Encryption algorithm using Advanced 
037             * Encryption Standard (AES) in Cipher Block Chaining (CBC) mode with 
038             * PKCS #5 padding (NIST.800-38A) with an integrity calculation using 
039             * HMAC SHA-256, using a 256 bit CMK (and a 128 bit CEK) (required).
040             */
041            public static final EncryptionMethod A128CBC_HS256 = 
042                    new EncryptionMethod("A128CBC+HS256", Requirement.REQUIRED, 256);
043    
044    
045            /**
046             * Composite Authenticated Encryption algorithm using Advanced 
047             * Encryption Standard (AES) in Cipher Block Chaining (CBC) mode with 
048             * PKCS #5 padding (NIST.800-38A) with an integrity calculation using 
049             * HMAC SHA-512, using a 512 bit CMK (and a 256 bit CEK) (required).
050             */
051            public static final EncryptionMethod A256CBC_HS512 = 
052                    new EncryptionMethod("A256CBC+HS512", Requirement.REQUIRED, 512);
053    
054    
055            /**
056             * Advanced Encryption Standard (AES) in Galois/Counter Mode (GCM)
057             * (NIST.800-38D) using 128 bit keys (recommended).
058             */
059            public static final EncryptionMethod A128GCM = 
060                    new EncryptionMethod("A128GCM", Requirement.RECOMMENDED, 128);
061    
062    
063            /**
064             * Advanced Encryption Standard (AES) in Galois/Counter Mode (GCM)
065             * (NIST.800-38D) using 256 bit keys (recommended).
066             */
067            public static final EncryptionMethod A256GCM = 
068                    new EncryptionMethod("A256GCM", Requirement.RECOMMENDED, 256);
069    
070    
071            /**
072             * Creates a new encryption method.
073             *
074             * @param name         The encryption method name. Must not be 
075             *                     {@code null}.
076             * @param req          The implementation requirement, {@code null} if 
077             *                     not known.
078             * @param cmkBitLength The Content Master Key (CMK) bit length, zero if
079             *                     not specified.
080             */
081            public EncryptionMethod(final String name, final Requirement req, final int cmkBitLength) {
082    
083                    super(name, req);
084    
085                    this.cmkBitLength = cmkBitLength;
086            }
087    
088    
089            /**
090             * Creates a new encryption method.
091             *
092             * @param name The encryption method name. Must not be {@code null}.
093             * @param req  The implementation requirement, {@code null} if not 
094             *             known.
095             */
096            public EncryptionMethod(final String name, final Requirement req) {
097    
098                    this(name, req, 0);
099            }
100    
101    
102            /**
103             * Creates a new encryption method.
104             *
105             * @param name The encryption method name. Must not be {@code null}.
106             */
107            public EncryptionMethod(final String name) {
108    
109                    this(name, null, 0);
110            }
111    
112    
113            /**
114             * Gets the length of the associated Content Master Key (CMK) for
115             * encryption.
116             *
117             * @return The Content Master Key (CMK) bit length, zero if not 
118             *         specified.
119             */
120            public int cmkBitLength() {
121    
122                    return cmkBitLength;
123            }
124    
125    
126            /**
127             * Parses an encryption method from the specified string.
128             *
129             * @param s The string to parse. Must not be {@code null}.
130             *
131             * @return The encryption method  (matching standard algorithm constant,
132             *         else a newly created algorithm).
133             */
134            public static EncryptionMethod parse(final String s) {
135    
136                    if (s.equals(A128CBC_HS256.getName())) {
137    
138                            return A128CBC_HS256;
139    
140                    } else if (s.equals(A256CBC_HS512.getName())) {
141    
142                            return A256CBC_HS512;
143    
144                    } else if (s.equals(A128GCM.getName())) {
145    
146                            return A128GCM;
147    
148                    } else if (s.equals(A256GCM.getName())) {
149    
150                            return A256GCM;
151    
152                    } else {
153    
154                            return new EncryptionMethod(s);
155                    }
156            }
157    }