001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2013-2016 ForgeRock AS.
015 */
016
017package org.forgerock.json.jose.jwe;
018
019import java.util.Locale;
020
021import org.forgerock.json.jose.exceptions.JweException;
022
023/**
024 * An Enum of the possible encryption methods that can be used when encrypting a JWT.
025 * <p>
026 * @see <a href="http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-11#section-4.2">
027 *     JWE Encryption Methods</a>
028 *
029 * @since 2.0.0
030 */
031public enum EncryptionMethod {
032
033    /**
034     * AES encryption in CBC mode with PKCS5 Padding and a 128 bit length, AES encryption for CEK, HMAC using SHA-256
035     * hash algorithm for authentication tag.
036     */
037    A128CBC_HS256("AES_128_CBC_HMAC_SHA_256", "AES/CBC/PKCS5Padding", "HMACSHA256", "AES", 16, 256),
038    /**
039     * AES encryption in CBC mode with PKCS5 Padding and a 192 bit length, AES encryption for CEK, HMAC using SHA-384
040     * hash algorithm for the authentication tag.
041     */
042    A192CBC_HS384("AES_192_CBC_HMAC_SHA_384", "AES/CBC/PKCS5Padding", "HMACSHA384", "AES", 24, 384),
043    /**
044     * AES encryption in CBC mode with PKCS5 Padding and a 256 bit length, AES encryption for CEK, HMAC using SHA-256
045     * hash algorithm for authentication tag.
046     */
047    A256CBC_HS512("AES_256_CBC_HMAC_SHA_512", "AES/CBC/PKCS5Padding", "HMACSHA512", "AES", 32, 512),
048    /**
049     * AES encryption in Galois Counter Mode (GCM) with a 128 bit key length.
050     */
051    A128GCM("AES_128_GCM", "AES/GCM/NoPadding", null, "AES", 16, 128),
052    /**
053     * AES encryption in Galois Counter Mode (GCM) with a 192 bit key length.
054     */
055    A192GCM("AES_192_GCM", "AES/GCM/NoPadding", null, "AES", 24, 192),
056    /**
057     * AES encryption in Galois Counter Mode (GCM) with a 256 bit key length.
058     */
059    A256GCM("AES_256_GCM", "AES/GCM/NoPadding", null, "AES", 32, 256);
060
061    private final String name;
062    private final String transformation;
063    private final String macAlgorithm;
064    private final String encryptionAlgorithm;
065    private final int keyOffset;
066    private final int keySize;
067
068    /**
069     * Constructs a new EncryptionMethod with the given cryptographic parameters.
070     *
071     * @param name The full name of the encryption algorithm.
072     * @param transformation The Java Cryptographic algorithm name for the algorithm that will be used to encrypt the
073     *                       plaintext.
074     * @param macAlgorithm The Java Cryptographic algorithm name for the algorithm that will generate the MAC key.
075     * @param encryptionAlgorithm The Java Cryptographic algorithm name for the algorithm that will create the Content
076     *                            Encryption Key (CEK).
077     * @param keyOffset The number of octets in each of the CEK and MAC key.
078     * @param keySize The bit length of the Content Encryption Key (CEK).
079     */
080    EncryptionMethod(String name, String transformation, String macAlgorithm, String encryptionAlgorithm,
081            int keyOffset, int keySize) {
082        this.name = name;
083        this.transformation = transformation;
084        this.macAlgorithm = macAlgorithm;
085        this.encryptionAlgorithm = encryptionAlgorithm;
086        this.keyOffset = keyOffset;
087        this.keySize = keySize;
088    }
089
090    /**
091     * Gets the full name of the encryption method.
092     *
093     * @return The name of the encryption method.
094     */
095    public String getName() {
096        return name;
097    }
098
099    /**
100     * Gets the Java Cryptographic algorithm name for the algorithm that will eb used to encrypt the plaintext.
101     *
102     * @return The transformation algorithm.
103     */
104    public String getTransformation() {
105        return transformation;
106    }
107
108    /**
109     * Gets the Java Cryptographic algorithm name for the algorithm that will generate the MAC key.
110     *
111     * @return The mac algorithm.
112     */
113    public String getMacAlgorithm() {
114        return macAlgorithm;
115    }
116
117    /**
118     * Gets the Java Cryptographic algorithm name for the algorithm that will create the Content Encryption Key (CEK).
119     *
120     * @return The encryption algorithm.
121     */
122    public String getEncryptionAlgorithm() {
123        return encryptionAlgorithm;
124    }
125
126    /**
127     * Gets the number of octets in each of the CEK and MAC key.
128     *
129     * @return The Key Offset.
130     */
131    public int getKeyOffset() {
132        return keyOffset;
133    }
134
135    /**
136     * Gets the bit length of the Content Encryption Key (CEK).
137     *
138     * @return The key size.
139     */
140    public int getKeySize() {
141        return keySize;
142    }
143
144    /**
145     * Parses the given algorithm string to find the matching EncryptionMethod enum constant.
146     *
147     * @param method The encryption method.
148     * @return The EncryptionMethod enum.
149     */
150    public static EncryptionMethod parseMethod(String method) {
151        try {
152            return EncryptionMethod.valueOf(method.toUpperCase(Locale.ROOT).replaceAll("-", "_"));
153        } catch (IllegalArgumentException e) {
154            for (EncryptionMethod encryptionMethod : EncryptionMethod.values()) {
155                if (encryptionMethod.getName().equalsIgnoreCase(method)) {
156                    return encryptionMethod;
157                }
158            }
159        }
160
161        throw new JweException("Unknown Encryption Method, " + method);
162    }
163
164    /**
165     * Turns the EncryptionMethod constant into a JSON value string.
166     *
167     * @return {@inheritDoc}
168     */
169    @Override
170    public String toString() {
171        return super.toString().replaceAll("_", "-");
172    }
173}