changeset 1843:d48b76755a16

8202613: Improve TLS connections stability Reviewed-by: xuelei, wetmore
author igerasim
date Thu, 14 Jun 2018 15:32:54 -0700
parents 3efabfaa21db
children 74d77272a72e
files src/share/classes/sun/security/ssl/ClientHandshaker.java src/share/classes/sun/security/ssl/Handshaker.java src/share/classes/sun/security/ssl/SSLSessionImpl.java src/share/classes/sun/security/ssl/ServerHandshaker.java
diffstat 4 files changed, 71 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/security/ssl/ClientHandshaker.java	Fri Oct 05 17:33:13 2018 -0700
+++ b/src/share/classes/sun/security/ssl/ClientHandshaker.java	Thu Jun 14 15:32:54 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -651,7 +651,8 @@
         // Create a new session, we need to do the full handshake
         session = new SSLSessionImpl(protocolVersion, cipherSuite,
                             mesg.sessionId, getHostSE(), getPortSE(),
-                            (extendedMasterSecretExt != null));
+                            (extendedMasterSecretExt != null),
+                            getEndpointIdentificationAlgorithmSE());
         if (debug != null && Debug.isOn("handshake")) {
             System.out.println("** " + cipherSuite);
         }
@@ -1260,6 +1261,24 @@
                 }
             }
 
+            // ensure that the endpoint identification algorithm matches the
+            // one in the session
+            String identityAlg = getEndpointIdentificationAlgorithmSE();
+            if (session != null && identityAlg != null) {
+
+                String sessionIdentityAlg =
+                    session.getEndpointIdentificationAlgorithm();
+                if (!objectsEquals(identityAlg, sessionIdentityAlg)) {
+
+                    if (debug != null && Debug.isOn("session")) {
+                        System.out.println("%% can't resume, endpoint id" +
+                            " algorithm does not match, requested: " +
+                            identityAlg + ", cached: " + sessionIdentityAlg);
+                    }
+                    session = null;
+                }
+            }
+
             if (session != null) {
                 if (debug != null) {
                     if (Debug.isOn("handshake") || Debug.isOn("session")) {
--- a/src/share/classes/sun/security/ssl/Handshaker.java	Fri Oct 05 17:33:13 2018 -0700
+++ b/src/share/classes/sun/security/ssl/Handshaker.java	Thu Jun 14 15:32:54 2018 -0700
@@ -391,6 +391,14 @@
         }
     }
 
+    String getEndpointIdentificationAlgorithmSE() {
+        if (conn != null) {
+            return conn.getHostnameVerification();
+        } else {
+            return engine.getHostnameVerification();
+        }
+    }
+
     private void setVersionSE(ProtocolVersion protocolVersion) {
         if (conn != null) {
             conn.setVersion(protocolVersion);
--- a/src/share/classes/sun/security/ssl/SSLSessionImpl.java	Fri Oct 05 17:33:13 2018 -0700
+++ b/src/share/classes/sun/security/ssl/SSLSessionImpl.java	Thu Jun 14 15:32:54 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -112,6 +112,10 @@
     private Principal peerPrincipal;
     private Principal localPrincipal;
 
+    // The endpoint identification algorithm used to check certificates
+    // in this session.
+    private final String              endpointIdentificationAlgorithm;
+
     /*
      * Is the session currently re-established with a session-resumption
      * abbreviated initial handshake?
@@ -143,7 +147,7 @@
      */
     private SSLSessionImpl() {
         this(ProtocolVersion.NONE, CipherSuite.C_NULL,
-             new SessionId(false, null), null, -1, false);
+             new SessionId(false, null), null, -1, false, null);
     }
 
     /*
@@ -153,9 +157,10 @@
      */
     SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
             SecureRandom generator, String host, int port,
-            boolean useExtendedMasterSecret) {
+            boolean useExtendedMasterSecret, String endpointIdAlgorithm) {
         this(protocolVersion, cipherSuite,
-             new SessionId(defaultRejoinable, generator), host, port, useExtendedMasterSecret);
+             new SessionId(defaultRejoinable, generator), host, port,
+            useExtendedMasterSecret, endpointIdAlgorithm);
     }
 
     /*
@@ -163,7 +168,8 @@
      */
     SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
             SessionId id, String host, int port,
-            boolean useExtendedMasterSecret) {
+            boolean useExtendedMasterSecret,
+            String endpointIdAlgorithm){
         this.protocolVersion = protocolVersion;
         sessionId = id;
         peerCerts = null;
@@ -174,6 +180,7 @@
         this.port = port;
         sessionCount = ++counter;
         this.useExtendedMasterSecret = useExtendedMasterSecret;
+        this.endpointIdentificationAlgorithm = endpointIdAlgorithm;
 
         if (debug != null && Debug.isOn("session")) {
             System.out.println("%% Created:  " + this);
@@ -229,6 +236,10 @@
         localPrincipal = principal;
     }
 
+    String getEndpointIdentificationAlgorithm() {
+        return this.endpointIdentificationAlgorithm;
+    }
+
     /**
      * Returns true iff this session may be resumed ... sessions are
      * usually resumable.  Security policies may suggest otherwise,
--- a/src/share/classes/sun/security/ssl/ServerHandshaker.java	Fri Oct 05 17:33:13 2018 -0700
+++ b/src/share/classes/sun/security/ssl/ServerHandshaker.java	Thu Jun 14 15:32:54 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -662,6 +662,25 @@
                     }
                 }
 
+                // ensure that the endpoint identification algorithm matches the
+                // one in the session
+                String identityAlg = getEndpointIdentificationAlgorithmSE();
+                if (resumingSession && identityAlg != null) {
+
+                    String sessionIdentityAlg =
+                    previous.getEndpointIdentificationAlgorithm();
+                    if (!objectsEquals(identityAlg, sessionIdentityAlg)) {
+
+                        if (debug != null && Debug.isOn("session")) {
+                            System.out.println("%% can't resume, endpoint id"
+                                + " algorithm does not match, requested: " +
+                                identityAlg + ", cached: " +
+                                sessionIdentityAlg);
+                        }
+                        resumingSession = false;
+                    }
+                }
+
                 if (resumingSession) {
                     CipherSuite suite = previous.getSuite();
                     // verify that the ciphersuite from the cached session
@@ -704,7 +723,8 @@
                 sslContext.getSecureRandom(),
                 getHostAddressSE(), getPortSE(),
                 (requestedToUseEMS &&
-                (protocolVersion.v >= ProtocolVersion.TLS10.v)));
+                    (protocolVersion.v >= ProtocolVersion.TLS10.v)),
+                getEndpointIdentificationAlgorithmSE());
             session.setLocalPrivateKey(privateKey);
             // chooseCompression(mesg);
         }
@@ -1762,4 +1782,8 @@
     private static int parseUnsignedInt(String s) throws NumberFormatException {
         return parseUnsignedInt(s, 10);
     }
+
+    private static boolean objectsEquals(Object a, Object b) {
+        return (a == b) || (a != null && a.equals(b));
+    }
 }