8208209: Improve TLS connection stability again
authorapetcher
Mon, 30 Jul 2018 13:53:30 -0400
changeset 52170 2990f1e1c325
parent 52169 ca48ad1b6e21
child 52171 0da586f1ed05
8208209: Improve TLS connection stability again Reviewed-by: xuelei
src/java.base/share/classes/sun/security/ssl/ClientHello.java
src/java.base/share/classes/sun/security/ssl/PreSharedKeyExtension.java
src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java
--- a/src/java.base/share/classes/sun/security/ssl/ClientHello.java	Tue Jul 10 08:20:13 2018 +0100
+++ b/src/java.base/share/classes/sun/security/ssl/ClientHello.java	Mon Jul 30 13:53:30 2018 -0400
@@ -35,6 +35,7 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
+import java.util.Objects;
 import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLHandshakeException;
 import javax.net.ssl.SSLPeerUnverifiedException;
@@ -510,6 +511,23 @@
                 }
             }
 
+            // ensure that the endpoint identification algorithm matches the
+            // one in the session
+            String identityAlg = chc.sslConfig.identificationProtocol;
+            if (session != null && identityAlg != null) {
+                String sessionIdentityAlg =
+                    session.getIdentificationProtocol();
+                if (!Objects.equals(identityAlg, sessionIdentityAlg)) {
+                    if (SSLLogger.isOn &&
+                    SSLLogger.isOn("ssl,handshake,verbose")) {
+                        SSLLogger.finest("Can't resume, endpoint id" +
+                            " algorithm does not match, requested: " +
+                            identityAlg + ", cached: " + sessionIdentityAlg);
+                    }
+                    session = null;
+                }
+            }
+
             if (session != null) {
                 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake,verbose")) {
                     SSLLogger.finest("Try resuming session", session);
@@ -1011,6 +1029,23 @@
                     }
                 }
 
+                // ensure that the endpoint identification algorithm matches the
+                // one in the session
+                String identityAlg = shc.sslConfig.identificationProtocol;
+                if (resumingSession && identityAlg != null) {
+                    String sessionIdentityAlg =
+                        previous.getIdentificationProtocol();
+                    if (!Objects.equals(identityAlg, sessionIdentityAlg)) {
+                        if (SSLLogger.isOn &&
+                        SSLLogger.isOn("ssl,handshake,verbose")) {
+                            SSLLogger.finest("Can't resume, endpoint id" +
+                            " algorithm does not match, requested: " +
+                            identityAlg + ", cached: " + sessionIdentityAlg);
+                        }
+                        resumingSession = false;
+                    }
+                }
+
                 // So far so good.  Note that the handshake extensions may reset
                 // the resuming options later.
                 shc.isResumption = resumingSession;
--- a/src/java.base/share/classes/sun/security/ssl/PreSharedKeyExtension.java	Tue Jul 10 08:20:13 2018 +0100
+++ b/src/java.base/share/classes/sun/security/ssl/PreSharedKeyExtension.java	Mon Jul 30 13:53:30 2018 -0400
@@ -32,6 +32,7 @@
 import java.util.ArrayList;
 import java.util.Locale;
 import java.util.Arrays;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Collection;
 import javax.crypto.Mac;
@@ -170,7 +171,7 @@
 
         int getIdsEncodedLength() {
             int idEncodedLength = 0;
-            for (PskIdentity curId : identities) {
+            for(PskIdentity curId : identities) {
                 idEncodedLength += curId.getEncodedLength();
             }
 
@@ -193,7 +194,7 @@
             byte[] buffer = new byte[encodedLength];
             ByteBuffer m = ByteBuffer.wrap(buffer);
             Record.putInt16(m, idsEncodedLength);
-            for (PskIdentity curId : identities) {
+            for(PskIdentity curId : identities) {
                 curId.writeEncoded(m);
             }
             Record.putInt16(m, bindersEncodedLength);
@@ -443,6 +444,23 @@
             }
         }
 
+        // ensure that the endpoint identification algorithm matches the
+        // one in the session
+        String identityAlg = shc.sslConfig.identificationProtocol;
+        if (result && identityAlg != null) {
+            String sessionIdentityAlg = s.getIdentificationProtocol();
+            if (!Objects.equals(identityAlg, sessionIdentityAlg)) {
+                if (SSLLogger.isOn &&
+                    SSLLogger.isOn("ssl,handshake,verbose")) {
+
+                    SSLLogger.finest("Can't resume, endpoint id" +
+                        " algorithm does not match, requested: " +
+                        identityAlg + ", cached: " + sessionIdentityAlg);
+                }
+                result = false;
+            }
+        }
+
         // Ensure cipher suite can be negotiated
         if (result && (!shc.isNegotiable(s.getSuite()) ||
             !clientHello.cipherSuites.contains(s.getSuite()))) {
--- a/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java	Tue Jul 10 08:20:13 2018 +0100
+++ b/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java	Mon Jul 30 13:53:30 2018 -0400
@@ -132,6 +132,10 @@
     // Counter used to create unique nonces in NewSessionTicket
     private BigInteger ticketNonceCounter = BigInteger.ONE;
 
+    // The endpoint identification algorithm used to check certificates
+    // in this session.
+    private final String              identificationProtocol;
+
     /*
      * Create a new non-rejoinable session, using the default (null)
      * cipher spec.  This constructor returns a session which could
@@ -149,6 +153,7 @@
         this.requestedServerNames = Collections.<SNIServerName>emptyList();
         this.useExtendedMasterSecret = false;
         this.creationTime = System.currentTimeMillis();
+        this.identificationProtocol = null;
     }
 
     /*
@@ -198,6 +203,7 @@
                 (!hc.negotiatedProtocol.useTLS13PlusSpec());
         }
         this.creationTime = creationTime;
+        this.identificationProtocol = hc.sslConfig.identificationProtocol;
 
         if (SSLLogger.isOn && SSLLogger.isOn("session")) {
              SSLLogger.finest("Session initialized:  " + this);
@@ -259,6 +265,10 @@
         return ticketAgeAdd;
     }
 
+    String getIdentificationProtocol() {
+        return this.identificationProtocol;
+    }
+
     /*
      * Get the PSK identity. Take care not to use it in multiple connections.
      */