external/boringssl: Sync to 3120950b1e27635ee9b9d167052ce11ce9c96fd4.
This includes the following changes:
https://boringssl.googlesource.com/boringssl/+log/5e578c9dba73460c3eb17f771c77fc8e36f7812e..3120950b1e27635ee9b9d167052ce11ce9c96fd4
Test: BoringSSL CTS Presubmits.
Change-Id: I54d7540777ffdf1e72c4ff67f3138097cbdbeafb
diff --git a/src/ssl/handshake_server.c b/src/ssl/handshake_server.c
index 4eaf3cb..d591c80 100644
--- a/src/ssl/handshake_server.c
+++ b/src/ssl/handshake_server.c
@@ -175,31 +175,17 @@
static int ssl3_select_parameters(SSL_HANDSHAKE *hs);
static int ssl3_send_server_hello(SSL_HANDSHAKE *hs);
static int ssl3_send_server_certificate(SSL_HANDSHAKE *hs);
-static int ssl3_send_certificate_status(SSL_HANDSHAKE *hs);
static int ssl3_send_server_key_exchange(SSL_HANDSHAKE *hs);
-static int ssl3_send_certificate_request(SSL_HANDSHAKE *hs);
static int ssl3_send_server_hello_done(SSL_HANDSHAKE *hs);
static int ssl3_get_client_certificate(SSL_HANDSHAKE *hs);
static int ssl3_get_client_key_exchange(SSL_HANDSHAKE *hs);
static int ssl3_get_cert_verify(SSL_HANDSHAKE *hs);
static int ssl3_get_next_proto(SSL_HANDSHAKE *hs);
static int ssl3_get_channel_id(SSL_HANDSHAKE *hs);
-static int ssl3_send_new_session_ticket(SSL_HANDSHAKE *hs);
-
-static struct CRYPTO_STATIC_MUTEX g_v2clienthello_lock =
- CRYPTO_STATIC_MUTEX_INIT;
-static uint64_t g_v2clienthello_count = 0;
-
-uint64_t SSL_get_v2clienthello_count(void) {
- CRYPTO_STATIC_MUTEX_lock_read(&g_v2clienthello_lock);
- uint64_t ret = g_v2clienthello_count;
- CRYPTO_STATIC_MUTEX_unlock_read(&g_v2clienthello_lock);
- return ret;
-}
+static int ssl3_send_server_finished(SSL_HANDSHAKE *hs);
int ssl3_accept(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- uint32_t alg_a;
int ret = -1;
assert(ssl->handshake_func == ssl3_accept);
@@ -255,55 +241,28 @@
goto end;
}
if (ssl->session != NULL) {
- hs->state = SSL3_ST_SW_SESSION_TICKET_A;
+ hs->state = SSL3_ST_SW_FINISHED_A;
} else {
hs->state = SSL3_ST_SW_CERT_A;
}
break;
case SSL3_ST_SW_CERT_A:
- if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
- ret = ssl3_send_server_certificate(hs);
- if (ret <= 0) {
- goto end;
- }
- }
- hs->state = SSL3_ST_SW_CERT_STATUS_A;
- break;
-
- case SSL3_ST_SW_CERT_STATUS_A:
- if (hs->certificate_status_expected) {
- ret = ssl3_send_certificate_status(hs);
- if (ret <= 0) {
- goto end;
- }
+ ret = ssl3_send_server_certificate(hs);
+ if (ret <= 0) {
+ goto end;
}
hs->state = SSL3_ST_SW_KEY_EXCH_A;
break;
case SSL3_ST_SW_KEY_EXCH_A:
- case SSL3_ST_SW_KEY_EXCH_B:
- alg_a = hs->new_cipher->algorithm_auth;
-
- /* PSK ciphers send ServerKeyExchange if there is an identity hint. */
- if (ssl_cipher_requires_server_key_exchange(hs->new_cipher) ||
- ((alg_a & SSL_aPSK) && ssl->psk_identity_hint)) {
+ if (hs->server_params_len > 0) {
ret = ssl3_send_server_key_exchange(hs);
if (ret <= 0) {
goto end;
}
}
- hs->state = SSL3_ST_SW_CERT_REQ_A;
- break;
-
- case SSL3_ST_SW_CERT_REQ_A:
- if (hs->cert_request) {
- ret = ssl3_send_certificate_request(hs);
- if (ret <= 0) {
- goto end;
- }
- }
hs->state = SSL3_ST_SW_SRVR_DONE_A;
break;
@@ -388,7 +347,7 @@
if (ssl->session != NULL) {
hs->state = SSL_ST_OK;
} else {
- hs->state = SSL3_ST_SW_SESSION_TICKET_A;
+ hs->state = SSL3_ST_SW_FINISHED_A;
}
/* If this is a full handshake with ChannelID then record the handshake
@@ -402,28 +361,8 @@
}
break;
- case SSL3_ST_SW_SESSION_TICKET_A:
- if (hs->ticket_expected) {
- ret = ssl3_send_new_session_ticket(hs);
- if (ret <= 0) {
- goto end;
- }
- }
- hs->state = SSL3_ST_SW_CHANGE;
- break;
-
- case SSL3_ST_SW_CHANGE:
- if (!ssl->method->add_change_cipher_spec(ssl) ||
- !tls1_change_cipher_state(hs, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
- ret = -1;
- goto end;
- }
-
- hs->state = SSL3_ST_SW_FINISHED_A;
- break;
-
case SSL3_ST_SW_FINISHED_A:
- ret = ssl3_send_finished(hs);
+ ret = ssl3_send_server_finished(hs);
if (ret <= 0) {
goto end;
}
@@ -485,12 +424,6 @@
hs->new_session = NULL;
}
- if (hs->v2_clienthello) {
- CRYPTO_STATIC_MUTEX_lock_write(&g_v2clienthello_lock);
- g_v2clienthello_count++;
- CRYPTO_STATIC_MUTEX_unlock_write(&g_v2clienthello_lock);
- }
-
ssl->s3->initial_handshake_complete = 1;
ssl_update_cache(hs, SSL_SESS_CACHE_SERVER);
@@ -538,12 +471,6 @@
const SSL_CLIENT_HELLO *client_hello) {
SSL *const ssl = hs->ssl;
assert(!ssl->s3->have_version);
- uint16_t min_version, max_version;
- if (!ssl_get_version_range(ssl, &min_version, &max_version)) {
- *out_alert = SSL_AD_PROTOCOL_VERSION;
- return 0;
- }
-
uint16_t version = 0;
/* Check supported_versions extension if it is present. */
CBS supported_versions;
@@ -572,8 +499,8 @@
if (!ssl->method->version_from_wire(&ext_version, ext_version)) {
continue;
}
- if (min_version <= ext_version &&
- ext_version <= max_version &&
+ if (hs->min_version <= ext_version &&
+ ext_version <= hs->max_version &&
(!found_version || version < ext_version)) {
version = ext_version;
found_version = 1;
@@ -609,11 +536,11 @@
}
/* Apply our minimum and maximum version. */
- if (version > max_version) {
- version = max_version;
+ if (version > hs->max_version) {
+ version = hs->max_version;
}
- if (version < min_version) {
+ if (version < hs->min_version) {
goto unsupported_protocol;
}
}
@@ -621,7 +548,7 @@
/* Handle FALLBACK_SCSV. */
if (ssl_client_cipher_list_contains_cipher(client_hello,
SSL3_CK_FALLBACK_SCSV & 0xffff) &&
- version < max_version) {
+ version < hs->max_version) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INAPPROPRIATE_FALLBACK);
*out_alert = SSL3_AD_INAPPROPRIATE_FALLBACK;
return 0;
@@ -821,6 +748,11 @@
}
}
+ /* Freeze the version range after the early callback. */
+ if (!ssl_get_version_range(ssl, &hs->min_version, &hs->max_version)) {
+ return -1;
+ }
+
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!negotiate_version(hs, &alert, &client_hello)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
@@ -903,7 +835,6 @@
static int ssl3_select_parameters(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- uint8_t al = SSL_AD_INTERNAL_ERROR;
int ret = -1;
SSL_SESSION *session = NULL;
@@ -933,9 +864,9 @@
if (session->extended_master_secret && !hs->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);
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ goto err;
}
if (!ssl_session_is_resumable(hs, session) ||
@@ -969,9 +900,9 @@
if (ssl->ctx->dos_protection_cb != NULL &&
ssl->ctx->dos_protection_cb(&client_hello) == 0) {
/* Connection rejected for DOS reasons. */
- al = SSL_AD_INTERNAL_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ goto err;
}
if (ssl->session == NULL) {
@@ -982,8 +913,8 @@
OPENSSL_free(hs->new_session->tlsext_hostname);
hs->new_session->tlsext_hostname = BUF_strdup(hs->hostname);
if (hs->new_session->tlsext_hostname == NULL) {
- al = SSL_AD_INTERNAL_ERROR;
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ goto err;
}
}
@@ -1008,8 +939,10 @@
/* HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was
* deferred. Complete it now. */
- if (!ssl_negotiate_alpn(hs, &al, &client_hello)) {
- goto f_err;
+ uint8_t alert = SSL_AD_DECODE_ERROR;
+ if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ goto err;
}
/* Now that all parameters are known, initialize the handshake hash and hash
@@ -1017,7 +950,8 @@
if (!SSL_TRANSCRIPT_init_hash(&hs->transcript, ssl3_protocol_version(ssl),
hs->new_cipher->algorithm_prf) ||
!ssl_hash_current_message(hs)) {
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ goto err;
}
/* Release the handshake buffer if client authentication isn't required. */
@@ -1027,11 +961,6 @@
ret = 1;
- if (0) {
- f_err:
- ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
- }
-
err:
SSL_SESSION_free(session);
return ret;
@@ -1094,48 +1023,48 @@
static int ssl3_send_server_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (!ssl_has_certificate(ssl)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
- return -1;
- }
-
- if (!ssl3_output_cert_chain(ssl)) {
- return -1;
- }
- return 1;
-}
-
-static int ssl3_send_certificate_status(SSL_HANDSHAKE *hs) {
- SSL *const ssl = hs->ssl;
- CBB cbb, body, ocsp_response;
- if (!ssl->method->init_message(ssl, &cbb, &body,
- SSL3_MT_CERTIFICATE_STATUS) ||
- !CBB_add_u8(&body, TLSEXT_STATUSTYPE_ocsp) ||
- !CBB_add_u24_length_prefixed(&body, &ocsp_response) ||
- !CBB_add_bytes(&ocsp_response,
- CRYPTO_BUFFER_data(ssl->cert->ocsp_response),
- CRYPTO_BUFFER_len(ssl->cert->ocsp_response)) ||
- !ssl_add_message_cbb(ssl, &cbb)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- CBB_cleanup(&cbb);
- return -1;
- }
-
- return 1;
-}
-
-static int ssl3_send_server_key_exchange(SSL_HANDSHAKE *hs) {
- SSL *const ssl = hs->ssl;
- CBB cbb, child;
+ int ret = -1;
+ CBB cbb;
CBB_zero(&cbb);
- /* Put together the parameters. */
- if (hs->state == SSL3_ST_SW_KEY_EXCH_A) {
- uint32_t alg_k = hs->new_cipher->algorithm_mkey;
- uint32_t alg_a = hs->new_cipher->algorithm_auth;
+ if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
+ if (!ssl_has_certificate(ssl)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
+ goto err;
+ }
- /* Pre-allocate enough room to comfortably fit an ECDHE public key. */
- if (!CBB_init(&cbb, 128)) {
+ if (!ssl3_output_cert_chain(ssl)) {
+ goto err;
+ }
+
+ if (hs->certificate_status_expected) {
+ CBB body, ocsp_response;
+ if (!ssl->method->init_message(ssl, &cbb, &body,
+ SSL3_MT_CERTIFICATE_STATUS) ||
+ !CBB_add_u8(&body, TLSEXT_STATUSTYPE_ocsp) ||
+ !CBB_add_u24_length_prefixed(&body, &ocsp_response) ||
+ !CBB_add_bytes(&ocsp_response,
+ CRYPTO_BUFFER_data(ssl->cert->ocsp_response),
+ CRYPTO_BUFFER_len(ssl->cert->ocsp_response)) ||
+ !ssl_add_message_cbb(ssl, &cbb)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+ }
+
+ /* Assemble ServerKeyExchange parameters if needed. */
+ uint32_t alg_k = hs->new_cipher->algorithm_mkey;
+ uint32_t alg_a = hs->new_cipher->algorithm_auth;
+ if (ssl_cipher_requires_server_key_exchange(hs->new_cipher) ||
+ ((alg_a & SSL_aPSK) && ssl->psk_identity_hint)) {
+
+ /* Pre-allocate enough room to comfortably fit an ECDHE public key. Prepend
+ * the client and server randoms for the signing transcript. */
+ CBB child;
+ if (!CBB_init(&cbb, SSL3_RANDOM_SIZE * 2 + 128) ||
+ !CBB_add_bytes(&cbb, ssl->s3->client_random, SSL3_RANDOM_SIZE) ||
+ !CBB_add_bytes(&cbb, ssl->s3->server_random, SSL3_RANDOM_SIZE)) {
goto err;
}
@@ -1177,11 +1106,22 @@
}
}
- /* Assemble the message. */
- CBB body;
+ ret = 1;
+
+err:
+ CBB_cleanup(&cbb);
+ return ret;
+}
+
+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,
SSL3_MT_SERVER_KEY_EXCHANGE) ||
- !CBB_add_bytes(&body, hs->server_params, hs->server_params_len)) {
+ /* |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;
}
@@ -1214,36 +1154,9 @@
}
size_t sig_len;
- enum ssl_private_key_result_t sign_result;
- if (hs->state == SSL3_ST_SW_KEY_EXCH_A) {
- CBB transcript;
- uint8_t *transcript_data;
- size_t transcript_len;
- if (!CBB_init(&transcript,
- 2 * SSL3_RANDOM_SIZE + hs->server_params_len) ||
- !CBB_add_bytes(&transcript, ssl->s3->client_random,
- SSL3_RANDOM_SIZE) ||
- !CBB_add_bytes(&transcript, ssl->s3->server_random,
- SSL3_RANDOM_SIZE) ||
- !CBB_add_bytes(&transcript, hs->server_params,
- hs->server_params_len) ||
- !CBB_finish(&transcript, &transcript_data, &transcript_len)) {
- CBB_cleanup(&transcript);
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- goto err;
- }
-
- sign_result = ssl_private_key_sign(ssl, ptr, &sig_len, max_sig_len,
- signature_algorithm, transcript_data,
- transcript_len);
- OPENSSL_free(transcript_data);
- } else {
- assert(hs->state == SSL3_ST_SW_KEY_EXCH_B);
- sign_result = ssl_private_key_complete(ssl, ptr, &sig_len, max_sig_len);
- }
-
- switch (sign_result) {
+ switch (ssl_private_key_sign(hs, ptr, &sig_len, max_sig_len,
+ signature_algorithm, hs->server_params,
+ hs->server_params_len)) {
case ssl_private_key_success:
if (!CBB_did_write(&child, sig_len)) {
goto err;
@@ -1253,7 +1166,6 @@
goto err;
case ssl_private_key_retry:
ssl->rwstate = SSL_PRIVATE_KEY_OPERATION;
- hs->state = SSL3_ST_SW_KEY_EXCH_B;
goto err;
}
}
@@ -1273,26 +1185,28 @@
return -1;
}
-static int ssl3_send_certificate_request(SSL_HANDSHAKE *hs) {
+static int ssl3_send_server_hello_done(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- CBB cbb, body, cert_types, sigalgs_cbb;
- if (!ssl->method->init_message(ssl, &cbb, &body,
- SSL3_MT_CERTIFICATE_REQUEST) ||
- !CBB_add_u8_length_prefixed(&body, &cert_types) ||
- !CBB_add_u8(&cert_types, SSL3_CT_RSA_SIGN) ||
- (ssl->version >= TLS1_VERSION &&
- !CBB_add_u8(&cert_types, TLS_CT_ECDSA_SIGN))) {
- goto err;
- }
+ CBB cbb, body;
- if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
- if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb) ||
- !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb)) {
+ if (hs->cert_request) {
+ CBB cert_types, sigalgs_cbb;
+ if (!ssl->method->init_message(ssl, &cbb, &body,
+ SSL3_MT_CERTIFICATE_REQUEST) ||
+ !CBB_add_u8_length_prefixed(&body, &cert_types) ||
+ !CBB_add_u8(&cert_types, SSL3_CT_RSA_SIGN) ||
+ (ssl3_protocol_version(ssl) >= TLS1_VERSION &&
+ !CBB_add_u8(&cert_types, TLS_CT_ECDSA_SIGN)) ||
+ (ssl3_protocol_version(ssl) >= TLS1_2_VERSION &&
+ (!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;
}
}
- if (!ssl_add_client_CA_list(ssl, &body) ||
+ if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO_DONE) ||
!ssl_add_message_cbb(ssl, &cbb)) {
goto err;
}
@@ -1305,19 +1219,6 @@
return -1;
}
-static int ssl3_send_server_hello_done(SSL_HANDSHAKE *hs) {
- SSL *const ssl = hs->ssl;
- CBB cbb, body;
- if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO_DONE) ||
- !ssl_add_message_cbb(ssl, &cbb)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- CBB_cleanup(&cbb);
- return -1;
- }
-
- return 1;
-}
-
static int ssl3_get_client_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
assert(hs->cert_request);
@@ -1417,34 +1318,27 @@
static int ssl3_get_client_key_exchange(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- int al;
CBS client_key_exchange;
- uint32_t alg_k;
- uint32_t alg_a;
uint8_t *premaster_secret = NULL;
size_t premaster_secret_len = 0;
uint8_t *decrypt_buf = NULL;
- unsigned psk_len = 0;
- uint8_t psk[PSK_MAX_PSK_LEN];
-
if (hs->state == SSL3_ST_SR_KEY_EXCH_A) {
int ret = ssl->method->ssl_get_message(ssl);
if (ret <= 0) {
return ret;
}
+ }
- if (!ssl_check_message_type(ssl, SSL3_MT_CLIENT_KEY_EXCHANGE) ||
- !ssl_hash_current_message(hs)) {
- return -1;
- }
+ if (!ssl_check_message_type(ssl, SSL3_MT_CLIENT_KEY_EXCHANGE)) {
+ return -1;
}
CBS_init(&client_key_exchange, ssl->init_msg, ssl->init_num);
- alg_k = hs->new_cipher->algorithm_mkey;
- alg_a = hs->new_cipher->algorithm_auth;
+ uint32_t alg_k = hs->new_cipher->algorithm_mkey;
+ uint32_t alg_a = hs->new_cipher->algorithm_auth;
- /* If using a PSK key exchange, prepare the pre-shared key. */
+ /* If using a PSK key exchange, parse the PSK identity. */
if (alg_a & SSL_aPSK) {
CBS psk_identity;
@@ -1453,47 +1347,40 @@
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);
- al = SSL_AD_DECODE_ERROR;
- goto f_err;
- }
-
- if (ssl->psk_server_callback == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_SERVER_CB);
- al = SSL_AD_INTERNAL_ERROR;
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ goto 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);
- al = SSL_AD_ILLEGAL_PARAMETER;
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ goto err;
}
if (!CBS_strdup(&psk_identity, &hs->new_session->psk_identity)) {
- al = SSL_AD_INTERNAL_ERROR;
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto f_err;
- }
-
- /* Look up the key for the identity. */
- psk_len = ssl->psk_server_callback(ssl, hs->new_session->psk_identity, psk,
- sizeof(psk));
- if (psk_len > PSK_MAX_PSK_LEN) {
- 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, SSL_R_PSK_IDENTITY_NOT_FOUND);
- al = SSL_AD_UNKNOWN_PSK_IDENTITY;
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ goto err;
}
}
/* Depending on the key exchange method, compute |premaster_secret| and
* |premaster_secret_len|. */
if (alg_k & SSL_kRSA) {
+ CBS encrypted_premaster_secret;
+ if (ssl->version > SSL3_VERSION) {
+ if (!CBS_get_u16_length_prefixed(&client_key_exchange,
+ &encrypted_premaster_secret) ||
+ CBS_len(&client_key_exchange) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ goto err;
+ }
+ } else {
+ encrypted_premaster_secret = client_key_exchange;
+ }
+
/* Allocate a buffer large enough for an RSA decryption. */
const size_t rsa_size = EVP_PKEY_size(hs->local_pubkey);
decrypt_buf = OPENSSL_malloc(rsa_size);
@@ -1502,43 +1389,12 @@
goto err;
}
- enum ssl_private_key_result_t decrypt_result;
+ /* Decrypt with no padding. PKCS#1 padding will be removed as part of the
+ * timing-sensitive code below. */
size_t decrypt_len;
- if (hs->state == SSL3_ST_SR_KEY_EXCH_A) {
- if (!ssl_has_private_key(ssl) ||
- EVP_PKEY_id(hs->local_pubkey) != EVP_PKEY_RSA) {
- al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_RSA_CERTIFICATE);
- goto f_err;
- }
- CBS encrypted_premaster_secret;
- if (ssl->version > SSL3_VERSION) {
- if (!CBS_get_u16_length_prefixed(&client_key_exchange,
- &encrypted_premaster_secret) ||
- CBS_len(&client_key_exchange) != 0) {
- al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL,
- SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
- goto f_err;
- }
- } else {
- encrypted_premaster_secret = client_key_exchange;
- }
-
- /* Decrypt with no padding. PKCS#1 padding will be removed as part of the
- * timing-sensitive code below. */
- decrypt_result = ssl_private_key_decrypt(
- ssl, decrypt_buf, &decrypt_len, rsa_size,
- CBS_data(&encrypted_premaster_secret),
- CBS_len(&encrypted_premaster_secret));
- } else {
- assert(hs->state == SSL3_ST_SR_KEY_EXCH_B);
- /* Complete async decrypt. */
- decrypt_result =
- ssl_private_key_complete(ssl, decrypt_buf, &decrypt_len, rsa_size);
- }
-
- switch (decrypt_result) {
+ switch (ssl_private_key_decrypt(hs, decrypt_buf, &decrypt_len, rsa_size,
+ CBS_data(&encrypted_premaster_secret),
+ CBS_len(&encrypted_premaster_secret))) {
case ssl_private_key_success:
break;
case ssl_private_key_failure:
@@ -1550,9 +1406,9 @@
}
if (decrypt_len != rsa_size) {
- al = SSL_AD_DECRYPT_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
+ goto err;
}
/* Prepare a random premaster, to be used on invalid padding. See RFC 5246,
@@ -1570,9 +1426,9 @@
/* The smallest padded premaster is 11 bytes of overhead. Small keys are
* publicly invalid. */
if (decrypt_len < 11 + premaster_secret_len) {
- al = SSL_AD_DECRYPT_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
+ goto err;
}
/* Check the padding. See RFC 3447, section 7.2.2. */
@@ -1605,9 +1461,9 @@
CBS peer_key;
if (!CBS_get_u8_length_prefixed(&client_key_exchange, &peer_key) ||
CBS_len(&client_key_exchange) != 0) {
- al = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ goto err;
}
/* Compute the premaster. */
@@ -1615,35 +1471,57 @@
if (!SSL_ECDH_CTX_finish(&hs->ecdh_ctx, &premaster_secret,
&premaster_secret_len, &alert, CBS_data(&peer_key),
CBS_len(&peer_key))) {
- al = alert;
- goto f_err;
+ 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);
- } else if (alg_k & SSL_kPSK) {
- /* For plain PSK, other_secret is a block of 0s with the same length as the
- * pre-shared key. */
- premaster_secret_len = psk_len;
- premaster_secret = OPENSSL_malloc(premaster_secret_len);
- if (premaster_secret == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- OPENSSL_memset(premaster_secret, 0, premaster_secret_len);
- } else {
- al = SSL_AD_HANDSHAKE_FAILURE;
+ } else if (!(alg_k & SSL_kPSK)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_TYPE);
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ goto err;
}
/* For a PSK cipher suite, the actual pre-master secret is combined with the
* pre-shared key. */
if (alg_a & SSL_aPSK) {
+ if (ssl->psk_server_callback == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_SERVER_CB);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ goto err;
+ }
+
+ /* Look up the key for the identity. */
+ uint8_t psk[PSK_MAX_PSK_LEN];
+ unsigned psk_len = ssl->psk_server_callback(
+ ssl, hs->new_session->psk_identity, psk, sizeof(psk));
+ if (psk_len > PSK_MAX_PSK_LEN) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ goto err;
+ } else if (psk_len == 0) {
+ /* PSK related to the given identity not found */
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNKNOWN_PSK_IDENTITY);
+ goto err;
+ }
+
+ if (alg_k & SSL_kPSK) {
+ /* In plain PSK, other_secret is a block of 0s with the same length as the
+ * pre-shared key. */
+ premaster_secret_len = psk_len;
+ premaster_secret = OPENSSL_malloc(premaster_secret_len);
+ if (premaster_secret == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ OPENSSL_memset(premaster_secret, 0, premaster_secret_len);
+ }
+
CBB new_premaster, 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) ||
@@ -1662,6 +1540,10 @@
premaster_secret_len = new_len;
}
+ if (!ssl_hash_current_message(hs)) {
+ goto err;
+ }
+
/* Compute the master secret */
hs->new_session->master_key_length = tls1_generate_master_secret(
hs, hs->new_session->master_key, premaster_secret, premaster_secret_len);
@@ -1674,8 +1556,6 @@
OPENSSL_free(premaster_secret);
return 1;
-f_err:
- ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
err:
if (premaster_secret != NULL) {
OPENSSL_cleanse(premaster_secret, premaster_secret_len);
@@ -1688,7 +1568,6 @@
static int ssl3_get_cert_verify(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- int al;
CBS certificate_verify, signature;
/* Only RSA and ECDSA client certificates are supported, so a
@@ -1714,27 +1593,29 @@
uint16_t signature_algorithm = 0;
if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
if (!CBS_get_u16(&certificate_verify, &signature_algorithm)) {
- al = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return -1;
}
- if (!tls12_check_peer_sigalg(ssl, &al, signature_algorithm)) {
- goto f_err;
+ uint8_t alert = SSL_AD_DECODE_ERROR;
+ if (!tls12_check_peer_sigalg(ssl, &alert, signature_algorithm)) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ return -1;
}
hs->new_session->peer_signature_algorithm = signature_algorithm;
} else if (!tls1_get_legacy_signature_algorithm(&signature_algorithm,
hs->peer_pubkey)) {
- al = SSL_AD_UNSUPPORTED_CERTIFICATE;
OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_CERTIFICATE);
+ return -1;
}
/* Parse and verify the signature. */
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);
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return -1;
}
int sig_ok;
@@ -1746,7 +1627,7 @@
if (!SSL_TRANSCRIPT_ssl3_cert_verify_hash(&hs->transcript, digest,
&digest_len, hs->new_session,
signature_algorithm)) {
- goto err;
+ return -1;
}
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(hs->peer_pubkey, NULL);
@@ -1767,24 +1648,19 @@
ERR_clear_error();
#endif
if (!sig_ok) {
- al = SSL_AD_DECRYPT_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
- goto f_err;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
+ return -1;
}
/* The handshake buffer is no longer necessary, and we may hash the current
* message.*/
SSL_TRANSCRIPT_free_buffer(&hs->transcript);
if (!ssl_hash_current_message(hs)) {
- goto err;
+ return -1;
}
return 1;
-
-f_err:
- ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
-err:
- return 0;
}
/* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It
@@ -1835,40 +1711,46 @@
return 1;
}
-static int ssl3_send_new_session_ticket(SSL_HANDSHAKE *hs) {
+static int ssl3_send_server_finished(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- const SSL_SESSION *session;
- SSL_SESSION *session_copy = NULL;
- 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;
- } 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) {
- return -1;
+
+ if (hs->ticket_expected) {
+ const SSL_SESSION *session;
+ SSL_SESSION *session_copy = NULL;
+ 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;
+ } 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) {
+ return -1;
+ }
+
+ ssl_session_rebase_time(ssl, session_copy);
+ session = session_copy;
}
- ssl_session_rebase_time(ssl, session_copy);
- session = session_copy;
+ 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) {
+ return -1;
+ }
}
- 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) {
+ if (!ssl->method->add_change_cipher_spec(ssl) ||
+ !tls1_change_cipher_state(hs, SSL3_CHANGE_CIPHER_SERVER_WRITE)) {
return -1;
}
- return 1;
+ return ssl3_send_finished(hs);
}