diff --git a/ssl/internal.h b/ssl/internal.h index bb2c30f6..a4c00abc 100644 --- a/ssl/internal.h +++ b/ssl/internal.h @@ -1475,6 +1475,10 @@ typedef struct ssl3_state_st { * and future messages should use the record layer. */ unsigned v2_hello_done:1; + /* is_v2_hello is true if the current handshake message was derived from a + * V2ClientHello rather than received from the peer directly. */ + unsigned is_v2_hello:1; + /* initial_handshake_complete is true if the initial handshake has * completed. */ unsigned initial_handshake_complete:1; diff --git a/ssl/s3_both.c b/ssl/s3_both.c index 70ed4351..e53e8692 100644 --- a/ssl/s3_both.c +++ b/ssl/s3_both.c @@ -506,7 +506,7 @@ static int extend_handshake_buffer(SSL *ssl, size_t length) { return 1; } -static int read_v2_client_hello(SSL *ssl, int *out_is_v2_client_hello) { +static int read_v2_client_hello(SSL *ssl) { /* Read the first 5 bytes, the size of the TLS record header. This is * sufficient to detect a V2ClientHello and ensures that we never read beyond * the first record. */ @@ -534,7 +534,6 @@ static int read_v2_client_hello(SSL *ssl, int *out_is_v2_client_hello) { if ((p[0] & 0x80) == 0 || p[2] != SSL2_MT_CLIENT_HELLO || p[3] != SSL3_VERSION_MAJOR) { /* Not a V2ClientHello. */ - *out_is_v2_client_hello = 0; return 1; } @@ -656,7 +655,9 @@ static int read_v2_client_hello(SSL *ssl, int *out_is_v2_client_hello) { ssl_read_buffer_consume(ssl, 2 + msg_length); ssl_read_buffer_discard(ssl); - *out_is_v2_client_hello = 1; + ssl->s3->is_v2_hello = 1; + /* This is the first message, so hs must be non-NULL. */ + ssl->s3->hs->v2_clienthello = 1; return 1; } @@ -672,18 +673,10 @@ again: if (ssl->server && !ssl->s3->v2_hello_done) { /* Bypass the record layer for the first message to handle V2ClientHello. */ - assert(hash_message == ssl_hash_message); - int is_v2_client_hello = 0; - int ret = read_v2_client_hello(ssl, &is_v2_client_hello); + int ret = read_v2_client_hello(ssl); if (ret <= 0) { return ret; } - if (is_v2_client_hello) { - /* This is the first message, so hs must be non-NULL. */ - ssl->s3->hs->v2_clienthello = 1; - /* V2ClientHello is hashed separately. */ - hash_message = ssl_dont_hash_message; - } ssl->s3->v2_hello_done = 1; } @@ -752,6 +745,11 @@ void ssl3_get_current_message(const SSL *ssl, CBS *out) { } int ssl_hash_current_message(SSL *ssl) { + /* V2ClientHellos are hashed implicitly. */ + if (ssl->s3->is_v2_hello) { + return 1; + } + CBS cbs; ssl->method->get_current_message(ssl, &cbs); return ssl3_update_handshake_hash(ssl, CBS_data(&cbs), CBS_len(&cbs)); @@ -766,6 +764,7 @@ void ssl3_release_current_message(SSL *ssl, int free_buffer) { ssl->init_msg = NULL; ssl->init_num = 0; ssl->init_buf->length = 0; + ssl->s3->is_v2_hello = 0; } if (free_buffer) {