src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java
branchJDK-8145252-TLS13-branch
changeset 56542 56aaa6cb3693
parent 47216 71c04702a3d5
child 56611 f8f7e604e1f8
--- a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Fri May 11 14:55:56 2018 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java	Fri May 11 15:53:12 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, 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
@@ -25,23 +25,23 @@
 
 package sun.security.ssl;
 
+import java.io.*;
 import java.net.Socket;
-
-import java.io.*;
-import java.util.*;
 import java.security.*;
 import java.security.cert.*;
-import java.security.cert.Certificate;
-
+import java.util.*;
 import javax.net.ssl.*;
-
+import sun.security.action.GetPropertyAction;
 import sun.security.provider.certpath.AlgorithmChecker;
-import sun.security.action.GetPropertyAction;
 import sun.security.validator.Validator;
 
-public abstract class SSLContextImpl extends SSLContextSpi {
+/**
+ * Implementation of an SSLContext.
+ *
+ * Instances of this class are immutable after the context is initialized.
+ */
 
-    private static final Debug debug = Debug.getInstance("ssl");
+public abstract class SSLContextImpl extends SSLContextSpi {
 
     private final EphemeralKeyManager ephemeralKeyManager;
     private final SSLSessionContextImpl clientCache;
@@ -56,13 +56,13 @@
     // DTLS cookie exchange manager
     private volatile HelloCookieManager helloCookieManager;
 
-    private final boolean clientEnableStapling = Debug.getBooleanProperty(
+    private final boolean clientEnableStapling = Utilities.getBooleanProperty(
             "jdk.tls.client.enableStatusRequestExtension", true);
-    private final boolean serverEnableStapling = Debug.getBooleanProperty(
+    private final boolean serverEnableStapling = Utilities.getBooleanProperty(
             "jdk.tls.server.enableStatusRequestExtension", false);
-    private final static Collection<CipherSuite> clientCustomizedCipherSuites =
+    private static final Collection<CipherSuite> clientCustomizedCipherSuites =
             getCustomizedCipherSuites("jdk.tls.client.cipherSuites");
-    private final static Collection<CipherSuite> serverCustomizedCipherSuites =
+    private static final Collection<CipherSuite> serverCustomizedCipherSuites =
             getCustomizedCipherSuites("jdk.tls.server.cipherSuites");
 
     private volatile StatusResponseManager statusResponseManager;
@@ -109,12 +109,12 @@
          * first connection to timeout and fail. Make sure it is
          * primed and ready by getting some initial output from it.
          */
-        if (debug != null && Debug.isOn("sslctx")) {
-            System.out.println("trigger seeding of SecureRandom");
+        if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
+            SSLLogger.finest("trigger seeding of SecureRandom");
         }
         secureRandom.nextInt();
-        if (debug != null && Debug.isOn("sslctx")) {
-            System.out.println("done seeding SecureRandom");
+        if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
+            SSLLogger.finest("done seeding of SecureRandom");
         }
 
         isInitialized = true;
@@ -168,10 +168,10 @@
             if (km instanceof X509ExtendedKeyManager) {
                 return (X509ExtendedKeyManager)km;
             }
-            if (debug != null && Debug.isOn("sslctx")) {
-                System.out.println(
-                    "X509KeyManager passed to " +
-                    "SSLContext.init():  need an " +
+
+            if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
+                SSLLogger.warning(
+                    "X509KeyManager passed to SSLContext.init():  need an " +
                     "X509ExtendedKeyManager for SSLEngine use");
             }
             return new AbstractKeyManagerWrapper((X509KeyManager)km);
@@ -242,36 +242,27 @@
         return ephemeralKeyManager;
     }
 
-    // Used for DTLS in server mode only, see ServerHandshaker.
-    HelloCookieManager getHelloCookieManager() {
-        if (!isInitialized) {
-            throw new IllegalStateException("SSLContext is not initialized");
-        }
-
+    // Used for DTLS in server mode only.
+    HelloCookieManager getHelloCookieManager(ProtocolVersion protocolVersion) {
         if (helloCookieManager != null) {
-            return helloCookieManager;
+            return helloCookieManager.valueOf(protocolVersion);
         }
 
         synchronized (this) {
             if (helloCookieManager == null) {
-                helloCookieManager = getHelloCookieManager(secureRandom);
+                helloCookieManager = new HelloCookieManager(secureRandom);
             }
         }
 
-        return helloCookieManager;
-    }
-
-    HelloCookieManager getHelloCookieManager(SecureRandom secureRandom) {
-        throw new UnsupportedOperationException(
-                "Cookie exchange applies to DTLS only");
+        return helloCookieManager.valueOf(protocolVersion);
     }
 
     StatusResponseManager getStatusResponseManager() {
         if (serverEnableStapling && statusResponseManager == null) {
             synchronized (this) {
                 if (statusResponseManager == null) {
-                    if (debug != null && Debug.isOn("sslctx")) {
-                        System.out.println(
+                    if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
+                        SSLLogger.finest(
                                 "Initializing StatusResponseManager");
                     }
                     statusResponseManager = new StatusResponseManager();
@@ -282,52 +273,55 @@
         return statusResponseManager;
     }
 
-    // Get supported ProtocolList.
-    abstract ProtocolList getSuportedProtocolList();
+    // Get supported protocols.
+    abstract List<ProtocolVersion> getSuportedProtocolVersions();
+
+    // Get default protocols for server mode.
+    abstract List<ProtocolVersion> getServerDefaultProtocolVersions();
 
-    // Get default ProtocolList for server mode.
-    abstract ProtocolList getServerDefaultProtocolList();
+    // Get default protocols for client mode.
+    abstract List<ProtocolVersion> getClientDefaultProtocolVersions();
 
-    // Get default ProtocolList for client mode.
-    abstract ProtocolList getClientDefaultProtocolList();
+    // Get supported CipherSuite list.
+    abstract List<CipherSuite> getSupportedCipherSuites();
 
-    // Get supported CipherSuiteList.
-    abstract CipherSuiteList getSupportedCipherSuiteList();
+    // Get default CipherSuite list for server mode.
+    abstract List<CipherSuite> getServerDefaultCipherSuites();
 
-    // Get default CipherSuiteList for server mode.
-    abstract CipherSuiteList getServerDefaultCipherSuiteList();
+    // Get default CipherSuite list for client mode.
+    abstract List<CipherSuite> getClientDefaultCipherSuites();
 
-    // Get default CipherSuiteList for client mode.
-    abstract CipherSuiteList getClientDefaultCipherSuiteList();
+    // Is the context for DTLS protocols?
+    abstract boolean isDTLS();
 
-    // Get default ProtocolList.
-    ProtocolList getDefaultProtocolList(boolean roleIsServer) {
-        return roleIsServer ? getServerDefaultProtocolList()
-                            : getClientDefaultProtocolList();
+    // Get default protocols.
+    List<ProtocolVersion> getDefaultProtocolVersions(boolean roleIsServer) {
+        return roleIsServer ? getServerDefaultProtocolVersions()
+                            : getClientDefaultProtocolVersions();
     }
 
-    // Get default CipherSuiteList.
-    CipherSuiteList getDefaultCipherSuiteList(boolean roleIsServer) {
-        return roleIsServer ? getServerDefaultCipherSuiteList()
-                            : getClientDefaultCipherSuiteList();
+    // Get default CipherSuite list.
+    List<CipherSuite> getDefaultCipherSuites(boolean roleIsServer) {
+        return roleIsServer ? getServerDefaultCipherSuites()
+                            : getClientDefaultCipherSuites();
     }
 
     /**
      * Return whether a protocol list is the original default enabled
      * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
      */
-    boolean isDefaultProtocolList(ProtocolList protocols) {
-        return (protocols == getServerDefaultProtocolList()) ||
-               (protocols == getClientDefaultProtocolList());
+    boolean isDefaultProtocolVesions(List<ProtocolVersion> protocols) {
+        return (protocols == getServerDefaultProtocolVersions()) ||
+               (protocols == getClientDefaultProtocolVersions());
     }
 
     /**
      * Return whether a protocol list is the original default enabled
      * protocols.  See: SSLSocket/SSLEngine.setEnabledProtocols()
      */
-    boolean isDefaultCipherSuiteList(CipherSuiteList cipherSuites) {
-        return (cipherSuites == getServerDefaultCipherSuiteList()) ||
-               (cipherSuites == getClientDefaultCipherSuiteList());
+    boolean isDefaultCipherSuiteList(List<CipherSuite> cipherSuites) {
+        return (cipherSuites == getServerDefaultCipherSuites()) ||
+               (cipherSuites == getClientDefaultCipherSuites());
     }
 
     /**
@@ -342,93 +336,83 @@
         return isClient ? clientEnableStapling : serverEnableStapling;
     }
 
-
     /*
      * Return the list of all available CipherSuites that are supported
      * using currently installed providers.
      */
-    private static CipherSuiteList getApplicableSupportedCipherSuiteList(
-            ProtocolList protocols) {
+    private static List<CipherSuite> getApplicableSupportedCipherSuites(
+            List<ProtocolVersion> protocols) {
 
-        return getApplicableCipherSuiteList(
-                CipherSuite.allowedCipherSuites(),
-                protocols, CipherSuite.SUPPORTED_SUITES_PRIORITY);
+        return getApplicableCipherSuites(
+                CipherSuite.allowedCipherSuites(), protocols);
     }
 
     /*
      * Return the list of all available CipherSuites that are default enabled
      * in client or server side.
      */
-    private static CipherSuiteList getApplicableEnabledCipherSuiteList(
-            ProtocolList protocols, boolean isClient) {
+    private static List<CipherSuite> getApplicableEnabledCipherSuites(
+            List<ProtocolVersion> protocols, boolean isClient) {
 
         if (isClient) {
             if (!clientCustomizedCipherSuites.isEmpty()) {
-                return getApplicableCipherSuiteList(
-                        clientCustomizedCipherSuites,
-                        protocols, CipherSuite.SUPPORTED_SUITES_PRIORITY);
+                return getApplicableCipherSuites(
+                        clientCustomizedCipherSuites, protocols);
             }
         } else {
             if (!serverCustomizedCipherSuites.isEmpty()) {
-                return getApplicableCipherSuiteList(
-                        serverCustomizedCipherSuites,
-                        protocols, CipherSuite.SUPPORTED_SUITES_PRIORITY);
+                return getApplicableCipherSuites(
+                        serverCustomizedCipherSuites, protocols);
             }
         }
 
-        return getApplicableCipherSuiteList(
-                CipherSuite.allowedCipherSuites(),
-                protocols, CipherSuite.DEFAULT_SUITES_PRIORITY);
+        return getApplicableCipherSuites(
+                CipherSuite.defaultCipherSuites(), protocols);
     }
 
     /*
      * Return the list of available CipherSuites which are applicable to
      * the specified protocols.
      */
-    private static CipherSuiteList getApplicableCipherSuiteList(
+    private static List<CipherSuite> getApplicableCipherSuites(
             Collection<CipherSuite> allowedCipherSuites,
-            ProtocolList protocols, int minPriority) {
-
+            List<ProtocolVersion> protocols) {
         TreeSet<CipherSuite> suites = new TreeSet<>();
-        if (!(protocols.collection().isEmpty()) &&
-                protocols.min.v != ProtocolVersion.NONE.v) {
+        if (protocols != null && (!protocols.isEmpty())) {
             for (CipherSuite suite : allowedCipherSuites) {
-                if (!suite.allowed || suite.priority < minPriority) {
+                if (!suite.isAvailable()) {
                     continue;
                 }
 
-                if (suite.isAvailable() &&
-                        !protocols.min.obsoletes(suite) &&
-                        protocols.max.supports(suite)) {
+                boolean isSupported = false;
+                for (ProtocolVersion protocol : protocols) {
+                    if (!suite.supports(protocol)) {
+                        continue;
+                    }
+
                     if (SSLAlgorithmConstraints.DEFAULT.permits(
                             EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
                             suite.name, null)) {
                         suites.add(suite);
-                    } else {
-                        if (debug != null && Debug.isOn("sslctx") &&
-                                Debug.isOn("verbose")) {
-                            System.out.println(
-                                    "Ignoring disabled cipher suite: " +
-                                            suite.name);
-                        }
+                        isSupported = true;
+                    } else if (SSLLogger.isOn &&
+                            SSLLogger.isOn("ssl,sslctx,verbose")) {
+                        SSLLogger.fine(
+                                "Ignore disabled cipher suite: " + suite.name);
                     }
-                } else if (debug != null &&
-                        Debug.isOn("sslctx") && Debug.isOn("verbose")) {
-                    if (protocols.min.obsoletes(suite)) {
-                        System.out.println(
-                            "Ignoring obsoleted cipher suite: " + suite);
-                    } else if (!protocols.max.supports(suite)) {
-                        System.out.println(
-                            "Ignoring unsupported cipher suite: " + suite);
-                    } else {
-                        System.out.println(
-                            "Ignoring unavailable cipher suite: " + suite);
-                    }
+
+                    break;
+                }
+
+                if (!isSupported && SSLLogger.isOn &&
+                        SSLLogger.isOn("ssl,sslctx,verbose")) {
+                    SSLLogger.finest(
+                            "Ignore unsupported cipher suite: " + suite);
                 }
             }
         }
 
-        return new CipherSuiteList(suites);
+        return Arrays.asList(suites.toArray(new CipherSuite[0]));
     }
 
     /*
@@ -438,8 +422,8 @@
             String propertyName) {
 
         String property = GetPropertyAction.privilegedGetProperty(propertyName);
-        if (debug != null && Debug.isOn("sslctx")) {
-            System.out.println(
+        if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
+            SSLLogger.fine(
                     "System property " + propertyName + " is set to '" +
                     property + "'");
         }
@@ -463,10 +447,10 @@
 
                 CipherSuite suite;
                 try {
-                    suite = CipherSuite.valueOf(cipherSuiteNames[i]);
+                    suite = CipherSuite.nameOf(cipherSuiteNames[i]);
                 } catch (IllegalArgumentException iae) {
-                    if (debug != null && Debug.isOn("sslctx")) {
-                        System.out.println(
+                    if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
+                        SSLLogger.fine(
                                 "Unknown or unsupported cipher suite name: " +
                                 cipherSuiteNames[i]);
                     }
@@ -474,11 +458,11 @@
                     continue;
                 }
 
-                if (suite.isAvailable()) {
+                if (suite != null && suite.isAvailable()) {
                     cipherSuites.add(suite);
                 } else {
-                    if (debug != null && Debug.isOn("sslctx")) {
-                        System.out.println(
+                    if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
+                        SSLLogger.fine(
                                 "The current installed providers do not " +
                                 "support cipher suite: " + cipherSuiteNames[i]);
                     }
@@ -492,23 +476,23 @@
     }
 
 
-    private static String[] getAvailableProtocols(
+    private static List<ProtocolVersion> getAvailableProtocols(
             ProtocolVersion[] protocolCandidates) {
 
-        List<String> availableProtocols = Collections.<String>emptyList();
+        List<ProtocolVersion> availableProtocols =
+                Collections.<ProtocolVersion>emptyList();
         if (protocolCandidates !=  null && protocolCandidates.length != 0) {
             availableProtocols = new ArrayList<>(protocolCandidates.length);
             for (ProtocolVersion p : protocolCandidates) {
-                if (ProtocolVersion.availableProtocols.contains(p)) {
-                    availableProtocols.add(p.name);
+                if (p.isAvailable) {
+                    availableProtocols.add(p);
                 }
             }
         }
 
-        return availableProtocols.toArray(new String[0]);
+        return availableProtocols;
     }
 
-
     /*
      * The SSLContext implementation for SSL/(D)TLS algorithm
      *
@@ -548,79 +532,88 @@
      * @see SSLContext
      */
     private abstract static class AbstractTLSContext extends SSLContextImpl {
-        private static final ProtocolList supportedProtocolList;
-        private static final ProtocolList serverDefaultProtocolList;
+        private static final List<ProtocolVersion> supportedProtocols;
+        private static final List<ProtocolVersion> serverDefaultProtocols;
 
-        private static final CipherSuiteList supportedCipherSuiteList;
-        private static final CipherSuiteList serverDefaultCipherSuiteList;
+        private static final List<CipherSuite> supportedCipherSuites;
+        private static final List<CipherSuite> serverDefaultCipherSuites;
 
         static {
             if (SunJSSE.isFIPS()) {
-                supportedProtocolList = new ProtocolList(new String[] {
-                    ProtocolVersion.TLS10.name,
-                    ProtocolVersion.TLS11.name,
-                    ProtocolVersion.TLS12.name
-                });
+                supportedProtocols = Arrays.asList(
+                    ProtocolVersion.TLS13,
+                    ProtocolVersion.TLS12,
+                    ProtocolVersion.TLS11,
+                    ProtocolVersion.TLS10
+                );
 
-                serverDefaultProtocolList = new ProtocolList(
-                        getAvailableProtocols(new ProtocolVersion[] {
-                    ProtocolVersion.TLS10,
+                serverDefaultProtocols = getAvailableProtocols(
+                        new ProtocolVersion[] {
+                    ProtocolVersion.TLS13,
+                    ProtocolVersion.TLS12,
                     ProtocolVersion.TLS11,
-                    ProtocolVersion.TLS12
-                }));
+                    ProtocolVersion.TLS10
+                });
             } else {
-                supportedProtocolList = new ProtocolList(new String[] {
-                    ProtocolVersion.SSL20Hello.name,
-                    ProtocolVersion.SSL30.name,
-                    ProtocolVersion.TLS10.name,
-                    ProtocolVersion.TLS11.name,
-                    ProtocolVersion.TLS12.name
-                });
+                supportedProtocols = Arrays.asList(
+                    ProtocolVersion.TLS13,
+                    ProtocolVersion.TLS12,
+                    ProtocolVersion.TLS11,
+                    ProtocolVersion.TLS10,
+                    ProtocolVersion.SSL30,
+                    ProtocolVersion.SSL20Hello
+                );
 
-                serverDefaultProtocolList = new ProtocolList(
-                        getAvailableProtocols(new ProtocolVersion[] {
-                    ProtocolVersion.SSL20Hello,
+                serverDefaultProtocols = getAvailableProtocols(
+                        new ProtocolVersion[] {
+                    ProtocolVersion.TLS13,
+                    ProtocolVersion.TLS12,
+                    ProtocolVersion.TLS11,
+                    ProtocolVersion.TLS10,
                     ProtocolVersion.SSL30,
-                    ProtocolVersion.TLS10,
-                    ProtocolVersion.TLS11,
-                    ProtocolVersion.TLS12
-                }));
+                    ProtocolVersion.SSL20Hello
+                });
             }
 
-            supportedCipherSuiteList = getApplicableSupportedCipherSuiteList(
-                    supportedProtocolList);
-            serverDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
-                    serverDefaultProtocolList, false);
+            supportedCipherSuites = getApplicableSupportedCipherSuites(
+                    supportedProtocols);
+            serverDefaultCipherSuites = getApplicableEnabledCipherSuites(
+                    serverDefaultProtocols, false);
         }
 
         @Override
-        ProtocolList getSuportedProtocolList() {
-            return supportedProtocolList;
+        List<ProtocolVersion> getSuportedProtocolVersions() {
+            return supportedProtocols;
         }
 
         @Override
-        CipherSuiteList getSupportedCipherSuiteList() {
-            return supportedCipherSuiteList;
+        List<CipherSuite> getSupportedCipherSuites() {
+            return supportedCipherSuites;
         }
 
         @Override
-        ProtocolList getServerDefaultProtocolList() {
-            return serverDefaultProtocolList;
+        List<ProtocolVersion> getServerDefaultProtocolVersions() {
+            return serverDefaultProtocols;
         }
 
         @Override
-        CipherSuiteList getServerDefaultCipherSuiteList() {
-            return serverDefaultCipherSuiteList;
+        List<CipherSuite> getServerDefaultCipherSuites() {
+            return serverDefaultCipherSuites;
         }
 
         @Override
         SSLEngine createSSLEngineImpl() {
-            return new SSLEngineImpl(this, false);
+            return new SSLEngineImpl(this);
         }
 
         @Override
         SSLEngine createSSLEngineImpl(String host, int port) {
-            return new SSLEngineImpl(this, host, port, false);
+            return new SSLEngineImpl(this, host, port);
+        }
+
+        @Override
+        boolean isDTLS() {
+            return false;
         }
     }
 
@@ -630,35 +623,35 @@
      * @see SSLContext
      */
     public static final class TLS10Context extends AbstractTLSContext {
-        private static final ProtocolList clientDefaultProtocolList;
-        private static final CipherSuiteList clientDefaultCipherSuiteList;
+        private static final List<ProtocolVersion> clientDefaultProtocols;
+        private static final List<CipherSuite> clientDefaultCipherSuites;
 
         static {
             if (SunJSSE.isFIPS()) {
-                clientDefaultProtocolList = new ProtocolList(
-                        getAvailableProtocols(new ProtocolVersion[] {
+                clientDefaultProtocols = getAvailableProtocols(
+                        new ProtocolVersion[] {
                     ProtocolVersion.TLS10
-                }));
+                });
             } else {
-                clientDefaultProtocolList = new ProtocolList(
-                        getAvailableProtocols(new ProtocolVersion[] {
-                    ProtocolVersion.SSL30,
-                    ProtocolVersion.TLS10
-                }));
+                clientDefaultProtocols = getAvailableProtocols(
+                        new ProtocolVersion[] {
+                    ProtocolVersion.TLS10,
+                    ProtocolVersion.SSL30
+                });
             }
 
-            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
-                    clientDefaultProtocolList, true);
+            clientDefaultCipherSuites = getApplicableEnabledCipherSuites(
+                    clientDefaultProtocols, true);
         }
 
         @Override
-        ProtocolList getClientDefaultProtocolList() {
-            return clientDefaultProtocolList;
+        List<ProtocolVersion> getClientDefaultProtocolVersions() {
+            return clientDefaultProtocols;
         }
 
         @Override
-        CipherSuiteList getClientDefaultCipherSuiteList() {
-            return clientDefaultCipherSuiteList;
+        List<CipherSuite> getClientDefaultCipherSuites() {
+            return clientDefaultCipherSuites;
         }
     }
 
@@ -668,38 +661,38 @@
      * @see SSLContext
      */
     public static final class TLS11Context extends AbstractTLSContext {
-        private static final ProtocolList clientDefaultProtocolList;
-        private static final CipherSuiteList clientDefaultCipherSuiteList;
+        private static final List<ProtocolVersion> clientDefaultProtocols;
+        private static final List<CipherSuite> clientDefaultCipherSuites;
 
         static {
             if (SunJSSE.isFIPS()) {
-                clientDefaultProtocolList = new ProtocolList(
-                        getAvailableProtocols(new ProtocolVersion[] {
-                    ProtocolVersion.TLS10,
-                    ProtocolVersion.TLS11
-                }));
+                clientDefaultProtocols = getAvailableProtocols(
+                        new ProtocolVersion[] {
+                    ProtocolVersion.TLS11,
+                    ProtocolVersion.TLS10
+                });
             } else {
-                clientDefaultProtocolList = new ProtocolList(
-                        getAvailableProtocols(new ProtocolVersion[] {
-                    ProtocolVersion.SSL30,
+                clientDefaultProtocols = getAvailableProtocols(
+                        new ProtocolVersion[] {
+                    ProtocolVersion.TLS11,
                     ProtocolVersion.TLS10,
-                    ProtocolVersion.TLS11
-                }));
+                    ProtocolVersion.SSL30
+                });
             }
 
-            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
-                    clientDefaultProtocolList, true);
+            clientDefaultCipherSuites = getApplicableEnabledCipherSuites(
+                    clientDefaultProtocols, true);
 
         }
 
         @Override
-        ProtocolList getClientDefaultProtocolList() {
-            return clientDefaultProtocolList;
+        List<ProtocolVersion> getClientDefaultProtocolVersions() {
+            return clientDefaultProtocols;
         }
 
         @Override
-        CipherSuiteList getClientDefaultCipherSuiteList() {
-            return clientDefaultCipherSuiteList;
+        List<CipherSuite> getClientDefaultCipherSuites() {
+            return clientDefaultCipherSuites;
         }
     }
 
@@ -709,39 +702,83 @@
      * @see SSLContext
      */
     public static final class TLS12Context extends AbstractTLSContext {
-        private static final ProtocolList clientDefaultProtocolList;
-        private static final CipherSuiteList clientDefaultCipherSuiteList;
+        private static final List<ProtocolVersion> clientDefaultProtocols;
+        private static final List<CipherSuite> clientDefaultCipherSuites;
 
         static {
             if (SunJSSE.isFIPS()) {
-                clientDefaultProtocolList = new ProtocolList(
-                        getAvailableProtocols(new ProtocolVersion[] {
-                    ProtocolVersion.TLS10,
+                clientDefaultProtocols = getAvailableProtocols(
+                        new ProtocolVersion[] {
+                    ProtocolVersion.TLS12,
                     ProtocolVersion.TLS11,
-                    ProtocolVersion.TLS12
-                }));
+                    ProtocolVersion.TLS10
+                });
             } else {
-                clientDefaultProtocolList = new ProtocolList(
-                        getAvailableProtocols(new ProtocolVersion[] {
-                    ProtocolVersion.SSL30,
+                clientDefaultProtocols = getAvailableProtocols(
+                        new ProtocolVersion[] {
+                    ProtocolVersion.TLS12,
+                    ProtocolVersion.TLS11,
                     ProtocolVersion.TLS10,
-                    ProtocolVersion.TLS11,
-                    ProtocolVersion.TLS12
-                }));
+                    ProtocolVersion.SSL30
+                });
             }
 
-            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
-                    clientDefaultProtocolList, true);
+            clientDefaultCipherSuites = getApplicableEnabledCipherSuites(
+                    clientDefaultProtocols, true);
+        }
+
+        @Override
+        List<ProtocolVersion> getClientDefaultProtocolVersions() {
+            return clientDefaultProtocols;
         }
 
         @Override
-        ProtocolList getClientDefaultProtocolList() {
-            return clientDefaultProtocolList;
+        List<CipherSuite> getClientDefaultCipherSuites() {
+            return clientDefaultCipherSuites;
+        }
+    }
+
+    /*
+     * The SSLContext implementation for TLS1.3 algorithm
+     *
+     * @see SSLContext
+     */
+    public static final class TLS13Context extends AbstractTLSContext {
+        private static final List<ProtocolVersion> clientDefaultProtocols;
+        private static final List<CipherSuite> clientDefaultCipherSuites;
+
+        static {
+            if (SunJSSE.isFIPS()) {
+                clientDefaultProtocols = getAvailableProtocols(
+                        new ProtocolVersion[] {
+                    ProtocolVersion.TLS13,
+                    ProtocolVersion.TLS12,
+                    ProtocolVersion.TLS11,
+                    ProtocolVersion.TLS10
+                });
+            } else {
+                clientDefaultProtocols = getAvailableProtocols(
+                        new ProtocolVersion[] {
+                    ProtocolVersion.TLS13,
+                    ProtocolVersion.TLS12,
+                    ProtocolVersion.TLS11,
+                    ProtocolVersion.TLS10,
+                    ProtocolVersion.SSL30
+                });
+            }
+
+            clientDefaultCipherSuites = getApplicableEnabledCipherSuites(
+                    clientDefaultProtocols, true);
         }
 
         @Override
-        CipherSuiteList getClientDefaultCipherSuiteList() {
-            return clientDefaultCipherSuiteList;
+        List<ProtocolVersion> getClientDefaultProtocolVersions() {
+            return clientDefaultProtocols;
+        }
+
+        @Override
+        List<CipherSuite> getClientDefaultCipherSuites() {
+            return clientDefaultCipherSuites;
         }
     }
 
@@ -753,7 +790,7 @@
     private static class CustomizedSSLProtocols {
         private static final String PROPERTY_NAME = "jdk.tls.client.protocols";
         static IllegalArgumentException reservedException = null;
-        static ArrayList<ProtocolVersion>
+        static final ArrayList<ProtocolVersion>
                                 customizedProtocols = new ArrayList<>();
 
         // Don't want a java.lang.LinkageError for illegal system property.
@@ -778,28 +815,27 @@
                 for (int i = 0; i < protocols.length; i++) {
                     protocols[i] = protocols[i].trim();
                     // Is it a supported protocol name?
-                    try {
-                        ProtocolVersion pro =
-                                ProtocolVersion.valueOf(protocols[i]);
-
-                        if (SunJSSE.isFIPS() &&
-                                ((pro.v == ProtocolVersion.SSL30.v) ||
-                                 (pro.v == ProtocolVersion.SSL20Hello.v))) {
-                            reservedException = new IllegalArgumentException(
-                                    PROPERTY_NAME + ": " + pro +
-                                    " is not FIPS compliant");
+                    ProtocolVersion pv =
+                            ProtocolVersion.nameOf(protocols[i]);
+                    if (pv == null) {
+                        reservedException = new IllegalArgumentException(
+                            PROPERTY_NAME + ": " + protocols[i] +
+                            " is not a supported SSL protocol name");
+                    }
 
-                            break;
-                        }
+                    if (SunJSSE.isFIPS() &&
+                            ((pv == ProtocolVersion.SSL30) ||
+                             (pv == ProtocolVersion.SSL20Hello))) {
+                        reservedException = new IllegalArgumentException(
+                                PROPERTY_NAME + ": " + pv +
+                                " is not FIPS compliant");
 
-                        // ignore duplicated protocols
-                        if (!customizedProtocols.contains(pro)) {
-                            customizedProtocols.add(pro);
-                        }
-                    } catch (IllegalArgumentException iae) {
-                        reservedException = new IllegalArgumentException(
-                                PROPERTY_NAME + ": " + protocols[i] +
-                                " is not a standard SSL protocol name", iae);
+                        break;
+                    }
+
+                    // ignore duplicated protocols
+                    if (!customizedProtocols.contains(pv)) {
+                        customizedProtocols.add(pv);
                     }
                 }
             }
@@ -813,10 +849,9 @@
      */
     private static class CustomizedTLSContext extends AbstractTLSContext {
 
-        private static final ProtocolList clientDefaultProtocolList;
-        private static final CipherSuiteList clientDefaultCipherSuiteList;
-
-        private static IllegalArgumentException reservedException = null;
+        private static final List<ProtocolVersion> clientDefaultProtocols;
+        private static final List<CipherSuite> clientDefaultCipherSuites;
+        private static final IllegalArgumentException reservedException;
 
         // Don't want a java.lang.LinkageError for illegal system property.
         //
@@ -831,7 +866,7 @@
                         customizedTLSProtocols = new ArrayList<>();
                 for (ProtocolVersion protocol :
                         CustomizedSSLProtocols.customizedProtocols) {
-                    if (!protocol.isDTLSProtocol()) {
+                    if (!protocol.isDTLS) {
                         customizedTLSProtocols.add(protocol);
                     }
                 }
@@ -843,16 +878,18 @@
                     // customized TLS protocols.
                     if (SunJSSE.isFIPS()) {
                         candidates = new ProtocolVersion[] {
-                            ProtocolVersion.TLS10,
+                            ProtocolVersion.TLS13,
+                            ProtocolVersion.TLS12,
                             ProtocolVersion.TLS11,
-                            ProtocolVersion.TLS12
+                            ProtocolVersion.TLS10
                         };
                     } else {
                         candidates = new ProtocolVersion[] {
-                            ProtocolVersion.SSL30,
+                            ProtocolVersion.TLS13,
+                            ProtocolVersion.TLS12,
+                            ProtocolVersion.TLS11,
                             ProtocolVersion.TLS10,
-                            ProtocolVersion.TLS11,
-                            ProtocolVersion.TLS12
+                            ProtocolVersion.SSL30
                         };
                     }
                 } else {
@@ -862,14 +899,13 @@
                     candidates = customizedTLSProtocols.toArray(candidates);
                 }
 
-                clientDefaultProtocolList = new ProtocolList(
-                        getAvailableProtocols(candidates));
-                clientDefaultCipherSuiteList =
-                        getApplicableEnabledCipherSuiteList(
-                                clientDefaultProtocolList, true);
+                clientDefaultProtocols = getAvailableProtocols(candidates);
+                clientDefaultCipherSuites =
+                        getApplicableEnabledCipherSuites(
+                                clientDefaultProtocols, true);
             } else {
-                clientDefaultProtocolList = null;       // unlikely to be used
-                clientDefaultCipherSuiteList = null;    // unlikely to be used
+                clientDefaultProtocols = null;       // unlikely to be used
+                clientDefaultCipherSuites = null;    // unlikely to be used
             }
         }
 
@@ -880,13 +916,13 @@
         }
 
         @Override
-        ProtocolList getClientDefaultProtocolList() {
-            return clientDefaultProtocolList;
+        List<ProtocolVersion> getClientDefaultProtocolVersions() {
+            return clientDefaultProtocols;
         }
 
         @Override
-        CipherSuiteList getClientDefaultCipherSuiteList() {
-            return clientDefaultCipherSuiteList;
+        List<CipherSuite> getClientDefaultCipherSuites() {
+            return clientDefaultCipherSuites;
         }
     }
 
@@ -909,30 +945,33 @@
         private static final TrustManager[] trustManagers;
         private static final KeyManager[] keyManagers;
 
-        static Exception reservedException = null;
+        private static final Exception reservedException;
 
         static {
+            Exception reserved = null;
             TrustManager[] tmMediator;
             try {
                 tmMediator = getTrustManagers();
             } catch (Exception e) {
-                reservedException = e;
+                reserved = e;
                 tmMediator = new TrustManager[0];
             }
             trustManagers = tmMediator;
 
-            if (reservedException == null) {
+            if (reserved == null) {
                 KeyManager[] kmMediator;
                 try {
                     kmMediator = getKeyManagers();
                 } catch (Exception e) {
-                    reservedException = e;
+                    reserved = e;
                     kmMediator = new KeyManager[0];
                 }
                 keyManagers = kmMediator;
             } else {
                 keyManagers = new KeyManager[0];
             }
+
+            reservedException = reserved;
         }
 
         private static TrustManager[] getTrustManagers() throws Exception {
@@ -976,11 +1015,11 @@
             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 : " +
+            if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) {
+                SSLLogger.fine("keyStore is : " + defaultKeyStore);
+                SSLLogger.fine("keyStore type is : " +
                                         defaultKeyStoreType);
-                System.out.println("keyStore provider is : " +
+                SSLLogger.fine("keyStore provider is : " +
                                         defaultKeyStoreProvider);
             }
 
@@ -1014,8 +1053,8 @@
                  * Try to initialize key store.
                  */
                 if ((defaultKeyStoreType.length()) != 0) {
-                    if (debug != null && Debug.isOn("defaultctx")) {
-                        System.out.println("init keystore");
+                    if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) {
+                        SSLLogger.finest("init keystore");
                     }
                     if (defaultKeyStoreProvider.length() == 0) {
                         ks = KeyStore.getInstance(defaultKeyStoreType);
@@ -1037,8 +1076,8 @@
             /*
              * Try to initialize key manager.
              */
-            if (debug != null && Debug.isOn("defaultctx")) {
-                System.out.println("init keymanager of type " +
+            if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) {
+                SSLLogger.fine("init keymanager of type " +
                     KeyManagerFactory.getDefaultAlgorithm());
             }
             KeyManagerFactory kmf = KeyManagerFactory.getInstance(
@@ -1095,8 +1134,8 @@
                 super.engineInit(DefaultManagersHolder.keyManagers,
                         DefaultManagersHolder.trustManagers, null);
             } catch (Exception e) {
-                if (debug != null && Debug.isOn("defaultctx")) {
-                    System.out.println("default context init failed: " + e);
+                if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) {
+                    SSLLogger.fine("default context init failed: ", e);
                 }
                 throw e;
             }
@@ -1128,65 +1167,65 @@
      * @see SSLContext
      */
     private abstract static class AbstractDTLSContext extends SSLContextImpl {
-        private static final ProtocolList supportedProtocolList;
-        private static final ProtocolList serverDefaultProtocolList;
+        private static final List<ProtocolVersion> supportedProtocols;
+        private static final List<ProtocolVersion> serverDefaultProtocols;
 
-        private static final CipherSuiteList supportedCipherSuiteList;
-        private static final CipherSuiteList serverDefaultCipherSuiteList;
+        private static final List<CipherSuite> supportedCipherSuites;
+        private static final List<CipherSuite> serverDefaultCipherSuites;
 
         static {
             // Both DTLSv1.0 and DTLSv1.2 can be used in FIPS mode.
-            supportedProtocolList = new ProtocolList(new String[] {
-                ProtocolVersion.DTLS10.name,
-                ProtocolVersion.DTLS12.name
-            });
+            supportedProtocols = Arrays.asList(
+                ProtocolVersion.DTLS12,
+                ProtocolVersion.DTLS10
+            );
 
             // available protocols for server mode
-            serverDefaultProtocolList = new ProtocolList(
-                    getAvailableProtocols(new ProtocolVersion[] {
-                ProtocolVersion.DTLS10,
-                ProtocolVersion.DTLS12
-            }));
+            serverDefaultProtocols = getAvailableProtocols(
+                    new ProtocolVersion[] {
+                ProtocolVersion.DTLS12,
+                ProtocolVersion.DTLS10
+            });
 
-            supportedCipherSuiteList = getApplicableSupportedCipherSuiteList(
-                    supportedProtocolList);
-            serverDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
-                    serverDefaultProtocolList, false);
+            supportedCipherSuites = getApplicableSupportedCipherSuites(
+                    supportedProtocols);
+            serverDefaultCipherSuites = getApplicableEnabledCipherSuites(
+                    serverDefaultProtocols, false);
         }
 
         @Override
-        ProtocolList getSuportedProtocolList() {
-            return supportedProtocolList;
+        List<ProtocolVersion> getSuportedProtocolVersions() {
+            return supportedProtocols;
         }
 
         @Override
-        CipherSuiteList getSupportedCipherSuiteList() {
-            return supportedCipherSuiteList;
+        List<CipherSuite> getSupportedCipherSuites() {
+            return supportedCipherSuites;
         }
 
         @Override
-        ProtocolList getServerDefaultProtocolList() {
-            return serverDefaultProtocolList;
+        List<ProtocolVersion> getServerDefaultProtocolVersions() {
+            return serverDefaultProtocols;
         }
 
         @Override
-        CipherSuiteList getServerDefaultCipherSuiteList() {
-            return serverDefaultCipherSuiteList;
+        List<CipherSuite> getServerDefaultCipherSuites() {
+            return serverDefaultCipherSuites;
         }
 
         @Override
         SSLEngine createSSLEngineImpl() {
-            return new SSLEngineImpl(this, true);
+            return new SSLEngineImpl(this);
         }
 
         @Override
         SSLEngine createSSLEngineImpl(String host, int port) {
-            return new SSLEngineImpl(this, host, port, true);
+            return new SSLEngineImpl(this, host, port);
         }
 
         @Override
-        HelloCookieManager getHelloCookieManager(SecureRandom secureRandom) {
-            return new HelloCookieManager(secureRandom);
+        boolean isDTLS() {
+            return true;
         }
     }
 
@@ -1196,28 +1235,28 @@
      * @see SSLContext
      */
     public static final class DTLS10Context extends AbstractDTLSContext {
-        private static final ProtocolList clientDefaultProtocolList;
-        private static final CipherSuiteList clientDefaultCipherSuiteList;
+        private static final List<ProtocolVersion> clientDefaultProtocols;
+        private static final List<CipherSuite> clientDefaultCipherSuites;
 
         static {
             // available protocols for client mode
-            clientDefaultProtocolList = new ProtocolList(
-                    getAvailableProtocols(new ProtocolVersion[] {
+            clientDefaultProtocols = getAvailableProtocols(
+                    new ProtocolVersion[] {
                 ProtocolVersion.DTLS10
-            }));
+            });
 
-            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
-                    clientDefaultProtocolList, true);
+            clientDefaultCipherSuites = getApplicableEnabledCipherSuites(
+                    clientDefaultProtocols, true);
         }
 
         @Override
-        ProtocolList getClientDefaultProtocolList() {
-            return clientDefaultProtocolList;
+        List<ProtocolVersion> getClientDefaultProtocolVersions() {
+            return clientDefaultProtocols;
         }
 
         @Override
-        CipherSuiteList getClientDefaultCipherSuiteList() {
-            return clientDefaultCipherSuiteList;
+        List<CipherSuite> getClientDefaultCipherSuites() {
+            return clientDefaultCipherSuites;
         }
     }
 
@@ -1227,29 +1266,29 @@
      * @see SSLContext
      */
     public static final class DTLS12Context extends AbstractDTLSContext {
-        private static final ProtocolList clientDefaultProtocolList;
-        private static final CipherSuiteList clientDefaultCipherSuiteList;
+        private static final List<ProtocolVersion> clientDefaultProtocols;
+        private static final List<CipherSuite> clientDefaultCipherSuites;
 
         static {
             // available protocols for client mode
-            clientDefaultProtocolList = new ProtocolList(
-                    getAvailableProtocols(new ProtocolVersion[] {
-                ProtocolVersion.DTLS10,
-                ProtocolVersion.DTLS12
-            }));
+            clientDefaultProtocols = getAvailableProtocols(
+                    new ProtocolVersion[] {
+                ProtocolVersion.DTLS12,
+                ProtocolVersion.DTLS10
+            });
 
-            clientDefaultCipherSuiteList = getApplicableEnabledCipherSuiteList(
-                    clientDefaultProtocolList, true);
+            clientDefaultCipherSuites = getApplicableEnabledCipherSuites(
+                    clientDefaultProtocols, true);
         }
 
         @Override
-        ProtocolList getClientDefaultProtocolList() {
-            return clientDefaultProtocolList;
+        List<ProtocolVersion> getClientDefaultProtocolVersions() {
+            return clientDefaultProtocols;
         }
 
         @Override
-        CipherSuiteList getClientDefaultCipherSuiteList() {
-            return clientDefaultCipherSuiteList;
+        List<CipherSuite> getClientDefaultCipherSuites() {
+            return clientDefaultCipherSuites;
         }
     }
 
@@ -1259,8 +1298,8 @@
      * @see SSLContext
      */
     private static class CustomizedDTLSContext extends AbstractDTLSContext {
-        private static final ProtocolList clientDefaultProtocolList;
-        private static final CipherSuiteList clientDefaultCipherSuiteList;
+        private static final List<ProtocolVersion> clientDefaultProtocols;
+        private static final List<CipherSuite> clientDefaultCipherSuites;
 
         private static IllegalArgumentException reservedException = null;
 
@@ -1277,7 +1316,7 @@
                         customizedDTLSProtocols = new ArrayList<>();
                 for (ProtocolVersion protocol :
                         CustomizedSSLProtocols.customizedProtocols) {
-                    if (protocol.isDTLSProtocol()) {
+                    if (protocol.isDTLS) {
                         customizedDTLSProtocols.add(protocol);
                     }
                 }
@@ -1290,8 +1329,8 @@
                     //
                     // Both DTLSv1.0 and DTLSv1.2 can be used in FIPS mode.
                     candidates = new ProtocolVersion[] {
-                        ProtocolVersion.DTLS10,
-                        ProtocolVersion.DTLS12
+                        ProtocolVersion.DTLS12,
+                        ProtocolVersion.DTLS10
                     };
 
                 } else {
@@ -1301,14 +1340,13 @@
                     candidates = customizedDTLSProtocols.toArray(candidates);
                 }
 
-                clientDefaultProtocolList = new ProtocolList(
-                        getAvailableProtocols(candidates));
-                clientDefaultCipherSuiteList =
-                        getApplicableEnabledCipherSuiteList(
-                                clientDefaultProtocolList, true);
+                clientDefaultProtocols = getAvailableProtocols(candidates);
+                clientDefaultCipherSuites =
+                        getApplicableEnabledCipherSuites(
+                                clientDefaultProtocols, true);
             } else {
-                clientDefaultProtocolList = null;       // unlikely to be used
-                clientDefaultCipherSuiteList = null;    // unlikely to be used
+                clientDefaultProtocols = null;       // unlikely to be used
+                clientDefaultCipherSuites = null;    // unlikely to be used
             }
         }
 
@@ -1319,13 +1357,13 @@
         }
 
         @Override
-        ProtocolList getClientDefaultProtocolList() {
-            return clientDefaultProtocolList;
+        List<ProtocolVersion> getClientDefaultProtocolVersions() {
+            return clientDefaultProtocols;
         }
 
         @Override
-        CipherSuiteList getClientDefaultCipherSuiteList() {
-            return clientDefaultCipherSuiteList;
+        List<CipherSuite> getClientDefaultCipherSuites() {
+            return clientDefaultCipherSuites;
         }
     }
 
@@ -1340,7 +1378,6 @@
 
 }
 
-
 final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
             implements X509TrustManager {
 
@@ -1417,10 +1454,8 @@
             }
 
             // try the best to check the algorithm constraints
-            ProtocolVersion protocolVersion =
-                ProtocolVersion.valueOf(session.getProtocol());
-            AlgorithmConstraints constraints = null;
-            if (protocolVersion.useTLS12PlusSpec()) {
+            AlgorithmConstraints constraints;
+            if (ProtocolVersion.useTLS12PlusSpec(session.getProtocol())) {
                 if (session instanceof ExtendedSSLSession) {
                     ExtendedSSLSession extSession =
                                     (ExtendedSSLSession)session;
@@ -1459,10 +1494,8 @@
             }
 
             // try the best to check the algorithm constraints
-            ProtocolVersion protocolVersion =
-                ProtocolVersion.valueOf(session.getProtocol());
-            AlgorithmConstraints constraints = null;
-            if (protocolVersion.useTLS12PlusSpec()) {
+            AlgorithmConstraints constraints;
+            if (ProtocolVersion.useTLS12PlusSpec(session.getProtocol())) {
                 if (session instanceof ExtendedSSLSession) {
                     ExtendedSSLSession extSession =
                                     (ExtendedSSLSession)session;
@@ -1484,8 +1517,8 @@
     }
 
     private void checkAlgorithmConstraints(X509Certificate[] chain,
-            AlgorithmConstraints constraints, boolean isClient) throws CertificateException {
-
+            AlgorithmConstraints constraints,
+            boolean isClient) throws CertificateException {
         try {
             // Does the certificate chain end with a trusted certificate?
             int checkedLength = chain.length - 1;
@@ -1503,11 +1536,12 @@
             // A forward checker, need to check from trust to target
             if (checkedLength >= 0) {
                 AlgorithmChecker checker =
-                        new AlgorithmChecker(constraints, null,
-                                (isClient ? Validator.VAR_TLS_CLIENT : Validator.VAR_TLS_SERVER));
+                    new AlgorithmChecker(constraints, null,
+                            (isClient ? Validator.VAR_TLS_CLIENT :
+                                        Validator.VAR_TLS_SERVER));
                 checker.init(false);
                 for (int i = checkedLength; i >= 0; i--) {
-                    Certificate cert = chain[i];
+                    X509Certificate cert = chain[i];
                     // We don't care about the unresolved critical extensions.
                     checker.check(cert, Collections.<String>emptySet());
                 }