Browse Source

Switch handshake_client and handshake_server to C++.

Bug: 132
Change-Id: Ic68252de7b3a8f90d60f052a3cb707730d5a2b16
Reviewed-on: https://boringssl-review.googlesource.com/17744
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
kris/onging/CECPQ3_patch15
David Benjamin 7 years ago
parent
commit
d781fc424b
3 changed files with 83 additions and 99 deletions
  1. +2
    -2
      ssl/CMakeLists.txt
  2. +35
    -41
      ssl/handshake_client.cc
  3. +46
    -56
      ssl/handshake_server.cc

+ 2
- 2
ssl/CMakeLists.txt View File

@@ -11,8 +11,8 @@ add_library(
d1_srtp.cc
dtls_method.cc
dtls_record.cc
handshake_client.c
handshake_server.c
handshake_client.cc
handshake_server.cc
s3_both.cc
s3_lib.cc
s3_pkt.cc


ssl/handshake_client.c → ssl/handshake_client.cc View File

@@ -647,9 +647,10 @@ static int ssl_write_client_cipher_list(SSL_HANDSHAKE *hs, CBB *out) {

int ssl_write_client_hello(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
CBB cbb, body;
if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CLIENT_HELLO)) {
goto err;
bssl::ScopedCBB cbb;
CBB body;
if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO)) {
return 0;
}

/* Renegotiations do not participate in session resumption. */
@@ -661,13 +662,13 @@ int ssl_write_client_hello(SSL_HANDSHAKE *hs) {
if (!CBB_add_u16(&body, hs->client_version) ||
!CBB_add_bytes(&body, ssl->s3->client_random, SSL3_RANDOM_SIZE) ||
!CBB_add_u8_length_prefixed(&body, &child)) {
goto err;
return 0;
}

if (has_session_id) {
if (!CBB_add_bytes(&child, ssl->session->session_id,
ssl->session->session_id_length)) {
goto err;
return 0;
}
} else {
/* In TLS 1.3 experimental encodings, send a fake placeholder session ID
@@ -675,14 +676,14 @@ int ssl_write_client_hello(SSL_HANDSHAKE *hs) {
if (hs->max_version >= TLS1_3_VERSION &&
ssl->tls13_variant != tls13_default &&
!CBB_add_bytes(&child, hs->session_id, hs->session_id_len)) {
goto err;
return 0;
}
}

if (SSL_is_dtls(ssl)) {
if (!CBB_add_u8_length_prefixed(&body, &child) ||
!CBB_add_bytes(&child, ssl->d1->cookie, ssl->d1->cookie_len)) {
goto err;
return 0;
}
}

@@ -692,13 +693,13 @@ int ssl_write_client_hello(SSL_HANDSHAKE *hs) {
!CBB_add_u8(&body, 1 /* one compression method */) ||
!CBB_add_u8(&body, 0 /* null compression */) ||
!ssl_add_clienthello_tlsext(hs, &body, header_len + CBB_len(&body))) {
goto err;
return 0;
}

