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-2017 ForgeRock AS.
015 */
016
017package org.forgerock.json.jose.jws;
018
019import org.forgerock.json.jose.jwt.Algorithm;
020
021/**
022 * An Enum of the possible signing algorithms that can be used to sign a JWT.
023 * <p>
024 * @see <a href="http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-11#section-3.1">JWS Algorithms</a>
025 *
026 * @since 2.0.0
027 */
028public enum JwsAlgorithm implements Algorithm {
029
030    /** No digital signature or MAC value included. */
031    NONE(null, null, JwsAlgorithmType.NONE),
032    /** HMAC using SHA-256 hash algorithm. */
033    HS256("HmacSHA256", "SHA-256", JwsAlgorithmType.HMAC),
034    /** HMAC using SHA-384 hash algorithm. */
035    HS384("HmacSHA384", "SHA-384", JwsAlgorithmType.HMAC),
036    /** HMAC using SHA-512 hash algorithm. */
037    HS512("HmacSHA512", "SHA-512", JwsAlgorithmType.HMAC),
038    /** RSA using SHA-256 hash algorithm. **/
039    RS256("SHA256withRSA", "SHA-256", JwsAlgorithmType.RSA),
040    /** ECDSA using SHA-256 hash algorithm. */
041    ES256("SHA256WithECDSA", "SHA-256", JwsAlgorithmType.ECDSA),
042    /** ECDSA using SHA-384 hash algorithm. */
043    ES384("SHA384WithECDSA", "SHA-384", JwsAlgorithmType.ECDSA),
044    /** ECDSA using SHA-512 hash algorithm. */
045    ES512("SHA512WithECDSA", "SHA-512", JwsAlgorithmType.ECDSA);
046
047    private final String algorithm;
048    private final String mdAlgorithm;
049    private final JwsAlgorithmType algorithmType;
050
051    /**
052     * Constructs a new JwsAlgorithm with the Java Cryptographic string name of the algorithm and the JwsAlgorithmType
053     * of the algorithm.
054     *
055     * @param algorithm The Java Cryptographic algorithm name.
056     * @param mdAlgorithm The MessageDigest algorithm.
057     * @param algorithmType The JwsAlgorithmType of the JwsAlgorithm.
058     */
059    JwsAlgorithm(String algorithm, String mdAlgorithm, JwsAlgorithmType algorithmType) {
060        this.algorithm = algorithm;
061        this.mdAlgorithm = mdAlgorithm;
062        this.algorithmType = algorithmType;
063    }
064
065    @Override
066    public String getAlgorithm() {
067        return algorithm;
068    }
069
070    @Override
071    public String getJwaAlgorithmName() {
072        return name();
073    }
074
075    /**
076     * Returns the Java-friendly name of the message digest algorithm
077     * implementation.
078     *
079     * @return the Java-friendly name of the message digest algorithm
080     *         implementation.
081     * @see <a
082     *      href="http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html">Standard
083     *      Names</a>
084     */
085    public String getMdAlgorithm() {
086        return mdAlgorithm;
087    }
088
089    /**
090     * Return the standard name of the elliptic curve definition. Only applicable for ECDSA algorithms.
091     *
092     * @return the curve name or null if not applicable.
093     */
094    public String getEllipticCurveName() {
095        switch (this) {
096        case ES256:
097            return "P-256";
098        case ES384:
099            return "P-384";
100        case ES512:
101            return "P-521"; // Not a typo!
102        default:
103            return null;
104        }
105    }
106
107    /**
108     * Gets the JwsAlgorithmType of the JwsAlgorithm.
109     *
110     * @return The JwsAlgorithmType.
111     */
112    public JwsAlgorithmType getAlgorithmType() {
113        return algorithmType;
114    }
115
116    /**
117     * See {@link #parseCryptographicAlgorithm(String)}}.
118     * @deprecated Replaced by {@link #parseCryptographicAlgorithm(String)}
119     *
120     * @param algorithm The Java Cryptographic string algorithm name.
121     * @return The matching JwsAlgorithm.
122     */
123    @Deprecated
124    public static JwsAlgorithm getJwsAlgorithm(String algorithm) {
125        return parseCryptographicAlgorithm(algorithm);
126    }
127
128    /**
129     * Parses the given algorithm string to find the matching Java Cryptographic algorithm name.
130     * <p>
131     * If the given algorithm name does not match the algorithm name of any of the constants, then an
132     * IllegalArgumentException will be thrown.
133     *
134     * @param algorithm The Java Cryptographic string algorithm name.
135     * @return The matching JwsAlgorithm.
136     */
137    public static JwsAlgorithm parseCryptographicAlgorithm(String algorithm) {
138        for (JwsAlgorithm jwsAlgorithm : JwsAlgorithm.values()) {
139            if (algorithm.equalsIgnoreCase(jwsAlgorithm.getAlgorithm())) {
140                return jwsAlgorithm;
141            }
142        }
143        throw new IllegalArgumentException("Unknown JwsAlgorithm, " + algorithm);
144    }
145
146    /**
147     * Turns the JwsAlgorithm constant into a JSON value string.
148     *
149     * @return {@inheritDoc}
150     */
151    @Override
152    public String toString() {
153        return super.toString();
154    }
155}