001/**
002 * Copyright 2014 Florent Daigniere
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package net.jsign;
018
019import java.security.MessageDigest;
020import java.security.NoSuchAlgorithmException;
021
022import org.bouncycastle.asn1.ASN1ObjectIdentifier;
023import org.bouncycastle.tsp.TSPAlgorithms;
024
025/**
026 * Digest algorithm.
027 * 
028* @author Florent Daigniere
029* @since 1.3
030*/
031public enum DigestAlgorithm {
032
033    /** MD5 Message-Digest Algorithm (128 bits) */
034    MD5("MD5", TSPAlgorithms.MD5),
035
036    /** Secure Hash Algorithm 1 (160 bits) */
037    SHA1("SHA-1", TSPAlgorithms.SHA1),
038
039    /** Secure Hash Algorithm 2 (256 bits) */
040    SHA256("SHA-256", TSPAlgorithms.SHA256),
041
042    /** Secure Hash Algorithm 2 (384 bits) */
043    SHA384("SHA-384", TSPAlgorithms.SHA384),
044
045    /** Secure Hash Algorithm 2 (512 bits) */
046    SHA512("SHA-512", TSPAlgorithms.SHA512);
047
048    /** The JCE name of the algorithm */
049    public final String id;
050
051    /** The object identifier of the algorithm */
052    public final ASN1ObjectIdentifier oid;
053
054    DigestAlgorithm(String id, ASN1ObjectIdentifier oid) {
055        this.id = id;
056        this.oid = oid;
057    }
058
059    /**
060     * Parse the specified value and returns the corresponding digest algorithm.
061     * This method is more permissive than {@link #valueOf(String)}, it's case
062     * insensitive and ignores hyphens.
063     * 
064     * @param name the name of the digest algorithm
065     * @return the digest algorithm, or <code>null</code> if the name specified doesn't match any supported algorithm
066     */
067    public static DigestAlgorithm of(String name) {
068        if (name == null) {
069            return null;
070        }
071        
072        name = name.toUpperCase().replaceAll("-", "");
073        for (DigestAlgorithm algorithm : values()) {
074            if (algorithm.name().equals(name)) {
075                return algorithm;
076            }
077        }
078        
079        if ("SHA2".equals(name)) {
080            return SHA256;
081        }
082        
083        return null;
084    }
085
086    /**
087     * Return the algorithm matching the specified object identifier.
088     * 
089     * @param oid the ASN.1 object identifier of the algorithm
090     * @return the digest algorithm, or <code>null</code> if none matches the specified oid
091     */
092    public static DigestAlgorithm of(ASN1ObjectIdentifier oid) {
093        for (DigestAlgorithm algorithm : values()) {
094            if (algorithm.oid.equals(oid)) {
095                return algorithm;
096            }
097        }
098        
099        return null;
100    }
101
102    /**
103     * Return a MessageDigest for this algorithm.
104     * 
105     * @return a MessageDigest for this algorithm
106     */
107    public MessageDigest getMessageDigest() {
108        try {
109            return MessageDigest.getInstance(id);
110        } catch (NoSuchAlgorithmException e) {
111            throw new RuntimeException(e);
112        }
113    }
114
115    /**
116     * Return the default algorithm (currently SHA-256, SHA-1 has been deprecated since January 1st 2016).
117     * 
118     * @return the default algorithm ({@link #SHA256})
119     * @see <a href="http://social.technet.microsoft.com/wiki/contents/articles/1760.windows-root-certificate-program-technical-requirements-version-2-0.aspx">Windows Root Certificate Program - Technical Requirements version 2.0</a>
120     * @see <a href="http://blogs.technet.com/b/pki/archive/2011/02/08/common-questions-about-sha2-and-windows.aspx">Common Questions about SHA2 and Windows</a>
121     */
122    public static DigestAlgorithm getDefault() {
123        return SHA256;
124    }
125}