Fix ALPS state machine in QUIC servers.

The state machine around EndOfEarlyData is a bit messy, which caused a
problem introducing the new message in QUIC. We keep waffling on whether
that state junction should no-op the EndOfEarlyData state or skip it.
Since skipping it caused us to miss this spot, let's try no-op-ing it.

As a test, so this CL is easier to cherry-pick, I've just duplicated the
basic server test. Better, however, would be to run all the extensions
tests under QUIC. (In particular, this is missing 0-RTT coverage.) But
this is a large diff and requires improving the mock QUIC transport,
etc., in runner. That work is done in follow-up CLs, which replace this
duplicated test.

Change-Id: I25b6feabdc6e5393ba7f486651986a90e3721667
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/44985
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
chromium-5359
David Benjamin 4 years ago committed by CQ bot account: commit-bot@chromium.org
parent f4a88296fc
commit 71ed9d7538
  1. 34
      ssl/test/runner/runner.go
  2. 42
      ssl/tls13_server.cc

@ -7008,6 +7008,40 @@ func addExtensionTests() {
}, },
}) })
// TODO(davidben): This is a copy of ALPS-Basic-Server to test a
// QUIC-specific ALPS issue. Remove this and instead run all the
// tests in this function at all protocols.
testCases = append(testCases, testCase{
protocol: quic,
testType: serverTest,
name: "ALPS-Basic-Server-QUIC-" + ver.name,
skipQUICALPNConfig: true,
config: Config{
MaxVersion: ver.version,
NextProtos: []string{"proto"},
ApplicationSettings: map[string][]byte{"proto": []byte("runner1")},
},
resumeConfig: &Config{
MaxVersion: ver.version,
NextProtos: []string{"proto"},
ApplicationSettings: map[string][]byte{"proto": []byte("runner2")},
},
resumeSession: true,
expectations: connectionExpectations{
peerApplicationSettings: []byte("shim1"),
},
resumeExpectations: &connectionExpectations{
peerApplicationSettings: []byte("shim2"),
},
flags: []string{
"-select-alpn", "proto",
"-on-initial-application-settings", "proto,shim1",
"-on-initial-expect-peer-application-settings", "runner1",
"-on-resume-application-settings", "proto,shim2",
"-on-resume-expect-peer-application-settings", "runner2",
},
})
// Test that the server can defer its ALPS configuration to the ALPN // Test that the server can defer its ALPS configuration to the ALPN
// selection callback. // selection callback.
testCases = append(testCases, testCase{ testCases = append(testCases, testCase{

@ -882,7 +882,7 @@ static enum ssl_hs_wait_t do_read_second_client_flight(SSL_HANDSHAKE *hs) {
hs->client_handshake_secret())) { hs->client_handshake_secret())) {
return ssl_hs_error; return ssl_hs_error;
} }
hs->tls13_state = state13_read_client_certificate; hs->tls13_state = state13_process_end_of_early_data;
return ssl->s3->early_data_accepted ? ssl_hs_early_return : ssl_hs_ok; return ssl->s3->early_data_accepted ? ssl_hs_early_return : ssl_hs_ok;
} }
@ -893,27 +893,31 @@ static enum ssl_hs_wait_t do_read_second_client_flight(SSL_HANDSHAKE *hs) {
static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) { static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl; SSL *const ssl = hs->ssl;
// If early data was not accepted, the EndOfEarlyData will be in the discarded // In protocols that use EndOfEarlyData, we must consume the extra message and
// early data. // switch to client_handshake_secret after the early return.
if (hs->ssl->s3->early_data_accepted) { if (ssl->quic_method == nullptr) {
SSLMessage msg; // If early data was not accepted, the EndOfEarlyData will be in the
if (!ssl->method->get_message(ssl, &msg)) { // discarded early data.
return ssl_hs_read_message; if (hs->ssl->s3->early_data_accepted) {
} SSLMessage msg;
if (!ssl_check_message_type(ssl, msg, SSL3_MT_END_OF_EARLY_DATA)) { if (!ssl->method->get_message(ssl, &msg)) {
return ssl_hs_error; return ssl_hs_read_message;
}
if (!ssl_check_message_type(ssl, msg, SSL3_MT_END_OF_EARLY_DATA)) {
return ssl_hs_error;
}
if (CBS_len(&msg.body) != 0) {
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return ssl_hs_error;
}
ssl->method->next_message(ssl);
} }
if (CBS_len(&msg.body) != 0) { if (!tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_open,
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); hs->new_session.get(),
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); hs->client_handshake_secret())) {
return ssl_hs_error; return ssl_hs_error;
} }
ssl->method->next_message(ssl);
}
if (!tls13_set_traffic_key(ssl, ssl_encryption_handshake, evp_aead_open,
hs->new_session.get(),
hs->client_handshake_secret())) {
return ssl_hs_error;
} }
hs->tls13_state = state13_read_client_encrypted_extensions; hs->tls13_state = state13_read_client_encrypted_extensions;
return ssl_hs_ok; return ssl_hs_ok;

Loading…
Cancel
Save