Prevent both early data and custom extensions from being accepted.
This loosens the earlier restriction to match Channel ID. Both may be configured and offered, but the server is obligated to select only one of them. This aligns with the current tokbind + 0-RTT draft where the combination is signaled by a separate extension. Bug: 183 Change-Id: I786102a679999705d399f0091f76da236be091c2 Reviewed-on: https://boringssl-review.googlesource.com/19124 Reviewed-by: Steven Valdez <svaldez@google.com> Commit-Queue: Steven Valdez <svaldez@google.com>
This commit is contained in:
parent
78f5e75739
commit
f4ecc84644
@ -34,7 +34,6 @@ SSL,125,CERTIFICATE_VERIFY_FAILED
|
||||
SSL,126,CERT_CB_ERROR
|
||||
SSL,127,CERT_LENGTH_MISMATCH
|
||||
SSL,128,CHANNEL_ID_NOT_P256
|
||||
SSL,279,CHANNEL_ID_ON_EARLY_DATA
|
||||
SSL,129,CHANNEL_ID_SIGNATURE_INVALID
|
||||
SSL,130,CIPHER_OR_HASH_UNAVAILABLE
|
||||
SSL,131,CLIENTHELLO_PARSE_FAILED
|
||||
@ -183,6 +182,7 @@ SSL,1117,TOO_MUCH_READ_EARLY_DATA
|
||||
SSL,270,TOO_MUCH_SKIPPED_EARLY_DATA
|
||||
SSL,221,UNABLE_TO_FIND_ECDH_PARAMETERS
|
||||
SSL,222,UNEXPECTED_EXTENSION
|
||||
SSL,279,UNEXPECTED_EXTENSION_ON_EARLY_DATA
|
||||
SSL,223,UNEXPECTED_MESSAGE
|
||||
SSL,224,UNEXPECTED_OPERATOR_IN_GROUP
|
||||
SSL,225,UNEXPECTED_RECORD
|
||||
|
@ -4878,7 +4878,7 @@ OPENSSL_EXPORT bool SealRecord(SSL *ssl, Span<uint8_t> out_prefix,
|
||||
#define SSL_R_TICKET_ENCRYPTION_FAILED 276
|
||||
#define SSL_R_ALPN_MISMATCH_ON_EARLY_DATA 277
|
||||
#define SSL_R_WRONG_VERSION_ON_EARLY_DATA 278
|
||||
#define SSL_R_CHANNEL_ID_ON_EARLY_DATA 279
|
||||
#define SSL_R_UNEXPECTED_EXTENSION_ON_EARLY_DATA 279
|
||||
#define SSL_R_NO_SUPPORTED_VERSIONS_ENABLED 280
|
||||
#define SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE 281
|
||||
#define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000
|
||||
|
@ -71,14 +71,6 @@ static int custom_ext_add_hello(SSL_HANDSHAKE *hs, CBB *extensions) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ssl->cert->enable_early_data) {
|
||||
/* TODO(svaldez): Support Custom Extensions with 0-RTT. For now the caller
|
||||
* is expected not to configure both together.
|
||||
* https://crbug.com/boringssl/173. */
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sk_SSL_CUSTOM_EXTENSION_num(stack); i++) {
|
||||
const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i);
|
||||
|
||||
|
@ -1249,6 +1249,8 @@ struct SSL_HANDSHAKE {
|
||||
|
||||
unsigned received_hello_retry_request:1;
|
||||
|
||||
unsigned received_custom_extension:1;
|
||||
|
||||
/* accept_psk_mode stores whether the client's PSK mode is compatible with our
|
||||
* preferences. */
|
||||
unsigned accept_psk_mode:1;
|
||||
|
@ -137,6 +137,7 @@ SSL_HANDSHAKE::SSL_HANDSHAKE(SSL *ssl_arg)
|
||||
scts_requested(0),
|
||||
needs_psk_binder(0),
|
||||
received_hello_retry_request(0),
|
||||
received_custom_extension(0),
|
||||
accept_psk_mode(0),
|
||||
cert_request(0),
|
||||
certificate_status_expected(0),
|
||||
|
@ -2795,7 +2795,6 @@ static int ssl_scan_clienthello_tlsext(SSL_HANDSHAKE *hs,
|
||||
|
||||
hs->extensions.received = 0;
|
||||
hs->custom_extensions.received = 0;
|
||||
|
||||
CBS extensions;
|
||||
CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len);
|
||||
while (CBS_len(&extensions) != 0) {
|
||||
@ -2919,6 +2918,7 @@ static int ssl_scan_serverhello_tlsext(SSL_HANDSHAKE *hs, CBS *cbs,
|
||||
tls_extension_find(&ext_index, type);
|
||||
|
||||
if (ext == NULL) {
|
||||
hs->received_custom_extension = 1;
|
||||
if (!custom_ext_parse_serverhello(hs, out_alert, type, &extension)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -8980,22 +8980,6 @@ func addCustomExtensionTests() {
|
||||
flags: []string{flag},
|
||||
})
|
||||
|
||||
// 0-RTT is not currently supported with Custom Extensions.
|
||||
testCases = append(testCases, testCase{
|
||||
testType: testType,
|
||||
name: "CustomExtensions-" + suffix + "-EarlyData",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
Bugs: ProtocolBugs{
|
||||
CustomExtension: expectedContents,
|
||||
ExpectedCustomExtension: &expectedContents,
|
||||
},
|
||||
},
|
||||
shouldFail: true,
|
||||
expectedError: ":CUSTOM_EXTENSION_ERROR:",
|
||||
flags: []string{flag, "-enable-early-data"},
|
||||
})
|
||||
|
||||
// If the parse callback fails, the handshake should also fail.
|
||||
testCases = append(testCases, testCase{
|
||||
testType: testType,
|
||||
@ -9090,6 +9074,121 @@ func addCustomExtensionTests() {
|
||||
})
|
||||
}
|
||||
|
||||
// If the client sends both early data and custom extension, the handshake
|
||||
// should succeed as long as both the extensions aren't returned by the
|
||||
// server.
|
||||
testCases = append(testCases, testCase{
|
||||
testType: clientTest,
|
||||
name: "CustomExtensions-Client-EarlyData-None",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
MaxEarlyDataSize: 16384,
|
||||
Bugs: ProtocolBugs{
|
||||
ExpectedCustomExtension: &expectedContents,
|
||||
AlwaysRejectEarlyData: true,
|
||||
},
|
||||
},
|
||||
resumeSession: true,
|
||||
flags: []string{
|
||||
"-enable-client-custom-extension",
|
||||
"-enable-early-data",
|
||||
"-expect-early-data-info",
|
||||
"-expect-reject-early-data",
|
||||
},
|
||||
})
|
||||
|
||||
testCases = append(testCases, testCase{
|
||||
testType: clientTest,
|
||||
name: "CustomExtensions-Client-EarlyData-EarlyDataAccepted",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
MaxEarlyDataSize: 16384,
|
||||
Bugs: ProtocolBugs{
|
||||
ExpectedCustomExtension: &expectedContents,
|
||||
},
|
||||
},
|
||||
resumeSession: true,
|
||||
flags: []string{
|
||||
"-enable-client-custom-extension",
|
||||
"-enable-early-data",
|
||||
"-expect-early-data-info",
|
||||
"-expect-accept-early-data",
|
||||
},
|
||||
})
|
||||
|
||||
testCases = append(testCases, testCase{
|
||||
testType: clientTest,
|
||||
name: "CustomExtensions-Client-EarlyData-CustomExtensionAccepted",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
MaxEarlyDataSize: 16384,
|
||||
Bugs: ProtocolBugs{
|
||||
AlwaysRejectEarlyData: true,
|
||||
CustomExtension: expectedContents,
|
||||
ExpectedCustomExtension: &expectedContents,
|
||||
},
|
||||
},
|
||||
resumeSession: true,
|
||||
flags: []string{
|
||||
"-enable-client-custom-extension",
|
||||
"-enable-early-data",
|
||||
"-expect-early-data-info",
|
||||
"-expect-reject-early-data",
|
||||
},
|
||||
})
|
||||
|
||||
testCases = append(testCases, testCase{
|
||||
testType: clientTest,
|
||||
name: "CustomExtensions-Client-EarlyDataAndCustomExtensions",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
MaxEarlyDataSize: 16384,
|
||||
Bugs: ProtocolBugs{
|
||||
CustomExtension: expectedContents,
|
||||
ExpectedCustomExtension: &expectedContents,
|
||||
},
|
||||
},
|
||||
resumeConfig: &Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
MaxEarlyDataSize: 16384,
|
||||
Bugs: ProtocolBugs{
|
||||
CustomExtension: expectedContents,
|
||||
ExpectedCustomExtension: &expectedContents,
|
||||
SendEarlyDataExtension: true,
|
||||
},
|
||||
},
|
||||
resumeSession: true,
|
||||
shouldFail: true,
|
||||
expectedError: ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:",
|
||||
flags: []string{
|
||||
"-enable-client-custom-extension",
|
||||
"-enable-early-data",
|
||||
"-expect-early-data-info",
|
||||
},
|
||||
})
|
||||
|
||||
// If the server receives both early data and custom extension, only the
|
||||
// custom extension should be accepted.
|
||||
testCases = append(testCases, testCase{
|
||||
testType: serverTest,
|
||||
name: "CustomExtensions-Server-EarlyDataAccepted",
|
||||
config: Config{
|
||||
MaxVersion: VersionTLS13,
|
||||
MaxEarlyDataSize: 16384,
|
||||
Bugs: ProtocolBugs{
|
||||
CustomExtension: expectedContents,
|
||||
ExpectedCustomExtension: &expectedContents,
|
||||
ExpectEarlyDataAccepted: false,
|
||||
},
|
||||
},
|
||||
resumeSession: true,
|
||||
flags: []string{
|
||||
"-enable-server-custom-extension",
|
||||
"-enable-early-data",
|
||||
"-expect-early-data-info",
|
||||
},
|
||||
})
|
||||
|
||||
// The custom extension add callback should not be called if the client
|
||||
// doesn't send the extension.
|
||||
testCases = append(testCases, testCase{
|
||||
@ -11661,7 +11760,7 @@ func addTLS13HandshakeTests() {
|
||||
resumeSession: true,
|
||||
expectChannelID: true,
|
||||
shouldFail: true,
|
||||
expectedError: ":CHANNEL_ID_ON_EARLY_DATA:",
|
||||
expectedError: ":UNEXPECTED_EXTENSION_ON_EARLY_DATA:",
|
||||
flags: []string{
|
||||
"-enable-early-data",
|
||||
"-expect-early-data-info",
|
||||
|
@ -417,8 +417,8 @@ static enum ssl_hs_wait_t do_read_encrypted_extensions(SSL_HANDSHAKE *hs) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_ALPN_MISMATCH_ON_EARLY_DATA);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
if (ssl->s3->tlsext_channel_id_valid) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_ON_EARLY_DATA);
|
||||
if (ssl->s3->tlsext_channel_id_valid || hs->received_custom_extension) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION_ON_EARLY_DATA);
|
||||
return ssl_hs_error;
|
||||
}
|
||||
}
|
||||
|
@ -380,6 +380,8 @@ static enum ssl_hs_wait_t do_select_session(SSL_HANDSHAKE *hs) {
|
||||
hs->early_data_offered &&
|
||||
/* Channel ID is incompatible with 0-RTT. */
|
||||
!ssl->s3->tlsext_channel_id_valid &&
|
||||
/* Custom extensions is incompatible with 0-RTT. */
|
||||
hs->custom_extensions.received == 0 &&
|
||||
/* The negotiated ALPN must match the one in the ticket. */
|
||||
ssl->s3->alpn_selected_len == session->early_alpn_len &&
|
||||
OPENSSL_memcmp(ssl->s3->alpn_selected, session->early_alpn,
|
||||
|
Loading…
Reference in New Issue
Block a user