From e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Mon, 11 May 2015 17:20:37 -0700 Subject: external/boringssl: bump revision. This change bumps the BoringSSL revision to the current tip-of-tree. Change-Id: I91d5bf467e16e8d86cb19a4de873985f524e5faa --- src/ssl/s3_clnt.c | 310 +++++++++++++++++++++++------------------------------- 1 file changed, 133 insertions(+), 177 deletions(-) (limited to 'src/ssl/s3_clnt.c') diff --git a/src/ssl/s3_clnt.c b/src/ssl/s3_clnt.c index 231cc65..d01acae 100644 --- a/src/ssl/s3_clnt.c +++ b/src/ssl/s3_clnt.c @@ -150,20 +150,21 @@ #include #include +#include #include #include #include #include +#include #include #include #include #include #include -#include #include -#include "ssl_locl.h" +#include "internal.h" #include "../crypto/dh/internal.h" @@ -195,12 +196,21 @@ int ssl3_connect(SSL *s) { case SSL_ST_RENEGOTIATE: s->renegotiate = 1; s->state = SSL_ST_CONNECT; - s->ctx->stats.sess_connect_renegotiate++; /* fallthrough */ case SSL_ST_CONNECT: case SSL_ST_BEFORE | SSL_ST_CONNECT: - if (cb != NULL) + 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_connect, ERR_R_INTERNAL_ERROR); + ret = -1; + goto end; + } if (s->init_buf == NULL) { buf = BUF_MEM_new(); @@ -214,8 +224,7 @@ int ssl3_connect(SSL *s) { buf = NULL; } - if (!ssl3_setup_buffers(s) || - !ssl_init_wbio_buffer(s, 0)) { + if (!ssl_init_wbio_buffer(s, 0)) { ret = -1; goto end; } @@ -229,7 +238,6 @@ int ssl3_connect(SSL *s) { } s->state = SSL3_ST_CW_CLNT_HELLO_A; - s->ctx->stats.sess_connect++; s->init_num = 0; break; @@ -389,12 +397,8 @@ int ssl3_connect(SSL *s) { s->init_num = 0; s->session->cipher = s->s3->tmp.new_cipher; - if (!s->enc_method->setup_key_block(s)) { - ret = -1; - goto end; - } - - if (!s->enc_method->change_cipher_state( + if (!s->enc_method->setup_key_block(s) || + !s->enc_method->change_cipher_state( s, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { ret = -1; goto end; @@ -445,15 +449,16 @@ int ssl3_connect(SSL *s) { * hashes. */ if (s->s3->tlsext_channel_id_new) { ret = tls1_record_handshake_hashes_for_channel_id(s); - if (ret <= 0) + if (ret <= 0) { goto end; + } } - if ((SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) && - ssl3_can_cutthrough(s) && - /* no cutthrough on renegotiation (would complicate the state - * machine) */ + if ((SSL_get_mode(s) & SSL_MODE_ENABLE_FALSE_START) && + ssl3_can_false_start(s) && + /* No False Start on renegotiation (would complicate the state + * machine). */ s->s3->previous_server_finished_len == 0) { - s->s3->tmp.next_state = SSL3_ST_CUTTHROUGH_COMPLETE; + s->s3->tmp.next_state = SSL3_ST_FALSE_START; } else { /* Allow NewSessionTicket if ticket expected */ if (s->tlsext_ticket_expected) { @@ -522,13 +527,14 @@ int ssl3_connect(SSL *s) { s->state = s->s3->tmp.next_state; break; - case SSL3_ST_CUTTHROUGH_COMPLETE: + case SSL3_ST_FALSE_START: /* Allow NewSessionTicket if ticket expected */ if (s->tlsext_ticket_expected) { s->state = SSL3_ST_CR_SESSION_TICKET_A; } else { s->state = SSL3_ST_CR_CHANGE; } + s->s3->tmp.in_false_start = 1; ssl_free_wbio_buffer(s); ret = 1; @@ -538,10 +544,8 @@ int ssl3_connect(SSL *s) { /* clean a few things up */ ssl3_cleanup_key_block(s); - if (s->init_buf != NULL) { - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; - } + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; /* Remove write buffering now. */ ssl_free_wbio_buffer(s); @@ -549,15 +553,12 @@ int ssl3_connect(SSL *s) { s->init_num = 0; s->renegotiate = 0; s->new_session = 0; + s->s3->tmp.in_false_start = 0; ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); - if (s->hit) { - s->ctx->stats.sess_hit++; - } ret = 1; /* s->server=0; */ - s->ctx->stats.sess_connect_good++; if (cb != NULL) { cb(s, SSL_CB_HANDSHAKE_DONE, 1); @@ -584,9 +585,7 @@ int ssl3_connect(SSL *s) { end: s->in_handshake--; - if (buf != NULL) { - BUF_MEM_free(buf); - } + BUF_MEM_free(buf); if (cb != NULL) { cb(s, SSL_CB_CONNECT_EXIT, ret); } @@ -625,8 +624,9 @@ int ssl3_send_client_hello(SSL *s) { /* If resending the ClientHello in DTLS after a HelloVerifyRequest, don't * renegerate the client_random. The random must be reused. */ - if (!SSL_IS_DTLS(s) || !s->d1->send_cookie) { - ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random)); + if ((!SSL_IS_DTLS(s) || !s->d1->send_cookie) && + !ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random))) { + goto err; } /* Do the message type and length last. Note: the final argument to @@ -720,7 +720,9 @@ int ssl3_send_client_hello(SSL *s) { } l = p - d; - ssl_set_handshake_header(s, SSL3_MT_CLIENT_HELLO, l); + if (!ssl_set_handshake_header(s, SSL3_MT_CLIENT_HELLO, l)) { + goto err; + } s->state = SSL3_ST_CW_CLNT_HELLO_B; } @@ -732,7 +734,7 @@ err: } int ssl3_get_server_hello(SSL *s) { - STACK_OF(SSL_CIPHER) * sk; + STACK_OF(SSL_CIPHER) *sk; const SSL_CIPHER *c; CERT *ct = s->cert; int al = SSL_AD_INTERNAL_ERROR, ok; @@ -740,12 +742,12 @@ int ssl3_get_server_hello(SSL *s) { CBS server_hello, server_random, session_id; uint16_t server_version, cipher_suite; uint8_t compression_method; - unsigned long mask_ssl; + uint32_t mask_ssl; n = s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_HELLO_A, SSL3_ST_CR_SRVR_HELLO_B, SSL3_MT_SERVER_HELLO, 20000, /* ?? */ - SSL_GET_MESSAGE_HASH_MESSAGE, &ok); + ssl_hash_message, &ok); if (!ok) { uint32_t err = ERR_peek_error(); @@ -858,24 +860,22 @@ int ssl3_get_server_hello(SSL *s) { goto f_err; } - if (s->hit && s->session->cipher != c) { - al = SSL_AD_ILLEGAL_PARAMETER; - OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, - SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); - goto f_err; + if (s->hit) { + if (s->session->cipher != c) { + al = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, + SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); + goto f_err; + } + if (s->session->ssl_version != s->version) { + al = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, + SSL_R_OLD_SESSION_VERSION_NOT_RETURNED); + goto f_err; + } } s->s3->tmp.new_cipher = c; - /* Most clients also require that the negotiated version match the session's - * version if resuming. However OpenSSL has historically not had the - * corresponding logic on the server, so this may not be compatible, - * depending on other factors. (Whether the ClientHello version is clamped to - * the session's version and whether the session cache is keyed on IP - * address.) - * - * TODO(davidben): See if we can still enforce this? Perhaps for the future - * TLS 1.3 and forward if this is fixed upstream. */ - /* Don't digest cached records if no sigalgs: we may need them for client * authentication. */ if (!SSL_USE_SIGALGS(s) && @@ -924,8 +924,8 @@ int ssl3_get_server_certificate(SSL *s) { const uint8_t *data; n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_A, SSL3_ST_CR_CERT_B, - SSL3_MT_CERTIFICATE, s->max_cert_list, - SSL_GET_MESSAGE_HASH_MESSAGE, &ok); + SSL3_MT_CERTIFICATE, (long)s->max_cert_list, + ssl_hash_message, &ok); if (!ok) { return n; @@ -988,9 +988,7 @@ int ssl3_get_server_certificate(SSL *s) { goto err; } - if (s->session->sess_cert) { - ssl_sess_cert_free(s->session->sess_cert); - } + ssl_sess_cert_free(s->session->sess_cert); s->session->sess_cert = sc; sc->cert_chain = sk; @@ -1028,17 +1026,11 @@ int ssl3_get_server_certificate(SSL *s) { goto f_err; } sc->peer_cert_type = i; - /* Why would the following ever happen? We just created sc a couple of lines - * ago. */ - if (sc->peer_pkeys[i].x509 != NULL) { - X509_free(sc->peer_pkeys[i].x509); - } + X509_free(sc->peer_pkeys[i].x509); sc->peer_pkeys[i].x509 = X509_up_ref(x); sc->peer_key = &(sc->peer_pkeys[i]); - if (s->session->peer != NULL) { - X509_free(s->session->peer); - } + X509_free(s->session->peer); s->session->peer = X509_up_ref(x); s->session->verify_result = s->verify_result; @@ -1075,7 +1067,7 @@ int ssl3_get_server_key_exchange(SSL *s) { * ServerKeyExchange message may be skipped */ n = s->method->ssl_get_message(s, SSL3_ST_CR_KEY_EXCH_A, SSL3_ST_CR_KEY_EXCH_B, -1, s->max_cert_list, - SSL_GET_MESSAGE_HASH_MESSAGE, &ok); + ssl_hash_message, &ok); if (!ok) { return n; } @@ -1096,14 +1088,15 @@ int ssl3_get_server_key_exchange(SSL *s) { * initialized |sess_cert|. */ if (s->session->sess_cert == NULL) { s->session->sess_cert = ssl_sess_cert_new(); + if (s->session->sess_cert == NULL) { + return -1; + } } /* TODO(davidben): This should be reset in one place with the rest of the * handshake state. */ - if (s->s3->tmp.peer_psk_identity_hint) { - OPENSSL_free(s->s3->tmp.peer_psk_identity_hint); - s->s3->tmp.peer_psk_identity_hint = NULL; - } + OPENSSL_free(s->s3->tmp.peer_psk_identity_hint); + s->s3->tmp.peer_psk_identity_hint = NULL; } s->s3->tmp.reuse_message = 1; return 1; @@ -1114,16 +1107,15 @@ int ssl3_get_server_key_exchange(SSL *s) { server_key_exchange_orig = server_key_exchange; if (s->session->sess_cert != NULL) { - if (s->session->sess_cert->peer_dh_tmp) { - DH_free(s->session->sess_cert->peer_dh_tmp); - s->session->sess_cert->peer_dh_tmp = NULL; - } - if (s->session->sess_cert->peer_ecdh_tmp) { - EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp); - s->session->sess_cert->peer_ecdh_tmp = NULL; - } + DH_free(s->session->sess_cert->peer_dh_tmp); + s->session->sess_cert->peer_dh_tmp = NULL; + EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp); + s->session->sess_cert->peer_ecdh_tmp = NULL; } else { s->session->sess_cert = ssl_sess_cert_new(); + if (s->session->sess_cert == NULL) { + return -1; + } } alg_k = s->s3->tmp.new_cipher->algorithm_mkey; @@ -1165,7 +1157,7 @@ int ssl3_get_server_key_exchange(SSL *s) { } } - if (alg_k & SSL_kEDH) { + if (alg_k & SSL_kDHE) { CBS dh_p, dh_g, dh_Ys; if (!CBS_get_u16_length_prefixed(&server_key_exchange, &dh_p) || @@ -1207,10 +1199,9 @@ int ssl3_get_server_key_exchange(SSL *s) { s->session->sess_cert->peer_dh_tmp = dh; dh = NULL; - } else if (alg_k & SSL_kEECDH) { + } else if (alg_k & SSL_kECDHE) { uint16_t curve_id; int curve_nid = 0; - EC_GROUP *ngroup; const EC_GROUP *group; CBS point; @@ -1231,20 +1222,12 @@ int ssl3_get_server_key_exchange(SSL *s) { goto f_err; } - ecdh = EC_KEY_new(); + ecdh = EC_KEY_new_by_curve_name(curve_nid); if (ecdh == NULL) { OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, - ERR_R_MALLOC_FAILURE); - goto err; - } - - ngroup = EC_GROUP_new_by_curve_name(curve_nid); - if (ngroup == NULL || - EC_KEY_set_group(ecdh, ngroup) == 0) { - OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_EC_LIB); + ERR_R_EC_LIB); goto err; } - EC_GROUP_free(ngroup); group = EC_KEY_get0_group(ecdh); @@ -1362,17 +1345,11 @@ f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); err: EVP_PKEY_free(pkey); - if (rsa != NULL) { - RSA_free(rsa); - } - if (dh != NULL) { - DH_free(dh); - } + RSA_free(rsa); + DH_free(dh); BN_CTX_free(bn_ctx); EC_POINT_free(srvr_ecpoint); - if (ecdh != NULL) { - EC_KEY_free(ecdh); - } + EC_KEY_free(ecdh); EVP_MD_CTX_cleanup(&md_ctx); return -1; } @@ -1393,7 +1370,7 @@ int ssl3_get_certificate_request(SSL *s) { n = s->method->ssl_get_message(s, SSL3_ST_CR_CERT_REQ_A, SSL3_ST_CR_CERT_REQ_B, -1, s->max_cert_list, - SSL_GET_MESSAGE_HASH_MESSAGE, &ok); + ssl_hash_message, &ok); if (!ok) { return n; @@ -1419,15 +1396,6 @@ int ssl3_get_certificate_request(SSL *s) { goto err; } - /* TLS does not like anon-DH with client cert */ - if (s->version > SSL3_VERSION && - (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); - OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, - SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER); - goto err; - } - CBS_init(&cbs, s->init_msg, n); ca_sk = sk_X509_NAME_new(ca_dn_cmp); @@ -1493,7 +1461,7 @@ int ssl3_get_certificate_request(SSL *s) { if (!CBS_skip(&distinguished_name, data - CBS_data(&distinguished_name))) { ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_INTERNAL_ERROR); goto err; } @@ -1513,29 +1481,25 @@ int ssl3_get_certificate_request(SSL *s) { /* we should setup a certificate to return.... */ s->s3->tmp.cert_req = 1; - if (s->s3->tmp.ca_names != NULL) { - sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); - } + sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); s->s3->tmp.ca_names = ca_sk; ca_sk = NULL; ret = 1; err: - if (ca_sk != NULL) { - sk_X509_NAME_pop_free(ca_sk, X509_NAME_free); - } + sk_X509_NAME_pop_free(ca_sk, X509_NAME_free); return ret; } int ssl3_get_new_session_ticket(SSL *s) { - int ok, al, ret = 0; + int ok, al; long n; CBS new_session_ticket, ticket; n = s->method->ssl_get_message( s, SSL3_ST_CR_SESSION_TICKET_A, SSL3_ST_CR_SESSION_TICKET_B, - SSL3_MT_NEWSESSION_TICKET, 16384, SSL_GET_MESSAGE_HASH_MESSAGE, &ok); + SSL3_MT_NEWSESSION_TICKET, 16384, ssl_hash_message, &ok); if (!ok) { return n; @@ -1558,21 +1522,15 @@ int ssl3_get_new_session_ticket(SSL *s) { goto err; } - /* There are two ways to detect a resumed ticket sesion. One is to set an - * appropriate session ID and then the server must return a match in - * ServerHello. This allows the normal client session ID matching to work and - * we know much earlier that the ticket has been accepted. - * - * The other way is to set zero length session ID when the ticket is - * presented and rely on the handshake to determine session resumption. - * - * We choose the former approach because this fits in with assumptions - * elsewhere in OpenSSL. The session ID is set to the SHA256 (or SHA1 is - * SHA256 is disabled) hash of the ticket. */ - EVP_Digest(CBS_data(&ticket), CBS_len(&ticket), s->session->session_id, - &s->session->session_id_length, EVP_sha256(), NULL); - ret = 1; - return ret; + /* Generate a session ID for this session based on the session ticket. We use + * the session ID mechanism for detecting ticket resumption. This also fits in + * with assumptions elsewhere in OpenSSL.*/ + if (!EVP_Digest(CBS_data(&ticket), CBS_len(&ticket), s->session->session_id, + &s->session->session_id_length, EVP_sha256(), NULL)) { + goto err; + } + + return 1; f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); @@ -1588,12 +1546,19 @@ int ssl3_get_cert_status(SSL *s) { n = s->method->ssl_get_message( s, SSL3_ST_CR_CERT_STATUS_A, SSL3_ST_CR_CERT_STATUS_B, - SSL3_MT_CERTIFICATE_STATUS, 16384, SSL_GET_MESSAGE_HASH_MESSAGE, &ok); + -1, 16384, ssl_hash_message, &ok); if (!ok) { return n; } + if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_STATUS) { + /* A server may send status_request in ServerHello and then change + * its mind about sending CertificateStatus. */ + s->s3->tmp.reuse_message = 1; + return 1; + } + CBS_init(&certificate_status, s->init_msg, n); if (!CBS_get_u8(&certificate_status, &status_type) || status_type != TLSEXT_STATUSTYPE_ocsp || @@ -1625,7 +1590,7 @@ int ssl3_get_server_done(SSL *s) { n = s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_DONE_A, SSL3_ST_CR_SRVR_DONE_B, SSL3_MT_SERVER_DONE, 30, /* should be very small, like 0 :-) */ - SSL_GET_MESSAGE_HASH_MESSAGE, &ok); + ssl_hash_message, &ok); if (!ok) { return n; @@ -1645,8 +1610,8 @@ int ssl3_get_server_done(SSL *s) { int ssl3_send_client_key_exchange(SSL *s) { uint8_t *p; int n = 0; - unsigned long alg_k; - unsigned long alg_a; + uint32_t alg_k; + uint32_t alg_a; uint8_t *q; EVP_PKEY *pkey = NULL; EC_KEY *clnt_ecdh = NULL; @@ -1699,10 +1664,7 @@ int ssl3_send_client_key_exchange(SSL *s) { goto err; } - if (s->session->psk_identity != NULL) { - OPENSSL_free(s->session->psk_identity); - } - + OPENSSL_free(s->session->psk_identity); s->session->psk_identity = BUF_strdup(identity); if (s->session->psk_identity == NULL) { OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, @@ -1744,9 +1706,7 @@ int ssl3_send_client_key_exchange(SSL *s) { pkey->pkey.rsa == NULL) { OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_INTERNAL_ERROR); - if (pkey != NULL) { - EVP_PKEY_free(pkey); - } + EVP_PKEY_free(pkey); goto err; } @@ -1785,7 +1745,7 @@ int ssl3_send_client_key_exchange(SSL *s) { if (s->version > SSL3_VERSION) { s2n(enc_pms_len, q); } - } else if (alg_k & SSL_kEDH) { + } else if (alg_k & SSL_kDHE) { DH *dh_srvr, *dh_clnt; SESS_CERT *scert = s->session->sess_cert; int dh_len; @@ -1841,7 +1801,7 @@ int ssl3_send_client_key_exchange(SSL *s) { n += 2 + pub_len; DH_free(dh_clnt); - } else if (alg_k & SSL_kEECDH) { + } else if (alg_k & SSL_kECDHE) { const EC_GROUP *srvr_group = NULL; EC_KEY *tkey; int field_size = 0, ecdh_len; @@ -1993,7 +1953,9 @@ int ssl3_send_client_key_exchange(SSL *s) { /* The message must be added to the finished hash before calculating the * master secret. */ - ssl_set_handshake_header(s, SSL3_MT_CLIENT_KEY_EXCHANGE, n); + if (!ssl_set_handshake_header(s, SSL3_MT_CLIENT_KEY_EXCHANGE, n)) { + goto err; + } s->state = SSL3_ST_CW_KEY_EXCH_B; s->session->master_key_length = s->enc_method->generate_master_secret( @@ -2007,16 +1969,12 @@ int ssl3_send_client_key_exchange(SSL *s) { } /* SSL3_ST_CW_KEY_EXCH_B */ - return s->enc_method->do_write(s); + return s->method->do_write(s); err: BN_CTX_free(bn_ctx); - if (encodedPoint != NULL) { - OPENSSL_free(encodedPoint); - } - if (clnt_ecdh != NULL) { - EC_KEY_free(clnt_ecdh); - } + OPENSSL_free(encodedPoint); + EC_KEY_free(clnt_ecdh); EVP_PKEY_free(srvr_pub_pkey); if (pms) { OPENSSL_cleanse(pms, pms_len); @@ -2089,7 +2047,9 @@ int ssl3_send_cert_verify(SSL *s) { s2n(signature_length, p); n += signature_length + 2; - ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n); + if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n)) { + goto err; + } s->state = SSL3_ST_CW_CERT_VRFY_B; } @@ -2156,12 +2116,8 @@ int ssl3_send_client_certificate(SSL *s) { SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); } - if (x509 != NULL) { - X509_free(x509); - } - if (pkey != NULL) { - EVP_PKEY_free(pkey); - } + X509_free(x509); + EVP_PKEY_free(pkey); if (i && !ssl3_has_client_certificate(s)) { i = 0; } @@ -2180,8 +2136,10 @@ int ssl3_send_client_certificate(SSL *s) { } if (s->state == SSL3_ST_CW_CERT_C) { - s->state = SSL3_ST_CW_CERT_D; - ssl3_output_cert_chain(s, (s->s3->tmp.cert_req == 2) ? NULL : s->cert->key); + CERT_PKEY *cert_pkey = (s->s3->tmp.cert_req == 2) ? NULL : s->cert->key; + if (!ssl3_output_cert_chain(s, cert_pkey)) { + return -1; + } } /* SSL3_ST_CW_CERT_D */ @@ -2246,7 +2204,7 @@ int ssl3_check_cert_and_algorithm(SSL *s) { goto f_err; } - if ((alg_k & SSL_kEDH) && + if ((alg_k & SSL_kDHE) && !(has_bits(i, EVP_PK_DH | EVP_PKT_EXCH) || dh != NULL)) { OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, SSL_R_MISSING_DH_KEY); goto f_err; @@ -2276,7 +2234,9 @@ int ssl3_send_next_proto(SSL *s) { memset(p, 0, padding_len); p += padding_len; - ssl_set_handshake_header(s, SSL3_MT_NEXT_PROTO, p - d); + if (!ssl_set_handshake_header(s, SSL3_MT_NEXT_PROTO, p - d)) { + return -1; + } s->state = SSL3_ST_CW_NEXT_PROTO_B; } @@ -2387,23 +2347,19 @@ int ssl3_send_channel_id(SSL *s) { goto err; } - ssl_set_handshake_header(s, SSL3_MT_ENCRYPTED_EXTENSIONS, - 2 + 2 + TLSEXT_CHANNEL_ID_SIZE); + if (!ssl_set_handshake_header(s, SSL3_MT_ENCRYPTED_EXTENSIONS, + 2 + 2 + TLSEXT_CHANNEL_ID_SIZE)) { + goto err; + } s->state = SSL3_ST_CW_CHANNEL_ID_B; ret = ssl_do_write(s); err: EVP_MD_CTX_cleanup(&md_ctx); - if (public_key) { - OPENSSL_free(public_key); - } - if (der_sig) { - OPENSSL_free(der_sig); - } - if (sig) { - ECDSA_SIG_free(sig); - } + OPENSSL_free(public_key); + OPENSSL_free(der_sig); + ECDSA_SIG_free(sig); return ret; } -- cgit v1.1