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 <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:
David Benjamin 2016-11-14 17:12:11 +09:00 committed by CQ bot account: commit-bot@chromium.org
parent e8b554dff8
commit ced9479fd1
8 changed files with 37 additions and 30 deletions

View File

@ -433,7 +433,7 @@ int dtls1_get_message(SSL *ssl, int msg_type,
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
return -1; 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; return -1;
} }
@ -442,13 +442,12 @@ int dtls1_get_message(SSL *ssl, int msg_type,
return 1; 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)); assert(dtls1_is_current_message_complete(ssl));
hm_fragment *frag = ssl->d1->incoming_messages[ssl->d1->handshake_read_seq % hm_fragment *frag = ssl->d1->incoming_messages[ssl->d1->handshake_read_seq %
SSL_MAX_HANDSHAKE_FLIGHT]; SSL_MAX_HANDSHAKE_FLIGHT];
return ssl3_update_handshake_hash(ssl, frag->data, CBS_init(out, frag->data, DTLS1_HM_HEADER_LENGTH + frag->msg_len);
DTLS1_HM_HEADER_LENGTH + frag->msg_len);
} }
void dtls1_release_current_message(SSL *ssl, int free_buffer) { void dtls1_release_current_message(SSL *ssl, int free_buffer) {

View File

@ -132,7 +132,7 @@ static const SSL_PROTOCOL_METHOD kDTLSProtocolMethod = {
dtls1_new, dtls1_new,
dtls1_free, dtls1_free,
dtls1_get_message, dtls1_get_message,
dtls1_hash_current_message, dtls1_get_current_message,
dtls1_release_current_message, dtls1_release_current_message,
dtls1_read_app_data, dtls1_read_app_data,
dtls1_read_change_cipher_spec, dtls1_read_change_cipher_spec,

View File

@ -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 /* The handshake buffer is no longer necessary, and we may hash the current
* message.*/ * message.*/
ssl3_free_handshake_buffer(ssl); ssl3_free_handshake_buffer(ssl);
if (!ssl->method->hash_current_message(ssl)) { if (!ssl_hash_current_message(ssl)) {
goto err; goto err;
} }
@ -1812,7 +1812,7 @@ static int ssl3_get_channel_id(SSL *ssl) {
} }
if (!tls1_verify_channel_id(ssl) || if (!tls1_verify_channel_id(ssl) ||
!ssl->method->hash_current_message(ssl)) { !ssl_hash_current_message(ssl)) {
return -1; return -1;
} }
return 1; return 1;

View File

@ -1247,10 +1247,9 @@ struct ssl_protocol_method_st {
* Otherwise, it returns <= 0. */ * Otherwise, it returns <= 0. */
int (*ssl_get_message)(SSL *ssl, int msg_type, int (*ssl_get_message)(SSL *ssl, int msg_type,
enum ssl_hash_message_t hash_message); enum ssl_hash_message_t hash_message);
/* hash_current_message incorporates the current handshake message into the /* get_current_message sets |*out| to the current handshake message. This
* handshake hash. It returns one on success and zero on allocation * includes the protocol-specific message header. */
* failure. */ void (*get_current_message)(const SSL *ssl, CBS *out);
int (*hash_current_message)(SSL *ssl);
/* release_current_message is called to release the current handshake message. /* release_current_message is called to release the current handshake message.
* If |free_buffer| is one, buffers will also be released. */ * If |free_buffer| is one, buffers will also be released. */
void (*release_current_message)(SSL *ssl, int free_buffer); 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_send_alert(SSL *ssl, int level, int desc);
int ssl3_get_message(SSL *ssl, int msg_type, int ssl3_get_message(SSL *ssl, int msg_type,
enum ssl_hash_message_t hash_message); 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); void ssl3_release_current_message(SSL *ssl, int free_buffer);
/* ssl3_cert_verify_hash writes the SSL 3.0 CertificateVerify hash into the /* 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. */ * queue the message for writing. */
int ssl_complete_message(SSL *ssl, CBB *cbb); 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 /* 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 * |ssl->s3->rrec| and returns one. Otherwise it returns <= 0 on error or if
* more data is needed. */ * more data is needed. */
@ -1788,7 +1791,7 @@ int dtls1_connect(SSL *ssl);
void dtls1_free(SSL *ssl); void dtls1_free(SSL *ssl);
int dtls1_get_message(SSL *ssl, int mt, enum ssl_hash_message_t hash_message); 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); void dtls1_release_current_message(SSL *ssl, int free_buffer);
int dtls1_dispatch_alert(SSL *ssl); int dtls1_dispatch_alert(SSL *ssl);

View File

@ -320,7 +320,7 @@ int ssl3_get_finished(SSL *ssl) {
size_t finished_len = size_t finished_len =
ssl->s3->enc_method->final_finish_mac(ssl, !ssl->server, finished); ssl->s3->enc_method->final_finish_mac(ssl, !ssl->server, finished);
if (finished_len == 0 || if (finished_len == 0 ||
!ssl->method->hash_current_message(ssl)) { !ssl_hash_current_message(ssl)) {
return -1; return -1;
} }
@ -660,16 +660,21 @@ again:
} }
/* Feed this message into MAC computation. */ /* 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;
} }
return 1; return 1;
} }
int ssl3_hash_current_message(SSL *ssl) { void ssl3_get_current_message(const SSL *ssl, CBS *out) {
return ssl3_update_handshake_hash(ssl, (uint8_t *)ssl->init_buf->data, CBS_init(out, (uint8_t *)ssl->init_buf->data, ssl->init_buf->length);
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) { void ssl3_release_current_message(SSL *ssl, int free_buffer) {

View File

@ -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 /* If there was no HelloRetryRequest, the version negotiation logic has
* already hashed the message. */ * already hashed the message. */
if (hs->received_hello_retry_request && if (hs->received_hello_retry_request &&
!ssl->method->hash_current_message(ssl)) { !ssl_hash_current_message(ssl)) {
return ssl_hs_error; return ssl_hs_error;
} }
@ -409,7 +409,7 @@ static enum ssl_hs_wait_t do_process_encrypted_extensions(SSL *ssl,
return ssl_hs_error; return ssl_hs_error;
} }
if (!ssl->method->hash_current_message(ssl)) { if (!ssl_hash_current_message(ssl)) {
return ssl_hs_error; 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); sk_X509_NAME_pop_free(ssl->s3->hs->ca_names, X509_NAME_free);
ssl->s3->hs->ca_names = ca_sk; ssl->s3->hs->ca_names = ca_sk;
if (!ssl->method->hash_current_message(ssl)) { if (!ssl_hash_current_message(ssl)) {
return ssl_hs_error; return ssl_hs_error;
} }
@ -477,7 +477,7 @@ static enum ssl_hs_wait_t do_process_server_certificate(SSL *ssl,
SSL_HANDSHAKE *hs) { SSL_HANDSHAKE *hs) {
if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) || if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
!tls13_process_certificate(ssl, 0 /* certificate required */) || !tls13_process_certificate(ssl, 0 /* certificate required */) ||
!ssl->method->hash_current_message(ssl)) { !ssl_hash_current_message(ssl)) {
return ssl_hs_error; return ssl_hs_error;
} }
@ -489,7 +489,7 @@ static enum ssl_hs_wait_t do_process_server_certificate_verify(
SSL *ssl, SSL_HANDSHAKE *hs) { SSL *ssl, SSL_HANDSHAKE *hs) {
if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) || if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
!tls13_process_certificate_verify(ssl) || !tls13_process_certificate_verify(ssl) ||
!ssl->method->hash_current_message(ssl)) { !ssl_hash_current_message(ssl)) {
return 0; 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}; static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0};
if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) || if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) ||
!tls13_process_finished(ssl) || !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. */ /* Update the secret to the master secret and derive traffic keys. */
!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len) || !tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len) ||
!tls13_derive_traffic_secret_0(ssl)) { !tls13_derive_traffic_secret_0(ssl)) {

View File

@ -349,7 +349,7 @@ static enum ssl_hs_wait_t do_process_second_client_hello(SSL *ssl,
return ssl_hs_error; return ssl_hs_error;
} }
if (!ssl->method->hash_current_message(ssl)) { if (!ssl_hash_current_message(ssl)) {
return ssl_hs_error; 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) || if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE) ||
!tls13_process_certificate(ssl, allow_anonymous) || !tls13_process_certificate(ssl, allow_anonymous) ||
!ssl->method->hash_current_message(ssl)) { !ssl_hash_current_message(ssl)) {
return ssl_hs_error; 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) || if (!tls13_check_message_type(ssl, SSL3_MT_CERTIFICATE_VERIFY) ||
!tls13_process_certificate_verify(ssl) || !tls13_process_certificate_verify(ssl) ||
!ssl->method->hash_current_message(ssl)) { !ssl_hash_current_message(ssl)) {
return 0; 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) || if (!tls13_check_message_type(ssl, SSL3_MT_CHANNEL_ID) ||
!tls1_verify_channel_id(ssl) || !tls1_verify_channel_id(ssl) ||
!ssl->method->hash_current_message(ssl)) { !ssl_hash_current_message(ssl)) {
return ssl_hs_error; return ssl_hs_error;
} }
@ -588,7 +588,7 @@ static enum ssl_hs_wait_t do_process_client_finished(SSL *ssl,
SSL_HANDSHAKE *hs) { SSL_HANDSHAKE *hs) {
if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) || if (!tls13_check_message_type(ssl, SSL3_MT_FINISHED) ||
!tls13_process_finished(ssl) || !tls13_process_finished(ssl) ||
!ssl->method->hash_current_message(ssl) || !ssl_hash_current_message(ssl) ||
/* evp_aead_seal keys have already been switched. */ /* evp_aead_seal keys have already been switched. */
!tls13_set_traffic_key(ssl, type_data, evp_aead_open, !tls13_set_traffic_key(ssl, type_data, evp_aead_open,
hs->client_traffic_secret_0, hs->hash_len) || hs->client_traffic_secret_0, hs->hash_len) ||

View File

@ -130,7 +130,7 @@ static const SSL_PROTOCOL_METHOD kTLSProtocolMethod = {
ssl3_new, ssl3_new,
ssl3_free, ssl3_free,
ssl3_get_message, ssl3_get_message,
ssl3_hash_current_message, ssl3_get_current_message,
ssl3_release_current_message, ssl3_release_current_message,
ssl3_read_app_data, ssl3_read_app_data,
ssl3_read_change_cipher_spec, ssl3_read_change_cipher_spec,