Skip to content

Commit 004dd67

Browse files
committed
TlsServerProtocol.java - Session Resumption - RFC 3546 saied client / server extensions are irrelevant during resumption, but RFC 7627 and RFC 5746 define special handlings for some extensions during session resumption
1 parent 1f1b442 commit 004dd67

1 file changed

Lines changed: 35 additions & 13 deletions

File tree

core/src/main/java/org/bouncycastle/crypto/tls/TlsServerProtocol.java

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.io.InputStream;
66
import java.io.OutputStream;
77
import java.security.SecureRandom;
8+
import java.util.Hashtable;
89
import java.util.Vector;
910

1011
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
@@ -151,7 +152,7 @@ protected void handleHandshakeMessage(short type, byte[] data)
151152
if (this.securityParameters.cipherSuite != this.sessionParameters.getCipherSuite()
152153
|| this.securityParameters.compressionAlgorithm != this.sessionParameters.getCompressionAlgorithm())
153154
{
154-
throw new TlsFatalAlert(AlertDescription.internal_error);
155+
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
155156
}
156157
this.securityParameters.masterSecret = this.sessionParameters.getMasterSecret();
157158
this.securityParameters.pskIdentity = this.sessionParameters.getPSKIdentity();
@@ -631,8 +632,34 @@ protected void receiveClientHelloMessage(ByteArrayInputStream buf)
631632
*/
632633
if (this.resumedSession)
633634
{
634-
readExtensions(buf); // drop provided extensions...
635+
Hashtable newClientExtensions = readExtensions(buf);
635636
this.clientExtensions = this.sessionParameters.readPeerExtensions();
637+
/*
638+
* RFC 3546 indicates we MUST ignore extensions, but RFC 7627 Section 5.3 says:
639+
* o If the original session did not use the "extended_master_secret"
640+
* extension but the new ClientHello contains the extension, then the
641+
* server MUST NOT perform the abbreviated handshake. Instead, it
642+
* SHOULD continue with a full handshake (as described in
643+
* Section 5.2) to negotiate a new session.
644+
*
645+
* o If the original session used the "extended_master_secret"
646+
* extension but the new ClientHello does not contain it, the server
647+
* MUST abort the abbreviated handshake.
648+
*/
649+
boolean prevHasEMS = TlsExtensionsUtils.hasExtendedMasterSecretExtension(clientExtensions);
650+
boolean curHasEMS = TlsExtensionsUtils.hasExtendedMasterSecretExtension(newClientExtensions);
651+
if (curHasEMS != prevHasEMS) {
652+
if (!prevHasEMS) {
653+
/*
654+
* This is the case where we SHOULD continue with a full handshake...
655+
*/
656+
this.sessionParameters = null;
657+
this.tlsSession = null;
658+
this.resumedSession = false;
659+
this.clientExtensions = newClientExtensions;
660+
} else
661+
throw new TlsFatalAlert(AlertDescription.illegal_parameter);
662+
}
636663
}
637664
else
638665
{
@@ -835,18 +862,13 @@ protected void sendServerHelloMessage()
835862
* RFC 3546 2.3 If [...] the older session is resumed, then the server MUST ignore
836863
* extensions appearing in the client hello, and send a server hello containing no
837864
* extensions.
865+
*
866+
* The server hello containing no extensions is not entirely true. RFC 5746 explicitly
867+
* states out in 3.6. Server Behavior that the secure_renegotiation extensions is also
868+
* sent during session resumption. So we need to handle this part.
838869
*/
839-
840-
if (this.resumedSession)
841-
{
842-
applyMaxFragmentLengthExtension();
843-
844-
// we don't need the serverExtensions for resumed sessions. So we can leave here...
845-
message.writeToRecordStream();
846-
return;
847-
}
848-
849-
this.serverExtensions = tlsServer.getServerExtensions();
870+
if (!this.resumedSession)
871+
this.serverExtensions = tlsServer.getServerExtensions();
850872

851873
/*
852874
* RFC 5746 3.6. Server Behavior: Initial Handshake

0 commit comments

Comments
 (0)