Tolerate cipher changes on TLS 1.3 resumption as a client.
As a client, we must tolerate this to avoid interoperability failures
with allowed server behaviors.
BUG=117
Change-Id: I9c40a2a048282e2e63ab5ee1d40773fc2eda110a
Reviewed-on: https://boringssl-review.googlesource.com/12311
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/err/ssl.errordata b/crypto/err/ssl.errordata
index 3fb4d8f..e034001 100644
--- a/crypto/err/ssl.errordata
+++ b/crypto/err/ssl.errordata
@@ -99,6 +99,7 @@
SSL,185,NULL_SSL_CTX
SSL,186,NULL_SSL_METHOD_PASSED
SSL,187,OLD_SESSION_CIPHER_NOT_RETURNED
+SSL,268,OLD_SESSION_PRF_HASH_MISMATCH
SSL,188,OLD_SESSION_VERSION_NOT_RETURNED
SSL,189,OUTPUT_ALIASES_INPUT
SSL,190,PARSE_TLSEXT
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 827ae28..6d7ae2f 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -4537,6 +4537,7 @@
#define SSL_R_NO_GROUPS_SPECIFIED 265
#define SSL_R_NO_SHARED_GROUP 266
#define SSL_R_PRE_SHARED_KEY_MUST_BE_LAST 267
+#define SSL_R_OLD_SESSION_PRF_HASH_MISMATCH 268
#define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000
#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010
#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 8a18e8f..ad71167 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -5805,6 +5805,8 @@
expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:",
})
+ // Session resumption in TLS 1.3 may change the cipher suite if the PRF
+ // matches.
testCases = append(testCases, testCase{
name: "Resume-Client-CipherMismatch-TLS13",
resumeSession: true,
@@ -5814,13 +5816,27 @@
},
resumeConfig: &Config{
MaxVersion: VersionTLS13,
+ CipherSuites: []uint16{TLS_CHACHA20_POLY1305_SHA256},
+ },
+ })
+
+ // Session resumption in TLS 1.3 is forbidden if the PRF does not match.
+ testCases = append(testCases, testCase{
+ name: "Resume-Client-PRFMismatch-TLS13",
+ resumeSession: true,
+ config: Config{
+ MaxVersion: VersionTLS13,
+ CipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
+ },
+ resumeConfig: &Config{
+ MaxVersion: VersionTLS13,
CipherSuites: []uint16{TLS_AES_128_GCM_SHA256},
Bugs: ProtocolBugs{
SendCipherSuite: TLS_AES_256_GCM_SHA384,
},
},
shouldFail: true,
- expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:",
+ expectedError: ":OLD_SESSION_PRF_HASH_MISMATCH:",
})
testCases = append(testCases, testCase{
diff --git a/ssl/tls13_client.c b/ssl/tls13_client.c
index ee82535..4a30ce3 100644
--- a/ssl/tls13_client.c
+++ b/ssl/tls13_client.c
@@ -241,8 +241,8 @@
return ssl_hs_error;
}
- if (ssl->session->cipher != cipher) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
+ if (ssl->session->cipher->algorithm_prf != cipher->algorithm_prf) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_PRF_HASH_MISMATCH);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}