For TLS 1.3 draft 18, it will be useful to get at the full current message and not just the body. Add a hook to expose it and replace hash_current_message with a wrapper over it. BUG=112 Change-Id: Ib9e00dd1b78e8b72e12409d85c80e96c5b411a8b Reviewed-on: https://boringssl-review.googlesource.com/12238 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>kris/onging/CECPQ3_patch15
@@ -433,7 +433,7 @@ int dtls1_get_message(SSL *ssl, int msg_type, | |||
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); | |||
return -1; | |||
} | |||
if (hash_message == ssl_hash_message && !dtls1_hash_current_message(ssl)) { | |||
if (hash_message == ssl_hash_message && !ssl_hash_current_message(ssl)) { | |||
return -1; | |||
} | |||
@@ -442,13 +442,12 @@ int dtls1_get_message(SSL *ssl, int msg_type, | |||
return 1; | |||
} | |||
int dtls1_hash_current_message(SSL *ssl) { | |||
void dtls1_get_current_message(const SSL *ssl, CBS *out) { | |||
assert(dtls1_is_current_message_complete(ssl)); | |||
hm_fragment *frag = ssl->d1->incoming_messages[ssl->d1->handshake_read_seq % | |||
SSL_MAX_HANDSHAKE_FLIGHT]; | |||
return ssl3_update_handshake_hash(ssl, frag->data, | |||
DTLS1_HM_HEADER_LENGTH + frag->msg_len); | |||
CBS_init(out, frag->data, DTLS1_HM_HEADER_LENGTH + frag->msg_len); | |||
} | |||
void dtls1_release_current_message(SSL *ssl, int free_buffer) { | |||
@@ -132,7 +132,7 @@ static const SSL_PROTOCOL_METHOD kDTLSProtocolMethod = { | |||
dtls1_new, | |||
dtls1_free, | |||
dtls1_get_message, | |||
dtls1_hash_current_message, | |||
dtls1_get_current_message, | |||
dtls1_release_current_message, | |||
dtls1_read_app_data, | |||
dtls1_read_change_cipher_spec, | |||
@@ -1759,7 +1759,7 @@ static int ssl3_get_cert_verify(SSL *ssl) { | |||
/* The handshake buffer is no longer necessary, and we may hash the current | |||
* message.*/ | |||
ssl3_free_handshake_buffer(ssl); | |||
if (!ssl->method->hash_current_message(ssl)) { | |||
if (!ssl_hash_current_message(ssl)) { | |||
goto err; | |||
} | |||
@@ -1812,7 +1812,7 @@ static int ssl3_get_channel_id(SSL *ssl) { | |||
} | |||
if (!tls1_verify_channel_id(ssl) || | |||
!ssl->method->hash_current_message(ssl)) { | |||
!ssl_hash_current_message(ssl)) { | |||
return -1; | |||
} | |||
return 1; | |||
@@ -1247,10 +1247,9 @@ struct ssl_protocol_method_st { | |||
* Otherwise, it returns <= 0. */ | |||
int (*ssl_get_message)(SSL *ssl, int msg_type, | |||
enum ssl_hash_message_t hash_message); | |||
/* hash_current_message incorporates the current handshake message into the | |||
* handshake hash. It returns one on success and zero on allocation | |||
* failure. */ | |||
int (*hash_current_message)(SSL *ssl); | |||
/* get_current_message sets |*out| to the current handshake message. This | |||
* includes the protocol-specific message header. */ | |||
void (*get_current_message)(const SSL *ssl, CBS *out); | |||
/* release_current_message is called to release the current handshake message. | |||
* If |free_buffer| is one, buffers will also be released. */ | |||
void (*release_current_message)(SSL *ssl, int free_buffer); | |||
@@ -1694,7 +1693,7 @@ int ssl3_send_change_cipher_spec(SSL *ssl); | |||
int ssl3_send_alert(SSL *ssl, int level, int desc); | |||
int ssl3_get_message(SSL *ssl, int msg_type, | |||
enum ssl_hash_message_t hash_message); | |||
int ssl3_hash_current_message(SSL *ssl); | |||
void ssl3_get_current_message(const SSL *ssl, CBS *out); | |||
void ssl3_release_current_message(SSL *ssl, int free_buffer); | |||
/* ssl3_cert_verify_hash writes the SSL 3.0 CertificateVerify hash into the | |||
@@ -1747,6 +1746,10 @@ int dtls1_write_message(SSL *ssl); | |||
* queue the message for writing. */ | |||
int ssl_complete_message(SSL *ssl, CBB *cbb); | |||
/* ssl_hash_current_message incorporates the current handshake message into the | |||
* handshake hash. It returns one on success and zero on allocation failure. */ | |||
int ssl_hash_current_message(SSL *ssl); | |||
/* dtls1_get_record reads a new input record. On success, it places it in | |||
* |ssl->s3->rrec| and returns one. Otherwise it returns <= 0 on error or if | |||
* more data is needed. */ | |||
@@ -1788,7 +1791,7 @@ int dtls1_connect(SSL *ssl); | |||
void dtls1_free(SSL *ssl); | |||
int dtls1_get_message(SSL *ssl, int mt, enum ssl_hash_message_t hash_message); | |||
int dtls1_hash_current_message(SSL *ssl); | |||
void dtls1_get_current_message(const SSL *ssl, CBS *out); | |||
void dtls1_release_current_message(SSL *ssl, int free_buffer); | |||
int dtls1_dispatch_alert(SSL *ssl); | |||
@@ -320,7 +320,7 @@ int ssl3_get_finished(SSL *ssl) { | |||
size_t finished_len = | |||
ssl->s3->enc_method->final_finish_mac(ssl, !ssl->server, finished); | |||
if (finished_len == 0 || | |||
!ssl->method->hash_current_message(ssl)) { | |||
!ssl_hash_current_message(ssl)) { | |||
return -1; | |||
} | |||
@@ -660,16 +660,21 @@ again: | |||
} | |||
/* Feed this message into MAC computation. */ | |||
if (hash_message == ssl_hash_message && !ssl3_hash_current_message(ssl)) { | |||
if (hash_message == ssl_hash_message && !ssl_hash_current_message(ssl)) { | |||
return -1; | |||
} | |||
return 1; | |||
} | |||
int ssl3_hash_current_message(SSL *ssl) { | |||
return ssl3_update_handshake_hash(ssl, (uint8_t *)ssl->init_buf->data, | |||
ssl->init_buf->length); | |||
void ssl3_get_current_message(const SSL *ssl, CBS *out) { | |||
CBS_init(out, (uint8_t *)ssl->init_buf->data, ssl->init_buf->length); | |||
} | |||
int ssl_hash_current_message(SSL *ssl) { | |||
CBS cbs; | |||
ssl->method->get_current_message(ssl, &cbs); | |||
return ssl3_update_handshake_hash(ssl, CBS_data(&cbs), CBS_len(&cbs)); | |||
} | |||
void ssl3_release_current_message(SSL *ssl, int free_buffer) { | |||
@@ -379,7 +379,7 @@ static enum ssl_hs_wait_t do_process_server_hello(SSL *ssl, SSL_HANDSHAKE *hs) { | |||
/* If there was no HelloRetryRequest, the version negotiation logic has | |||
* already hashed the message. */ | |||
if (hs->received_hello_retry_request && | |||
!ssl->method->hash_current_message(ssl)) { | |||
!ssl_hash_current_message(ssl)) { | |||
return ssl_hs_error; | |||
} | |||
@@ -409,7 +409,7 @@ static enum ssl_hs_wait_t do_process_encrypted_extensions(SSL *ssl, | |||
return ssl_hs_error; | |||
} | |||
if (!ssl->method->hash_current_message(ssl)) { | |||
if (!ssl_hash_current_message(ssl)) { | |||
return ssl_hs_error; | |||
} | |||
@@ -465,7 +465,7 @@ static enum ssl_hs_wait_t do_process_certificate_request(SSL *ssl, | |||
sk_X509_NAME_pop_free(ssl->s3->hs->ca_names, X509_NAME_free); | |||
ssl->s3->hs->ca_names = ca_sk; | |||
if (!ssl->method->hash_current_message(ssl)) { | |||
if (!ssl_hash_current_message(ssl)) { | |||
return ssl_hs_error; | |||
} | |||
@@ -477,7 +477,7 @@ static enum ssl_hs_wait_t do_process_server_certificate(SSL *ssl, | |||
SSL_HANDSHAKE *hs) { | |||
if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) || | |||
!tls13_process_certificate(ssl, 0 /* certificate required */) || | |||
!ssl->method->hash_current_message(ssl)) { | |||
!ssl_hash_current_message(ssl)) { | |||
return ssl_hs_error; | |||
} | |||
@@ -489,7 +489,7 @@ static enum ssl_hs_wait_t do_process_server_certificate_verify( | |||
SSL *ssl, SSL_HANDSHAKE *hs) { | |||
if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) || | |||
!tls13_process_certificate_verify(ssl) || | |||
!ssl->method->hash_current_message(ssl)) { | |||
!ssl_hash_current_message(ssl)) { | |||
return 0; | |||
} | |||
@@ -502,7 +502,7 @@ static enum ssl_hs_wait_t do_process_server_finished(SSL *ssl, | |||
static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0}; | |||
if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) || | |||
!tls13_process_finished(ssl) || | |||
!ssl->method->hash_current_message(ssl) || | |||
!ssl_hash_current_message(ssl) || | |||
/* Update the secret to the master secret and derive traffic keys. */ | |||
!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len) || | |||
!tls13_derive_traffic_secret_0(ssl)) { | |||
@@ -349,7 +349,7 @@ static enum ssl_hs_wait_t do_process_second_client_hello(SSL *ssl, | |||
return ssl_hs_error; | |||
} | |||
if (!ssl->method->hash_current_message(ssl)) { | |||
if (!ssl_hash_current_message(ssl)) { | |||
return ssl_hs_error; | |||
} | |||
@@ -536,7 +536,7 @@ static enum ssl_hs_wait_t do_process_client_certificate(SSL *ssl, | |||
if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) || | |||
!tls13_process_certificate(ssl, allow_anonymous) || | |||
!ssl->method->hash_current_message(ssl)) { | |||
!ssl_hash_current_message(ssl)) { | |||
return ssl_hs_error; | |||
} | |||
@@ -560,7 +560,7 @@ static enum ssl_hs_wait_t do_process_client_certificate_verify( | |||
if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) || | |||
!tls13_process_certificate_verify(ssl) || | |||
!ssl->method->hash_current_message(ssl)) { | |||
!ssl_hash_current_message(ssl)) { | |||
return 0; | |||
} | |||
@@ -576,7 +576,7 @@ static enum ssl_hs_wait_t do_process_channel_id(SSL *ssl, SSL_HANDSHAKE *hs) { | |||
if (!tls13_check_message_type(ssl, SSL3_MT_CHANNEL_ID) || | |||
!tls1_verify_channel_id(ssl) || | |||
!ssl->method->hash_current_message(ssl)) { | |||
!ssl_hash_current_message(ssl)) { | |||
return ssl_hs_error; | |||
} | |||
@@ -588,7 +588,7 @@ static enum ssl_hs_wait_t do_process_client_finished(SSL *ssl, | |||
SSL_HANDSHAKE *hs) { | |||
if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) || | |||
!tls13_process_finished(ssl) || | |||
!ssl->method->hash_current_message(ssl) || | |||
!ssl_hash_current_message(ssl) || | |||
/* evp_aead_seal keys have already been switched. */ | |||
!tls13_set_traffic_key(ssl, type_data, evp_aead_open, | |||
hs->client_traffic_secret_0, hs->hash_len) || | |||
@@ -130,7 +130,7 @@ static const SSL_PROTOCOL_METHOD kTLSProtocolMethod = { | |||
ssl3_new, | |||
ssl3_free, | |||
ssl3_get_message, | |||
ssl3_hash_current_message, | |||
ssl3_get_current_message, | |||
ssl3_release_current_message, | |||
ssl3_read_app_data, | |||
ssl3_read_change_cipher_spec, | |||