1 /*
2  * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package sun.security.ssl;
27 
28 import java.math.BigInteger;
29 import java.security.*;
30 import java.security.interfaces.RSAPublicKey;
31 import java.security.spec.*;
32 import javax.crypto.*;
33 
34 /**
35  * This class contains a few static methods for interaction with the JCA/JCE
36  * to obtain implementations, etc.
37  *
38  * @author  Andreas Sterbenz
39  */
40 final class JsseJce {
41     static final boolean ALLOW_ECC =
42             Utilities.getBooleanProperty("com.sun.net.ssl.enableECC", true);
43 
44     /**
45      * JCE transformation string for RSA with PKCS#1 v1.5 padding.
46      * Can be used for encryption, decryption, signing, verifying.
47      */
48     static final String CIPHER_RSA_PKCS1 = "RSA/ECB/PKCS1Padding";
49 
50     /**
51      * JCE transformation string for the stream cipher RC4.
52      */
53     static final String CIPHER_RC4 = "RC4";
54 
55     /**
56      * JCE transformation string for DES in CBC mode without padding.
57      */
58     static final String CIPHER_DES = "DES/CBC/NoPadding";
59 
60     /**
61      * JCE transformation string for (3-key) Triple DES in CBC mode
62      * without padding.
63      */
64     static final String CIPHER_3DES = "DESede/CBC/NoPadding";
65 
66     /**
67      * JCE transformation string for AES in CBC mode
68      * without padding.
69      */
70     static final String CIPHER_AES = "AES/CBC/NoPadding";
71 
72     /**
73      * JCE transformation string for AES in GCM mode
74      * without padding.
75      */
76     static final String CIPHER_AES_GCM = "AES/GCM/NoPadding";
77 
78     /**
79      * JCE transformation string for ChaCha20-Poly1305
80      */
81     static final String CIPHER_CHACHA20_POLY1305 = "ChaCha20-Poly1305";
82 
83     /**
84      * JCA identifier string for DSA, i.e. a DSA with SHA-1.
85      */
86     static final String SIGNATURE_DSA = "DSA";
87 
88     /**
89      * JCA identifier string for ECDSA, i.e. a ECDSA with SHA-1.
90      */
91     static final String SIGNATURE_ECDSA = "SHA1withECDSA";
92 
93     /**
94      * JCA identifier for EdDSA signatures.
95      */
96     static final String SIGNATURE_EDDSA = "EdDSA";
97 
98     /**
99      * JCA identifier string for Raw DSA, i.e. a DSA signature without
100      * hashing where the application provides the SHA-1 hash of the data.
101      * Note that the standard name is "NONEwithDSA" but we use "RawDSA"
102      * for compatibility.
103      */
104     static final String SIGNATURE_RAWDSA = "RawDSA";
105 
106     /**
107      * JCA identifier string for Raw ECDSA, i.e. a DSA signature without
108      * hashing where the application provides the SHA-1 hash of the data.
109      */
110     static final String SIGNATURE_RAWECDSA = "NONEwithECDSA";
111 
112     /**
113      * JCA identifier string for Raw RSA, i.e. a RSA PKCS#1 v1.5 signature
114      * without hashing where the application provides the hash of the data.
115      * Used for RSA client authentication with a 36 byte hash.
116      */
117     static final String SIGNATURE_RAWRSA = "NONEwithRSA";
118 
119     /**
120      * JCA identifier string for the SSL/TLS style RSA Signature. I.e.
121      * an signature using RSA with PKCS#1 v1.5 padding signing a
122      * concatenation of an MD5 and SHA-1 digest.
123      */
124     static final String SIGNATURE_SSLRSA = "MD5andSHA1withRSA";
125 
JsseJce()126     private JsseJce() {
127         // no instantiation of this class
128     }
129 
isEcAvailable()130     static boolean isEcAvailable() {
131         return EcAvailability.isAvailable;
132     }
133 
getRSAKeyLength(PublicKey key)134     static int getRSAKeyLength(PublicKey key) {
135         BigInteger modulus;
136         if (key instanceof RSAPublicKey) {
137             modulus = ((RSAPublicKey)key).getModulus();
138         } else {
139             RSAPublicKeySpec spec = getRSAPublicKeySpec(key);
140             modulus = spec.getModulus();
141         }
142         return modulus.bitLength();
143     }
144 
getRSAPublicKeySpec(PublicKey key)145     static RSAPublicKeySpec getRSAPublicKeySpec(PublicKey key) {
146         if (key instanceof RSAPublicKey) {
147             RSAPublicKey rsaKey = (RSAPublicKey)key;
148             return new RSAPublicKeySpec(rsaKey.getModulus(),
149                                         rsaKey.getPublicExponent());
150         }
151         try {
152             KeyFactory factory = KeyFactory.getInstance("RSA");
153             return factory.getKeySpec(key, RSAPublicKeySpec.class);
154         } catch (Exception e) {
155             throw new RuntimeException(e);
156         }
157     }
158 
159     // lazy initialization holder class idiom for static default parameters
160     //
161     // See Effective Java Second Edition: Item 71.
162     private static class EcAvailability {
163         // Is EC crypto available?
164         private static final boolean isAvailable;
165 
166         static {
167             boolean mediator = true;
168             try {
169                 Signature.getInstance(SIGNATURE_ECDSA);
170                 Signature.getInstance(SIGNATURE_RAWECDSA);
171                 KeyAgreement.getInstance("ECDH");
172                 KeyFactory.getInstance("EC");
173                 KeyPairGenerator.getInstance("EC");
174                 AlgorithmParameters.getInstance("EC");
175             } catch (Exception e) {
176                 mediator = false;
177             }
178 
179             isAvailable = mediator;
180         }
181     }
182 }
183