Add a ssl_hs_flush_and_read_message wait mode.
Every flush but the last is always immediately followed by a read. Add a combined wait mode to make things simpler. Unfortunately, both flights we have (the state machine doesn't write the first ClientHello) are followed immediately by a state change, which means we still need some state in between because we must run code after write_message but before read_message. (This way to fix that is to get rid of the buffer BIO, change write_message to write_flight, and allow things like init_message / finish_message / init_message / finish_message / set_write_state / init_message / finish_message / write_flight.) Change-Id: Iebaa388ccbe7fcad48c1b2256e1c0d3a7c9c8a2a Reviewed-on: https://boringssl-review.googlesource.com/8828 Reviewed-by: Steven Valdez <svaldez@google.com> Reviewed-by: David Benjamin <davidben@google.com> Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
parent
feff406782
commit
f2401eb42b
@ -844,6 +844,7 @@ enum ssl_hs_wait_t {
|
||||
ssl_hs_read_message,
|
||||
ssl_hs_write_message,
|
||||
ssl_hs_flush,
|
||||
ssl_hs_flush_and_read_message,
|
||||
ssl_hs_x509_lookup,
|
||||
ssl_hs_private_key_operation,
|
||||
};
|
||||
|
@ -68,6 +68,20 @@ int tls13_handshake(SSL *ssl) {
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
|
||||
return -1;
|
||||
|
||||
case ssl_hs_flush:
|
||||
case ssl_hs_flush_and_read_message: {
|
||||
int ret = BIO_flush(ssl->wbio);
|
||||
if (ret <= 0) {
|
||||
ssl->rwstate = SSL_WRITING;
|
||||
return ret;
|
||||
}
|
||||
if (hs->wait != ssl_hs_flush_and_read_message) {
|
||||
break;
|
||||
}
|
||||
hs->wait = ssl_hs_read_message;
|
||||
/* Fall-through. */
|
||||
}
|
||||
|
||||
case ssl_hs_read_message: {
|
||||
int ret = ssl->method->ssl_get_message(ssl, -1, ssl_dont_hash_message);
|
||||
if (ret <= 0) {
|
||||
@ -84,15 +98,6 @@ int tls13_handshake(SSL *ssl) {
|
||||
break;
|
||||
}
|
||||
|
||||
case ssl_hs_flush: {
|
||||
int ret = BIO_flush(ssl->wbio);
|
||||
if (ret <= 0) {
|
||||
ssl->rwstate = SSL_WRITING;
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ssl_hs_x509_lookup:
|
||||
ssl->rwstate = SSL_X509_LOOKUP;
|
||||
hs->wait = ssl_hs_ok;
|
||||
@ -316,6 +321,8 @@ int tls13_check_message_type(SSL *ssl, int type) {
|
||||
if (ssl->s3->tmp.message_type != type) {
|
||||
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
|
||||
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
|
||||
ERR_add_error_dataf("got type %d, wanted type %d",
|
||||
ssl->s3->tmp.message_type, type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,6 @@ enum server_hs_state_t {
|
||||
state_complete_server_certificate_verify,
|
||||
state_send_server_finished,
|
||||
state_flush,
|
||||
state_read_client_second_flight,
|
||||
state_process_client_certificate,
|
||||
state_process_client_certificate_verify,
|
||||
state_process_client_finished,
|
||||
@ -352,12 +351,6 @@ static enum ssl_hs_wait_t do_send_server_finished(SSL *ssl, SSL_HANDSHAKE *hs) {
|
||||
}
|
||||
|
||||
static enum ssl_hs_wait_t do_flush(SSL *ssl, SSL_HANDSHAKE *hs) {
|
||||
hs->state = state_read_client_second_flight;
|
||||
return ssl_hs_flush;
|
||||
}
|
||||
|
||||
static enum ssl_hs_wait_t do_read_client_second_flight(SSL *ssl,
|
||||
SSL_HANDSHAKE *hs) {
|
||||
/* Update the secret to the master secret and derive traffic keys. */
|
||||
static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
|
||||
if (!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len) ||
|
||||
@ -368,7 +361,7 @@ static enum ssl_hs_wait_t do_read_client_second_flight(SSL *ssl,
|
||||
}
|
||||
|
||||
hs->state = state_process_client_certificate;
|
||||
return ssl_hs_read_message;
|
||||
return ssl_hs_flush_and_read_message;
|
||||
}
|
||||
|
||||
static enum ssl_hs_wait_t do_process_client_certificate(SSL *ssl,
|
||||
@ -457,9 +450,6 @@ enum ssl_hs_wait_t tls13_server_handshake(SSL *ssl) {
|
||||
case state_flush:
|
||||
ret = do_flush(ssl, hs);
|
||||
break;
|
||||
case state_read_client_second_flight:
|
||||
ret = do_read_client_second_flight(ssl, hs);
|
||||
break;
|
||||
case state_process_client_certificate:
|
||||
ret = do_process_client_certificate(ssl, hs);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user