8212885: TLS 1.3 resumed session does not retain peer certificate chain

Reviewed-by: xuelei, wetmore
This commit is contained in:
Jamil Nimeh 2018-11-13 18:22:52 -08:00
parent 65dc116bf6
commit acd81b508e
5 changed files with 134 additions and 17 deletions

View file

@ -260,9 +260,8 @@ final class NewSessionTicket {
// create and cache the new session
// The new session must be a child of the existing session so
// they will be invalidated together, etc.
SSLSessionImpl sessionCopy = new SSLSessionImpl(shc,
shc.handshakeSession.getSuite(), newId,
shc.handshakeSession.getCreationTime());
SSLSessionImpl sessionCopy =
new SSLSessionImpl(shc.handshakeSession, newId);
shc.handshakeSession.addChild(sessionCopy);
sessionCopy.setPreSharedKey(psk);
sessionCopy.setPskIdentity(newId.getId());
@ -375,9 +374,8 @@ final class NewSessionTicket {
// they will be invalidated together, etc.
SessionId newId =
new SessionId(true, hc.sslContext.getSecureRandom());
SSLSessionImpl sessionCopy = new SSLSessionImpl(
hc, sessionToSave.getSuite(), newId,
sessionToSave.getCreationTime());
SSLSessionImpl sessionCopy = new SSLSessionImpl(sessionToSave,
newId);
sessionToSave.addChild(sessionCopy);
sessionCopy.setPreSharedKey(psk);
sessionCopy.setTicketAgeAdd(nstm.ticketAgeAdd);

View file

@ -50,9 +50,6 @@ final class PostHandshakeContext extends HandshakeContext {
this.localSupportedSignAlgs = new ArrayList<SignatureScheme>(
context.conSession.getLocalSupportedSignatureSchemes());
this.requestedServerNames =
context.conSession.getRequestedServerNames();
handshakeConsumers = new LinkedHashMap<>(consumers);
handshakeFinished = true;
}

View file

@ -415,6 +415,16 @@ final class PreSharedKeyExtension {
result = false;
}
// Make sure that the server handshake context's localSupportedSignAlgs
// field is populated. This is particularly important when
// client authentication was used in an initial session and it is
// now being resumed.
if (shc.localSupportedSignAlgs == null) {
shc.localSupportedSignAlgs =
SignatureScheme.getSupportedAlgorithms(
shc.algorithmConstraints, shc.activeProtocols);
}
// Validate the required client authentication.
if (result &&
(shc.sslConfig.clientAuthType == CLIENT_AUTH_REQUIRED)) {
@ -763,7 +773,7 @@ final class PreSharedKeyExtension {
SecretKey earlySecret = hkdf.extract(zeros, psk, "TlsEarlySecret");
byte[] label = ("tls13 res binder").getBytes();
MessageDigest md = MessageDigest.getInstance(hashAlg.toString());;
MessageDigest md = MessageDigest.getInstance(hashAlg.name);
byte[] hkdfInfo = SSLSecretDerivation.createHkdfInfo(
label, md.digest(new byte[0]), hashAlg.hashLength);
return hkdf.expand(earlySecret,

View file

@ -154,6 +154,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
this.useExtendedMasterSecret = false;
this.creationTime = System.currentTimeMillis();
this.identificationProtocol = null;
this.boundValues = new ConcurrentHashMap<>();
}
/*
@ -204,6 +205,41 @@ final class SSLSessionImpl extends ExtendedSSLSession {
}
this.creationTime = creationTime;
this.identificationProtocol = hc.sslConfig.identificationProtocol;
this.boundValues = new ConcurrentHashMap<>();
if (SSLLogger.isOn && SSLLogger.isOn("session")) {
SSLLogger.finest("Session initialized: " + this);
}
}
SSLSessionImpl(SSLSessionImpl baseSession, SessionId newId) {
this.protocolVersion = baseSession.getProtocolVersion();
this.cipherSuite = baseSession.cipherSuite;
this.sessionId = newId;
this.host = baseSession.getPeerHost();
this.port = baseSession.getPeerPort();
this.localSupportedSignAlgs =
baseSession.localSupportedSignAlgs == null ?
Collections.emptySet() :
Collections.unmodifiableCollection(
baseSession.localSupportedSignAlgs);
this.peerSupportedSignAlgs =
baseSession.getPeerSupportedSignatureAlgorithms();
this.serverNameIndication = baseSession.serverNameIndication;
this.requestedServerNames = baseSession.getRequestedServerNames();
this.masterSecret = baseSession.getMasterSecret();
this.useExtendedMasterSecret = baseSession.useExtendedMasterSecret;
this.creationTime = baseSession.getCreationTime();
this.lastUsedTime = System.currentTimeMillis();
this.identificationProtocol = baseSession.getIdentificationProtocol();
this.localCerts = baseSession.localCerts;
this.peerCerts = baseSession.peerCerts;
this.statusResponses = baseSession.statusResponses;
this.resumptionMasterSecret = baseSession.resumptionMasterSecret;
this.context = baseSession.context;
this.negotiatedMaxFragLen = baseSession.negotiatedMaxFragLen;
this.maximumPacketSize = baseSession.maximumPacketSize;
this.boundValues = baseSession.boundValues;
if (SSLLogger.isOn && SSLLogger.isOn("session")) {
SSLLogger.finest("Session initialized: " + this);
@ -772,8 +808,7 @@ final class SSLSessionImpl extends ExtendedSSLSession {
* key and the calling security context. This is important since
* sessions can be shared across different protection domains.
*/
private final ConcurrentHashMap<SecureKey, Object> boundValues =
new ConcurrentHashMap<>();
private final ConcurrentHashMap<SecureKey, Object> boundValues;
/**
* Assigns a session value. Session change events are given if