History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/security/ssl/JsseJce.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/security/ssl/JsseJce.java+412−0
@@ -0,0 +1,412 @@
1+/*
2+ * Copyright (c) 2001, 2011, 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.util.*;
29+import java.math.BigInteger;
30+
31+import java.security.*;
32+import java.security.interfaces.RSAPublicKey;
33+import java.security.spec.RSAPublicKeySpec;
34+import java.security.spec.*;
35+
36+import javax.crypto.*;
37+
38+// explicit import to override the Provider class in this package
39+import java.security.Provider;
40+
41+// need internal Sun classes for FIPS tricks
42+import sun.security.jca.Providers;
43+import sun.security.jca.ProviderList;
44+
45+import sun.security.ec.ECParameters;
46+import sun.security.ec.NamedCurve;
47+
48+import static sun.security.ssl.SunJSSE.cryptoProvider;
49+
50+/**
51+ * This class contains a few static methods for interaction with the JCA/JCE
52+ * to obtain implementations, etc.
53+ *
54+ * @author Andreas Sterbenz
55+ */
56+final class JsseJce {
57+
58+ private final static Debug debug = Debug.getInstance("ssl");
59+
60+ private final static ProviderList fipsProviderList;
61+
62+ // Flag indicating whether EC crypto is available.
63+ // If null, then we have not checked yet.
64+ // If yes, then all the EC based crypto we need is available.
65+ private static Boolean ecAvailable;
66+
67+ // Flag indicating whether Kerberos crypto is available.
68+ // If true, then all the Kerberos-based crypto we need is available.
69+ private final static boolean kerberosAvailable;
70+ static {
71+ boolean temp;
72+ try {
73+ AccessController.doPrivileged(
74+ new PrivilegedExceptionAction<Void>() {
75+ public Void run() throws Exception {
76+ // Test for Kerberos using the bootstrap class loader
77+ Class.forName("sun.security.krb5.PrincipalName", true,
78+ null);
79+ return null;
80+ }
81+ });
82+ temp = true;
83+
84+ } catch (Exception e) {
85+ temp = false;
86+ }
87+ kerberosAvailable = temp;
88+ }
89+
90+ static {
91+ // force FIPS flag initialization
92+ // Because isFIPS() is synchronized and cryptoProvider is not modified
93+ // after it completes, this also eliminates the need for any further
94+ // synchronization when accessing cryptoProvider
95+ if (SunJSSE.isFIPS() == false) {
96+ fipsProviderList = null;
97+ } else {
98+ // Setup a ProviderList that can be used by the trust manager
99+ // during certificate chain validation. All the crypto must be
100+ // from the FIPS provider, but we also allow the required
101+ // certificate related services from the SUN provider.
102+ Provider sun = Security.getProvider("SUN");
103+ if (sun == null) {
104+ throw new RuntimeException
105+ ("FIPS mode: SUN provider must be installed");
106+ }
107+ Provider sunCerts = new SunCertificates(sun);
108+ fipsProviderList = ProviderList.newList(cryptoProvider, sunCerts);
109+ }
110+ }
111+
112+ private static final class SunCertificates extends Provider {
113+ SunCertificates(final Provider p) {
114+ super("SunCertificates", 1.0d, "SunJSSE internal");
115+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
116+ public Object run() {
117+ // copy certificate related services from the Sun provider
118+ for (Map.Entry<Object,Object> entry : p.entrySet()) {
119+ String key = (String)entry.getKey();
120+ if (key.startsWith("CertPathValidator.")
121+ || key.startsWith("CertPathBuilder.")
122+ || key.startsWith("CertStore.")
123+ || key.startsWith("CertificateFactory.")) {
124+ put(key, entry.getValue());
125+ }
126+ }
127+ return null;
128+ }
129+ });
130+ }
131+ }
132+
133+ /**
134+ * JCE transformation string for RSA with PKCS#1 v1.5 padding.
135+ * Can be used for encryption, decryption, signing, verifying.
136+ */
137+ final static String CIPHER_RSA_PKCS1 = "RSA/ECB/PKCS1Padding";
138+ /**
139+ * JCE transformation string for the stream cipher RC4.
140+ */
141+ final static String CIPHER_RC4 = "RC4";
142+ /**
143+ * JCE transformation string for DES in CBC mode without padding.
144+ */
145+ final static String CIPHER_DES = "DES/CBC/NoPadding";
146+ /**
147+ * JCE transformation string for (3-key) Triple DES in CBC mode
148+ * without padding.
149+ */
150+ final static String CIPHER_3DES = "DESede/CBC/NoPadding";
151+ /**
152+ * JCE transformation string for AES in CBC mode
153+ * without padding.
154+ */
155+ final static String CIPHER_AES = "AES/CBC/NoPadding";
156+ /**
157+ * JCA identifier string for DSA, i.e. a DSA with SHA-1.
158+ */
159+ final static String SIGNATURE_DSA = "DSA";
160+ /**
161+ * JCA identifier string for ECDSA, i.e. a ECDSA with SHA-1.
162+ */
163+ final static String SIGNATURE_ECDSA = "SHA1withECDSA";
164+ /**
165+ * JCA identifier string for Raw DSA, i.e. a DSA signature without
166+ * hashing where the application provides the SHA-1 hash of the data.
167+ * Note that the standard name is "NONEwithDSA" but we use "RawDSA"
168+ * for compatibility.
169+ */
170+ final static String SIGNATURE_RAWDSA = "RawDSA";
171+ /**
172+ * JCA identifier string for Raw ECDSA, i.e. a DSA signature without
173+ * hashing where the application provides the SHA-1 hash of the data.
174+ */
175+ final static String SIGNATURE_RAWECDSA = "NONEwithECDSA";
176+ /**
177+ * JCA identifier string for Raw RSA, i.e. a RSA PKCS#1 v1.5 signature
178+ * without hashing where the application provides the hash of the data.
179+ * Used for RSA client authentication with a 36 byte hash.
180+ */
181+ final static String SIGNATURE_RAWRSA = "NONEwithRSA";
182+ /**
183+ * JCA identifier string for the SSL/TLS style RSA Signature. I.e.
184+ * an signature using RSA with PKCS#1 v1.5 padding signing a
185+ * concatenation of an MD5 and SHA-1 digest.
186+ */
187+ final static String SIGNATURE_SSLRSA = "MD5andSHA1withRSA";
188+
189+ private JsseJce() {
190+ // no instantiation of this class
191+ }
192+
193+ synchronized static boolean isEcAvailable() {
194+ if (ecAvailable == null) {
195+ try {
196+ JsseJce.getSignature(SIGNATURE_ECDSA);
197+ JsseJce.getSignature(SIGNATURE_RAWECDSA);
198+ JsseJce.getKeyAgreement("ECDH");
199+ JsseJce.getKeyFactory("EC");
200+ JsseJce.getKeyPairGenerator("EC");
201+ ecAvailable = true;
202+ } catch (Exception e) {
203+ ecAvailable = false;
204+ }
205+ }
206+ return ecAvailable;
207+ }
208+
209+ synchronized static void clearEcAvailable() {
210+ ecAvailable = null;
211+ }
212+
213+ static boolean isKerberosAvailable() {
214+ return kerberosAvailable;
215+ }
216+
217+ /**
218+ * Return an JCE cipher implementation for the specified algorithm.
219+ */
220+ static Cipher getCipher(String transformation)
221+ throws NoSuchAlgorithmException {
222+ try {
223+ if (cryptoProvider == null) {
224+ return Cipher.getInstance(transformation);
225+ } else {
226+ return Cipher.getInstance(transformation, cryptoProvider);
227+ }
228+ } catch (NoSuchPaddingException e) {
229+ throw new NoSuchAlgorithmException(e);
230+ }
231+ }
232+
233+ /**
234+ * Return an JCA signature implementation for the specified algorithm.
235+ * The algorithm string should be one of the constants defined
236+ * in this class.
237+ */
238+ static Signature getSignature(String algorithm)
239+ throws NoSuchAlgorithmException {
240+ if (cryptoProvider == null) {
241+ return Signature.getInstance(algorithm);
242+ } else {
243+ // reference equality
244+ if (algorithm == SIGNATURE_SSLRSA) {
245+ // The SunPKCS11 provider currently does not support this
246+ // special algorithm. We allow a fallback in this case because
247+ // the SunJSSE implementation does the actual crypto using
248+ // a NONEwithRSA signature obtained from the cryptoProvider.
249+ if (cryptoProvider.getService("Signature", algorithm) == null) {
250+ // Calling Signature.getInstance() and catching the
251+ // exception would be cleaner, but exceptions are a little
252+ // expensive. So we check directly via getService().
253+ try {
254+ return Signature.getInstance(algorithm, "SunJSSE");
255+ } catch (NoSuchProviderException e) {
256+ throw new NoSuchAlgorithmException(e);
257+ }
258+ }
259+ }
260+ return Signature.getInstance(algorithm, cryptoProvider);
261+ }
262+ }
263+
264+ static KeyGenerator getKeyGenerator(String algorithm)
265+ throws NoSuchAlgorithmException {
266+ if (cryptoProvider == null) {
267+ return KeyGenerator.getInstance(algorithm);
268+ } else {
269+ return KeyGenerator.getInstance(algorithm, cryptoProvider);
270+ }
271+ }
272+
273+ static KeyPairGenerator getKeyPairGenerator(String algorithm)
274+ throws NoSuchAlgorithmException {
275+ if (cryptoProvider == null) {
276+ return KeyPairGenerator.getInstance(algorithm);
277+ } else {
278+ return KeyPairGenerator.getInstance(algorithm, cryptoProvider);
279+ }
280+ }
281+
282+ static KeyAgreement getKeyAgreement(String algorithm)
283+ throws NoSuchAlgorithmException {
284+ if (cryptoProvider == null) {
285+ return KeyAgreement.getInstance(algorithm);
286+ } else {
287+ return KeyAgreement.getInstance(algorithm, cryptoProvider);
288+ }
289+ }
290+
291+ static Mac getMac(String algorithm)
292+ throws NoSuchAlgorithmException {
293+ if (cryptoProvider == null) {
294+ return Mac.getInstance(algorithm);
295+ } else {
296+ return Mac.getInstance(algorithm, cryptoProvider);
297+ }
298+ }
299+
300+ static KeyFactory getKeyFactory(String algorithm)
301+ throws NoSuchAlgorithmException {
302+ if (cryptoProvider == null) {
303+ return KeyFactory.getInstance(algorithm);
304+ } else {
305+ return KeyFactory.getInstance(algorithm, cryptoProvider);
306+ }
307+ }
308+
309+ static SecureRandom getSecureRandom() throws KeyManagementException {
310+ if (cryptoProvider == null) {
311+ return new SecureRandom();
312+ }
313+ // Try "PKCS11" first. If that is not supported, iterate through
314+ // the provider and return the first working implementation.
315+ try {
316+ return SecureRandom.getInstance("PKCS11", cryptoProvider);
317+ } catch (NoSuchAlgorithmException e) {
318+ // ignore
319+ }
320+ for (Provider.Service s : cryptoProvider.getServices()) {
321+ if (s.getType().equals("SecureRandom")) {
322+ try {
323+ return SecureRandom.getInstance(s.getAlgorithm(), cryptoProvider);
324+ } catch (NoSuchAlgorithmException ee) {
325+ // ignore
326+ }
327+ }
328+ }
329+ throw new KeyManagementException("FIPS mode: no SecureRandom "
330+ + " implementation found in provider " + cryptoProvider.getName());
331+ }
332+
333+ static MessageDigest getMD5() {
334+ return getMessageDigest("MD5");
335+ }
336+
337+ static MessageDigest getSHA() {
338+ return getMessageDigest("SHA");
339+ }
340+
341+ static MessageDigest getMessageDigest(String algorithm) {
342+ try {
343+ if (cryptoProvider == null) {
344+ return MessageDigest.getInstance(algorithm);
345+ } else {
346+ return MessageDigest.getInstance(algorithm, cryptoProvider);
347+ }
348+ } catch (NoSuchAlgorithmException e) {
349+ throw new RuntimeException
350+ ("Algorithm " + algorithm + " not available", e);
351+ }
352+ }
353+
354+ static int getRSAKeyLength(PublicKey key) {
355+ BigInteger modulus;
356+ if (key instanceof RSAPublicKey) {
357+ modulus = ((RSAPublicKey)key).getModulus();
358+ } else {
359+ RSAPublicKeySpec spec = getRSAPublicKeySpec(key);
360+ modulus = spec.getModulus();
361+ }
362+ return modulus.bitLength();
363+ }
364+
365+ static RSAPublicKeySpec getRSAPublicKeySpec(PublicKey key) {
366+ if (key instanceof RSAPublicKey) {
367+ RSAPublicKey rsaKey = (RSAPublicKey)key;
368+ return new RSAPublicKeySpec(rsaKey.getModulus(),
369+ rsaKey.getPublicExponent());
370+ }
371+ try {
372+ KeyFactory factory = JsseJce.getKeyFactory("RSA");
373+ return factory.getKeySpec(key, RSAPublicKeySpec.class);
374+ } catch (Exception e) {
375+ throw (RuntimeException)new RuntimeException().initCause(e);
376+ }
377+ }
378+
379+ static ECParameterSpec getECParameterSpec(String namedCurveOid) {
380+ return NamedCurve.getECParameterSpec(namedCurveOid);
381+ }
382+
383+ static String getNamedCurveOid(ECParameterSpec params) {
384+ return ECParameters.getCurveName(params);
385+ }
386+
387+ static ECPoint decodePoint(byte[] encoded, EllipticCurve curve)
388+ throws java.io.IOException {
389+ return ECParameters.decodePoint(encoded, curve);
390+ }
391+
392+ static byte[] encodePoint(ECPoint point, EllipticCurve curve) {
393+ return ECParameters.encodePoint(point, curve);
394+ }
395+
396+ // In FIPS mode, set thread local providers; otherwise a no-op.
397+ // Must be paired with endFipsProvider.
398+ static Object beginFipsProvider() {
399+ if (fipsProviderList == null) {
400+ return null;
401+ } else {
402+ return Providers.beginThreadProviderList(fipsProviderList);
403+ }
404+ }
405+
406+ static void endFipsProvider(Object o) {
407+ if (fipsProviderList != null) {
408+ Providers.endThreadProviderList((ProviderList)o);
409+ }
410+ }
411+
412+}