8214688: TLS 1.3 session resumption with hello retry request failed with "illegal_parameter"
authorapetcher
Tue, 11 Dec 2018 11:01:02 -0500
changeset 52947 01b519fcb8a8
parent 52946 752e57845ad2
child 52948 04c9b7111aac
8214688: TLS 1.3 session resumption with hello retry request failed with "illegal_parameter" Reviewed-by: jnimeh
src/java.base/share/classes/sun/security/ssl/ClientHandshakeContext.java
src/java.base/share/classes/sun/security/ssl/PreSharedKeyExtension.java
--- a/src/java.base/share/classes/sun/security/ssl/ClientHandshakeContext.java	Tue Dec 11 09:42:45 2018 -0500
+++ b/src/java.base/share/classes/sun/security/ssl/ClientHandshakeContext.java	Tue Dec 11 11:01:02 2018 -0500
@@ -90,6 +90,9 @@
 
     ClientHelloMessage initialClientHelloMsg = null;
 
+    // PSK identity is selected in first Hello and used again after HRR
+    byte[] pskIdentity;
+
     ClientHandshakeContext(SSLContextImpl sslContext,
             TransportContext conContext) throws IOException {
         super(sslContext, conContext);
--- a/src/java.base/share/classes/sun/security/ssl/PreSharedKeyExtension.java	Tue Dec 11 09:42:45 2018 -0500
+++ b/src/java.base/share/classes/sun/security/ssl/PreSharedKeyExtension.java	Tue Dec 11 11:01:02 2018 -0500
@@ -656,7 +656,11 @@
                 return null;
             }
             SecretKey psk = pskOpt.get();
-            Optional<byte[]> pskIdOpt = chc.resumingSession.consumePskIdentity();
+            // The PSK ID can only be used in one connections, but this method
+            // may be called twice in a connection if the server sends HRR.
+            // ID is saved in the context so it can be used in the second call.
+            Optional<byte[]> pskIdOpt = Optional.ofNullable(chc.pskIdentity)
+                .or(chc.resumingSession::consumePskIdentity);
             if (!pskIdOpt.isPresent()) {
                 if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
                     SSLLogger.fine(
@@ -664,7 +668,7 @@
                 }
                 return null;
             }
-            byte[] pskId = pskIdOpt.get();
+            chc.pskIdentity = pskIdOpt.get();
 
             //The session cannot be used again. Remove it from the cache.
             SSLSessionContextImpl sessionCache = (SSLSessionContextImpl)
@@ -681,7 +685,7 @@
                     chc.resumingSession.getTicketCreationTime());
             int obfuscatedAge =
                     ageMillis + chc.resumingSession.getTicketAgeAdd();
-            identities.add(new PskIdentity(pskId, obfuscatedAge));
+            identities.add(new PskIdentity(chc.pskIdentity, obfuscatedAge));
 
             SecretKey binderKey = deriveBinderKey(psk, chc.resumingSession);
             ClientHelloMessage clientHello = (ClientHelloMessage)message;