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");
+        }
+    }
+}