From ced9479fd1669cc8ca0762e612316d1f18098361 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Mon, 14 Nov 2016 17:12:11 +0900 Subject: [PATCH] Replace hash_current_message with get_current_message. 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 Commit-Queue: David Benjamin CQ-Verified: CQ bot account: commit-bot@chromium.org --- ssl/d1_both.c | 7 +++---- ssl/dtls_method.c | 2 +- ssl/handshake_server.c | 4 ++-- ssl/internal.h | 15 +++++++++------ ssl/s3_both.c | 15 ++++++++++----- ssl/tls13_client.c | 12 ++++++------ ssl/tls13_server.c | 10 +++++----- ssl/tls_method.c | 2 +- 8 files changed, 37 insertions(+), 30 deletions(-) diff --git a/ssl/d1_both.c b/ssl/d1_both.c index 0364664e..f9bb8f49 100644 --- a/ssl/d1_both.c +++ b/ssl/d1_both.c @@ -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) { diff --git a/ssl/dtls_method.c b/ssl/dtls_method.c index 80265795..8e92cc9f 100644 --- a/ssl/dtls_method.c +++ b/ssl/dtls_method.c @@ -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, diff --git a/ssl/handshake_server.c b/ssl/handshake_server.c index 710af02c..c8208add 100644 --- a/ssl/handshake_server.c +++ b/ssl/handshake_server.c @@ -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; diff --git a/ssl/internal.h b/ssl/internal.h index 030542d1..861f8bda 100644 --- a/ssl/internal.h +++ b/ssl/internal.h @@ -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); diff --git a/ssl/s3_both.c b/ssl/s3_both.c index 9f9dfadc..98ebf176 100644 --- a/ssl/s3_both.c +++ b/ssl/s3_both.c @@ -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) { diff --git a/ssl/tls13_client.c b/ssl/tls13_client.c index 4b0b56bc..a5b2e85d 100644 --- a/ssl/tls13_client.c +++ b/ssl/tls13_client.c @@ -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)) { diff --git a/ssl/tls13_server.c b/ssl/tls13_server.c index 446dd1ce..ca7b17e4 100644 --- a/ssl/tls13_server.c +++ b/ssl/tls13_server.c @@ -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) || diff --git a/ssl/tls_method.c b/ssl/tls_method.c index 0c7a9529..ce42904b 100644 --- a/ssl/tls_method.c +++ b/ssl/tls_method.c @@ -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,