Mercurial > hg > openjdk > jdk7 > jdk
changeset 3988:9c29dd06e138
6976117: SSLContext.getInstance("TLSv1.1") returns SSLEngines/SSLSockets without TLSv1.1 enabled
Summary: Reorg the SSLContext implementation
Reviewed-by: weijun
author | xuelei |
---|---|
date | Fri, 08 Apr 2011 02:00:09 -0700 |
parents | 587e968b03ee |
children | 8fbd15bd6149 dc74b14a8753 |
files | src/share/classes/sun/security/ssl/CipherSuiteList.java src/share/classes/sun/security/ssl/DefaultSSLContextImpl.java src/share/classes/sun/security/ssl/JsseJce.java src/share/classes/sun/security/ssl/ProtocolList.java src/share/classes/sun/security/ssl/SSLContextImpl.java src/share/classes/sun/security/ssl/SSLEngineImpl.java src/share/classes/sun/security/ssl/SSLServerSocketFactoryImpl.java src/share/classes/sun/security/ssl/SSLServerSocketImpl.java src/share/classes/sun/security/ssl/SSLSocketFactoryImpl.java src/share/classes/sun/security/ssl/SSLSocketImpl.java src/share/classes/sun/security/ssl/SunJSSE.java test/sun/security/ssl/javax/net/ssl/SSLContextVersion.java |
diffstat | 12 files changed, 718 insertions(+), 390 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/sun/security/ssl/CipherSuiteList.java Thu Apr 07 17:08:16 2011 -0700 +++ b/src/share/classes/sun/security/ssl/CipherSuiteList.java Fri Apr 08 02:00:09 2011 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,10 +40,6 @@ */ final class CipherSuiteList { - // lists of supported and default enabled ciphersuites - // created on demand - private static CipherSuiteList supportedSuites, defaultSuites; - private final Collection<CipherSuite> cipherSuites; private String[] suiteNames; @@ -206,57 +202,8 @@ */ static synchronized void clearAvailableCache() { if (CipherSuite.DYNAMIC_AVAILABILITY) { - supportedSuites = null; - defaultSuites = null; CipherSuite.BulkCipher.clearAvailableCache(); JsseJce.clearEcAvailable(); } } - - /** - * Return the list of all available CipherSuites with a priority of - * minPriority or above. - * Should be called with the Class lock held. - */ - private static CipherSuiteList buildAvailableCache(int minPriority) { - // SortedSet automatically arranges ciphersuites in default - // preference order - Set<CipherSuite> cipherSuites = new TreeSet<>(); - Collection<CipherSuite> allowedCipherSuites = - CipherSuite.allowedCipherSuites(); - for (CipherSuite c : allowedCipherSuites) { - if ((c.allowed == false) || (c.priority < minPriority)) { - continue; - } - - if (c.isAvailable()) { - cipherSuites.add(c); - } - } - - return new CipherSuiteList(cipherSuites); - } - - /** - * Return supported CipherSuites in preference order. - */ - static synchronized CipherSuiteList getSupported() { - if (supportedSuites == null) { - supportedSuites = - buildAvailableCache(CipherSuite.SUPPORTED_SUITES_PRIORITY); - } - return supportedSuites; - } - - /** - * Return default enabled CipherSuites in preference order. - */ - static synchronized CipherSuiteList getDefault() { - if (defaultSuites == null) { - defaultSuites = - buildAvailableCache(CipherSuite.DEFAULT_SUITES_PRIORITY); - } - return defaultSuites; - } - }
--- a/src/share/classes/sun/security/ssl/DefaultSSLContextImpl.java Thu Apr 07 17:08:16 2011 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.security.ssl; - -import java.io.*; -import java.util.*; - -import java.security.*; - -import javax.net.ssl.*; - -/** - * "Default" SSLContext as returned by SSLContext.getDefault(). It comes - * initialized with default KeyManagers and TrustManagers created using - * various system properties. - * - * @since 1.6 - */ -public final class DefaultSSLContextImpl extends SSLContextImpl { - - private static final String NONE = "NONE"; - private static final String P11KEYSTORE = "PKCS11"; - private static final Debug debug = Debug.getInstance("ssl"); - - private static volatile SSLContextImpl defaultImpl; - - private static TrustManager[] defaultTrustManagers; - - private static KeyManager[] defaultKeyManagers; - - public DefaultSSLContextImpl() throws Exception { - super(defaultImpl); - try { - super.engineInit(getDefaultKeyManager(), getDefaultTrustManager(), null); - } catch (Exception e) { - if (debug != null && Debug.isOn("defaultctx")) { - System.out.println("default context init failed: " + e); - } - throw e; - } - if (defaultImpl == null) { - defaultImpl = this; - } - } - - protected void engineInit(KeyManager[] km, TrustManager[] tm, - SecureRandom sr) throws KeyManagementException { - throw new KeyManagementException - ("Default SSLContext is initialized automatically"); - } - - static synchronized SSLContextImpl getDefaultImpl() throws Exception { - if (defaultImpl == null) { - new DefaultSSLContextImpl(); - } - return defaultImpl; - } - - private static synchronized TrustManager[] getDefaultTrustManager() throws Exception { - if (defaultTrustManagers != null) { - return defaultTrustManagers; - } - - KeyStore ks = TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx"); - - TrustManagerFactory tmf = TrustManagerFactory.getInstance( - TrustManagerFactory.getDefaultAlgorithm()); - tmf.init(ks); - defaultTrustManagers = tmf.getTrustManagers(); - return defaultTrustManagers; - } - - private static synchronized KeyManager[] getDefaultKeyManager() throws Exception { - if (defaultKeyManagers != null) { - return defaultKeyManagers; - } - - final Map<String,String> props = new HashMap<>(); - AccessController.doPrivileged( - new PrivilegedExceptionAction<Object>() { - public Object run() throws Exception { - props.put("keyStore", System.getProperty( - "javax.net.ssl.keyStore", "")); - props.put("keyStoreType", System.getProperty( - "javax.net.ssl.keyStoreType", - KeyStore.getDefaultType())); - props.put("keyStoreProvider", System.getProperty( - "javax.net.ssl.keyStoreProvider", "")); - props.put("keyStorePasswd", System.getProperty( - "javax.net.ssl.keyStorePassword", "")); - return null; - } - }); - - final String defaultKeyStore = props.get("keyStore"); - String defaultKeyStoreType = props.get("keyStoreType"); - String defaultKeyStoreProvider = props.get("keyStoreProvider"); - if (debug != null && Debug.isOn("defaultctx")) { - System.out.println("keyStore is : " + defaultKeyStore); - System.out.println("keyStore type is : " + - defaultKeyStoreType); - System.out.println("keyStore provider is : " + - defaultKeyStoreProvider); - } - - if (P11KEYSTORE.equals(defaultKeyStoreType) && - !NONE.equals(defaultKeyStore)) { - throw new IllegalArgumentException("if keyStoreType is " - + P11KEYSTORE + ", then keyStore must be " + NONE); - } - - FileInputStream fs = null; - if (defaultKeyStore.length() != 0 && !NONE.equals(defaultKeyStore)) { - fs = AccessController.doPrivileged( - new PrivilegedExceptionAction<FileInputStream>() { - public FileInputStream run() throws Exception { - return new FileInputStream(defaultKeyStore); - } - }); - } - - String defaultKeyStorePassword = props.get("keyStorePasswd"); - char[] passwd = null; - if (defaultKeyStorePassword.length() != 0) { - passwd = defaultKeyStorePassword.toCharArray(); - } - - /** - * Try to initialize key store. - */ - KeyStore ks = null; - if ((defaultKeyStoreType.length()) != 0) { - if (debug != null && Debug.isOn("defaultctx")) { - System.out.println("init keystore"); - } - if (defaultKeyStoreProvider.length() == 0) { - ks = KeyStore.getInstance(defaultKeyStoreType); - } else { - ks = KeyStore.getInstance(defaultKeyStoreType, - defaultKeyStoreProvider); - } - - // if defaultKeyStore is NONE, fs will be null - ks.load(fs, passwd); - } - if (fs != null) { - fs.close(); - fs = null; - } - - /* - * Try to initialize key manager. - */ - if (debug != null && Debug.isOn("defaultctx")) { - System.out.println("init keymanager of type " + - KeyManagerFactory.getDefaultAlgorithm()); - } - KeyManagerFactory kmf = KeyManagerFactory.getInstance( - KeyManagerFactory.getDefaultAlgorithm()); - - if (P11KEYSTORE.equals(defaultKeyStoreType)) { - kmf.init(ks, null); // do not pass key passwd if using token - } else { - kmf.init(ks, passwd); - } - - defaultKeyManagers = kmf.getKeyManagers(); - return defaultKeyManagers; - } -}
--- a/src/share/classes/sun/security/ssl/JsseJce.java Thu Apr 07 17:08:16 2011 -0700 +++ b/src/share/classes/sun/security/ssl/JsseJce.java Fri Apr 08 02:00:09 2011 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -247,9 +247,9 @@ // the SunJSSE implementation does the actual crypto using // a NONEwithRSA signature obtained from the cryptoProvider. if (cryptoProvider.getService("Signature", algorithm) == null) { - // Calling Signature.getInstance() and catching the exception - // would be cleaner, but exceptions are a little expensive. - // So we check directly via getService(). + // Calling Signature.getInstance() and catching the + // exception would be cleaner, but exceptions are a little + // expensive. So we check directly via getService(). try { return Signature.getInstance(algorithm, "SunJSSE"); } catch (NoSuchProviderException e) {
--- a/src/share/classes/sun/security/ssl/ProtocolList.java Thu Apr 07 17:08:16 2011 -0700 +++ b/src/share/classes/sun/security/ssl/ProtocolList.java Fri Apr 08 02:00:09 2011 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,10 +37,6 @@ */ final class ProtocolList { - private static final ProtocolList SUPPORTED; - private static final ProtocolList CLIENT_DEFAULT; - private static final ProtocolList SERVER_DEFAULT; - // the sorted protocol version list private final ArrayList<ProtocolVersion> protocols; @@ -154,66 +150,4 @@ public String toString() { return protocols.toString(); } - - /** - * Return the list of default enabled protocols. - */ - static ProtocolList getDefault(boolean isServer) { - return isServer ? SERVER_DEFAULT : CLIENT_DEFAULT; - } - - /** - * Return whether a protocol list is the original default enabled - * protocols. See: SSLSocket/SSLEngine.setEnabledProtocols() - */ - static boolean isDefaultProtocolList(ProtocolList protocols) { - return protocols == CLIENT_DEFAULT || protocols == SERVER_DEFAULT; - } - - /** - * Return the list of supported protocols. - */ - static ProtocolList getSupported() { - return SUPPORTED; - } - - static { - if (SunJSSE.isFIPS()) { - SUPPORTED = new ProtocolList(new String[] { - ProtocolVersion.TLS10.name, - ProtocolVersion.TLS11.name, - ProtocolVersion.TLS12.name - }); - - SERVER_DEFAULT = SUPPORTED; - CLIENT_DEFAULT = new ProtocolList(new String[] { - ProtocolVersion.TLS10.name - }); - } else { - SUPPORTED = new ProtocolList(new String[] { - ProtocolVersion.SSL20Hello.name, - ProtocolVersion.SSL30.name, - ProtocolVersion.TLS10.name, - ProtocolVersion.TLS11.name, - ProtocolVersion.TLS12.name - }); - - SERVER_DEFAULT = SUPPORTED; - - /* - * RFC 5246 says that sending SSLv2 backward-compatible - * hello SHOULD NOT be done any longer. - * - * We are not enabling TLS 1.1/1.2 by default yet on clients - * out of concern for interop with existing - * SSLv3/TLS1.0-only servers. When these versions of TLS - * gain more traction, we'll enable them. - */ - CLIENT_DEFAULT = new ProtocolList(new String[] { - ProtocolVersion.SSL30.name, - ProtocolVersion.TLS10.name - }); - } - } - }
--- a/src/share/classes/sun/security/ssl/SSLContextImpl.java Thu Apr 07 17:08:16 2011 -0700 +++ b/src/share/classes/sun/security/ssl/SSLContextImpl.java Fri Apr 08 02:00:09 2011 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ import java.net.Socket; +import java.io.*; import java.util.*; import java.security.*; import java.security.cert.*; @@ -36,7 +37,7 @@ import sun.security.provider.certpath.AlgorithmChecker; -public class SSLContextImpl extends SSLContextSpi { +public abstract class SSLContextImpl extends SSLContextSpi { private static final Debug debug = Debug.getInstance("ssl"); @@ -50,20 +51,24 @@ private X509TrustManager trustManager; private SecureRandom secureRandom; - public SSLContextImpl() { - this(null); - } + // The default algrithm constraints + private AlgorithmConstraints defaultAlgorithmConstraints = + new SSLAlgorithmConstraints(null); + + // supported and default protocols + private ProtocolList defaultServerProtocolList; + private ProtocolList defaultClientProtocolList; + private ProtocolList supportedProtocolList; - SSLContextImpl(SSLContextImpl other) { - if (other == null) { - ephemeralKeyManager = new EphemeralKeyManager(); - clientCache = new SSLSessionContextImpl(); - serverCache = new SSLSessionContextImpl(); - } else { - ephemeralKeyManager = other.ephemeralKeyManager; - clientCache = other.clientCache; - serverCache = other.serverCache; - } + // supported and default cipher suites + private CipherSuiteList defaultServerCipherSuiteList; + private CipherSuiteList defaultClientCipherSuiteList; + private CipherSuiteList supportedCipherSuiteList; + + SSLContextImpl() { + ephemeralKeyManager = new EphemeralKeyManager(); + clientCache = new SSLSessionContextImpl(); + serverCache = new SSLSessionContextImpl(); } protected void engineInit(KeyManager[] km, TrustManager[] tm, @@ -177,7 +182,7 @@ throw new IllegalStateException( "SSLContextImpl is not initialized"); } - return new SSLSocketFactoryImpl(this); + return new SSLSocketFactoryImpl(this); } protected SSLServerSocketFactory engineGetServerSocketFactory() { @@ -227,6 +232,535 @@ return ephemeralKeyManager; } + abstract SSLParameters getDefaultServerSSLParams(); + abstract SSLParameters getDefaultClientSSLParams(); + abstract SSLParameters getSupportedSSLParams(); + + // Get suported ProtoclList. + ProtocolList getSuportedProtocolList() { + if (supportedProtocolList == null) { + supportedProtocolList = + new ProtocolList(getSupportedSSLParams().getProtocols()); + } + + return supportedProtocolList; + } + + // Get default ProtoclList. + ProtocolList getDefaultProtocolList(boolean roleIsServer) { + if (roleIsServer) { + if (defaultServerProtocolList == null) { + defaultServerProtocolList = new ProtocolList( + getDefaultServerSSLParams().getProtocols()); + } + + return defaultServerProtocolList; + } else { + if (defaultClientProtocolList == null) { + defaultClientProtocolList = new ProtocolList( + getDefaultClientSSLParams().getProtocols()); + } + + return defaultClientProtocolList; + } + } + + // Get suported CipherSuiteList. + CipherSuiteList getSuportedCipherSuiteList() { + // Clear cache of available ciphersuites. + clearAvailableCache(); + + if (supportedCipherSuiteList == null) { + supportedCipherSuiteList = + getApplicableCipherSuiteList(getSuportedProtocolList(), false); + } + + return supportedCipherSuiteList; + } + + // Get default CipherSuiteList. + CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) { + // Clear cache of available ciphersuites. + clearAvailableCache(); + + if (roleIsServer) { + if (defaultServerCipherSuiteList == null) { + defaultServerCipherSuiteList = getApplicableCipherSuiteList( + getDefaultProtocolList(true), true); + } + + return defaultServerCipherSuiteList; + } else { + if (defaultClientCipherSuiteList == null) { + defaultClientCipherSuiteList = getApplicableCipherSuiteList( + getDefaultProtocolList(false), true); + } + + return defaultClientCipherSuiteList; + } + } + + /** + * Return whether a protocol list is the original default enabled + * protocols. See: SSLSocket/SSLEngine.setEnabledProtocols() + */ + boolean isDefaultProtocolList(ProtocolList protocols) { + return (protocols == defaultServerProtocolList) || + (protocols == defaultClientProtocolList); + } + + + /* + * Return the list of all available CipherSuites with a priority of + * minPriority or above. + */ + private CipherSuiteList getApplicableCipherSuiteList( + ProtocolList protocols, boolean onlyEnabled) { + + int minPriority = CipherSuite.SUPPORTED_SUITES_PRIORITY; + if (onlyEnabled) { + minPriority = CipherSuite.DEFAULT_SUITES_PRIORITY; + } + + Collection<CipherSuite> allowedCipherSuites = + CipherSuite.allowedCipherSuites(); + + ArrayList<CipherSuite> suites = new ArrayList<>(); + if (!(protocols.collection().isEmpty()) && + protocols.min.v != ProtocolVersion.NONE.v) { + for (CipherSuite suite : allowedCipherSuites) { + if (suite.allowed == false || suite.priority < minPriority) { + continue; + } + + if (suite.isAvailable() && + suite.obsoleted > protocols.min.v && + suite.supported <= protocols.max.v) { + if (defaultAlgorithmConstraints.permits( + EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), + suite.name, null)) { + suites.add(suite); + } + } else if (debug != null && + Debug.isOn("sslctx") && Debug.isOn("verbose")) { + if (suite.obsoleted <= protocols.min.v) { + System.out.println( + "Ignoring obsoleted cipher suite: " + suite); + } else if (suite.supported > protocols.max.v) { + System.out.println( + "Ignoring unsupported cipher suite: " + suite); + } else { + System.out.println( + "Ignoring unavailable cipher suite: " + suite); + } + } + } + } + + return new CipherSuiteList(suites); + } + + /** + * Clear cache of available ciphersuites. If we support all ciphers + * internally, there is no need to clear the cache and calling this + * method has no effect. + */ + synchronized void clearAvailableCache() { + if (CipherSuite.DYNAMIC_AVAILABILITY) { + supportedCipherSuiteList = null; + defaultServerCipherSuiteList = null; + defaultClientCipherSuiteList = null; + CipherSuite.BulkCipher.clearAvailableCache(); + JsseJce.clearEcAvailable(); + } + } + + /* + * The SSLContext implementation for TLS/SSL algorithm + * + * SSL/TLS protocols specify the forward compatibility and version + * roll-back attack protections, however, a number of SSL/TLS server + * vendors did not implement these aspects properly, and some current + * SSL/TLS servers may refuse to talk to a TLS 1.1 or later client. + * + * Considering above interoperability issues, SunJSSE will not set + * TLS 1.1 and TLS 1.2 as the enabled protocols for client by default. + * + * For SSL/TLS servers, there is no such interoperability issues as + * SSL/TLS clients. In SunJSSE, TLS 1.1 or later version will be the + * enabled protocols for server by default. + * + * We may change the behavior when popular TLS/SSL vendors support TLS + * forward compatibility properly. + * + * SSLv2Hello is no longer necessary. This interoperability option was + * put in place in the late 90's when SSLv3/TLS1.0 were relatively new + * and there were a fair number of SSLv2-only servers deployed. Because + * of the security issues in SSLv2, it is rarely (if ever) used, as + * deployments should now be using SSLv3 and TLSv1. + * + * Considering the issues of SSLv2Hello, we should not enable SSLv2Hello + * by default. Applications still can use it by enabling SSLv2Hello with + * the series of setEnabledProtocols APIs. + */ + + /* + * The conservative SSLContext implementation for TLS, SSL, SSLv3 and + * TLS10 algorithm. + * + * This is a super class of DefaultSSLContext and TLS10Context. + * + * @see SSLContext + */ + private static class ConservativeSSLContext extends SSLContextImpl { + // parameters + private static SSLParameters defaultServerSSLParams; + private static SSLParameters defaultClientSSLParams; + private static SSLParameters supportedSSLParams; + + static { + if (SunJSSE.isFIPS()) { + supportedSSLParams = new SSLParameters(); + supportedSSLParams.setProtocols(new String[] { + ProtocolVersion.TLS10.name, + ProtocolVersion.TLS11.name, + ProtocolVersion.TLS12.name + }); + + defaultServerSSLParams = supportedSSLParams; + + defaultClientSSLParams = new SSLParameters(); + defaultClientSSLParams.setProtocols(new String[] { + ProtocolVersion.TLS10.name + }); + + } else { + supportedSSLParams = new SSLParameters(); + supportedSSLParams.setProtocols(new String[] { + ProtocolVersion.SSL20Hello.name, + ProtocolVersion.SSL30.name, + ProtocolVersion.TLS10.name, + ProtocolVersion.TLS11.name, + ProtocolVersion.TLS12.name + }); + + defaultServerSSLParams = supportedSSLParams; + + defaultClientSSLParams = new SSLParameters(); + defaultClientSSLParams.setProtocols(new String[] { + ProtocolVersion.SSL30.name, + ProtocolVersion.TLS10.name + }); + } + } + + SSLParameters getDefaultServerSSLParams() { + return defaultServerSSLParams; + } + + SSLParameters getDefaultClientSSLParams() { + return defaultClientSSLParams; + } + + SSLParameters getSupportedSSLParams() { + return supportedSSLParams; + } + } + + /* + * The SSLContext implementation for default algorithm + * + * @see SSLContext + */ + public static final class DefaultSSLContext extends ConservativeSSLContext { + private static final String NONE = "NONE"; + private static final String P11KEYSTORE = "PKCS11"; + + private static volatile SSLContextImpl defaultImpl; + + private static TrustManager[] defaultTrustManagers; + private static KeyManager[] defaultKeyManagers; + + public DefaultSSLContext() throws Exception { + try { + super.engineInit(getDefaultKeyManager(), + getDefaultTrustManager(), null); + } catch (Exception e) { + if (debug != null && Debug.isOn("defaultctx")) { + System.out.println("default context init failed: " + e); + } + throw e; + } + + if (defaultImpl == null) { + defaultImpl = this; + } + } + + protected void engineInit(KeyManager[] km, TrustManager[] tm, + SecureRandom sr) throws KeyManagementException { + throw new KeyManagementException + ("Default SSLContext is initialized automatically"); + } + + static synchronized SSLContextImpl getDefaultImpl() throws Exception { + if (defaultImpl == null) { + new DefaultSSLContext(); + } + return defaultImpl; + } + + private static synchronized TrustManager[] getDefaultTrustManager() + throws Exception { + if (defaultTrustManagers != null) { + return defaultTrustManagers; + } + + KeyStore ks = + TrustManagerFactoryImpl.getCacertsKeyStore("defaultctx"); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance( + TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(ks); + defaultTrustManagers = tmf.getTrustManagers(); + return defaultTrustManagers; + } + + private static synchronized KeyManager[] getDefaultKeyManager() + throws Exception { + if (defaultKeyManagers != null) { + return defaultKeyManagers; + } + + final Map<String,String> props = new HashMap<>(); + AccessController.doPrivileged( + new PrivilegedExceptionAction<Object>() { + public Object run() throws Exception { + props.put("keyStore", System.getProperty( + "javax.net.ssl.keyStore", "")); + props.put("keyStoreType", System.getProperty( + "javax.net.ssl.keyStoreType", + KeyStore.getDefaultType())); + props.put("keyStoreProvider", System.getProperty( + "javax.net.ssl.keyStoreProvider", "")); + props.put("keyStorePasswd", System.getProperty( + "javax.net.ssl.keyStorePassword", "")); + return null; + } + }); + + final String defaultKeyStore = props.get("keyStore"); + String defaultKeyStoreType = props.get("keyStoreType"); + String defaultKeyStoreProvider = props.get("keyStoreProvider"); + if (debug != null && Debug.isOn("defaultctx")) { + System.out.println("keyStore is : " + defaultKeyStore); + System.out.println("keyStore type is : " + + defaultKeyStoreType); + System.out.println("keyStore provider is : " + + defaultKeyStoreProvider); + } + + if (P11KEYSTORE.equals(defaultKeyStoreType) && + !NONE.equals(defaultKeyStore)) { + throw new IllegalArgumentException("if keyStoreType is " + + P11KEYSTORE + ", then keyStore must be " + NONE); + } + + FileInputStream fs = null; + if (defaultKeyStore.length() != 0 && !NONE.equals(defaultKeyStore)) { + fs = AccessController.doPrivileged( + new PrivilegedExceptionAction<FileInputStream>() { + public FileInputStream run() throws Exception { + return new FileInputStream(defaultKeyStore); + } + }); + } + + String defaultKeyStorePassword = props.get("keyStorePasswd"); + char[] passwd = null; + if (defaultKeyStorePassword.length() != 0) { + passwd = defaultKeyStorePassword.toCharArray(); + } + + /** + * Try to initialize key store. + */ + KeyStore ks = null; + if ((defaultKeyStoreType.length()) != 0) { + if (debug != null && Debug.isOn("defaultctx")) { + System.out.println("init keystore"); + } + if (defaultKeyStoreProvider.length() == 0) { + ks = KeyStore.getInstance(defaultKeyStoreType); + } else { + ks = KeyStore.getInstance(defaultKeyStoreType, + defaultKeyStoreProvider); + } + + // if defaultKeyStore is NONE, fs will be null + ks.load(fs, passwd); + } + if (fs != null) { + fs.close(); + fs = null; + } + + /* + * Try to initialize key manager. + */ + if (debug != null && Debug.isOn("defaultctx")) { + System.out.println("init keymanager of type " + + KeyManagerFactory.getDefaultAlgorithm()); + } + KeyManagerFactory kmf = KeyManagerFactory.getInstance( + KeyManagerFactory.getDefaultAlgorithm()); + + if (P11KEYSTORE.equals(defaultKeyStoreType)) { + kmf.init(ks, null); // do not pass key passwd if using token + } else { + kmf.init(ks, passwd); + } + + defaultKeyManagers = kmf.getKeyManagers(); + return defaultKeyManagers; + } + } + + /* + * The SSLContext implementation for TLS, SSL, SSLv3 and TLS10 algorithm + * + * @see SSLContext + */ + public static final class TLS10Context extends ConservativeSSLContext { + // use the default constructor and methods + } + + /* + * The SSLContext implementation for TLS11 algorithm + * + * @see SSLContext + */ + public static final class TLS11Context extends SSLContextImpl { + // parameters + private static SSLParameters defaultServerSSLParams; + private static SSLParameters defaultClientSSLParams; + private static SSLParameters supportedSSLParams; + + static { + if (SunJSSE.isFIPS()) { + supportedSSLParams = new SSLParameters(); + supportedSSLParams.setProtocols(new String[] { + ProtocolVersion.TLS10.name, + ProtocolVersion.TLS11.name, + ProtocolVersion.TLS12.name + }); + + defaultServerSSLParams = supportedSSLParams; + + defaultClientSSLParams = new SSLParameters(); + defaultClientSSLParams.setProtocols(new String[] { + ProtocolVersion.TLS10.name, + ProtocolVersion.TLS11.name + }); + + } else { + supportedSSLParams = new SSLParameters(); + supportedSSLParams.setProtocols(new String[] { + ProtocolVersion.SSL20Hello.name, + ProtocolVersion.SSL30.name, + ProtocolVersion.TLS10.name, + ProtocolVersion.TLS11.name, + ProtocolVersion.TLS12.name + }); + + defaultServerSSLParams = supportedSSLParams; + + defaultClientSSLParams = new SSLParameters(); + defaultClientSSLParams.setProtocols(new String[] { + ProtocolVersion.SSL30.name, + ProtocolVersion.TLS10.name, + ProtocolVersion.TLS11.name + }); + } + } + + SSLParameters getDefaultServerSSLParams() { + return defaultServerSSLParams; + } + + SSLParameters getDefaultClientSSLParams() { + return defaultClientSSLParams; + } + + SSLParameters getSupportedSSLParams() { + return supportedSSLParams; + } + } + + /* + * The SSLContext implementation for TLS12 algorithm + * + * @see SSLContext + */ + public static final class TLS12Context extends SSLContextImpl { + // parameters + private static SSLParameters defaultServerSSLParams; + private static SSLParameters defaultClientSSLParams; + private static SSLParameters supportedSSLParams; + + static { + if (SunJSSE.isFIPS()) { + supportedSSLParams = new SSLParameters(); + supportedSSLParams.setProtocols(new String[] { + ProtocolVersion.TLS10.name, + ProtocolVersion.TLS11.name, + ProtocolVersion.TLS12.name + }); + + defaultServerSSLParams = supportedSSLParams; + + defaultClientSSLParams = new SSLParameters(); + defaultClientSSLParams.setProtocols(new String[] { + ProtocolVersion.TLS10.name, + ProtocolVersion.TLS11.name, + ProtocolVersion.TLS12.name + }); + + } else { + supportedSSLParams = new SSLParameters(); + supportedSSLParams.setProtocols(new String[] { + ProtocolVersion.SSL20Hello.name, + ProtocolVersion.SSL30.name, + ProtocolVersion.TLS10.name, + ProtocolVersion.TLS11.name, + ProtocolVersion.TLS12.name + }); + + defaultServerSSLParams = supportedSSLParams; + + defaultClientSSLParams = new SSLParameters(); + defaultClientSSLParams.setProtocols(new String[] { + ProtocolVersion.SSL30.name, + ProtocolVersion.TLS10.name, + ProtocolVersion.TLS11.name, + ProtocolVersion.TLS12.name + }); + } + } + + SSLParameters getDefaultServerSSLParams() { + return defaultServerSSLParams; + } + + SSLParameters getDefaultClientSSLParams() { + return defaultClientSSLParams; + } + + SSLParameters getSupportedSSLParams() { + return supportedSSLParams; + } + } + }
--- a/src/share/classes/sun/security/ssl/SSLEngineImpl.java Thu Apr 07 17:08:16 2011 -0700 +++ b/src/share/classes/sun/security/ssl/SSLEngineImpl.java Fri Apr 08 02:00:09 2011 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -374,8 +374,10 @@ clientVerifyData = new byte[0]; serverVerifyData = new byte[0]; - enabledCipherSuites = CipherSuiteList.getDefault(); - enabledProtocols = ProtocolList.getDefault(roleIsServer); + enabledCipherSuites = + sslContext.getDefaultCipherSuiteList(roleIsServer); + enabledProtocols = + sslContext.getDefaultProtocolList(roleIsServer); wrapLock = new Object(); unwrapLock = new Object(); @@ -1883,8 +1885,8 @@ * change them to the corresponding default ones. */ if (roleIsServer != (!flag) && - ProtocolList.isDefaultProtocolList(enabledProtocols)) { - enabledProtocols = ProtocolList.getDefault(!flag); + sslContext.isDefaultProtocolList(enabledProtocols)) { + enabledProtocols = sslContext.getDefaultProtocolList(!flag); } roleIsServer = !flag; @@ -1907,8 +1909,8 @@ * change them to the corresponding default ones. */ if (roleIsServer != (!flag) && - ProtocolList.isDefaultProtocolList(enabledProtocols)) { - enabledProtocols = ProtocolList.getDefault(!flag); + sslContext.isDefaultProtocolList(enabledProtocols)) { + enabledProtocols = sslContext.getDefaultProtocolList(!flag); } roleIsServer = !flag; @@ -1951,8 +1953,7 @@ * @return an array of cipher suite names */ public String[] getSupportedCipherSuites() { - CipherSuiteList.clearAvailableCache(); - return CipherSuiteList.getSupported().toStringArray(); + return sslContext.getSuportedCipherSuiteList().toStringArray(); } /** @@ -1992,7 +1993,7 @@ * @return an array of protocol names. */ public String[] getSupportedProtocols() { - return ProtocolList.getSupported().toStringArray(); + return sslContext.getSuportedProtocolList().toStringArray(); } /**
--- a/src/share/classes/sun/security/ssl/SSLServerSocketFactoryImpl.java Thu Apr 07 17:08:16 2011 -0700 +++ b/src/share/classes/sun/security/ssl/SSLServerSocketFactoryImpl.java Fri Apr 08 02:00:09 2011 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,7 @@ * java.security file is set. */ public SSLServerSocketFactoryImpl() throws Exception { - this.context = DefaultSSLContextImpl.getDefaultImpl(); + this.context = SSLContextImpl.DefaultSSLContext.getDefaultImpl(); } /** @@ -99,8 +99,7 @@ * is encrypted to provide confidentiality. */ public String[] getDefaultCipherSuites() { - CipherSuiteList.clearAvailableCache(); - return CipherSuiteList.getDefault().toStringArray(); + return context.getDefaultCipherSuiteList(true).toStringArray(); } /** @@ -114,8 +113,7 @@ * @return an array of cipher suite names */ public String[] getSupportedCipherSuites() { - CipherSuiteList.clearAvailableCache(); - return CipherSuiteList.getSupported().toStringArray(); + return context.getSuportedCipherSuiteList().toStringArray(); } }
--- a/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java Thu Apr 07 17:08:16 2011 -0700 +++ b/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java Fri Apr 08 02:00:09 2011 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -153,8 +153,8 @@ throw new SSLException("No Authentication context given"); } sslContext = context; - enabledCipherSuites = CipherSuiteList.getDefault(); - enabledProtocols = ProtocolList.getDefault(true); + enabledCipherSuites = sslContext.getDefaultCipherSuiteList(true); + enabledProtocols = sslContext.getDefaultProtocolList(true); } /** @@ -168,8 +168,7 @@ * @return an array of cipher suite names */ public String[] getSupportedCipherSuites() { - CipherSuiteList.clearAvailableCache(); - return CipherSuiteList.getSupported().toStringArray(); + return sslContext.getSuportedCipherSuiteList().toStringArray(); } /** @@ -194,7 +193,7 @@ } public String[] getSupportedProtocols() { - return ProtocolList.getSupported().toStringArray(); + return sslContext.getSuportedProtocolList().toStringArray(); } /** @@ -253,8 +252,8 @@ * change them to the corresponding default ones. */ if (useServerMode != (!flag) && - ProtocolList.isDefaultProtocolList(enabledProtocols)) { - enabledProtocols = ProtocolList.getDefault(!flag); + sslContext.isDefaultProtocolList(enabledProtocols)) { + enabledProtocols = sslContext.getDefaultProtocolList(!flag); } useServerMode = !flag;
--- a/src/share/classes/sun/security/ssl/SSLSocketFactoryImpl.java Thu Apr 07 17:08:16 2011 -0700 +++ b/src/share/classes/sun/security/ssl/SSLSocketFactoryImpl.java Fri Apr 08 02:00:09 2011 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,20 +42,18 @@ * * @author David Brownell */ -final -public class SSLSocketFactoryImpl extends SSLSocketFactory -{ +final public class SSLSocketFactoryImpl extends SSLSocketFactory { + private static SSLContextImpl defaultContext; private SSLContextImpl context; - /** * Constructor used to instantiate the default factory. This method is * only called if the old "ssl.SocketFactory.provider" property in the * java.security file is set. */ public SSLSocketFactoryImpl() throws Exception { - this.context = DefaultSSLContextImpl.getDefaultImpl(); + this.context = SSLContextImpl.DefaultSSLContext.getDefaultImpl(); } /** @@ -167,11 +165,9 @@ * is encrypted to provide confidentiality. */ public String[] getDefaultCipherSuites() { - CipherSuiteList.clearAvailableCache(); - return CipherSuiteList.getDefault().toStringArray(); + return context.getDefaultCipherSuiteList(false).toStringArray(); } - /** * Returns the names of the cipher suites which could be enabled for use * on an SSL connection. Normally, only a subset of these will actually @@ -181,7 +177,6 @@ * certain kinds of certificates to use certain cipher suites. */ public String[] getSupportedCipherSuites() { - CipherSuiteList.clearAvailableCache(); - return CipherSuiteList.getSupported().toStringArray(); + return context.getSuportedCipherSuiteList().toStringArray(); } }
--- a/src/share/classes/sun/security/ssl/SSLSocketImpl.java Thu Apr 07 17:08:16 2011 -0700 +++ b/src/share/classes/sun/security/ssl/SSLSocketImpl.java Fri Apr 08 02:00:09 2011 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -562,8 +562,11 @@ clientVerifyData = new byte[0]; serverVerifyData = new byte[0]; - enabledCipherSuites = CipherSuiteList.getDefault(); - enabledProtocols = ProtocolList.getDefault(roleIsServer); + enabledCipherSuites = + sslContext.getDefaultCipherSuiteList(roleIsServer); + enabledProtocols = + sslContext.getDefaultProtocolList(roleIsServer); + inrec = null; // save the acc @@ -2170,8 +2173,8 @@ * change them to the corresponding default ones. */ if (roleIsServer != (!flag) && - ProtocolList.isDefaultProtocolList(enabledProtocols)) { - enabledProtocols = ProtocolList.getDefault(!flag); + sslContext.isDefaultProtocolList(enabledProtocols)) { + enabledProtocols = sslContext.getDefaultProtocolList(!flag); } roleIsServer = !flag; break; @@ -2192,8 +2195,8 @@ * change them to the corresponding default ones. */ if (roleIsServer != (!flag) && - ProtocolList.isDefaultProtocolList(enabledProtocols)) { - enabledProtocols = ProtocolList.getDefault(!flag); + sslContext.isDefaultProtocolList(enabledProtocols)) { + enabledProtocols = sslContext.getDefaultProtocolList(!flag); } roleIsServer = !flag; connectionState = cs_START; @@ -2230,8 +2233,7 @@ * @return an array of cipher suite names */ public String[] getSupportedCipherSuites() { - CipherSuiteList.clearAvailableCache(); - return CipherSuiteList.getSupported().toStringArray(); + return sslContext.getSuportedCipherSuiteList().toStringArray(); } /** @@ -2271,7 +2273,7 @@ * @return an array of protocol names. */ public String[] getSupportedProtocols() { - return ProtocolList.getSupported().toStringArray(); + return sslContext.getSuportedProtocolList().toStringArray(); } /**
--- a/src/share/classes/sun/security/ssl/SunJSSE.java Thu Apr 07 17:08:16 2011 -0700 +++ b/src/share/classes/sun/security/ssl/SunJSSE.java Fri Apr 08 02:00:09 2011 -0700 @@ -204,22 +204,21 @@ put("Alg.Alias.TrustManagerFactory.SunPKIX", "PKIX"); put("Alg.Alias.TrustManagerFactory.X509", "PKIX"); put("Alg.Alias.TrustManagerFactory.X.509", "PKIX"); + + put("SSLContext.TLSv1", + "sun.security.ssl.SSLContextImpl$TLS10Context"); + put("Alg.Alias.SSLContext.TLS", "TLSv1"); if (isfips == false) { - put("SSLContext.SSL", - "sun.security.ssl.SSLContextImpl"); - put("SSLContext.SSLv3", - "sun.security.ssl.SSLContextImpl"); + put("Alg.Alias.SSLContext.SSL", "TLSv1"); + put("Alg.Alias.SSLContext.SSLv3", "TLSv1"); } - put("SSLContext.TLS", - "sun.security.ssl.SSLContextImpl"); - put("SSLContext.TLSv1", - "sun.security.ssl.SSLContextImpl"); + put("SSLContext.TLSv1.1", - "sun.security.ssl.SSLContextImpl"); + "sun.security.ssl.SSLContextImpl$TLS11Context"); put("SSLContext.TLSv1.2", - "sun.security.ssl.SSLContextImpl"); + "sun.security.ssl.SSLContextImpl$TLS12Context"); put("SSLContext.Default", - "sun.security.ssl.DefaultSSLContextImpl"); + "sun.security.ssl.SSLContextImpl$DefaultSSLContext"); /* * KeyStore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/security/ssl/javax/net/ssl/SSLContextVersion.java Fri Apr 08 02:00:09 2011 -0700 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6976117 + * @summary SSLContext.getInstance("TLSv1.1") returns SSLEngines/SSLSockets + * without TLSv1.1 enabled + */ + +import javax.net.ssl.*; + +public class SSLContextVersion { + static enum ContextVersion { + TLS_CV_01("SSL", "TLSv1", "TLSv1.2"), + TLS_CV_02("TLS", "TLSv1", "TLSv1.2"), + TLS_CV_03("SSLv3", "TLSv1", "TLSv1.2"), + TLS_CV_04("TLSv1", "TLSv1", "TLSv1.2"), + TLS_CV_05("TLSv1.1", "TLSv1.1", "TLSv1.2"), + TLS_CV_06("TLSv1.2", "TLSv1.2", "TLSv1.2"), + TLS_CV_07("Default", "TLSv1", "TLSv1.2"); + + final String contextVersion; + final String defaultProtocolVersion; + final String supportedProtocolVersion; + + ContextVersion(String contextVersion, String defaultProtocolVersion, + String supportedProtocolVersion) { + this.contextVersion = contextVersion; + this.defaultProtocolVersion = defaultProtocolVersion; + this.supportedProtocolVersion = supportedProtocolVersion; + } + } + + public static void main(String[] args) throws Exception { + for (ContextVersion cv : ContextVersion.values()) { + System.out.println("Checking SSLContext of " + cv.contextVersion); + SSLContext context = SSLContext.getInstance(cv.contextVersion); + + // Default SSLContext is initialized automatically. + if (!cv.contextVersion.equals("Default")) { + // Use default TK, KM and random. + context.init((KeyManager[])null, (TrustManager[])null, null); + } + + SSLParameters parameters = context.getDefaultSSLParameters(); + + String[] protocols = parameters.getProtocols(); + String[] ciphers = parameters.getCipherSuites(); + + if (protocols.length == 0 || ciphers.length == 0) { + throw new Exception("No default protocols or cipher suites"); + } + + boolean isMatch = false; + for (String protocol : protocols) { + System.out.println("\tdefault protocol version " + protocol); + if (protocol.equals(cv.defaultProtocolVersion)) { + isMatch = true; + break; + } + } + + if (!isMatch) { + throw new Exception("No matched default protocol"); + } + + parameters = context.getSupportedSSLParameters(); + + protocols = parameters.getProtocols(); + ciphers = parameters.getCipherSuites(); + + if (protocols.length == 0 || ciphers.length == 0) { + throw new Exception("No default protocols or cipher suites"); + } + + isMatch = false; + for (String protocol : protocols) { + System.out.println("\tsupported protocol version " + protocol); + if (protocol.equals(cv.supportedProtocolVersion)) { + isMatch = true; + break; + } + } + + if (!isMatch) { + throw new Exception("No matched default protocol"); + } + System.out.println("\t... Success"); + } + } +}