diff options
author | Kenny Root <kroot@google.com> | 2015-09-25 02:29:14 +0000 |
---|---|---|
committer | Kenny Root <kroot@google.com> | 2015-09-25 02:29:14 +0000 |
commit | b8494591d1b1a143f3b192d845c238bbf3bc629d (patch) | |
tree | dd743d9d64af3145fe96b8d5fc2f3427544794bd /src/ssl/s3_srvr.c | |
parent | a04d78d392463df4e69a64360c952ffa5abd22f7 (diff) | |
download | external_boringssl-b8494591d1b1a143f3b192d845c238bbf3bc629d.zip external_boringssl-b8494591d1b1a143f3b192d845c238bbf3bc629d.tar.gz external_boringssl-b8494591d1b1a143f3b192d845c238bbf3bc629d.tar.bz2 |
Revert "Revert "external/boringssl: sync with upstream.""
This reverts commit a04d78d392463df4e69a64360c952ffa5abd22f7.
Underlying issue was fixed.
Change-Id: I49685b653d16e728eb38e79e02b2c33ddeefed88
Diffstat (limited to 'src/ssl/s3_srvr.c')
-rw-r--r-- | src/ssl/s3_srvr.c | 645 |
1 files changed, 294 insertions, 351 deletions
diff --git a/src/ssl/s3_srvr.c b/src/ssl/s3_srvr.c index a72e17e..b428043 100644 --- a/src/ssl/s3_srvr.c +++ b/src/ssl/s3_srvr.c @@ -146,6 +146,8 @@ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR * OTHERWISE. */ +#include <openssl/ssl.h> + #include <assert.h> #include <stdio.h> #include <string.h> @@ -172,10 +174,6 @@ #include "../crypto/dh/internal.h" -/* INITIAL_SNIFF_BUFFER_SIZE is the number of bytes read in the initial sniff - * buffer. */ -#define INITIAL_SNIFF_BUFFER_SIZE 8 - int ssl3_accept(SSL *s) { BUF_MEM *buf = NULL; uint32_t alg_a; @@ -199,7 +197,7 @@ int ssl3_accept(SSL *s) { s->in_handshake++; if (s->cert == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_accept, SSL_R_NO_CERTIFICATE_SET); + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET); return -1; } @@ -230,8 +228,8 @@ int ssl3_accept(SSL *s) { goto end; } - if (!ssl3_init_finished_mac(s)) { - OPENSSL_PUT_ERROR(SSL, ssl3_accept, ERR_R_INTERNAL_ERROR); + if (!ssl3_init_handshake_buffer(s)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); ret = -1; goto end; } @@ -310,8 +308,19 @@ int ssl3_accept(SSL *s) { s->init_num = 0; break; + case SSL3_ST_SW_CERT_STATUS_A: + case SSL3_ST_SW_CERT_STATUS_B: + ret = ssl3_send_certificate_status(s); + if (ret <= 0) { + goto end; + } + s->state = SSL3_ST_SW_KEY_EXCH_A; + s->init_num = 0; + break; + case SSL3_ST_SW_KEY_EXCH_A: case SSL3_ST_SW_KEY_EXCH_B: + case SSL3_ST_SW_KEY_EXCH_C: alg_a = s->s3->tmp.new_cipher->algorithm_auth; /* Send a ServerKeyExchange message if: @@ -473,7 +482,7 @@ int ssl3_accept(SSL *s) { /* If this is a full handshake with ChannelID then record the hashshake * hashes in |s->session| in case we need them to verify a ChannelID * signature on a resumption of this session in the future. */ - if (!s->hit && s->s3->tlsext_channel_id_new) { + if (!s->hit) { ret = tls1_record_handshake_hashes_for_channel_id(s); if (ret <= 0) { goto end; @@ -550,6 +559,8 @@ int ssl3_accept(SSL *s) { if (s->ctx->retain_only_sha256_of_client_certs) { X509_free(s->session->peer); s->session->peer = NULL; + sk_X509_pop_free(s->session->cert_chain, X509_free); + s->session->cert_chain = NULL; } s->s3->initial_handshake_complete = 1; @@ -564,7 +575,7 @@ int ssl3_accept(SSL *s) { goto end; default: - OPENSSL_PUT_ERROR(SSL, ssl3_accept, SSL_R_UNKNOWN_STATE); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE); ret = -1; goto end; } @@ -587,42 +598,16 @@ end: return ret; } -static int ssl3_read_sniff_buffer(SSL *s, size_t n) { - if (s->s3->sniff_buffer == NULL) { - s->s3->sniff_buffer = BUF_MEM_new(); - } - if (s->s3->sniff_buffer == NULL || !BUF_MEM_grow(s->s3->sniff_buffer, n)) { - return -1; - } - - while (s->s3->sniff_buffer_len < n) { - int ret; - - s->rwstate = SSL_READING; - ret = BIO_read(s->rbio, s->s3->sniff_buffer->data + s->s3->sniff_buffer_len, - n - s->s3->sniff_buffer_len); - if (ret <= 0) { - return ret; - } - s->rwstate = SSL_NOTHING; - s->s3->sniff_buffer_len += ret; - } - - return 1; -} - int ssl3_get_initial_bytes(SSL *s) { - int ret; - const uint8_t *p; - - /* Read the first 8 bytes. To recognize a ClientHello or V2ClientHello only - * needs the first 6 bytes, but 8 is needed to recognize CONNECT below. */ - ret = ssl3_read_sniff_buffer(s, INITIAL_SNIFF_BUFFER_SIZE); + /* 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. */ + int ret = ssl_read_buffer_extend_to(s, SSL3_RT_HEADER_LENGTH); if (ret <= 0) { return ret; } - assert(s->s3->sniff_buffer_len >= INITIAL_SNIFF_BUFFER_SIZE); - p = (const uint8_t *)s->s3->sniff_buffer->data; + assert(ssl_read_buffer_len(s) == SSL3_RT_HEADER_LENGTH); + const uint8_t *p = ssl_read_buffer(s); /* Some dedicated error codes for protocol mixups should the application wish * to interpret them differently. (These do not overlap with ClientHello or @@ -631,46 +616,25 @@ int ssl3_get_initial_bytes(SSL *s) { strncmp("POST ", (const char *)p, 5) == 0 || strncmp("HEAD ", (const char *)p, 5) == 0 || strncmp("PUT ", (const char *)p, 4) == 0) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_initial_bytes, SSL_R_HTTP_REQUEST); + OPENSSL_PUT_ERROR(SSL, SSL_R_HTTP_REQUEST); return -1; } - if (strncmp("CONNECT ", (const char *)p, 8) == 0) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_initial_bytes, SSL_R_HTTPS_PROXY_REQUEST); + if (strncmp("CONNE", (const char *)p, 5) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HTTPS_PROXY_REQUEST); return -1; } - /* Determine if this is a ClientHello or V2ClientHello. */ + /* Determine if this is a V2ClientHello. */ if ((p[0] & 0x80) && p[2] == SSL2_MT_CLIENT_HELLO && p[3] >= SSL3_VERSION_MAJOR) { /* This is a V2ClientHello. */ s->state = SSL3_ST_SR_V2_CLIENT_HELLO; return 1; } - if (p[0] == SSL3_RT_HANDSHAKE && p[1] >= SSL3_VERSION_MAJOR && - p[5] == SSL3_MT_CLIENT_HELLO) { - /* This is a ClientHello. Initialize the record layer with the already - * consumed data and continue the handshake. */ - if (!ssl3_setup_read_buffer(s)) { - return -1; - } - assert(s->rstate == SSL_ST_READ_HEADER); - /* There cannot have already been data in the record layer. */ - assert(s->s3->rbuf.left == 0); - memcpy(s->s3->rbuf.buf, p, s->s3->sniff_buffer_len); - s->s3->rbuf.offset = 0; - s->s3->rbuf.left = s->s3->sniff_buffer_len; - s->packet_length = 0; - - BUF_MEM_free(s->s3->sniff_buffer); - s->s3->sniff_buffer = NULL; - s->s3->sniff_buffer_len = 0; - - s->state = SSL3_ST_SR_CLNT_HELLO_A; - return 1; - } - OPENSSL_PUT_ERROR(SSL, ssl3_get_initial_bytes, SSL_R_UNKNOWN_PROTOCOL); - return -1; + /* Fall through to the standard logic. */ + s->state = SSL3_ST_SR_CLNT_HELLO_A; + return 1; } int ssl3_get_v2_client_hello(SSL *s) { @@ -683,36 +647,34 @@ int ssl3_get_v2_client_hello(SSL *s) { CBB client_hello, hello_body, cipher_suites; uint8_t random[SSL3_RANDOM_SIZE]; - /* Read the remainder of the V2ClientHello. We have previously read 8 bytes - * in ssl3_get_initial_bytes. */ - assert(s->s3->sniff_buffer_len >= INITIAL_SNIFF_BUFFER_SIZE); - p = (const uint8_t *)s->s3->sniff_buffer->data; + /* Determine the length of the V2ClientHello. */ + assert(ssl_read_buffer_len(s) >= SSL3_RT_HEADER_LENGTH); + p = ssl_read_buffer(s); msg_length = ((p[0] & 0x7f) << 8) | p[1]; if (msg_length > (1024 * 4)) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, SSL_R_RECORD_TOO_LARGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); return -1; } - if (msg_length < INITIAL_SNIFF_BUFFER_SIZE - 2) { - /* Reject lengths that are too short early. We have already read 8 bytes, - * so we should not attempt to process an (invalid) V2ClientHello which - * would be shorter than that. */ - OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, - SSL_R_RECORD_LENGTH_MISMATCH); + if (msg_length < SSL3_RT_HEADER_LENGTH - 2) { + /* Reject lengths that are too short early. We have already read + * |SSL3_RT_HEADER_LENGTH| bytes, so we should not attempt to process an + * (invalid) V2ClientHello which would be shorter than that. */ + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_LENGTH_MISMATCH); return -1; } - ret = ssl3_read_sniff_buffer(s, msg_length + 2); + /* Read the remainder of the V2ClientHello. */ + ret = ssl_read_buffer_extend_to(s, 2 + msg_length); if (ret <= 0) { return ret; } - assert(s->s3->sniff_buffer_len == msg_length + 2); - CBS_init(&v2_client_hello, (const uint8_t *)s->s3->sniff_buffer->data + 2, - msg_length); + assert(ssl_read_buffer_len(s) == msg_length + 2); + CBS_init(&v2_client_hello, ssl_read_buffer(s) + 2, msg_length); - /* The V2ClientHello without the length is incorporated into the Finished + /* The V2ClientHello without the length is incorporated into the handshake * hash. */ - if (!ssl3_finish_mac(s, CBS_data(&v2_client_hello), - CBS_len(&v2_client_hello))) { + if (!ssl3_update_handshake_hash(s, CBS_data(&v2_client_hello), + CBS_len(&v2_client_hello))) { return -1; } if (s->msg_callback) { @@ -729,7 +691,7 @@ int ssl3_get_v2_client_hello(SSL *s) { !CBS_get_bytes(&v2_client_hello, &session_id, session_id_length) || !CBS_get_bytes(&v2_client_hello, &challenge, challenge_length) || CBS_len(&v2_client_hello) != 0) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); return -1; } @@ -747,12 +709,10 @@ int ssl3_get_v2_client_hello(SSL *s) { rand_len); /* Write out an equivalent SSLv3 ClientHello. */ + CBB_zero(&client_hello); if (!CBB_init_fixed(&client_hello, (uint8_t *)s->init_buf->data, - s->init_buf->max)) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_MALLOC_FAILURE); - return -1; - } - if (!CBB_add_u8(&client_hello, SSL3_MT_CLIENT_HELLO) || + s->init_buf->max) || + !CBB_add_u8(&client_hello, SSL3_MT_CLIENT_HELLO) || !CBB_add_u24_length_prefixed(&client_hello, &hello_body) || !CBB_add_u16(&hello_body, version) || !CBB_add_bytes(&hello_body, random, SSL3_RANDOM_SIZE) || @@ -760,7 +720,7 @@ int ssl3_get_v2_client_hello(SSL *s) { !CBB_add_u8(&hello_body, 0) || !CBB_add_u16_length_prefixed(&hello_body, &cipher_suites)) { CBB_cleanup(&client_hello); - OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); return -1; } @@ -769,7 +729,7 @@ int ssl3_get_v2_client_hello(SSL *s) { uint32_t cipher_spec; if (!CBS_get_u24(&cipher_specs, &cipher_spec)) { CBB_cleanup(&client_hello); - OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); return -1; } @@ -779,7 +739,7 @@ int ssl3_get_v2_client_hello(SSL *s) { } if (!CBB_add_u16(&cipher_suites, cipher_spec)) { CBB_cleanup(&client_hello); - OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return -1; } } @@ -788,7 +748,7 @@ int ssl3_get_v2_client_hello(SSL *s) { if (!CBB_add_u8(&hello_body, 1) || !CBB_add_u8(&hello_body, 0) || !CBB_finish(&client_hello, NULL, &len)) { CBB_cleanup(&client_hello); - OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return -1; } @@ -798,10 +758,9 @@ int ssl3_get_v2_client_hello(SSL *s) { /* The handshake message header is 4 bytes. */ s->s3->tmp.message_size = len - 4; - /* Drop the sniff buffer. */ - BUF_MEM_free(s->s3->sniff_buffer); - s->s3->sniff_buffer = NULL; - s->s3->sniff_buffer_len = 0; + /* Consume and discard the V2ClientHello. */ + ssl_read_buffer_consume(s, 2 + msg_length); + ssl_read_buffer_discard(s); return 1; } @@ -815,6 +774,7 @@ int ssl3_get_client_hello(SSL *s) { CBS client_hello; uint16_t client_version; CBS client_random, session_id, cipher_suites, compression_methods; + SSL_SESSION *session = NULL; /* We do this so that we will respond with our native type. If we are TLSv1 * and we get SSLv3, we will respond with TLSv1, This down switching should @@ -847,8 +807,7 @@ int ssl3_get_client_hello(SSL *s) { early_ctx.client_hello_len = n; if (!ssl_early_callback_init(&early_ctx)) { al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, - SSL_R_CLIENTHELLO_PARSE_FAILED); + OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED); goto f_err; } @@ -863,8 +822,7 @@ int ssl3_get_client_hello(SSL *s) { case -1: /* Connection rejected. */ al = SSL_AD_ACCESS_DENIED; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, - SSL_R_CONNECTION_REJECTED); + OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED); goto f_err; default: @@ -875,7 +833,7 @@ int ssl3_get_client_hello(SSL *s) { break; default: - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_UNKNOWN_STATE); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE); return -1; } @@ -885,7 +843,7 @@ int ssl3_get_client_hello(SSL *s) { !CBS_get_u8_length_prefixed(&client_hello, &session_id) || CBS_len(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) { al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto f_err; } @@ -902,7 +860,7 @@ int ssl3_get_client_hello(SSL *s) { if (!CBS_get_u8_length_prefixed(&client_hello, &cookie) || CBS_len(&cookie) > DTLS1_COOKIE_LENGTH) { al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto f_err; } } @@ -916,7 +874,7 @@ int ssl3_get_client_hello(SSL *s) { /* Select version to use */ uint16_t version = ssl3_get_mutual_version(s, client_version); if (version == 0) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_UNSUPPORTED_PROTOCOL); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL); s->version = s->client_version; al = SSL_AD_PROTOCOL_VERSION; goto f_err; @@ -929,19 +887,23 @@ int ssl3_get_client_hello(SSL *s) { s->s3->have_version = 1; } else if (SSL_IS_DTLS(s) ? (s->client_version > s->version) : (s->client_version < s->version)) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_WRONG_VERSION_NUMBER); + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER); al = SSL_AD_PROTOCOL_VERSION; goto f_err; } s->hit = 0; - int session_ret = ssl_get_prev_session(s, &early_ctx); - if (session_ret == PENDING_SESSION) { - s->rwstate = SSL_PENDING_SESSION; - goto err; - } else if (session_ret == -1) { - goto err; + int send_new_ticket = 0; + switch (ssl_get_prev_session(s, &session, &send_new_ticket, &early_ctx)) { + case ssl_session_success: + break; + case ssl_session_error: + goto err; + case ssl_session_retry: + s->rwstate = SSL_PENDING_SESSION; + goto err; } + s->tlsext_ticket_expected = send_new_ticket; /* The EMS state is needed when making the resumption decision, but * extensions are not normally parsed until later. This detects the EMS @@ -956,34 +918,40 @@ int ssl3_get_client_hello(SSL *s) { &ems_data, &ems_len) && ems_len == 0; - if (session_ret == 1) { - if (s->session->extended_master_secret && + if (session != NULL) { + if (session->extended_master_secret && !have_extended_master_secret) { /* A ClientHello without EMS that attempts to resume a session with EMS * is fatal to the connection. */ al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, - SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION); + OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION); goto f_err; } s->hit = /* Only resume if the session's version matches the negotiated version: * most clients do not accept a mismatch. */ - s->version == s->session->ssl_version && + s->version == session->ssl_version && /* If the client offers the EMS extension, but the previous session * didn't use it, then negotiate a new session. */ - have_extended_master_secret == s->session->extended_master_secret; + have_extended_master_secret == session->extended_master_secret; } - if (!s->hit && !ssl_get_new_session(s, 1)) { + if (s->hit) { + /* Use the new session. */ + SSL_SESSION_free(s->session); + s->session = session; + session = NULL; + + s->verify_result = s->session->verify_result; + } else if (!ssl_get_new_session(s, 1)) { goto err; } if (s->ctx->dos_protection_cb != NULL && s->ctx->dos_protection_cb(&early_ctx) == 0) { /* Connection rejected for DOS reasons. */ al = SSL_AD_ACCESS_DENIED; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_CONNECTION_REJECTED); + OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED); goto f_err; } @@ -993,7 +961,7 @@ int ssl3_get_client_hello(SSL *s) { !CBS_get_u8_length_prefixed(&client_hello, &compression_methods) || CBS_len(&compression_methods) == 0) { al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto f_err; } @@ -1020,8 +988,7 @@ int ssl3_get_client_hello(SSL *s) { /* we need to have the cipher in the cipher list if we are asked to reuse * it */ al = SSL_AD_ILLEGAL_PARAMETER; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, - SSL_R_REQUIRED_CIPHER_MISSING); + OPENSSL_PUT_ERROR(SSL, SSL_R_REQUIRED_CIPHER_MISSING); goto f_err; } } @@ -1030,15 +997,14 @@ int ssl3_get_client_hello(SSL *s) { if (memchr(CBS_data(&compression_methods), 0, CBS_len(&compression_methods)) == NULL) { al = SSL_AD_ILLEGAL_PARAMETER; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, - SSL_R_NO_COMPRESSION_SPECIFIED); + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMPRESSION_SPECIFIED); goto f_err; } /* TLS extensions. */ if (s->version >= SSL3_VERSION && !ssl_parse_clienthello_tlsext(s, &client_hello)) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_PARSE_TLSEXT); + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); goto err; } @@ -1046,13 +1012,13 @@ int ssl3_get_client_hello(SSL *s) { if (CBS_len(&client_hello) != 0) { /* wrong packet length */ al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_BAD_PACKET_LENGTH); + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH); goto f_err; } if (have_extended_master_secret != s->s3->tmp.extended_master_secret) { al = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_EMS_STATE_INCONSISTENT); + OPENSSL_PUT_ERROR(SSL, SSL_R_EMS_STATE_INCONSISTENT); goto f_err; } @@ -1060,7 +1026,7 @@ int ssl3_get_client_hello(SSL *s) { if (!s->hit) { if (ciphers == NULL) { al = SSL_AD_ILLEGAL_PARAMETER; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_NO_CIPHERS_PASSED); + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_PASSED); goto f_err; } @@ -1069,7 +1035,7 @@ int ssl3_get_client_hello(SSL *s) { int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg); if (rv == 0) { al = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_CERT_CB_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR); goto f_err; } if (rv < 0) { @@ -1082,7 +1048,7 @@ int ssl3_get_client_hello(SSL *s) { if (c == NULL) { al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_NO_SHARED_CIPHER); + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER); goto f_err; } s->s3->tmp.new_cipher = c; @@ -1104,11 +1070,15 @@ int ssl3_get_client_hello(SSL *s) { s->s3->tmp.cert_request = 0; } + /* Now that the cipher is known, initialize the handshake hash. */ + if (!ssl3_init_handshake_hash(s)) { + goto f_err; + } + /* In TLS 1.2, client authentication requires hashing the handshake transcript * under a different hash. Otherwise, release the handshake buffer. */ - if ((!SSL_USE_SIGALGS(s) || !s->s3->tmp.cert_request) && - !ssl3_digest_cached_records(s, free_handshake_buffer)) { - goto f_err; + if (!SSL_USE_SIGALGS(s) || !s->s3->tmp.cert_request) { + ssl3_free_handshake_buffer(s); } /* we now have the following setup; @@ -1132,6 +1102,7 @@ int ssl3_get_client_hello(SSL *s) { err: sk_SSL_CIPHER_free(ciphers); + SSL_SESSION_free(session); return ret; } @@ -1152,8 +1123,7 @@ int ssl3_send_server_hello(SSL *s) { /* If this is a resumption and the original handshake didn't support * ChannelID then we didn't record the original handshake hashes in the * session and so cannot resume with ChannelIDs. */ - if (s->hit && s->s3->tlsext_channel_id_new && - s->session->original_handshake_hash_len == 0) { + if (s->hit && s->session->original_handshake_hash_len == 0) { s->s3->tlsext_channel_id_valid = 0; } @@ -1167,7 +1137,7 @@ int ssl3_send_server_hello(SSL *s) { /* Random stuff */ if (!ssl_fill_hello_random(s->s3->server_random, SSL3_RANDOM_SIZE, 1 /* server */)) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return -1; } memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); @@ -1191,7 +1161,7 @@ int ssl3_send_server_hello(SSL *s) { sl = s->session->session_id_length; if (sl > (int)sizeof(s->session->session_id)) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return -1; } *(p++) = sl; @@ -1203,13 +1173,10 @@ int ssl3_send_server_hello(SSL *s) { /* put the compression method */ *(p++) = 0; - if (ssl_prepare_serverhello_tlsext(s) <= 0) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, SSL_R_SERVERHELLO_TLSEXT); - return -1; - } + p = ssl_add_serverhello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH); if (p == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return -1; } @@ -1225,6 +1192,32 @@ int ssl3_send_server_hello(SSL *s) { return ssl_do_write(s); } +int ssl3_send_certificate_status(SSL *ssl) { + if (ssl->state == SSL3_ST_SW_CERT_STATUS_A) { + CBB out, ocsp_response; + size_t length; + + CBB_zero(&out); + if (!CBB_init_fixed(&out, ssl_handshake_start(ssl), + ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) || + !CBB_add_u8(&out, TLSEXT_STATUSTYPE_ocsp) || + !CBB_add_u24_length_prefixed(&out, &ocsp_response) || + !CBB_add_bytes(&ocsp_response, ssl->ctx->ocsp_response, + ssl->ctx->ocsp_response_length) || + !CBB_finish(&out, NULL, &length) || + !ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE_STATUS, length)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + CBB_cleanup(&out); + return -1; + } + + ssl->state = SSL3_ST_SW_CERT_STATUS_B; + } + + /* SSL3_ST_SW_CERT_STATUS_B */ + return ssl_do_write(ssl); +} + int ssl3_send_server_done(SSL *s) { if (s->state == SSL3_ST_SW_SRVR_DONE_A) { if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0)) { @@ -1246,7 +1239,8 @@ int ssl3_send_server_key_exchange(SSL *s) { BN_CTX *bn_ctx = NULL; const char *psk_identity_hint = NULL; size_t psk_identity_hint_len = 0; - EVP_PKEY *pkey; + size_t sig_len; + size_t max_sig_len; uint8_t *p, *d; int al, i; uint32_t alg_k; @@ -1254,11 +1248,26 @@ int ssl3_send_server_key_exchange(SSL *s) { int n; CERT *cert; BIGNUM *r[4]; - int nr[4], kn; + int nr[4]; BUF_MEM *buf; EVP_MD_CTX md_ctx; + if (s->state == SSL3_ST_SW_KEY_EXCH_C) { + return ssl_do_write(s); + } + + if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) { + if (!ssl_has_private_key(s)) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + max_sig_len = ssl_private_key_max_signature_len(s); + } else { + max_sig_len = 0; + } + EVP_MD_CTX_init(&md_ctx); + enum ssl_private_key_result_t sign_result; if (s->state == SSL3_ST_SW_KEY_EXCH_A) { alg_k = s->s3->tmp.new_cipher->algorithm_mkey; alg_a = s->s3->tmp.new_cipher->algorithm_auth; @@ -1286,25 +1295,23 @@ int ssl3_send_server_key_exchange(SSL *s) { } if (dhp == NULL) { al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, - SSL_R_MISSING_TMP_DH_KEY); + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_DH_KEY); goto f_err; } if (s->s3->tmp.dh != NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, - ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); goto err; } dh = DHparams_dup(dhp); if (dh == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_DH_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); goto err; } s->s3->tmp.dh = dh; if (!DH_generate_key(dh)) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_DH_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); goto err; } @@ -1328,14 +1335,12 @@ int ssl3_send_server_key_exchange(SSL *s) { } if (nid == NID_undef) { al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, - SSL_R_MISSING_TMP_ECDH_KEY); + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_ECDH_KEY); goto f_err; } if (s->s3->tmp.ecdh != NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, - ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); goto err; } ecdh = EC_KEY_new_by_curve_name(nid); @@ -1345,15 +1350,14 @@ int ssl3_send_server_key_exchange(SSL *s) { s->s3->tmp.ecdh = ecdh; if (!EC_KEY_generate_key(ecdh)) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_ECDH_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB); goto err; } /* We only support ephemeral ECDH keys over named (not generic) curves. */ const EC_GROUP *group = EC_KEY_get0_group(ecdh); if (!tls1_ec_nid2curve_id(&curve_id, EC_GROUP_get_curve_name(group))) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, - SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); goto err; } @@ -1366,8 +1370,7 @@ int ssl3_send_server_key_exchange(SSL *s) { encodedPoint = (uint8_t *)OPENSSL_malloc(encodedlen * sizeof(uint8_t)); bn_ctx = BN_CTX_new(); if (encodedPoint == NULL || bn_ctx == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, - ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } @@ -1376,7 +1379,7 @@ int ssl3_send_server_key_exchange(SSL *s) { encodedPoint, encodedlen, bn_ctx); if (encodedlen == 0) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_ECDH_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB); goto err; } @@ -1396,8 +1399,7 @@ int ssl3_send_server_key_exchange(SSL *s) { r[3] = NULL; } else if (!(alg_k & SSL_kPSK)) { al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, - SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); goto f_err; } @@ -1406,20 +1408,8 @@ int ssl3_send_server_key_exchange(SSL *s) { n += 2 + nr[i]; } - if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) { - pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher); - if (pkey == NULL) { - al = SSL_AD_DECODE_ERROR; - goto f_err; - } - kn = EVP_PKEY_size(pkey); - } else { - pkey = NULL; - kn = 0; - } - - if (!BUF_MEM_grow_clean(buf, n + SSL_HM_HEADER_LENGTH(s) + kn)) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_LIB_BUF); + if (!BUF_MEM_grow_clean(buf, n + SSL_HM_HEADER_LENGTH(s) + max_sig_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_LIB_BUF); goto err; } d = p = ssl_handshake_start(s); @@ -1458,54 +1448,81 @@ int ssl3_send_server_key_exchange(SSL *s) { encodedPoint = NULL; } - /* not anonymous */ - if (pkey != NULL) { - /* n is the length of the params, they start at &(d[4]) and p points to + if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) { + /* n is the length of the params, they start at d and p points to * the space at the end. */ const EVP_MD *md; - size_t sig_len = EVP_PKEY_size(pkey); + uint8_t digest[EVP_MAX_MD_SIZE]; + unsigned int digest_length; + + const int pkey_type = ssl_private_key_type(s); /* Determine signature algorithm. */ if (SSL_USE_SIGALGS(s)) { - md = tls1_choose_signing_digest(s, pkey); - if (!tls12_get_sigandhash(p, pkey, md)) { + md = tls1_choose_signing_digest(s); + if (!tls12_get_sigandhash(s, p, md)) { /* Should never happen */ al = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, - ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); goto f_err; } p += 2; - } else if (pkey->type == EVP_PKEY_RSA) { + } else if (pkey_type == EVP_PKEY_RSA) { md = EVP_md5_sha1(); } else { md = EVP_sha1(); } - if (!EVP_DigestSignInit(&md_ctx, NULL, md, NULL, pkey) || - !EVP_DigestSignUpdate(&md_ctx, s->s3->client_random, - SSL3_RANDOM_SIZE) || - !EVP_DigestSignUpdate(&md_ctx, s->s3->server_random, - SSL3_RANDOM_SIZE) || - !EVP_DigestSignUpdate(&md_ctx, d, n) || - !EVP_DigestSignFinal(&md_ctx, &p[2], &sig_len)) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_LIB_EVP); + if (!EVP_DigestInit_ex(&md_ctx, md, NULL) || + !EVP_DigestUpdate(&md_ctx, s->s3->client_random, SSL3_RANDOM_SIZE) || + !EVP_DigestUpdate(&md_ctx, s->s3->server_random, SSL3_RANDOM_SIZE) || + !EVP_DigestUpdate(&md_ctx, d, n) || + !EVP_DigestFinal_ex(&md_ctx, digest, &digest_length)) { + OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP); goto err; } - s2n(sig_len, p); - n += sig_len + 2; - if (SSL_USE_SIGALGS(s)) { - n += 2; - } + sign_result = ssl_private_key_sign(s, &p[2], &sig_len, max_sig_len, + EVP_MD_CTX_md(&md_ctx), digest, + digest_length); + } else { + /* This key exchange doesn't involve a signature. */ + sign_result = ssl_private_key_success; + sig_len = 0; } + } else { + assert(s->state == SSL3_ST_SW_KEY_EXCH_B); + /* Restore |p|. */ + p = ssl_handshake_start(s) + s->init_num - SSL_HM_HEADER_LENGTH(s); + sign_result = ssl_private_key_sign_complete(s, &p[2], &sig_len, + max_sig_len); + } - if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n)) { + switch (sign_result) { + case ssl_private_key_success: + s->rwstate = SSL_NOTHING; + break; + case ssl_private_key_failure: + s->rwstate = SSL_NOTHING; + goto err; + case ssl_private_key_retry: + s->rwstate = SSL_PRIVATE_KEY_OPERATION; + /* Stash away |p|. */ + s->init_num = p - ssl_handshake_start(s) + SSL_HM_HEADER_LENGTH(s); + s->state = SSL3_ST_SW_KEY_EXCH_B; goto err; - } } - s->state = SSL3_ST_SW_KEY_EXCH_B; + if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) { + s2n(sig_len, p); + p += sig_len; + } + if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, + p - ssl_handshake_start(s))) { + goto err; + } + s->state = SSL3_ST_SW_KEY_EXCH_C; + EVP_MD_CTX_cleanup(&md_ctx); return ssl_do_write(s); @@ -1558,7 +1575,7 @@ int ssl3_send_certificate_request(SSL *s) { name = sk_X509_NAME_value(sk, i); j = i2d_X509_NAME(name, NULL); if (!BUF_MEM_grow_clean(buf, SSL_HM_HEADER_LENGTH(s) + n + j + 2)) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_certificate_request, ERR_R_BUF_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); goto err; } p = ssl_handshake_start(s) + n; @@ -1629,30 +1646,27 @@ int ssl3_get_client_key_exchange(SSL *s) { * then this is the only field in the message. */ if (!CBS_get_u16_length_prefixed(&client_key_exchange, &psk_identity) || ((alg_k & SSL_kPSK) && CBS_len(&client_key_exchange) != 0)) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); al = SSL_AD_DECODE_ERROR; goto f_err; } if (s->psk_server_callback == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - SSL_R_PSK_NO_SERVER_CB); + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_SERVER_CB); al = SSL_AD_INTERNAL_ERROR; goto f_err; } if (CBS_len(&psk_identity) > PSK_MAX_IDENTITY_LEN || CBS_contains_zero_byte(&psk_identity)) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - SSL_R_DATA_LENGTH_TOO_LONG); + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); al = SSL_AD_ILLEGAL_PARAMETER; goto f_err; } if (!CBS_strdup(&psk_identity, &s->session->psk_identity)) { al = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto f_err; } @@ -1660,14 +1674,12 @@ int ssl3_get_client_key_exchange(SSL *s) { psk_len = s->psk_server_callback(s, s->session->psk_identity, psk, sizeof(psk)); if (psk_len > PSK_MAX_PSK_LEN) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); al = SSL_AD_INTERNAL_ERROR; goto f_err; } else if (psk_len == 0) { /* PSK related to the given identity not found */ - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - SSL_R_PSK_IDENTITY_NOT_FOUND); + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND); al = SSL_AD_UNKNOWN_PSK_IDENTITY; goto f_err; } @@ -1681,11 +1693,10 @@ int ssl3_get_client_key_exchange(SSL *s) { uint8_t good; size_t rsa_size, decrypt_len, premaster_index, j; - pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey; + pkey = s->cert->privatekey; if (pkey == NULL || pkey->type != EVP_PKEY_RSA || pkey->pkey.rsa == NULL) { al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - SSL_R_MISSING_RSA_CERTIFICATE); + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_RSA_CERTIFICATE); goto f_err; } rsa = pkey->pkey.rsa; @@ -1698,8 +1709,7 @@ int ssl3_get_client_key_exchange(SSL *s) { CBS_len(&client_key_exchange) != 0) { if (!(s->options & SSL_OP_TLS_D5_BUG)) { al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); + OPENSSL_PUT_ERROR(SSL, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); goto f_err; } else { encrypted_premaster_secret = copy; @@ -1716,8 +1726,7 @@ int ssl3_get_client_key_exchange(SSL *s) { rsa_size = RSA_size(rsa); if (rsa_size < SSL_MAX_MASTER_KEY_LENGTH) { al = SSL_AD_DECRYPT_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - SSL_R_DECRYPTION_FAILED); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); goto f_err; } @@ -1733,8 +1742,7 @@ int ssl3_get_client_key_exchange(SSL *s) { /* Allocate a buffer large enough for an RSA decryption. */ decrypt_buf = OPENSSL_malloc(rsa_size); if (decrypt_buf == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } @@ -1748,8 +1756,7 @@ int ssl3_get_client_key_exchange(SSL *s) { if (decrypt_len != rsa_size) { /* This should never happen, but do a check so we do not read * uninitialized memory. */ - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); goto err; } @@ -1772,8 +1779,7 @@ int ssl3_get_client_key_exchange(SSL *s) { BUF_memdup(decrypt_buf + (rsa_size - SSL_MAX_MASTER_KEY_LENGTH), SSL_MAX_MASTER_KEY_LENGTH); if (premaster_secret == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } OPENSSL_free(decrypt_buf); @@ -1804,38 +1810,35 @@ int ssl3_get_client_key_exchange(SSL *s) { if (!CBS_get_u16_length_prefixed(&client_key_exchange, &dh_Yc) || CBS_len(&dh_Yc) == 0 || CBS_len(&client_key_exchange) != 0) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); + OPENSSL_PUT_ERROR(SSL, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); al = SSL_R_DECODE_ERROR; goto f_err; } if (s->s3->tmp.dh == NULL) { al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - SSL_R_MISSING_TMP_DH_KEY); + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_DH_KEY); goto f_err; } dh_srvr = s->s3->tmp.dh; pub = BN_bin2bn(CBS_data(&dh_Yc), CBS_len(&dh_Yc), NULL); if (pub == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_BN_LIB); + OPENSSL_PUT_ERROR(SSL, SSL_R_BN_LIB); goto err; } /* Allocate a buffer for the premaster secret. */ premaster_secret = OPENSSL_malloc(DH_size(dh_srvr)); if (premaster_secret == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); BN_clear_free(pub); goto err; } dh_len = DH_compute_key(premaster_secret, pub, dh_srvr); if (dh_len <= 0) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_DH_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); BN_clear_free(pub); goto err; } @@ -1856,8 +1859,7 @@ int ssl3_get_client_key_exchange(SSL *s) { /* initialize structures for server's ECDH key pair */ srvr_ecdh = EC_KEY_new(); if (srvr_ecdh == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } @@ -1870,15 +1872,14 @@ int ssl3_get_client_key_exchange(SSL *s) { if (!EC_KEY_set_group(srvr_ecdh, group) || !EC_KEY_set_private_key(srvr_ecdh, priv_key)) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_EC_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB); goto err; } /* Let's get client's public key */ clnt_ecpoint = EC_POINT_new(group); if (clnt_ecpoint == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } @@ -1887,35 +1888,33 @@ int ssl3_get_client_key_exchange(SSL *s) { if (!CBS_get_u8_length_prefixed(&client_key_exchange, &ecdh_Yc) || CBS_len(&client_key_exchange) != 0) { al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto f_err; } bn_ctx = BN_CTX_new(); if (bn_ctx == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } if (!EC_POINT_oct2point(group, clnt_ecpoint, CBS_data(&ecdh_Yc), CBS_len(&ecdh_Yc), bn_ctx)) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_EC_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB); goto err; } /* Allocate a buffer for both the secret and the PSK. */ field_size = EC_GROUP_get_degree(group); if (field_size <= 0) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_ECDH_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB); goto err; } ecdh_len = (field_size + 7) / 8; premaster_secret = OPENSSL_malloc(ecdh_len); if (premaster_secret == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } @@ -1923,7 +1922,7 @@ int ssl3_get_client_key_exchange(SSL *s) { ecdh_len = ECDH_compute_key(premaster_secret, ecdh_len, clnt_ecpoint, srvr_ecdh, NULL); if (ecdh_len <= 0) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_ECDH_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB); goto err; } @@ -1945,15 +1944,13 @@ int ssl3_get_client_key_exchange(SSL *s) { premaster_secret_len = psk_len; premaster_secret = OPENSSL_malloc(premaster_secret_len); if (premaster_secret == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } memset(premaster_secret, 0, premaster_secret_len); } else { al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - SSL_R_UNKNOWN_CIPHER_TYPE); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_TYPE); goto f_err; } @@ -1964,18 +1961,14 @@ int ssl3_get_client_key_exchange(SSL *s) { uint8_t *new_data; size_t new_len; - if (!CBB_init(&new_premaster, 2 + psk_len + 2 + premaster_secret_len)) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - ERR_R_MALLOC_FAILURE); - goto err; - } - if (!CBB_add_u16_length_prefixed(&new_premaster, &child) || + CBB_zero(&new_premaster); + if (!CBB_init(&new_premaster, 2 + psk_len + 2 + premaster_secret_len) || + !CBB_add_u16_length_prefixed(&new_premaster, &child) || !CBB_add_bytes(&child, premaster_secret, premaster_secret_len) || !CBB_add_u16_length_prefixed(&new_premaster, &child) || !CBB_add_bytes(&child, psk, psk_len) || !CBB_finish(&new_premaster, &new_data, &new_len)) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, - ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); CBB_cleanup(&new_premaster); goto err; } @@ -2031,10 +2024,7 @@ int ssl3_get_cert_verify(SSL *s) { * CertificateVerify is required if and only if there's a client certificate. * */ if (peer == NULL) { - if (s->s3->handshake_buffer && - !ssl3_digest_cached_records(s, free_handshake_buffer)) { - return -1; - } + ssl3_free_handshake_buffer(s); return 1; } @@ -2055,8 +2045,7 @@ int ssl3_get_cert_verify(SSL *s) { if (!(X509_certificate_type(peer, pkey) & EVP_PKT_SIGN) || (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_EC)) { al = SSL_AD_UNSUPPORTED_CERTIFICATE; - OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, - SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); goto f_err; } @@ -2069,16 +2058,13 @@ int ssl3_get_cert_verify(SSL *s) { } /* Compute the digest. */ - if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey)) { + if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey->type)) { goto err; } /* The handshake buffer is no longer necessary, and we may hash the current * message.*/ - if (s->s3->handshake_buffer && - !ssl3_digest_cached_records(s, free_handshake_buffer)) { - goto err; - } + ssl3_free_handshake_buffer(s); if (!ssl3_hash_current_message(s)) { goto err; } @@ -2087,7 +2073,7 @@ int ssl3_get_cert_verify(SSL *s) { if (!CBS_get_u16_length_prefixed(&certificate_verify, &signature) || CBS_len(&certificate_verify) != 0) { al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto f_err; } @@ -2100,7 +2086,7 @@ int ssl3_get_cert_verify(SSL *s) { !EVP_PKEY_verify(pctx, CBS_data(&signature), CBS_len(&signature), digest, digest_length)) { al = SSL_AD_DECRYPT_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_BAD_SIGNATURE); + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE); goto f_err; } @@ -2137,15 +2123,14 @@ int ssl3_get_client_certificate(SSL *s) { if (s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) { if ((s->verify_mode & SSL_VERIFY_PEER) && (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, - SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); al = SSL_AD_HANDSHAKE_FAILURE; goto f_err; } /* If tls asked for a client cert, the client must return a 0 list */ if (s->version > SSL3_VERSION && s->s3->tmp.cert_request) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, + OPENSSL_PUT_ERROR(SSL, SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST); al = SSL_AD_UNEXPECTED_MESSAGE; goto f_err; @@ -2157,8 +2142,7 @@ int ssl3_get_client_certificate(SSL *s) { if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { al = SSL_AD_UNEXPECTED_MESSAGE; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, - SSL_R_WRONG_MESSAGE_TYPE); + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_MESSAGE_TYPE); goto f_err; } @@ -2166,14 +2150,14 @@ int ssl3_get_client_certificate(SSL *s) { sk = sk_X509_new_null(); if (sk == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } if (!CBS_get_u24_length_prefixed(&certificate_msg, &certificate_list) || CBS_len(&certificate_msg) != 0) { al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto f_err; } @@ -2183,7 +2167,7 @@ int ssl3_get_client_certificate(SSL *s) { if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate)) { al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto f_err; } @@ -2201,50 +2185,42 @@ int ssl3_get_client_certificate(SSL *s) { x = d2i_X509(NULL, &data, CBS_len(&certificate)); if (x == NULL) { al = SSL_AD_BAD_CERTIFICATE; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, ERR_R_ASN1_LIB); + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); goto f_err; } if (data != CBS_data(&certificate) + CBS_len(&certificate)) { al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, - SSL_R_CERT_LENGTH_MISMATCH); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH); goto f_err; } if (!sk_X509_push(sk, x)) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } x = NULL; } if (sk_X509_num(sk) <= 0) { + /* No client certificate so the handshake buffer may be discarded. */ + ssl3_free_handshake_buffer(s); + /* TLS does not mind 0 certs returned */ if (s->version == SSL3_VERSION) { al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, - SSL_R_NO_CERTIFICATES_RETURNED); + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATES_RETURNED); goto f_err; - } - /* Fail for TLS only if we required a certificate */ - else if ((s->verify_mode & SSL_VERIFY_PEER) && + } else if ((s->verify_mode & SSL_VERIFY_PEER) && (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, - SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + /* Fail for TLS only if we required a certificate */ + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); al = SSL_AD_HANDSHAKE_FAILURE; goto f_err; } - /* No client certificate so digest cached records */ - if (s->s3->handshake_buffer && - !ssl3_digest_cached_records(s, free_handshake_buffer)) { - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } } else { i = ssl_verify_cert_chain(s, sk); if (i <= 0) { al = ssl_verify_alarm_type(s->verify_result); - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, - SSL_R_CERTIFICATE_VERIFY_FAILED); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED); goto f_err; } } @@ -2253,17 +2229,8 @@ int ssl3_get_client_certificate(SSL *s) { s->session->peer = sk_X509_shift(sk); s->session->verify_result = s->verify_result; - /* With the current implementation, sess_cert will always be NULL when we - * arrive here. */ - if (s->session->sess_cert == NULL) { - s->session->sess_cert = ssl_sess_cert_new(); - if (s->session->sess_cert == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, ERR_R_MALLOC_FAILURE); - goto err; - } - } - sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free); - s->session->sess_cert->cert_chain = sk; + sk_X509_pop_free(s->session->cert_chain, X509_free); + s->session->cert_chain = sk; /* Inconsistency alert: cert_chain does *not* include the peer's own * certificate, while we do include it in s3_clnt.c */ @@ -2283,17 +2250,8 @@ err: } int ssl3_send_server_certificate(SSL *s) { - CERT_PKEY *cpk; - if (s->state == SSL3_ST_SW_CERT_A) { - cpk = ssl_get_server_send_pkey(s); - if (cpk == NULL) { - OPENSSL_PUT_ERROR(SSL, ssl3_send_server_certificate, - ERR_R_INTERNAL_ERROR); - return 0; - } - - if (!ssl3_output_cert_chain(s, cpk)) { + if (!ssl3_output_cert_chain(s)) { return 0; } s->state = SSL3_ST_SW_CERT_B; @@ -2444,8 +2402,7 @@ int ssl3_get_next_proto(SSL *s) { /* Clients cannot send a NextProtocol message if we didn't see the extension * in their ClientHello */ if (!s->s3->next_proto_neg_seen) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_next_proto, - SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION); + OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION); return -1; } @@ -2465,8 +2422,7 @@ int ssl3_get_next_proto(SSL *s) { * TODO(davidben): Is this check now redundant with * SSL3_FLAGS_EXPECT_CCS? */ if (!s->s3->change_cipher_spec) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_next_proto, - SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS); + OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS); return -1; } @@ -2492,11 +2448,10 @@ int ssl3_get_next_proto(SSL *s) { int ssl3_get_channel_id(SSL *s) { int ret = -1, ok; long n; - EVP_MD_CTX md_ctx; - uint8_t channel_id_hash[SHA256_DIGEST_LENGTH]; - unsigned int channel_id_hash_len; + uint8_t channel_id_hash[EVP_MAX_MD_SIZE]; + size_t channel_id_hash_len; const uint8_t *p; - uint16_t extension_type, expected_extension_type; + uint16_t extension_type; EC_GROUP *p256 = NULL; EC_KEY *key = NULL; EC_POINT *point = NULL; @@ -2515,15 +2470,9 @@ int ssl3_get_channel_id(SSL *s) { /* Before incorporating the EncryptedExtensions message to the handshake * hash, compute the hash that should have been signed. */ - channel_id_hash_len = sizeof(channel_id_hash); - EVP_MD_CTX_init(&md_ctx); - if (!EVP_DigestInit_ex(&md_ctx, EVP_sha256(), NULL) || - !tls1_channel_id_hash(&md_ctx, s) || - !EVP_DigestFinal(&md_ctx, channel_id_hash, &channel_id_hash_len)) { - EVP_MD_CTX_cleanup(&md_ctx); + if (!tls1_channel_id_hash(s, channel_id_hash, &channel_id_hash_len)) { return -1; } - EVP_MD_CTX_cleanup(&md_ctx); assert(channel_id_hash_len == SHA256_DIGEST_LENGTH); if (!ssl3_hash_current_message(s)) { @@ -2536,8 +2485,7 @@ int ssl3_get_channel_id(SSL *s) { * * TODO(davidben): Is this check now redundant with SSL3_FLAGS_EXPECT_CCS? */ if (!s->s3->change_cipher_spec) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id, - SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS); + OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS); return -1; } @@ -2554,23 +2502,19 @@ int ssl3_get_channel_id(SSL *s) { * uint8 y[32]; * uint8 r[32]; * uint8 s[32]; */ - expected_extension_type = TLSEXT_TYPE_channel_id; - if (s->s3->tlsext_channel_id_new) { - expected_extension_type = TLSEXT_TYPE_channel_id_new; - } if (!CBS_get_u16(&encrypted_extensions, &extension_type) || !CBS_get_u16_length_prefixed(&encrypted_extensions, &extension) || CBS_len(&encrypted_extensions) != 0 || - extension_type != expected_extension_type || + extension_type != TLSEXT_TYPE_channel_id || CBS_len(&extension) != TLSEXT_CHANNEL_ID_SIZE) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id, SSL_R_INVALID_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_MESSAGE); return -1; } p256 = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); if (!p256) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id, SSL_R_NO_P256_SUPPORT); + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_P256_SUPPORT); return -1; } @@ -2604,8 +2548,7 @@ int ssl3_get_channel_id(SSL *s) { /* We stored the handshake hash in |tlsext_channel_id| the first time that we * were called. */ if (!ECDSA_do_verify(channel_id_hash, channel_id_hash_len, &sig, key)) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id, - SSL_R_CHANNEL_ID_SIGNATURE_INVALID); + OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID); s->s3->tlsext_channel_id_valid = 0; goto err; } |