Adding support for sending early data on the client.
BUG=76
Change-Id: If58a73da38e46549fd55f84a9104e2dfebfda43f
Reviewed-on: https://boringssl-review.googlesource.com/14164
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/ssl/tls13_client.c b/ssl/tls13_client.c
index 6de51e5..6b39371 100644
--- a/ssl/tls13_client.c
+++ b/ssl/tls13_client.c
@@ -33,6 +33,7 @@
state_send_second_client_hello,
state_process_server_hello,
state_process_encrypted_extensions,
+ state_continue_second_server_flight,
state_process_certificate_request,
state_process_server_certificate,
state_process_server_certificate_verify,
@@ -141,13 +142,15 @@
hs->received_hello_retry_request = 1;
hs->tls13_state = state_send_second_client_hello;
+ /* 0-RTT is rejected if we receive a HelloRetryRequest. */
+ if (hs->in_early_data) {
+ return ssl_hs_early_data_rejected;
+ }
return ssl_hs_ok;
}
static enum ssl_hs_wait_t do_send_second_client_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- /* TODO(svaldez): Ensure that we set can_early_write to false since 0-RTT is
- * rejected if we receive a HelloRetryRequest. */
if (!ssl->method->set_write_state(ssl, NULL) ||
!ssl_write_client_hello(hs)) {
return ssl_hs_error;
@@ -259,6 +262,7 @@
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
+ ssl_set_session(ssl, NULL);
/* Resumption incorporates fresh key material, so refresh the timeout. */
ssl_session_renew_timeout(ssl, hs->new_session,
@@ -358,9 +362,9 @@
}
if (ssl->early_data_accepted) {
- if (ssl->session->cipher != hs->new_session->cipher ||
- ssl->session->early_alpn_len != ssl->s3->alpn_selected_len ||
- OPENSSL_memcmp(ssl->session->early_alpn, ssl->s3->alpn_selected,
+ if (hs->early_session->cipher != hs->new_session->cipher ||
+ hs->early_session->early_alpn_len != ssl->s3->alpn_selected_len ||
+ OPENSSL_memcmp(hs->early_session->early_alpn, ssl->s3->alpn_selected,
ssl->s3->alpn_selected_len) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_ALPN_MISMATCH_ON_EARLY_DATA);
return ssl_hs_error;
@@ -371,15 +375,18 @@
}
}
- /* Release offered session now that it is no longer needed. */
- if (ssl->s3->session_reused) {
- ssl_set_session(ssl, NULL);
- }
-
if (!ssl_hash_current_message(hs)) {
return ssl_hs_error;
}
+ hs->tls13_state = state_continue_second_server_flight;
+ if (hs->in_early_data && !ssl->early_data_accepted) {
+ return ssl_hs_early_data_rejected;
+ }
+ return ssl_hs_ok;
+}
+
+static enum ssl_hs_wait_t do_continue_second_server_flight(SSL_HANDSHAKE *hs) {
hs->tls13_state = state_process_certificate_request;
return ssl_hs_read_message;
}
@@ -485,11 +492,13 @@
static enum ssl_hs_wait_t do_send_end_of_early_data(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- /* TODO(svaldez): Stop sending early data. */
- if (ssl->early_data_accepted &&
- !ssl->method->add_alert(ssl, SSL3_AL_WARNING,
- TLS1_AD_END_OF_EARLY_DATA)) {
- return ssl_hs_error;
+
+ if (ssl->early_data_accepted) {
+ hs->can_early_write = 0;
+ if (!ssl->method->add_alert(ssl, SSL3_AL_WARNING,
+ TLS1_AD_END_OF_EARLY_DATA)) {
+ return ssl_hs_error;
+ }
}
if (hs->early_data_offered &&
@@ -618,6 +627,9 @@
case state_process_encrypted_extensions:
ret = do_process_encrypted_extensions(hs);
break;
+ case state_continue_second_server_flight:
+ ret = do_continue_second_server_flight(hs);
+ break;
case state_process_certificate_request:
ret = do_process_certificate_request(hs);
break;