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    MD5("MD5", TSPAlgorithms.MD5),
033    SHA1("SHA-1", TSPAlgorithms.SHA1),
034    SHA256("SHA-256", TSPAlgorithms.SHA256),
035    SHA384("SHA-384", TSPAlgorithms.SHA384),
036    SHA512("SHA-512", TSPAlgorithms.SHA512);
037
038    /** The JCE name of the algorithm */
039    public final String id;
040
041    /** The object identifier of the algorithm */
042    public final ASN1ObjectIdentifier oid;
043
044    DigestAlgorithm(String id, ASN1ObjectIdentifier oid) {
045        this.id = id;
046        this.oid = oid;
047    }
048
049    /**
050     * Parse the specified value and returns the corresponding digest algorithm.
051     * This method is more permissive than {@link #valueOf(String)}, it's case
052     * insensitive and ignores hyphens.
053     * 
054     * @param s the name of the digest algorithm
055     */
056    public static DigestAlgorithm of(String s) {
057        if (s == null) {
058            return null;
059        }
060        
061        s = s.toUpperCase().replaceAll("-", "");
062        for (DigestAlgorithm algorithm : values()) {
063            if (algorithm.name().equals(s)) {
064                return algorithm;
065            }
066        }
067        
068        if ("SHA2".equals(s)) {
069            return SHA256;
070        }
071        
072        return null;
073    }
074
075    /**
076     * Return the algorithm matching the specified object identifier.
077     * 
078     * @param oid the ASN.1 object identifier of the algorithm
079     */
080    public static DigestAlgorithm of(ASN1ObjectIdentifier oid) {
081        for (DigestAlgorithm algorithm : values()) {
082            if (algorithm.oid.equals(oid)) {
083                return algorithm;
084            }
085        }
086        
087        return null;
088    }
089
090    /**
091     * Return a MessageDigest for this algorithm.
092     */
093    public MessageDigest getMessageDigest() {
094        try {
095            return MessageDigest.getInstance(id);
096        } catch (NoSuchAlgorithmException e) {
097            throw new RuntimeException(e);
098        }
099    }
100
101    /**
102     * Return the default algorithm (currently SHA-256, SHA-1 has been deprecated since January 1st 2016).
103     * 
104     * @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>
105     * @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>
106     */
107    public static DigestAlgorithm getDefault() {
108        return SHA256;
109    }
110}