uint8_t *msg = NULL;
size_t len;
if (!ssl->method->finish_message(ssl, &cbb, &msg, &len)) {
goto err;
if (!ssl->method->finish_message(ssl, cbb.get(), &msg, &len)) {
return 0;
}

/* Now that the length prefixes have been computed, fill in the placeholder
@@ -706,14 +707,10 @@ int ssl_write_client_hello(SSL_HANDSHAKE *hs) {
if (hs->needs_psk_binder &&
!tls13_write_psk_binder(hs, msg, len)) {
OPENSSL_free(msg);
goto err;
return 0;
}

return ssl->method->add_message(ssl, msg, len);

err:
CBB_cleanup(&cbb);
return 0;
}

static int ssl3_send_client_hello(SSL_HANDSHAKE *hs) {
@@ -1498,14 +1495,15 @@ OPENSSL_COMPILE_ASSERT(sizeof(size_t) >= sizeof(unsigned),

static int ssl3_send_client_key_exchange(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
uint8_t *pms = NULL;
size_t pms_len = 0;
CBB cbb, body;
if (!ssl->method->init_message(ssl, &cbb, &body,
bssl::ScopedCBB cbb;
CBB body;
if (!ssl->method->init_message(ssl, cbb.get(), &body,
SSL3_MT_CLIENT_KEY_EXCHANGE)) {
goto err;
return -1;
}

uint8_t *pms = NULL;
size_t pms_len = 0;
uint32_t alg_k = hs->new_cipher->algorithm_mkey;
uint32_t alg_a = hs->new_cipher->algorithm_auth;

@@ -1550,7 +1548,7 @@ static int ssl3_send_client_key_exchange(SSL_HANDSHAKE *hs) {
/* Depending on the key exchange method, compute |pms| and |pms_len|. */
if (alg_k & SSL_kRSA) {
pms_len = SSL_MAX_MASTER_KEY_LENGTH;
pms = OPENSSL_malloc(pms_len);
pms = (uint8_t *)OPENSSL_malloc(pms_len);
if (pms == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
@@ -1613,7 +1611,7 @@ static int ssl3_send_client_key_exchange(SSL_HANDSHAKE *hs) {
/* For plain PSK, other_secret is a block of 0s with the same length as
* the pre-shared key. */
pms_len = psk_len;
pms = OPENSSL_malloc(pms_len);
pms = (uint8_t *)OPENSSL_malloc(pms_len);
if (pms == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
@@ -1651,7 +1649,7 @@ static int ssl3_send_client_key_exchange(SSL_HANDSHAKE *hs) {

/* The message must be added to the finished hash before calculating the
* master secret. */
if (!ssl_add_message_cbb(ssl, &cbb)) {
if (!ssl_add_message_cbb(ssl, cbb.get())) {
goto err;
}

@@ -1667,7 +1665,6 @@ static int ssl3_send_client_key_exchange(SSL_HANDSHAKE *hs) {
return 1;

err:
CBB_cleanup(&cbb);
if (pms != NULL) {
OPENSSL_cleanse(pms, pms_len);
OPENSSL_free(pms);
@@ -1679,21 +1676,22 @@ static int ssl3_send_cert_verify(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
assert(ssl_has_private_key(ssl));

CBB cbb, body, child;
if (!ssl->method->init_message(ssl, &cbb, &body,
bssl::ScopedCBB cbb;
CBB body, child;
if (!ssl->method->init_message(ssl, cbb.get(), &body,
SSL3_MT_CERTIFICATE_VERIFY)) {
goto err;
return -1;
}

uint16_t signature_algorithm;
if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) {
goto err;
return -1;
}
if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
/* Write out the digest type in TLS 1.2. */
if (!CBB_add_u16(&body, signature_algorithm)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
return -1;
}
}

@@ -1702,7 +1700,7 @@ static int ssl3_send_cert_verify(SSL_HANDSHAKE *hs) {
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 = max_sig_len;
@@ -1711,7 +1709,7 @@ static int ssl3_send_cert_verify(SSL_HANDSHAKE *hs) {
if (ssl3_protocol_version(ssl) == SSL3_VERSION) {
if (ssl->cert->key_method != NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY);
goto err;
return -1;
}

uint8_t digest[EVP_MAX_MD_SIZE];
@@ -1719,7 +1717,7 @@ static int ssl3_send_cert_verify(SSL_HANDSHAKE *hs) {
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(ssl->cert->privatekey, NULL);
@@ -1728,7 +1726,7 @@ static int ssl3_send_cert_verify(SSL_HANDSHAKE *hs) {
EVP_PKEY_sign(pctx, ptr, &sig_len, digest, digest_len);
EVP_PKEY_CTX_free(pctx);
if (!ok) {
goto err;
return -1;
}
} else {
switch (ssl_private_key_sign(hs, ptr, &sig_len, max_sig_len,
@@ -1738,25 +1736,21 @@ static int ssl3_send_cert_verify(SSL_HANDSHAKE *hs) {
case ssl_private_key_success:
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 (!CBB_did_write(&child, sig_len) ||
!ssl_add_message_cbb(ssl, &cbb)) {
goto err;
!ssl_add_message_cbb(ssl, cbb.get())) {
return -1;
}

/* The handshake buffer is no longer necessary. */
SSL_TRANSCRIPT_free_buffer(&hs->transcript);
return 1;

err:
CBB_cleanup(&cbb);
return -1;
}

static int ssl3_send_next_proto(SSL_HANDSHAKE *hs) {

ssl/handshake_server.c → ssl/handshake_server.cc View File

@@ -800,9 +800,6 @@ static int ssl3_select_certificate(SSL_HANDSHAKE *hs) {

static int ssl3_select_parameters(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
int ret = -1;
SSL_SESSION *session = NULL;

SSL_CLIENT_HELLO client_hello;
if (!ssl_client_hello_init(ssl, &client_hello, ssl->init_msg,
ssl->init_num)) {
@@ -811,49 +808,52 @@ static int ssl3_select_parameters(SSL_HANDSHAKE *hs) {

/* Determine whether we are doing session resumption. */
int tickets_supported = 0, renew_ticket = 0;
switch (ssl_get_prev_session(ssl, &session, &tickets_supported, &renew_ticket,
&client_hello)) {
/* TODO(davidben): Switch |ssl_get_prev_session| to take a |bssl::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);
switch (session_ret) {
case ssl_session_success:
break;
case ssl_session_error:
goto err;
return -1;
case ssl_session_retry:
ssl->rwstate = SSL_PENDING_SESSION;
goto err;
return -1;
case ssl_session_ticket_retry:
ssl->rwstate = SSL_PENDING_TICKET;
goto err;
return -1;
}

if (session != NULL) {
if (session) {
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. */
OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
goto err;
return -1;
}

if (!ssl_session_is_resumable(hs, session) ||
if (!ssl_session_is_resumable(hs, session.get()) ||
/* If the client offers the EMS extension, but the previous session
* didn't use it, then negotiate a new session. */
hs->extended_master_secret != session->extended_master_secret) {
SSL_SESSION_free(session);
session = NULL;
session.reset();
}
}

if (session != NULL) {
if (session) {
/* Use the old session. */
hs->ticket_expected = renew_ticket;
ssl->session = session;
session = NULL;
ssl->session = session.release();
ssl->s3->session_reused = 1;
} else {
hs->ticket_expected = tickets_supported;
ssl_set_session(ssl, NULL);
if (!ssl_get_new_session(hs, 1 /* server */)) {
goto err;
return -1;
}

/* Clear the session ID if we want the session to be single-use. */
@@ -867,7 +867,7 @@ static int ssl3_select_parameters(SSL_HANDSHAKE *hs) {
/* Connection rejected for DOS reasons. */
OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
goto err;
return -1;
}

if (ssl->session == NULL) {
@@ -879,7 +879,7 @@ static int ssl3_select_parameters(SSL_HANDSHAKE *hs) {
hs->new_session->tlsext_hostname = BUF_strdup(hs->hostname);
if (hs->new_session->tlsext_hostname == NULL) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
goto err;
return -1;
}
}

@@ -907,7 +907,7 @@ static int ssl3_select_parameters(SSL_HANDSHAKE *hs) {
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;
return -1;
}

/* Now that all parameters are known, initialize the handshake hash and hash
@@ -916,7 +916,7 @@ static int ssl3_select_parameters(SSL_HANDSHAKE *hs) {
hs->new_cipher->algorithm_prf) ||
!ssl_hash_current_message(hs)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
goto err;
return -1;
}

/* Release the handshake buffer if client authentication isn't required. */
@@ -924,11 +924,7 @@ static int ssl3_select_parameters(SSL_HANDSHAKE *hs) {
SSL_TRANSCRIPT_free_buffer(&hs->transcript);
}

ret = 1;

err:
SSL_SESSION_free(session);
return ret;
return 1;
}

static int ssl3_send_server_hello(SSL_HANDSHAKE *hs) {
@@ -988,32 +984,30 @@ static int ssl3_send_server_hello(SSL_HANDSHAKE *hs) {

static int ssl3_send_server_certificate(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
int ret = -1;
CBB cbb;
CBB_zero(&cbb);
bssl::ScopedCBB cbb;

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;
return -1;
}

if (!ssl3_output_cert_chain(ssl)) {
goto err;
return -1;
}

if (hs->certificate_status_expected) {
CBB body, ocsp_response;
if (!ssl->method->init_message(ssl, &cbb, &body,
if (!ssl->method->init_message(ssl, cbb.get(), &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)) {
!ssl_add_message_cbb(ssl, cbb.get())) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
return -1;
}
}
}
@@ -1027,20 +1021,20 @@ static int ssl3_send_server_certificate(SSL_HANDSHAKE *hs) {
/* 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;
if (!CBB_init(cbb.get(), SSL3_RANDOM_SIZE * 2 + 128) ||
!CBB_add_bytes(cbb.get(), ssl->s3->client_random, SSL3_RANDOM_SIZE) ||
!CBB_add_bytes(cbb.get(), ssl->s3->server_random, SSL3_RANDOM_SIZE)) {
return -1;
}

/* PSK ciphers begin with an identity hint. */
if (alg_a & SSL_aPSK) {
size_t len =
(ssl->psk_identity_hint == NULL) ? 0 : strlen(ssl->psk_identity_hint);
if (!CBB_add_u16_length_prefixed(&cbb, &child) ||
if (!CBB_add_u16_length_prefixed(cbb.get(), &child) ||
!CBB_add_bytes(&child, (const uint8_t *)ssl->psk_identity_hint,
len)) {
goto err;
return -1;
}
}

@@ -1050,32 +1044,28 @@ static int ssl3_send_server_certificate(SSL_HANDSHAKE *hs) {
if (!tls1_get_shared_group(hs, &group_id)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
goto err;
}
return -1;
}
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) ||
!CBB_add_u8(&cbb, NAMED_CURVE_TYPE) ||
!CBB_add_u16(&cbb, group_id) ||
!CBB_add_u8_length_prefixed(&cbb, &child) ||
!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)) {
goto err;
return -1;
}
} else {
assert(alg_k & SSL_kPSK);
}

if (!CBB_finish(&cbb, &hs->server_params, &hs->server_params_len)) {
goto err;
if (!CBB_finish(cbb.get(), &hs->server_params, &hs->server_params_len)) {
return -1;
}
}

ret = 1;

err:
CBB_cleanup(&cbb);
return ret;
return 1;
}

static int ssl3_send_server_key_exchange(SSL_HANDSHAKE *hs) {
@@ -1348,7 +1338,7 @@ static int ssl3_get_client_key_exchange(SSL_HANDSHAKE *hs) {

/* 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);
decrypt_buf = (uint8_t *)OPENSSL_malloc(rsa_size);
if (decrypt_buf == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
@@ -1379,7 +1369,7 @@ static int ssl3_get_client_key_exchange(SSL_HANDSHAKE *hs) {
/* Prepare a random premaster, to be used on invalid padding. See RFC 5246,
* section 7.4.7.1. */
premaster_secret_len = SSL_MAX_MASTER_KEY_LENGTH;
premaster_secret = OPENSSL_malloc(premaster_secret_len);
premaster_secret = (uint8_t *)OPENSSL_malloc(premaster_secret_len);
if (premaster_secret == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
@@ -1476,7 +1466,7 @@ static int ssl3_get_client_key_exchange(SSL_HANDSHAKE *hs) {
/* 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);
premaster_secret = (uint8_t *)OPENSSL_malloc(premaster_secret_len);
if (premaster_secret == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;

Loading…
Cancel
Save