1/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.conscrypt;
18
19import java.security.NoSuchAlgorithmException;
20import java.util.Locale;
21
22/**
23 * Utility class to convert between BoringSSL- and JCE-style message digest identifiers.
24 */
25final class EvpMdRef {
26    static final String MGF1_ALGORITHM_NAME = "MGF1";
27    static final String MGF1_OID = "1.2.840.113549.1.1.8";
28
29    /**
30     * Returns the canonical JCA digest algorithm name for the provided digest
31     * algorithm name or {@code null} if the digest algorithm is not known.
32     */
33    static String getJcaDigestAlgorithmStandardName(String algorithm) {
34        String algorithmUpper = algorithm.toUpperCase(Locale.US);
35        if ((SHA256.JCA_NAME.equals(algorithmUpper)) || (SHA256.OID.equals(algorithmUpper))) {
36            return SHA256.JCA_NAME;
37        } else if ((SHA512.JCA_NAME.equals(algorithmUpper))
38                || (SHA512.OID.equals(algorithmUpper))) {
39            return SHA512.JCA_NAME;
40        } else if ((SHA1.JCA_NAME.equals(algorithmUpper)) || (SHA1.OID.equals(algorithmUpper))) {
41            return SHA1.JCA_NAME;
42        } else if ((SHA384.JCA_NAME.equals(algorithmUpper))
43                || (SHA384.OID.equals(algorithmUpper))) {
44            return SHA384.JCA_NAME;
45        } else if ((SHA224.JCA_NAME.equals(algorithmUpper))
46                || (SHA224.OID.equals(algorithmUpper))) {
47            return SHA224.JCA_NAME;
48        } else {
49            return null;
50        }
51    }
52
53    static long getEVP_MDByJcaDigestAlgorithmStandardName(String algorithm)
54            throws NoSuchAlgorithmException {
55        String algorithmUpper = algorithm.toUpperCase(Locale.US);
56        if (SHA256.JCA_NAME.equals(algorithmUpper)) {
57            return EvpMdRef.SHA256.EVP_MD;
58        } else if (SHA512.JCA_NAME.equals(algorithmUpper)) {
59            return EvpMdRef.SHA512.EVP_MD;
60        } else if (SHA1.JCA_NAME.equals(algorithmUpper)) {
61            return EvpMdRef.SHA1.EVP_MD;
62        } else if (SHA384.JCA_NAME.equals(algorithmUpper)) {
63            return EvpMdRef.SHA384.EVP_MD;
64        } else if (SHA224.JCA_NAME.equals(algorithmUpper)) {
65            return EvpMdRef.SHA224.EVP_MD;
66        } else {
67            throw new NoSuchAlgorithmException("Unsupported algorithm: " + algorithm);
68        }
69    }
70
71    static int getDigestSizeBytesByJcaDigestAlgorithmStandardName(String algorithm)
72            throws NoSuchAlgorithmException {
73        String algorithmUpper = algorithm.toUpperCase(Locale.US);
74        if (SHA256.JCA_NAME.equals(algorithmUpper)) {
75            return EvpMdRef.SHA256.SIZE_BYTES;
76        } else if (SHA512.JCA_NAME.equals(algorithmUpper)) {
77            return EvpMdRef.SHA512.SIZE_BYTES;
78        } else if (SHA1.JCA_NAME.equals(algorithmUpper)) {
79            return EvpMdRef.SHA1.SIZE_BYTES;
80        } else if (SHA384.JCA_NAME.equals(algorithmUpper)) {
81            return EvpMdRef.SHA384.SIZE_BYTES;
82        } else if (SHA224.JCA_NAME.equals(algorithmUpper)) {
83            return EvpMdRef.SHA224.SIZE_BYTES;
84        } else {
85            throw new NoSuchAlgorithmException("Unsupported algorithm: " + algorithm);
86        }
87    }
88
89    static String getJcaDigestAlgorithmStandardNameFromEVP_MD(long evpMdRef) {
90        if (evpMdRef == MD5.EVP_MD) {
91            return MD5.JCA_NAME;
92        } else if (evpMdRef == SHA1.EVP_MD) {
93            return SHA1.JCA_NAME;
94        } else if (evpMdRef == SHA224.EVP_MD) {
95            return SHA224.JCA_NAME;
96        } else if (evpMdRef == SHA256.EVP_MD) {
97            return SHA256.JCA_NAME;
98        } else if (evpMdRef == SHA384.EVP_MD) {
99            return SHA384.JCA_NAME;
100        } else if (evpMdRef == SHA512.EVP_MD) {
101            return SHA512.JCA_NAME;
102        } else {
103            throw new IllegalArgumentException("Unknown EVP_MD reference");
104        }
105    }
106
107    static final class MD5 {
108        static final String JCA_NAME = "MD5";
109        static final String OID = "1.2.840.113549.2.5";
110        static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("md5");
111        static final int SIZE_BYTES = NativeCrypto.EVP_MD_size(EVP_MD);
112
113        private MD5() {}
114    }
115
116    static final class SHA1 {
117        static final String JCA_NAME = "SHA-1";
118        static final String OID = "1.3.14.3.2.26";
119        static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha1");
120        static final int SIZE_BYTES = NativeCrypto.EVP_MD_size(EVP_MD);
121        private SHA1() {}
122    }
123
124    static final class SHA224 {
125        static final String JCA_NAME = "SHA-224";
126        static final String OID = "2.16.840.1.101.3.4.2.4";
127        static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha224");
128        static final int SIZE_BYTES = NativeCrypto.EVP_MD_size(EVP_MD);
129
130        private SHA224() {}
131    }
132
133    static final class SHA256 {
134        static final String JCA_NAME = "SHA-256";
135        static final String OID = "2.16.840.1.101.3.4.2.1";
136        static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha256");
137        static final int SIZE_BYTES = NativeCrypto.EVP_MD_size(EVP_MD);
138
139        private SHA256() {}
140    }
141
142    static final class SHA384 {
143        static final String JCA_NAME = "SHA-384";
144        static final String OID = "2.16.840.1.101.3.4.2.2";
145        static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha384");
146        static final int SIZE_BYTES = NativeCrypto.EVP_MD_size(EVP_MD);
147
148        private SHA384() {}
149    }
150
151    static final class SHA512 {
152        static final String JCA_NAME = "SHA-512";
153        static final String OID = "2.16.840.1.101.3.4.2.3";
154        static final long EVP_MD = NativeCrypto.EVP_get_digestbyname("sha512");
155        static final int SIZE_BYTES = NativeCrypto.EVP_MD_size(EVP_MD);
156
157        private SHA512() {}
158    }
159
160    private EvpMdRef() {}
161}
162