From f4e427204234da139fd0585def4b4e22502e33f0 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Thu, 4 Jun 2015 17:45:09 -0700 Subject: Bump revision of BoringSSL. This depends on https://android-review.googlesource.com/#/c/153481/ af0e32c Add SSL_get_tls_unique. 691992b Minor typo fix in comment. cc1e3df Make CBS_get_any_asn1_element accept only DER. 0976096 bytestring: Test out_header_len != NULL before writing. ba5934b Tighten up EMS resumption behaviour. b0eef0a runner: minor tidyups. 9f8ef2d Add |EVP_get_digestbyname|. b7326b0 Implement |PEM_def_callback| and call it where appropriate. e26e590 Avoid unused variable warnings with assert. efad697 Sync vs_toolschain.py up with Chromium. 39da317 Empty commit to kick the bots. 1550a84 Allow compilation for armv6 9a4996e Fix compilation of sha256-armv4.S when using -march=armv6 485a50a Match the ifdef check in bsaes-armv7.S e216288 Unexport and prune EVP_MD_CTX flags. af8731f Remove HMAC_CTX_set_flags. bf3208b Add additional HMAC tests. a1c90a5 Further tidy up cipher logic. 0fa4012 Add a test that DTLS does not support RC4. 9a980ab Fold TLS1_PRF_* into SSL_HANDSHAKE_MAC_* 29864b5 Remove SSL_CIPHER_ALGORITHM2_AEAD. 904dc72 Fold away SSL_PROTOCOL_METHOD hooks shared between TLS and DTLS. a602277 Split ssl_read_bytes hook into app_data and close_notify hooks. c933a47 Switch the ssl_write_bytes hook to ssl_write_app_data. 2c36792 EVP_Digest*Update, EVP_DigestFinal, and HMAC_Update can never fail. e2375e1 Low-level hash 'final' functions cannot fail. 049756b Fix integer types in low-level hash functions. 338e067 Reject sessions with the wrong structure version. f297e02 Reject unknown fields in d2i_SSL_SESSION. 8a228f5 Disable the malloc interceptor without glibc. bd15a8e Fix DTLS handling of multiple records in a packet. 15eaafb Fix bn_test's bc output and shut it up a little. efd8eb3 Tidy up overflows in obj_cmp. 05ead68 Readd CRYPTO_{LOCK|UNLOCK|READ|WRITE}. 71106ad Add |BIO_read_asn1| to read a single ASN.1 object. eb930b8 Fix signed/unsigned warning in bn_test.cc. b3a7b51 Fix off-by-one in BN_rand 074cc04 Reject negative shifts for BN_rshift and BN_lshift. 75fb74a aes/asm/bsaes-armv7.pl: fix compilation with Xcode 6.3. ff81e10 Add OPENSSL_PUT_ERROR line to X509V3_parse_list. 1590811 Fix typo in valid_star. e76ccae Release handshake buffer when sending no certificate. 5f04b65 Release the handshake buffer on the client for abbreviated handshakes. 5c1ce29 Decide whether or not to request client certificates early. 4b30b28 Remove server-side renego session resumption check. 5aea93e Deprecate and no-op SSL_VERIFY_CLIENT_ONCE. 34a1635 Remove fake RLE compression OID. 9c0918f Fix typo in objects.txt 91af02a Add some comments and tweak assertions for cbc.c. 74d8bc2 Don't make SSL_MODE_*HELLO_TIME configurable. 7b5aff4 Have consumers supply OPENSSL_C11_ATOMIC. ac63748 Revert "tool: we don't need -lrt." 444dce4 Do-nothing fns |OpenSSL_add_all_ciphers| and |OpenSSL_add_all_digests|. ece089c Deprecate and no-op SSL_set_state. be05c63 Remove compatibility s->version checks. 8ec8810 Remove SSL_in_before and SSL_ST_BEFORE. cd90f3a Remove renegotiation deferral logic. 44d3eed Forbid caller-initiated renegotiations and all renego as a servers. 3d59e04 Fix test used for not-in-place CBC mode. 5f387e3 Remove s->renegotiate check in SSL_clear. 20f6e97 Switch three more renegotiate checks to initial_handshake_complete. d23d5a5 Remove remnants of DTLS renegotiate. 9a41d1b Deprecate SSL_*_read_ahead and enforce DTLS packet boundaries. 76e48c5 Fix Windows mode. 3fa65f0 Fix some malloc test crashs. 0b635c5 Add malloc test support to unit tests. 3e3090d Pass a dtls1_use_epoch enum down to dtls1_seal_record. 31a0779 Factor SSL_AEAD_CTX into a dedicated type. 69d07d9 Get version-related functions from crypto.h rather than ssl.h. b487df6 Pull version, option, and mode APIs into their own sections. 7270cfc Prune version constants. 7ef9fff Remove ssl_ok. afc9ecd Unexport ssl_get_new_session and ssl_update_cache. 3b7456e Fix some documentation typos. b480428 Also skip #elif lines. 6deacb3 Parse macros in getNameFromDecl. 4831c33 Document some core SSL_CTX and SSL methods. 4dab297 Don't use struct names in ssl.h. 760b1dd Tidy up state machine coverage tests. 3629c7b Add client peer-initiated renego to the state machine tests. cff0b90 Add client-side tests for renegotiation_info enforcement. 6bff1ca Specify argc and argv arguments to refcount_test:main. 12a4768 Try to fix MSVC and __STDC_VERSION__ again. cb56c2a Cast refcounts to _Atomic before use. 0d1d0d5 Try again to only test __STDC_VERSION__ when defined. 7b348dc Disable C11 atomics on OS X. 04edcc8 Tag the mutex functions with OPENSSL_EXPORT. 6e1f645 Don't test __STDC_VERSION__ unless it's defined. 552df47 Remove leftovers of the old-style locks. 6fb174e Remove last references to named locks. 4bdb6e4 Remove remaining calls to the old lock functions. 03163f3 Remove |CRYPTO_add|. 0b5e390 Convert reference counts in ssl/ 0da323a Convert reference counts in crypto/ 6f2e733 Add infrastructure for reference counts. daaff93 Use C11 _Static_assert where available. dc8c739 Implement |DES_ede2_cbc_encrypt|. a7997f1 Set minimum DH group size to 1024 bits. 4a7b70d Add LICENSE file. b3a262c Fix |SSLeay|. f0320d3 Fix use after free in X509. 3dacff9 Always include x86_64-gcc.c in the standalone build. 9660032 Don't use x86_64-gcc.c with NO_ASM. 81091d5 Don't use uninitialized memory in RAND_bytes. d72e284 Support arbitrary elliptic curve groups. a07c0fc Fix SSL_get_current_cipher. 4b27d9f Never resume sessions on renegotiations. 785e07b Copy ecdsa_meth in EC_KEY_copy. 08dc68d Define no-op options consistently. e6df054 Add s->s3->initial_handshake_complete. 897e5e0 Default renegotiations to off. 4690bb5 Port cipher_test to file_test. 771a138 Add missing #include for abort() de12d6c Mind the end of the buffer in aligned case of generic RC4 implementation. 5694b3a Fix invalid assert in CRYPTO_ctr128_encrypt. 9b68e72 Define compatibility function |ERR_remove_state|. 2607383 Fix generate_build_files.py to account for crypto/test. af3d5bd Add no-op |RAND_load_file| function for compatibility. 58e95fc Remove a spurious semicolon after |DECLARE_LHASH_OF|. 3c65171 Add buffer.h for compatibility. c85373d Use EVP_AEAD_CTX in crypto/cipher/internal.h. Change-Id: Ife3698f4520572e1fca48732c6a1cbd4254ec85c --- src/ssl/s3_srvr.c | 231 +++++++++++++++++++----------------------------------- 1 file changed, 81 insertions(+), 150 deletions(-) (limited to 'src/ssl/s3_srvr.c') diff --git a/src/ssl/s3_srvr.c b/src/ssl/s3_srvr.c index 3cc3032..a72e17e 100644 --- a/src/ssl/s3_srvr.c +++ b/src/ssl/s3_srvr.c @@ -207,79 +207,11 @@ int ssl3_accept(SSL *s) { state = s->state; switch (s->state) { - case SSL_ST_RENEGOTIATE: - /* This state is the renegotiate entry point. It sends a HelloRequest - * and nothing else. */ - s->renegotiate = 1; - - if (cb != NULL) { - cb(s, SSL_CB_HANDSHAKE_START, 1); - } - - if (s->init_buf == NULL) { - buf = BUF_MEM_new(); - if (!buf || !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { - ret = -1; - goto end; - } - s->init_buf = buf; - buf = NULL; - } - s->init_num = 0; - - if (!s->s3->send_connection_binding && - !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { - /* Server attempting to renegotiate with client that doesn't support - * secure renegotiation. */ - OPENSSL_PUT_ERROR(SSL, ssl3_accept, - SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - ret = -1; - goto end; - } - - s->state = SSL3_ST_SW_HELLO_REQ_A; - break; - - case SSL3_ST_SW_HELLO_REQ_A: - case SSL3_ST_SW_HELLO_REQ_B: - s->shutdown = 0; - ret = ssl3_send_hello_request(s); - if (ret <= 0) { - goto end; - } - s->s3->tmp.next_state = SSL3_ST_SW_HELLO_REQ_C; - s->state = SSL3_ST_SW_FLUSH; - s->init_num = 0; - - if (!ssl3_init_finished_mac(s)) { - OPENSSL_PUT_ERROR(SSL, ssl3_accept, ERR_R_INTERNAL_ERROR); - ret = -1; - goto end; - } - break; - - case SSL3_ST_SW_HELLO_REQ_C: - s->state = SSL_ST_OK; - break; - case SSL_ST_ACCEPT: - case SSL_ST_BEFORE | SSL_ST_ACCEPT: - /* This state is the entry point for the handshake itself (initial and - * renegotiation). */ if (cb != NULL) { cb(s, SSL_CB_HANDSHAKE_START, 1); } - if ((s->version >> 8) != 3) { - /* TODO(davidben): Some consumers clear |s->version| to break the - * handshake in a callback. Remove this when they're using proper - * APIs. */ - OPENSSL_PUT_ERROR(SSL, ssl3_accept, ERR_R_INTERNAL_ERROR); - ret = -1; - goto end; - } - if (s->init_buf == NULL) { buf = BUF_MEM_new(); if (!buf || !BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { @@ -337,7 +269,6 @@ int ssl3_accept(SSL *s) { if (ret <= 0) { goto end; } - s->renegotiate = 2; s->state = SSL3_ST_SW_SRVR_HELLO_A; s->init_num = 0; break; @@ -406,35 +337,16 @@ int ssl3_accept(SSL *s) { case SSL3_ST_SW_CERT_REQ_A: case SSL3_ST_SW_CERT_REQ_B: - if (/* don't request cert unless asked for it: */ - !(s->verify_mode & SSL_VERIFY_PEER) || - /* Don't request a certificate if an obc was presented */ - ((s->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) && - s->s3->tlsext_channel_id_valid) || - /* if SSL_VERIFY_CLIENT_ONCE is set, - * don't request cert during re-negotiation: */ - ((s->session->peer != NULL) && - (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || - /* With normal PSK Certificates and - * Certificate Requests are omitted */ - (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - /* no cert request */ - skip = 1; - s->s3->tmp.cert_request = 0; - s->state = SSL3_ST_SW_SRVR_DONE_A; - if (s->s3->handshake_buffer && - !ssl3_digest_cached_records(s, free_handshake_buffer)) { - return -1; - } - } else { - s->s3->tmp.cert_request = 1; + if (s->s3->tmp.cert_request) { ret = ssl3_send_certificate_request(s); if (ret <= 0) { goto end; } - s->state = SSL3_ST_SW_SRVR_DONE_A; - s->init_num = 0; + } else { + skip = 1; } + s->state = SSL3_ST_SW_SRVR_DONE_A; + s->init_num = 0; break; case SSL3_ST_SW_SRVR_DONE_A: @@ -640,16 +552,12 @@ int ssl3_accept(SSL *s) { s->session->peer = NULL; } - if (s->renegotiate == 2) { - /* skipped if we just sent a HelloRequest */ - s->renegotiate = 0; - s->new_session = 0; + s->s3->initial_handshake_complete = 1; - ssl_update_cache(s, SSL_SESS_CACHE_SERVER); + ssl_update_cache(s, SSL_SESS_CACHE_SERVER); - if (cb != NULL) { - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - } + if (cb != NULL) { + cb(s, SSL_CB_HANDSHAKE_DONE, 1); } ret = 1; @@ -898,20 +806,8 @@ int ssl3_get_v2_client_hello(SSL *s) { return 1; } -int ssl3_send_hello_request(SSL *s) { - if (s->state == SSL3_ST_SW_HELLO_REQ_A) { - if (!ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0)) { - return -1; - } - s->state = SSL3_ST_SW_HELLO_REQ_B; - } - - /* SSL3_ST_SW_HELLO_REQ_B */ - return ssl_do_write(s); -} - int ssl3_get_client_hello(SSL *s) { - int i, ok, al = SSL_AD_INTERNAL_ERROR, ret = -1; + int ok, al = SSL_AD_INTERNAL_ERROR, ret = -1; long n; const SSL_CIPHER *c; STACK_OF(SSL_CIPHER) *ciphers = NULL; @@ -1011,6 +907,11 @@ int ssl3_get_client_hello(SSL *s) { } } + /* Note: This codepath may run twice if |ssl_get_prev_session| completes + * asynchronously. + * + * TODO(davidben): Clean up the order of events around ClientHello + * processing. */ if (!s->s3->have_version) { /* Select version to use */ uint16_t version = ssl3_get_mutual_version(s, client_version); @@ -1034,41 +935,49 @@ int ssl3_get_client_hello(SSL *s) { } s->hit = 0; - /* Versions before 0.9.7 always allow clients to resume sessions in - * renegotiation. 0.9.7 and later allow this by default, but optionally - * ignore resumption requests with flag - * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather than - * a change to default behavior so that applications relying on this for - * security won't even compile against older library versions). - * - * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to - * request renegotiation but not a new session (s->new_session remains - * unset): for servers, this essentially just means that the - * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be ignored. */ - if (s->new_session && - (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)) { - if (!ssl_get_new_session(s, 1)) { - goto err; - } - } else { - i = ssl_get_prev_session(s, &early_ctx); - if (i == PENDING_SESSION) { - s->rwstate = SSL_PENDING_SESSION; - goto err; - } else if (i == -1) { - goto err; - } + 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; + } - /* Only resume if the session's version matches the negotiated version: - * most clients do not accept a mismatch. */ - if (i == 1 && s->version == s->session->ssl_version) { - s->hit = 1; - } else { - /* No session was found or it was unacceptable. */ - if (!ssl_get_new_session(s, 1)) { - goto err; - } + /* The EMS state is needed when making the resumption decision, but + * extensions are not normally parsed until later. This detects the EMS + * extension for the resumption decision and it's checked against the result + * of the normal parse later in this function. */ + const uint8_t *ems_data; + size_t ems_len; + int have_extended_master_secret = + s->version != SSL3_VERSION && + SSL_early_callback_ctx_extension_get(&early_ctx, + TLSEXT_TYPE_extended_master_secret, + &ems_data, &ems_len) && + ems_len == 0; + + if (session_ret == 1) { + if (s->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); + 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 && + /* 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; + } + + if (!s->hit && !ssl_get_new_session(s, 1)) { + goto err; } if (s->ctx->dos_protection_cb != NULL && s->ctx->dos_protection_cb(&early_ctx) == 0) { @@ -1141,6 +1050,12 @@ int ssl3_get_client_hello(SSL *s) { 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); + goto f_err; + } + /* Given ciphers and SSL_get_ciphers, we must pick a cipher */ if (!s->hit) { if (ciphers == NULL) { @@ -1171,12 +1086,27 @@ int ssl3_get_client_hello(SSL *s) { goto f_err; } s->s3->tmp.new_cipher = c; + + /* Determine whether to request a client certificate. */ + s->s3->tmp.cert_request = !!(s->verify_mode & SSL_VERIFY_PEER); + /* Only request a certificate if Channel ID isn't negotiated. */ + if ((s->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) && + s->s3->tlsext_channel_id_valid) { + s->s3->tmp.cert_request = 0; + } + /* Plain PSK forbids Certificate and CertificateRequest. */ + if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK) { + s->s3->tmp.cert_request = 0; + } } else { /* Session-id reuse */ s->s3->tmp.new_cipher = s->session->cipher; + s->s3->tmp.cert_request = 0; } - if ((!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) && + /* 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; } @@ -1235,7 +1165,8 @@ int ssl3_send_server_hello(SSL *s) { *(p++) = s->version & 0xff; /* Random stuff */ - if (!ssl_fill_hello_random(s, 1, s->s3->server_random, SSL3_RANDOM_SIZE)) { + 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); return -1; } @@ -1268,7 +1199,7 @@ int ssl3_send_server_hello(SSL *s) { p += sl; /* put the cipher */ - s2n(ssl3_get_cipher_value(s->s3->tmp.new_cipher), p); + s2n(ssl_cipher_get_value(s->s3->tmp.new_cipher), p); /* put the compression method */ *(p++) = 0; -- cgit v1.1 From 1e4884f615b20946411a74e41eb9c6aa65e2d5f3 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Thu, 24 Sep 2015 10:57:52 -0700 Subject: external/boringssl: sync with upstream. This change imports the current version of BoringSSL. The only local change now is that |BORINGSSL_201509| is defined in base.h. This allows this change to be made without (hopefully) breaking the build. This change will need https://android-review.googlesource.com/172744 to be landed afterwards to update a test. Change-Id: I6d1f463f7785a2423bd846305af91c973c326104 --- src/ssl/s3_srvr.c | 645 +++++++++++++++++++++++++----------------------------- 1 file changed, 294 insertions(+), 351 deletions(-) (limited to 'src/ssl/s3_srvr.c') 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 + #include #include #include @@ -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; } -- cgit v1.1 From a04d78d392463df4e69a64360c952ffa5abd22f7 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Fri, 25 Sep 2015 00:26:37 +0000 Subject: Revert "external/boringssl: sync with upstream." This reverts commit 1e4884f615b20946411a74e41eb9c6aa65e2d5f3. This breaks some x86 builds. Change-Id: I4d4310663ce52bc0a130e6b9dbc22b868ff4fb25 --- src/ssl/s3_srvr.c | 645 +++++++++++++++++++++++++++++------------------------- 1 file changed, 351 insertions(+), 294 deletions(-) (limited to 'src/ssl/s3_srvr.c') diff --git a/src/ssl/s3_srvr.c b/src/ssl/s3_srvr.c index b428043..a72e17e 100644 --- a/src/ssl/s3_srvr.c +++ b/src/ssl/s3_srvr.c @@ -146,8 +146,6 @@ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR * OTHERWISE. */ -#include - #include #include #include @@ -174,6 +172,10 @@ #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; @@ -197,7 +199,7 @@ int ssl3_accept(SSL *s) { s->in_handshake++; if (s->cert == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET); + OPENSSL_PUT_ERROR(SSL, ssl3_accept, SSL_R_NO_CERTIFICATE_SET); return -1; } @@ -228,8 +230,8 @@ int ssl3_accept(SSL *s) { goto end; } - if (!ssl3_init_handshake_buffer(s)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + if (!ssl3_init_finished_mac(s)) { + OPENSSL_PUT_ERROR(SSL, ssl3_accept, ERR_R_INTERNAL_ERROR); ret = -1; goto end; } @@ -308,19 +310,8 @@ 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: @@ -482,7 +473,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) { + if (!s->hit && s->s3->tlsext_channel_id_new) { ret = tls1_record_handshake_hashes_for_channel_id(s); if (ret <= 0) { goto end; @@ -559,8 +550,6 @@ 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; @@ -575,7 +564,7 @@ int ssl3_accept(SSL *s) { goto end; default: - OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE); + OPENSSL_PUT_ERROR(SSL, ssl3_accept, SSL_R_UNKNOWN_STATE); ret = -1; goto end; } @@ -598,16 +587,42 @@ 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) { - /* 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); + 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); if (ret <= 0) { return ret; } - assert(ssl_read_buffer_len(s) == SSL3_RT_HEADER_LENGTH); - const uint8_t *p = ssl_read_buffer(s); + assert(s->s3->sniff_buffer_len >= INITIAL_SNIFF_BUFFER_SIZE); + p = (const uint8_t *)s->s3->sniff_buffer->data; /* Some dedicated error codes for protocol mixups should the application wish * to interpret them differently. (These do not overlap with ClientHello or @@ -616,25 +631,46 @@ 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, SSL_R_HTTP_REQUEST); + OPENSSL_PUT_ERROR(SSL, ssl3_get_initial_bytes, SSL_R_HTTP_REQUEST); return -1; } - if (strncmp("CONNE", (const char *)p, 5) == 0) { - OPENSSL_PUT_ERROR(SSL, SSL_R_HTTPS_PROXY_REQUEST); + if (strncmp("CONNECT ", (const char *)p, 8) == 0) { + OPENSSL_PUT_ERROR(SSL, ssl3_get_initial_bytes, SSL_R_HTTPS_PROXY_REQUEST); return -1; } - /* Determine if this is a V2ClientHello. */ + /* Determine if this is a ClientHello or 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; - /* Fall through to the standard logic. */ - s->state = SSL3_ST_SR_CLNT_HELLO_A; - return 1; + 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; } int ssl3_get_v2_client_hello(SSL *s) { @@ -647,34 +683,36 @@ int ssl3_get_v2_client_hello(SSL *s) { CBB client_hello, hello_body, cipher_suites; uint8_t random[SSL3_RANDOM_SIZE]; - /* Determine the length of the V2ClientHello. */ - assert(ssl_read_buffer_len(s) >= SSL3_RT_HEADER_LENGTH); - p = ssl_read_buffer(s); + /* 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; msg_length = ((p[0] & 0x7f) << 8) | p[1]; if (msg_length > (1024 * 4)) { - OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, SSL_R_RECORD_TOO_LARGE); return -1; } - 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); + 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); return -1; } - /* Read the remainder of the V2ClientHello. */ - ret = ssl_read_buffer_extend_to(s, 2 + msg_length); + ret = ssl3_read_sniff_buffer(s, msg_length + 2); if (ret <= 0) { return ret; } - assert(ssl_read_buffer_len(s) == msg_length + 2); - CBS_init(&v2_client_hello, ssl_read_buffer(s) + 2, msg_length); + 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); - /* The V2ClientHello without the length is incorporated into the handshake + /* The V2ClientHello without the length is incorporated into the Finished * hash. */ - if (!ssl3_update_handshake_hash(s, CBS_data(&v2_client_hello), - CBS_len(&v2_client_hello))) { + if (!ssl3_finish_mac(s, CBS_data(&v2_client_hello), + CBS_len(&v2_client_hello))) { return -1; } if (s->msg_callback) { @@ -691,7 +729,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, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, SSL_R_DECODE_ERROR); return -1; } @@ -709,10 +747,12 @@ 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) || - !CBB_add_u8(&client_hello, SSL3_MT_CLIENT_HELLO) || + 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) || !CBB_add_u24_length_prefixed(&client_hello, &hello_body) || !CBB_add_u16(&hello_body, version) || !CBB_add_bytes(&hello_body, random, SSL3_RANDOM_SIZE) || @@ -720,7 +760,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, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_INTERNAL_ERROR); return -1; } @@ -729,7 +769,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, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, SSL_R_DECODE_ERROR); return -1; } @@ -739,7 +779,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, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_INTERNAL_ERROR); return -1; } } @@ -748,7 +788,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, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_INTERNAL_ERROR); return -1; } @@ -758,9 +798,10 @@ int ssl3_get_v2_client_hello(SSL *s) { /* The handshake message header is 4 bytes. */ s->s3->tmp.message_size = len - 4; - /* Consume and discard the V2ClientHello. */ - ssl_read_buffer_consume(s, 2 + msg_length); - ssl_read_buffer_discard(s); + /* Drop the sniff buffer. */ + BUF_MEM_free(s->s3->sniff_buffer); + s->s3->sniff_buffer = NULL; + s->s3->sniff_buffer_len = 0; return 1; } @@ -774,7 +815,6 @@ 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 @@ -807,7 +847,8 @@ 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, SSL_R_CLIENTHELLO_PARSE_FAILED); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, + SSL_R_CLIENTHELLO_PARSE_FAILED); goto f_err; } @@ -822,7 +863,8 @@ int ssl3_get_client_hello(SSL *s) { case -1: /* Connection rejected. */ al = SSL_AD_ACCESS_DENIED; - OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, + SSL_R_CONNECTION_REJECTED); goto f_err; default: @@ -833,7 +875,7 @@ int ssl3_get_client_hello(SSL *s) { break; default: - OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_UNKNOWN_STATE); return -1; } @@ -843,7 +885,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, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_DECODE_ERROR); goto f_err; } @@ -860,7 +902,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, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_DECODE_ERROR); goto f_err; } } @@ -874,7 +916,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, SSL_R_UNSUPPORTED_PROTOCOL); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_UNSUPPORTED_PROTOCOL); s->version = s->client_version; al = SSL_AD_PROTOCOL_VERSION; goto f_err; @@ -887,23 +929,19 @@ 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, SSL_R_WRONG_VERSION_NUMBER); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_WRONG_VERSION_NUMBER); al = SSL_AD_PROTOCOL_VERSION; goto f_err; } s->hit = 0; - 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; + 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; } - 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 @@ -918,40 +956,34 @@ int ssl3_get_client_hello(SSL *s) { &ems_data, &ems_len) && ems_len == 0; - if (session != NULL) { - if (session->extended_master_secret && + if (session_ret == 1) { + if (s->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, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, + 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 == session->ssl_version && + s->version == s->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 == session->extended_master_secret; + have_extended_master_secret == s->session->extended_master_secret; } - 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)) { + if (!s->hit && !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, SSL_R_CONNECTION_REJECTED); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_CONNECTION_REJECTED); goto f_err; } @@ -961,7 +993,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, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_DECODE_ERROR); goto f_err; } @@ -988,7 +1020,8 @@ 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, SSL_R_REQUIRED_CIPHER_MISSING); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, + SSL_R_REQUIRED_CIPHER_MISSING); goto f_err; } } @@ -997,14 +1030,15 @@ 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, SSL_R_NO_COMPRESSION_SPECIFIED); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, + 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, SSL_R_PARSE_TLSEXT); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_PARSE_TLSEXT); goto err; } @@ -1012,13 +1046,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, SSL_R_BAD_PACKET_LENGTH); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, 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, SSL_R_EMS_STATE_INCONSISTENT); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_EMS_STATE_INCONSISTENT); goto f_err; } @@ -1026,7 +1060,7 @@ int ssl3_get_client_hello(SSL *s) { if (!s->hit) { if (ciphers == NULL) { al = SSL_AD_ILLEGAL_PARAMETER; - OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_PASSED); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_NO_CIPHERS_PASSED); goto f_err; } @@ -1035,7 +1069,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, SSL_R_CERT_CB_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_CERT_CB_ERROR); goto f_err; } if (rv < 0) { @@ -1048,7 +1082,7 @@ int ssl3_get_client_hello(SSL *s) { if (c == NULL) { al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_NO_SHARED_CIPHER); goto f_err; } s->s3->tmp.new_cipher = c; @@ -1070,15 +1104,11 @@ 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_free_handshake_buffer(s); + if ((!SSL_USE_SIGALGS(s) || !s->s3->tmp.cert_request) && + !ssl3_digest_cached_records(s, free_handshake_buffer)) { + goto f_err; } /* we now have the following setup; @@ -1102,7 +1132,6 @@ int ssl3_get_client_hello(SSL *s) { err: sk_SSL_CIPHER_free(ciphers); - SSL_SESSION_free(session); return ret; } @@ -1123,7 +1152,8 @@ 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->session->original_handshake_hash_len == 0) { + if (s->hit && s->s3->tlsext_channel_id_new && + s->session->original_handshake_hash_len == 0) { s->s3->tlsext_channel_id_valid = 0; } @@ -1137,7 +1167,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, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR); return -1; } memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); @@ -1161,7 +1191,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, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR); return -1; } *(p++) = sl; @@ -1173,10 +1203,13 @@ 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, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR); return -1; } @@ -1192,32 +1225,6 @@ 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)) { @@ -1239,8 +1246,7 @@ 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; - size_t sig_len; - size_t max_sig_len; + EVP_PKEY *pkey; uint8_t *p, *d; int al, i; uint32_t alg_k; @@ -1248,26 +1254,11 @@ int ssl3_send_server_key_exchange(SSL *s) { int n; CERT *cert; BIGNUM *r[4]; - int nr[4]; + int nr[4], kn; 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; @@ -1295,23 +1286,25 @@ int ssl3_send_server_key_exchange(SSL *s) { } if (dhp == NULL) { al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_DH_KEY); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, + SSL_R_MISSING_TMP_DH_KEY); goto f_err; } if (s->s3->tmp.dh != NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, + ERR_R_INTERNAL_ERROR); goto err; } dh = DHparams_dup(dhp); if (dh == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_DH_LIB); goto err; } s->s3->tmp.dh = dh; if (!DH_generate_key(dh)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_DH_LIB); goto err; } @@ -1335,12 +1328,14 @@ int ssl3_send_server_key_exchange(SSL *s) { } if (nid == NID_undef) { al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_ECDH_KEY); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, + SSL_R_MISSING_TMP_ECDH_KEY); goto f_err; } if (s->s3->tmp.ecdh != NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, + ERR_R_INTERNAL_ERROR); goto err; } ecdh = EC_KEY_new_by_curve_name(nid); @@ -1350,14 +1345,15 @@ int ssl3_send_server_key_exchange(SSL *s) { s->s3->tmp.ecdh = ecdh; if (!EC_KEY_generate_key(ecdh)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, 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, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, + SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); goto err; } @@ -1370,7 +1366,8 @@ 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, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, + ERR_R_MALLOC_FAILURE); goto err; } @@ -1379,7 +1376,7 @@ int ssl3_send_server_key_exchange(SSL *s) { encodedPoint, encodedlen, bn_ctx); if (encodedlen == 0) { - OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_ECDH_LIB); goto err; } @@ -1399,7 +1396,8 @@ 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, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, + SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); goto f_err; } @@ -1408,8 +1406,20 @@ int ssl3_send_server_key_exchange(SSL *s) { n += 2 + nr[i]; } - if (!BUF_MEM_grow_clean(buf, n + SSL_HM_HEADER_LENGTH(s) + max_sig_len)) { - OPENSSL_PUT_ERROR(SSL, ERR_LIB_BUF); + 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); goto err; } d = p = ssl_handshake_start(s); @@ -1448,81 +1458,54 @@ int ssl3_send_server_key_exchange(SSL *s) { encodedPoint = NULL; } - 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 + /* not anonymous */ + if (pkey != NULL) { + /* n is the length of the params, they start at &(d[4]) and p points to * the space at the end. */ const EVP_MD *md; - uint8_t digest[EVP_MAX_MD_SIZE]; - unsigned int digest_length; - - const int pkey_type = ssl_private_key_type(s); + size_t sig_len = EVP_PKEY_size(pkey); /* Determine signature algorithm. */ if (SSL_USE_SIGALGS(s)) { - md = tls1_choose_signing_digest(s); - if (!tls12_get_sigandhash(s, p, md)) { + md = tls1_choose_signing_digest(s, pkey); + if (!tls12_get_sigandhash(p, pkey, md)) { /* Should never happen */ al = SSL_AD_INTERNAL_ERROR; - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, + 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_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); + 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); goto err; } - 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; + s2n(sig_len, p); + n += sig_len + 2; + if (SSL_USE_SIGALGS(s)) { + n += 2; + } } - } 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); - } - switch (sign_result) { - case ssl_private_key_success: - s->rwstate = SSL_NOTHING; - break; - case ssl_private_key_failure: - s->rwstate = SSL_NOTHING; + if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n)) { 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; - } - - 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; + s->state = SSL3_ST_SW_KEY_EXCH_B; EVP_MD_CTX_cleanup(&md_ctx); return ssl_do_write(s); @@ -1575,7 +1558,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, ERR_R_BUF_LIB); + OPENSSL_PUT_ERROR(SSL, ssl3_send_certificate_request, ERR_R_BUF_LIB); goto err; } p = ssl_handshake_start(s) + n; @@ -1646,27 +1629,30 @@ 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, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DECODE_ERROR); al = SSL_AD_DECODE_ERROR; goto f_err; } if (s->psk_server_callback == NULL) { - OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_SERVER_CB); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + 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, SSL_R_DATA_LENGTH_TOO_LONG); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + 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, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + ERR_R_MALLOC_FAILURE); goto f_err; } @@ -1674,12 +1660,14 @@ 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, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + 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, SSL_R_PSK_IDENTITY_NOT_FOUND); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + SSL_R_PSK_IDENTITY_NOT_FOUND); al = SSL_AD_UNKNOWN_PSK_IDENTITY; goto f_err; } @@ -1693,10 +1681,11 @@ int ssl3_get_client_key_exchange(SSL *s) { uint8_t good; size_t rsa_size, decrypt_len, premaster_index, j; - pkey = s->cert->privatekey; + pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey; if (pkey == NULL || pkey->type != EVP_PKEY_RSA || pkey->pkey.rsa == NULL) { al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_RSA_CERTIFICATE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + SSL_R_MISSING_RSA_CERTIFICATE); goto f_err; } rsa = pkey->pkey.rsa; @@ -1709,7 +1698,8 @@ 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, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); goto f_err; } else { encrypted_premaster_secret = copy; @@ -1726,7 +1716,8 @@ 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, SSL_R_DECRYPTION_FAILED); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + SSL_R_DECRYPTION_FAILED); goto f_err; } @@ -1742,7 +1733,8 @@ 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, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + ERR_R_MALLOC_FAILURE); goto err; } @@ -1756,7 +1748,8 @@ 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, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + ERR_R_INTERNAL_ERROR); goto err; } @@ -1779,7 +1772,8 @@ 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, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + ERR_R_MALLOC_FAILURE); goto err; } OPENSSL_free(decrypt_buf); @@ -1810,35 +1804,38 @@ 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, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + 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, SSL_R_MISSING_TMP_DH_KEY); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + 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, SSL_R_BN_LIB); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, 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, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + 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, ERR_R_DH_LIB); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_DH_LIB); BN_clear_free(pub); goto err; } @@ -1859,7 +1856,8 @@ 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, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + ERR_R_MALLOC_FAILURE); goto err; } @@ -1872,14 +1870,15 @@ 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, ERR_R_EC_LIB); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, 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, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + ERR_R_MALLOC_FAILURE); goto err; } @@ -1888,33 +1887,35 @@ 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, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DECODE_ERROR); goto f_err; } bn_ctx = BN_CTX_new(); if (bn_ctx == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + 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, ERR_R_EC_LIB); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, 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, ERR_R_ECDH_LIB); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, 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, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + ERR_R_MALLOC_FAILURE); goto err; } @@ -1922,7 +1923,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, ERR_R_ECDH_LIB); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_ECDH_LIB); goto err; } @@ -1944,13 +1945,15 @@ 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, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + ERR_R_MALLOC_FAILURE); goto err; } memset(premaster_secret, 0, premaster_secret_len); } else { al = SSL_AD_HANDSHAKE_FAILURE; - OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_TYPE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + SSL_R_UNKNOWN_CIPHER_TYPE); goto f_err; } @@ -1961,14 +1964,18 @@ int ssl3_get_client_key_exchange(SSL *s) { uint8_t *new_data; size_t new_len; - CBB_zero(&new_premaster); - if (!CBB_init(&new_premaster, 2 + psk_len + 2 + premaster_secret_len) || - !CBB_add_u16_length_prefixed(&new_premaster, &child) || + 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_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, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, + ERR_R_INTERNAL_ERROR); CBB_cleanup(&new_premaster); goto err; } @@ -2024,7 +2031,10 @@ int ssl3_get_cert_verify(SSL *s) { * CertificateVerify is required if and only if there's a client certificate. * */ if (peer == NULL) { - ssl3_free_handshake_buffer(s); + if (s->s3->handshake_buffer && + !ssl3_digest_cached_records(s, free_handshake_buffer)) { + return -1; + } return 1; } @@ -2045,7 +2055,8 @@ 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, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, + SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); goto f_err; } @@ -2058,13 +2069,16 @@ int ssl3_get_cert_verify(SSL *s) { } /* Compute the digest. */ - if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey->type)) { + if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey)) { goto err; } /* The handshake buffer is no longer necessary, and we may hash the current * message.*/ - ssl3_free_handshake_buffer(s); + if (s->s3->handshake_buffer && + !ssl3_digest_cached_records(s, free_handshake_buffer)) { + goto err; + } if (!ssl3_hash_current_message(s)) { goto err; } @@ -2073,7 +2087,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, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_DECODE_ERROR); goto f_err; } @@ -2086,7 +2100,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, SSL_R_BAD_SIGNATURE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_BAD_SIGNATURE); goto f_err; } @@ -2123,14 +2137,15 @@ 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, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, + 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, + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST); al = SSL_AD_UNEXPECTED_MESSAGE; goto f_err; @@ -2142,7 +2157,8 @@ 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, SSL_R_WRONG_MESSAGE_TYPE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, + SSL_R_WRONG_MESSAGE_TYPE); goto f_err; } @@ -2150,14 +2166,14 @@ int ssl3_get_client_certificate(SSL *s) { sk = sk_X509_new_null(); if (sk == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, 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, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, SSL_R_DECODE_ERROR); goto f_err; } @@ -2167,7 +2183,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, SSL_R_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, SSL_R_DECODE_ERROR); goto f_err; } @@ -2185,42 +2201,50 @@ 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, ERR_R_ASN1_LIB); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, ERR_R_ASN1_LIB); goto f_err; } if (data != CBS_data(&certificate) + CBS_len(&certificate)) { al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, + SSL_R_CERT_LENGTH_MISMATCH); goto f_err; } if (!sk_X509_push(sk, x)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, 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, SSL_R_NO_CERTIFICATES_RETURNED); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, + SSL_R_NO_CERTIFICATES_RETURNED); goto f_err; - } else if ((s->verify_mode & SSL_VERIFY_PEER) && + } + /* Fail for TLS only if we required a certificate */ + else if ((s->verify_mode & SSL_VERIFY_PEER) && (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { - /* Fail for TLS only if we required a certificate */ - OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, + 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, SSL_R_CERTIFICATE_VERIFY_FAILED); + OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, + SSL_R_CERTIFICATE_VERIFY_FAILED); goto f_err; } } @@ -2229,8 +2253,17 @@ int ssl3_get_client_certificate(SSL *s) { s->session->peer = sk_X509_shift(sk); s->session->verify_result = s->verify_result; - sk_X509_pop_free(s->session->cert_chain, X509_free); - s->session->cert_chain = sk; + /* 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; /* Inconsistency alert: cert_chain does *not* include the peer's own * certificate, while we do include it in s3_clnt.c */ @@ -2250,8 +2283,17 @@ err: } int ssl3_send_server_certificate(SSL *s) { + CERT_PKEY *cpk; + if (s->state == SSL3_ST_SW_CERT_A) { - if (!ssl3_output_cert_chain(s)) { + 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)) { return 0; } s->state = SSL3_ST_SW_CERT_B; @@ -2402,7 +2444,8 @@ 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, SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION); + OPENSSL_PUT_ERROR(SSL, ssl3_get_next_proto, + SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION); return -1; } @@ -2422,7 +2465,8 @@ 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, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS); + OPENSSL_PUT_ERROR(SSL, ssl3_get_next_proto, + SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS); return -1; } @@ -2448,10 +2492,11 @@ int ssl3_get_next_proto(SSL *s) { int ssl3_get_channel_id(SSL *s) { int ret = -1, ok; long n; - uint8_t channel_id_hash[EVP_MAX_MD_SIZE]; - size_t channel_id_hash_len; + EVP_MD_CTX md_ctx; + uint8_t channel_id_hash[SHA256_DIGEST_LENGTH]; + unsigned int channel_id_hash_len; const uint8_t *p; - uint16_t extension_type; + uint16_t extension_type, expected_extension_type; EC_GROUP *p256 = NULL; EC_KEY *key = NULL; EC_POINT *point = NULL; @@ -2470,9 +2515,15 @@ int ssl3_get_channel_id(SSL *s) { /* Before incorporating the EncryptedExtensions message to the handshake * hash, compute the hash that should have been signed. */ - if (!tls1_channel_id_hash(s, channel_id_hash, &channel_id_hash_len)) { + 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); return -1; } + EVP_MD_CTX_cleanup(&md_ctx); assert(channel_id_hash_len == SHA256_DIGEST_LENGTH); if (!ssl3_hash_current_message(s)) { @@ -2485,7 +2536,8 @@ 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, SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS); + OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id, + SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS); return -1; } @@ -2502,19 +2554,23 @@ 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 != TLSEXT_TYPE_channel_id || + extension_type != expected_extension_type || CBS_len(&extension) != TLSEXT_CHANNEL_ID_SIZE) { - OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_MESSAGE); + OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id, SSL_R_INVALID_MESSAGE); return -1; } p256 = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); if (!p256) { - OPENSSL_PUT_ERROR(SSL, SSL_R_NO_P256_SUPPORT); + OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id, SSL_R_NO_P256_SUPPORT); return -1; } @@ -2548,7 +2604,8 @@ 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, SSL_R_CHANNEL_ID_SIGNATURE_INVALID); + OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id, + SSL_R_CHANNEL_ID_SIGNATURE_INVALID); s->s3->tlsext_channel_id_valid = 0; goto err; } -- cgit v1.1 From b8494591d1b1a143f3b192d845c238bbf3bc629d Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Fri, 25 Sep 2015 02:29:14 +0000 Subject: Revert "Revert "external/boringssl: sync with upstream."" This reverts commit a04d78d392463df4e69a64360c952ffa5abd22f7. Underlying issue was fixed. Change-Id: I49685b653d16e728eb38e79e02b2c33ddeefed88 --- src/ssl/s3_srvr.c | 645 +++++++++++++++++++++++++----------------------------- 1 file changed, 294 insertions(+), 351 deletions(-) (limited to 'src/ssl/s3_srvr.c') 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 + #include #include #include @@ -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; } -- cgit v1.1