external/boringssl: Sync to c642aca28feb7e18f244658559f4042286aed0c8.
This includes the following changes:
https://boringssl.googlesource.com/boringssl/+log/14308731e5446a73ac2258688a9688b524483cb6..c642aca28feb7e18f244658559f4042286aed0c8
Test: BoringSSL CTS Presubmits
Change-Id: Ia0b5b2cdd64eb2b54ec5335d48da9001e9d6dafa
diff --git a/src/ssl/handshake_server.cc b/src/ssl/handshake_server.cc
index ee5358c..38fbef4 100644
--- a/src/ssl/handshake_server.cc
+++ b/src/ssl/handshake_server.cc
@@ -170,6 +170,8 @@
#include "../crypto/internal.h"
+namespace bssl {
+
static int ssl3_process_client_hello(SSL_HANDSHAKE *hs);
static int ssl3_select_certificate(SSL_HANDSHAKE *hs);
static int ssl3_select_parameters(SSL_HANDSHAKE *hs);
@@ -282,6 +284,23 @@
goto end;
}
}
+ hs->state = SSL3_ST_VERIFY_CLIENT_CERT;
+ break;
+
+ case SSL3_ST_VERIFY_CLIENT_CERT:
+ if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) > 0) {
+ switch (ssl_verify_peer_cert(hs)) {
+ case ssl_verify_ok:
+ break;
+ case ssl_verify_invalid:
+ ret = -1;
+ goto end;
+ case ssl_verify_retry:
+ ssl->rwstate = SSL_CERTIFICATE_VERIFY;
+ ret = -1;
+ goto end;
+ }
+ }
hs->state = SSL3_ST_SR_KEY_EXCH_A;
break;
@@ -411,7 +430,7 @@
ssl->retain_only_sha256_of_client_certs) {
sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free);
hs->new_session->certs = NULL;
- ssl->ctx->x509_method->session_clear(hs->new_session);
+ ssl->ctx->x509_method->session_clear(hs->new_session.get());
}
SSL_SESSION_free(ssl->s3->established_session);
@@ -419,9 +438,8 @@
SSL_SESSION_up_ref(ssl->session);
ssl->s3->established_session = ssl->session;
} else {
- ssl->s3->established_session = hs->new_session;
+ ssl->s3->established_session = hs->new_session.release();
ssl->s3->established_session->not_resumable = 0;
- hs->new_session = NULL;
}
ssl->s3->initial_handshake_complete = 1;
@@ -586,8 +604,8 @@
uint32_t mask_a = 0;
if (ssl_has_certificate(ssl)) {
- mask_a |= ssl_cipher_auth_mask_for_key(hs->local_pubkey);
- if (EVP_PKEY_id(hs->local_pubkey) == EVP_PKEY_RSA) {
+ mask_a |= ssl_cipher_auth_mask_for_key(hs->local_pubkey.get());
+ if (EVP_PKEY_id(hs->local_pubkey.get()) == EVP_PKEY_RSA) {
mask_k |= SSL_kRSA;
}
}
@@ -808,12 +826,12 @@
/* Determine whether we are doing session resumption. */
int tickets_supported = 0, renew_ticket = 0;
- /* TODO(davidben): Switch |ssl_get_prev_session| to take a |bssl::UniquePtr|
+ /* TODO(davidben): Switch |ssl_get_prev_session| to take a |UniquePtr|
* output and simplify this. */
SSL_SESSION *session_raw = nullptr;
auto session_ret = ssl_get_prev_session(ssl, &session_raw, &tickets_supported,
&renew_ticket, &client_hello);
- bssl::UniquePtr<SSL_SESSION> session(session_raw);
+ UniquePtr<SSL_SESSION> session(session_raw);
switch (session_ret) {
case ssl_session_success:
break;
@@ -876,7 +894,7 @@
/* On new sessions, stash the SNI value in the session. */
if (hs->hostname != NULL) {
OPENSSL_free(hs->new_session->tlsext_hostname);
- hs->new_session->tlsext_hostname = BUF_strdup(hs->hostname);
+ hs->new_session->tlsext_hostname = BUF_strdup(hs->hostname.get());
if (hs->new_session->tlsext_hostname == NULL) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return -1;
@@ -912,8 +930,8 @@
/* Now that all parameters are known, initialize the handshake hash and hash
* the ClientHello. */
- if (!SSL_TRANSCRIPT_init_hash(&hs->transcript, ssl3_protocol_version(ssl),
- hs->new_cipher->algorithm_prf) ||
+ if (!hs->transcript.InitHash(ssl3_protocol_version(ssl),
+ hs->new_cipher->algorithm_prf) ||
!ssl_hash_current_message(hs)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return -1;
@@ -921,7 +939,7 @@
/* Release the handshake buffer if client authentication isn't required. */
if (!hs->cert_request) {
- SSL_TRANSCRIPT_free_buffer(&hs->transcript);
+ hs->transcript.FreeBuffer();
}
return 1;
@@ -958,13 +976,14 @@
/* TODO(davidben): Implement the TLS 1.1 and 1.2 downgrade sentinels once TLS
* 1.3 is finalized and we are not implementing a draft version. */
- const SSL_SESSION *session = hs->new_session;
+ const SSL_SESSION *session = hs->new_session.get();
if (ssl->session != NULL) {
session = ssl->session;
}
- CBB cbb, body, session_id;
- if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO) ||
+ ScopedCBB cbb;
+ CBB body, session_id;
+ if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) ||
!CBB_add_u16(&body, ssl->version) ||
!CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
!CBB_add_u8_length_prefixed(&body, &session_id) ||
@@ -973,9 +992,8 @@
!CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) ||
!CBB_add_u8(&body, 0 /* no compression */) ||
!ssl_add_serverhello_tlsext(hs, &body) ||
- !ssl_add_message_cbb(ssl, &cbb)) {
+ !ssl_add_message_cbb(ssl, cbb.get())) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- CBB_cleanup(&cbb);
return -1;
}
@@ -984,7 +1002,7 @@
static int ssl3_send_server_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- bssl::ScopedCBB cbb;
+ ScopedCBB cbb;
if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
if (!ssl_has_certificate(ssl)) {
@@ -1049,11 +1067,12 @@
hs->new_session->group_id = group_id;
/* Set up ECDH, generate a key, and emit the public half. */
- if (!SSL_ECDH_CTX_init(&hs->ecdh_ctx, group_id) ||
+ hs->key_share = SSLKeyShare::Create(group_id);
+ if (!hs->key_share ||
!CBB_add_u8(cbb.get(), NAMED_CURVE_TYPE) ||
!CBB_add_u16(cbb.get(), group_id) ||
!CBB_add_u8_length_prefixed(cbb.get(), &child) ||
- !SSL_ECDH_CTX_offer(&hs->ecdh_ctx, &child)) {
+ !hs->key_share->Offer(&child)) {
return -1;
}
} else {
@@ -1070,42 +1089,43 @@
static int ssl3_send_server_key_exchange(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- CBB cbb, body, child;
- if (!ssl->method->init_message(ssl, &cbb, &body,
+ ScopedCBB cbb;
+ CBB body, child;
+ if (!ssl->method->init_message(ssl, cbb.get(), &body,
SSL3_MT_SERVER_KEY_EXCHANGE) ||
/* |hs->server_params| contains a prefix for signing. */
hs->server_params_len < 2 * SSL3_RANDOM_SIZE ||
!CBB_add_bytes(&body, hs->server_params + 2 * SSL3_RANDOM_SIZE,
hs->server_params_len - 2 * SSL3_RANDOM_SIZE)) {
- goto err;
+ return -1;
}
/* Add a signature. */
if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
if (!ssl_has_private_key(ssl)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- goto err;
+ return -1;
}
/* Determine the signature algorithm. */
uint16_t signature_algorithm;
if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) {
- goto err;
+ return -1;
}
if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
if (!CBB_add_u16(&body, signature_algorithm)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- goto err;
+ return -1;
}
}
/* Add space for the signature. */
- const size_t max_sig_len = EVP_PKEY_size(hs->local_pubkey);
+ const size_t max_sig_len = EVP_PKEY_size(hs->local_pubkey.get());
uint8_t *ptr;
if (!CBB_add_u16_length_prefixed(&body, &child) ||
!CBB_reserve(&child, &ptr, max_sig_len)) {
- goto err;
+ return -1;
}
size_t sig_len;
@@ -1114,19 +1134,19 @@
hs->server_params_len)) {
case ssl_private_key_success:
if (!CBB_did_write(&child, sig_len)) {
- goto err;
+ return -1;
}
break;
case ssl_private_key_failure:
- goto err;
+ return -1;
case ssl_private_key_retry:
ssl->rwstate = SSL_PRIVATE_KEY_OPERATION;
- goto err;
+ return -1;
}
}
- if (!ssl_add_message_cbb(ssl, &cbb)) {
- goto err;
+ if (!ssl_add_message_cbb(ssl, cbb.get())) {
+ return -1;
}
OPENSSL_free(hs->server_params);
@@ -1134,19 +1154,16 @@
hs->server_params_len = 0;
return 1;
-
-err:
- CBB_cleanup(&cbb);
- return -1;
}
static int ssl3_send_server_hello_done(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- CBB cbb, body;
+ ScopedCBB cbb;
+ CBB body;
if (hs->cert_request) {
CBB cert_types, sigalgs_cbb;
- if (!ssl->method->init_message(ssl, &cbb, &body,
+ if (!ssl->method->init_message(ssl, cbb.get(), &body,
SSL3_MT_CERTIFICATE_REQUEST) ||
!CBB_add_u8_length_prefixed(&body, &cert_types) ||
!CBB_add_u8(&cert_types, SSL3_CT_RSA_SIGN) ||
@@ -1156,22 +1173,20 @@
(!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb) ||
!tls12_add_verify_sigalgs(ssl, &sigalgs_cbb))) ||
!ssl_add_client_CA_list(ssl, &body) ||
- !ssl_add_message_cbb(ssl, &cbb)) {
- goto err;
+ !ssl_add_message_cbb(ssl, cbb.get())) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
}
}
- if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO_DONE) ||
- !ssl_add_message_cbb(ssl, &cbb)) {
- goto err;
+ if (!ssl->method->init_message(ssl, cbb.get(), &body,
+ SSL3_MT_SERVER_HELLO_DONE) ||
+ !ssl_add_message_cbb(ssl, cbb.get())) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
}
return 1;
-
-err:
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- CBB_cleanup(&cbb);
- return -1;
}
static int ssl3_get_client_certificate(SSL_HANDSHAKE *hs) {
@@ -1214,21 +1229,22 @@
CBS_init(&certificate_msg, ssl->init_msg, ssl->init_num);
sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free);
- EVP_PKEY_free(hs->peer_pubkey);
- hs->peer_pubkey = NULL;
+ hs->peer_pubkey.reset();
uint8_t alert = SSL_AD_DECODE_ERROR;
- hs->new_session->certs = ssl_parse_cert_chain(
- &alert, &hs->peer_pubkey,
- ssl->retain_only_sha256_of_client_certs ? hs->new_session->peer_sha256
- : NULL,
- &certificate_msg, ssl->ctx->pool);
+ hs->new_session->certs =
+ ssl_parse_cert_chain(&alert, &hs->peer_pubkey,
+ ssl->retain_only_sha256_of_client_certs
+ ? hs->new_session->peer_sha256
+ : NULL,
+ &certificate_msg, ssl->ctx->pool)
+ .release();
if (hs->new_session->certs == NULL) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
return -1;
}
if (CBS_len(&certificate_msg) != 0 ||
- !ssl->ctx->x509_method->session_cache_objects(hs->new_session)) {
+ !ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return -1;
@@ -1236,7 +1252,7 @@
if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) {
/* No client certificate so the handshake buffer may be discarded. */
- SSL_TRANSCRIPT_free_buffer(&hs->transcript);
+ hs->transcript.FreeBuffer();
/* In SSL 3.0, sending no certificate is signaled by omitting the
* Certificate message. */
@@ -1264,10 +1280,6 @@
hs->new_session->peer_sha256_valid = 1;
}
- if (!ssl->ctx->x509_method->session_verify_cert_chain(hs->new_session, ssl)) {
- return -1;
- }
-
return 1;
}
@@ -1337,7 +1349,7 @@
}
/* Allocate a buffer large enough for an RSA decryption. */
- const size_t rsa_size = EVP_PKEY_size(hs->local_pubkey);
+ const size_t rsa_size = EVP_PKEY_size(hs->local_pubkey.get());
decrypt_buf = (uint8_t *)OPENSSL_malloc(rsa_size);
if (decrypt_buf == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
@@ -1423,15 +1435,14 @@
/* Compute the premaster. */
uint8_t alert = SSL_AD_DECODE_ERROR;
- if (!SSL_ECDH_CTX_finish(&hs->ecdh_ctx, &premaster_secret,
- &premaster_secret_len, &alert, CBS_data(&peer_key),
- CBS_len(&peer_key))) {
+ if (!hs->key_share->Finish(&premaster_secret, &premaster_secret_len, &alert,
+ CBS_data(&peer_key), CBS_len(&peer_key))) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
goto err;
}
/* The key exchange state may now be discarded. */
- SSL_ECDH_CTX_cleanup(&hs->ecdh_ctx);
+ hs->key_share.reset();
} else if (!(alg_k & SSL_kPSK)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
@@ -1474,18 +1485,18 @@
OPENSSL_memset(premaster_secret, 0, premaster_secret_len);
}
- CBB new_premaster, child;
+ ScopedCBB new_premaster;
+ CBB child;
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.get(),
+ 2 + psk_len + 2 + premaster_secret_len) ||
+ !CBB_add_u16_length_prefixed(new_premaster.get(), &child) ||
!CBB_add_bytes(&child, premaster_secret, premaster_secret_len) ||
- !CBB_add_u16_length_prefixed(&new_premaster, &child) ||
+ !CBB_add_u16_length_prefixed(new_premaster.get(), &child) ||
!CBB_add_bytes(&child, psk, psk_len) ||
- !CBB_finish(&new_premaster, &new_data, &new_len)) {
+ !CBB_finish(new_premaster.get(), &new_data, &new_len)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- CBB_cleanup(&new_premaster);
goto err;
}
@@ -1528,8 +1539,8 @@
/* Only RSA and ECDSA client certificates are supported, so a
* CertificateVerify is required if and only if there's a client certificate.
* */
- if (hs->peer_pubkey == NULL) {
- SSL_TRANSCRIPT_free_buffer(&hs->transcript);
+ if (!hs->peer_pubkey) {
+ hs->transcript.FreeBuffer();
return 1;
}
@@ -1559,7 +1570,7 @@
}
hs->new_session->peer_signature_algorithm = signature_algorithm;
} else if (!tls1_get_legacy_signature_algorithm(&signature_algorithm,
- hs->peer_pubkey)) {
+ hs->peer_pubkey.get())) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_CERTIFICATE);
return -1;
@@ -1579,23 +1590,22 @@
if (ssl3_protocol_version(ssl) == SSL3_VERSION) {
uint8_t digest[EVP_MAX_MD_SIZE];
size_t digest_len;
- if (!SSL_TRANSCRIPT_ssl3_cert_verify_hash(&hs->transcript, digest,
- &digest_len, hs->new_session,
- signature_algorithm)) {
+ if (!hs->transcript.GetSSL3CertVerifyHash(
+ digest, &digest_len, hs->new_session.get(), signature_algorithm)) {
return -1;
}
- EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(hs->peer_pubkey, NULL);
- sig_ok = pctx != NULL &&
- EVP_PKEY_verify_init(pctx) &&
- EVP_PKEY_verify(pctx, CBS_data(&signature), CBS_len(&signature),
- digest, digest_len);
- EVP_PKEY_CTX_free(pctx);
+ UniquePtr<EVP_PKEY_CTX> pctx(
+ EVP_PKEY_CTX_new(hs->peer_pubkey.get(), nullptr));
+ sig_ok = pctx &&
+ EVP_PKEY_verify_init(pctx.get()) &&
+ EVP_PKEY_verify(pctx.get(), CBS_data(&signature),
+ CBS_len(&signature), digest, digest_len);
} else {
sig_ok = ssl_public_key_verify(
ssl, CBS_data(&signature), CBS_len(&signature), signature_algorithm,
- hs->peer_pubkey, (const uint8_t *)hs->transcript.buffer->data,
- hs->transcript.buffer->length);
+ hs->peer_pubkey.get(), hs->transcript.buffer_data(),
+ hs->transcript.buffer_len());
}
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
@@ -1610,7 +1620,7 @@
/* The handshake buffer is no longer necessary, and we may hash the current
* message.*/
- SSL_TRANSCRIPT_free_buffer(&hs->transcript);
+ hs->transcript.FreeBuffer();
if (!ssl_hash_current_message(hs)) {
return -1;
}
@@ -1671,33 +1681,31 @@
if (hs->ticket_expected) {
const SSL_SESSION *session;
- SSL_SESSION *session_copy = NULL;
+ UniquePtr<SSL_SESSION> session_copy;
if (ssl->session == NULL) {
/* Fix the timeout to measure from the ticket issuance time. */
- ssl_session_rebase_time(ssl, hs->new_session);
- session = hs->new_session;
+ ssl_session_rebase_time(ssl, hs->new_session.get());
+ session = hs->new_session.get();
} else {
/* We are renewing an existing session. Duplicate the session to adjust
* the timeout. */
session_copy = SSL_SESSION_dup(ssl->session, SSL_SESSION_INCLUDE_NONAUTH);
- if (session_copy == NULL) {
+ if (!session_copy) {
return -1;
}
- ssl_session_rebase_time(ssl, session_copy);
- session = session_copy;
+ ssl_session_rebase_time(ssl, session_copy.get());
+ session = session_copy.get();
}
- CBB cbb, body, ticket;
- int ok = ssl->method->init_message(ssl, &cbb, &body,
- SSL3_MT_NEW_SESSION_TICKET) &&
- CBB_add_u32(&body, session->timeout) &&
- CBB_add_u16_length_prefixed(&body, &ticket) &&
- ssl_encrypt_ticket(ssl, &ticket, session) &&
- ssl_add_message_cbb(ssl, &cbb);
- SSL_SESSION_free(session_copy);
- CBB_cleanup(&cbb);
- if (!ok) {
+ ScopedCBB cbb;
+ CBB body, ticket;
+ if (!ssl->method->init_message(ssl, cbb.get(), &body,
+ SSL3_MT_NEW_SESSION_TICKET) ||
+ !CBB_add_u32(&body, session->timeout) ||
+ !CBB_add_u16_length_prefixed(&body, &ticket) ||
+ !ssl_encrypt_ticket(ssl, &ticket, session) ||
+ !ssl_add_message_cbb(ssl, cbb.get())) {
return -1;
}
}
@@ -1709,3 +1717,5 @@
return ssl3_send_finished(hs);
}
+
+} // namespace bssl