From e99801b603dea8893dcc61c70b327ef2d00b652c Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Fri, 6 Nov 2015 15:31:15 -0800 Subject: Revert "Revert "external/boringssl: sync with upstream."" This reverts commit 03bcf618b7ed811b305845461fbb5497dfe55ac3. No changes here. trusty build was fixed with the required rules.mk changes. --- src/ssl/s3_clnt.c | 436 +++++++++++++++++++++++++++--------------------------- 1 file changed, 219 insertions(+), 217 deletions(-) (limited to 'src/ssl/s3_clnt.c') diff --git a/src/ssl/s3_clnt.c b/src/ssl/s3_clnt.c index 559db72..13bc0e8 100644 --- a/src/ssl/s3_clnt.c +++ b/src/ssl/s3_clnt.c @@ -1,4 +1,3 @@ -/* ssl/s3_clnt.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -175,7 +174,7 @@ int ssl3_connect(SSL *s) { BUF_MEM *buf = NULL; - void (*cb)(const SSL *ssl, int type, int val) = NULL; + void (*cb)(const SSL *ssl, int type, int value) = NULL; int ret = -1; int new_state, state, skip = 0; @@ -589,140 +588,140 @@ end: return ret; } -int ssl3_send_client_hello(SSL *s) { - uint8_t *buf, *p, *d; - int i; - unsigned long l; - - buf = (uint8_t *)s->init_buf->data; - if (s->state == SSL3_ST_CW_CLNT_HELLO_A) { - if (!s->s3->have_version) { - uint16_t max_version = ssl3_get_max_client_version(s); - /* Disabling all versions is silly: return an error. */ - if (max_version == 0) { - OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION); - goto err; - } - s->version = max_version; - s->client_version = max_version; - } +static int ssl3_write_client_cipher_list(SSL *ssl, CBB *out) { + /* Prepare disabled cipher masks. */ + ssl_set_client_disabled(ssl); - /* If the configured session was created at a version higher than our - * maximum version, drop it. */ - if (s->session && - (s->session->session_id_length == 0 || s->session->not_resumable || - (!SSL_IS_DTLS(s) && s->session->ssl_version > s->version) || - (SSL_IS_DTLS(s) && s->session->ssl_version < s->version))) { - SSL_set_session(s, NULL); - } + CBB child; + if (!CBB_add_u16_length_prefixed(out, &child)) { + return 0; + } - /* else use the pre-loaded session */ - p = s->s3->client_random; + STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(ssl); - /* 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(p, sizeof(s->s3->client_random), - 0 /* client */)) { - goto err; + int any_enabled = 0; + size_t i; + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i); + /* Skip disabled ciphers */ + if (cipher->algorithm_ssl & ssl->cert->mask_ssl || + cipher->algorithm_mkey & ssl->cert->mask_k || + cipher->algorithm_auth & ssl->cert->mask_a) { + continue; } + any_enabled = 1; + if (!CBB_add_u16(&child, ssl_cipher_get_value(cipher))) { + return 0; + } + } - /* Do the message type and length last. Note: the final argument to - * ssl_add_clienthello_tlsext below depends on the size of this prefix. */ - d = p = ssl_handshake_start(s); + /* If all ciphers were disabled, return the error to the caller. */ + if (!any_enabled) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_AVAILABLE); + return 0; + } - /* version indicates the negotiated version: for example from an SSLv2/v3 - * compatible client hello). The client_version field is the maximum - * version we permit and it is also used in RSA encrypted premaster - * secrets. Some servers can choke if we initially report a higher version - * then renegotiate to a lower one in the premaster secret. This didn't - * happen with TLS 1.0 as most servers supported it but it can with TLS 1.1 - * or later if the server only supports 1.0. - * - * Possible scenario with previous logic: - * 1. Client hello indicates TLS 1.2 - * 2. Server hello says TLS 1.0 - * 3. RSA encrypted premaster secret uses 1.2. - * 4. Handhaked proceeds using TLS 1.0. - * 5. Server sends hello request to renegotiate. - * 6. Client hello indicates TLS v1.0 as we now - * know that is maximum server supports. - * 7. Server chokes on RSA encrypted premaster secret - * containing version 1.0. - * - * For interoperability it should be OK to always use the maximum version - * we support in client hello and then rely on the checking of version to - * ensure the servers isn't being inconsistent: for example initially - * negotiating with TLS 1.0 and renegotiating with TLS 1.2. We do this by - * using client_version in client hello and not resetting it to the - * negotiated version. */ - *(p++) = s->client_version >> 8; - *(p++) = s->client_version & 0xff; - - /* Random stuff */ - memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); - p += SSL3_RANDOM_SIZE; - - /* Session ID */ - if (s->s3->initial_handshake_complete || s->session == NULL) { - /* Renegotiations do not participate in session resumption. */ - i = 0; - } else { - i = s->session->session_id_length; - } - *(p++) = i; - if (i != 0) { - if (i > (int)sizeof(s->session->session_id)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - goto err; - } - memcpy(p, s->session->session_id, i); - p += i; + /* For SSLv3, the SCSV is added. Otherwise the renegotiation extension is + * added. */ + if (ssl->client_version == SSL3_VERSION && + !ssl->s3->initial_handshake_complete) { + if (!CBB_add_u16(&child, SSL3_CK_SCSV & 0xffff)) { + return 0; } + /* The renegotiation extension is required to be at index zero. */ + ssl->s3->tmp.extensions.sent |= (1u << 0); + } - /* cookie stuff for DTLS */ - if (SSL_IS_DTLS(s)) { - if (s->d1->cookie_len > sizeof(s->d1->cookie)) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); - goto err; - } - *(p++) = s->d1->cookie_len; - memcpy(p, s->d1->cookie, s->d1->cookie_len); - p += s->d1->cookie_len; - } + if ((ssl->mode & SSL_MODE_SEND_FALLBACK_SCSV) && + !CBB_add_u16(&child, SSL3_CK_FALLBACK_SCSV & 0xffff)) { + return 0; + } - /* Ciphers supported */ - i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]); - if (i == 0) { - OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_AVAILABLE); - goto err; - } - s2n(i, p); - p += i; + return CBB_flush(out); +} - /* COMPRESSION */ - *(p++) = 1; - *(p++) = 0; /* Add the NULL method */ +int ssl3_send_client_hello(SSL *ssl) { + if (ssl->state == SSL3_ST_CW_CLNT_HELLO_B) { + return ssl_do_write(ssl); + } - /* TLS extensions*/ - p = ssl_add_clienthello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH, - p - buf); - if (p == NULL) { - OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + CBB cbb; + CBB_zero(&cbb); + + assert(ssl->state == SSL3_ST_CW_CLNT_HELLO_A); + if (!ssl->s3->have_version) { + uint16_t max_version = ssl3_get_max_client_version(ssl); + /* Disabling all versions is silly: return an error. */ + if (max_version == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION); goto err; } - l = p - d; - if (!ssl_set_handshake_header(s, SSL3_MT_CLIENT_HELLO, l)) { + ssl->version = max_version; + /* Only set |ssl->client_version| on the initial handshake. Renegotiations, + * although locked to a version, reuse the value. When using the plain RSA + * key exchange, the ClientHello version is checked in the premaster secret. + * Some servers fail when this value changes. */ + ssl->client_version = max_version; + } + + /* If the configured session has expired or was created at a version higher + * than our maximum version, drop it. */ + if (ssl->session != NULL && + (ssl->session->session_id_length == 0 || ssl->session->not_resumable || + ssl->session->timeout < (long)(time(NULL) - ssl->session->time) || + (!SSL_IS_DTLS(ssl) && ssl->session->ssl_version > ssl->version) || + (SSL_IS_DTLS(ssl) && ssl->session->ssl_version < ssl->version))) { + SSL_set_session(ssl, NULL); + } + + /* If resending the ClientHello in DTLS after a HelloVerifyRequest, don't + * renegerate the client_random. The random must be reused. */ + if ((!SSL_IS_DTLS(ssl) || !ssl->d1->send_cookie) && + !ssl_fill_hello_random(ssl->s3->client_random, + sizeof(ssl->s3->client_random), 0 /* client */)) { + goto err; + } + + /* Renegotiations do not participate in session resumption. */ + int has_session = ssl->session != NULL && + !ssl->s3->initial_handshake_complete; + + CBB child; + if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl), + ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) || + !CBB_add_u16(&cbb, ssl->client_version) || + !CBB_add_bytes(&cbb, ssl->s3->client_random, SSL3_RANDOM_SIZE) || + !CBB_add_u8_length_prefixed(&cbb, &child) || + (has_session && + !CBB_add_bytes(&child, ssl->session->session_id, + ssl->session->session_id_length))) { + goto err; + } + + if (SSL_IS_DTLS(ssl)) { + if (!CBB_add_u8_length_prefixed(&cbb, &child) || + !CBB_add_bytes(&child, ssl->d1->cookie, ssl->d1->cookie_len)) { goto err; } - s->state = SSL3_ST_CW_CLNT_HELLO_B; } - /* SSL3_ST_CW_CLNT_HELLO_B */ - return ssl_do_write(s); + size_t length; + if (!ssl3_write_client_cipher_list(ssl, &cbb) || + !CBB_add_u8(&cbb, 1 /* one compression method */) || + !CBB_add_u8(&cbb, 0 /* null compression */) || + !ssl_add_clienthello_tlsext(ssl, &cbb, + CBB_len(&cbb) + SSL_HM_HEADER_LENGTH(ssl)) || + !CBB_finish(&cbb, NULL, &length) || + !ssl_set_handshake_header(ssl, SSL3_MT_CLIENT_HELLO, length)) { + goto err; + } + + ssl->state = SSL3_ST_CW_CLNT_HELLO_B; + return ssl_do_write(ssl); err: + CBB_cleanup(&cbb); return -1; } @@ -813,7 +812,7 @@ int ssl3_get_server_hello(SSL *s) { /* The session wasn't resumed. Create a fresh SSL_SESSION to * fill out. */ s->hit = 0; - if (!ssl_get_new_session(s, 0)) { + if (!ssl_get_new_session(s, 0 /* client */)) { goto f_err; } /* Note: session_id could be empty. */ @@ -1429,10 +1428,7 @@ err: int ssl3_get_new_session_ticket(SSL *s) { int ok, al; - long n; - CBS new_session_ticket, ticket; - - n = s->method->ssl_get_message( + long 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_hash_message, &ok); @@ -1440,6 +1436,24 @@ int ssl3_get_new_session_ticket(SSL *s) { return n; } + CBS new_session_ticket, ticket; + uint32_t ticket_lifetime_hint; + CBS_init(&new_session_ticket, s->init_msg, n); + if (!CBS_get_u32(&new_session_ticket, &ticket_lifetime_hint) || + !CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) || + CBS_len(&new_session_ticket) != 0) { + al = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + goto f_err; + } + + if (CBS_len(&ticket) == 0) { + /* RFC 5077 allows a server to change its mind and send no ticket after + * negotiating the extension. Behave as if no ticket was sent. */ + s->tlsext_ticket_expected = 0; + return 1; + } + if (s->hit) { /* The server is sending a new ticket for an existing session. Sessions are * immutable once established, so duplicate all but the ticket of the @@ -1461,22 +1475,12 @@ int ssl3_get_new_session_ticket(SSL *s) { s->session = new_session; } - CBS_init(&new_session_ticket, s->init_msg, n); - - if (!CBS_get_u32(&new_session_ticket, - &s->session->tlsext_tick_lifetime_hint) || - !CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) || - CBS_len(&new_session_ticket) != 0) { - al = SSL_AD_DECODE_ERROR; - OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); - goto f_err; - } - if (!CBS_stow(&ticket, &s->session->tlsext_tick, &s->session->tlsext_ticklen)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } + s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint; /* 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 @@ -1562,6 +1566,8 @@ int ssl3_get_server_done(SSL *s) { return 1; } +OPENSSL_COMPILE_ASSERT(sizeof(size_t) >= sizeof(unsigned), + SIZE_T_IS_SMALLER_THAN_UNSIGNED); int ssl3_send_client_key_exchange(SSL *s) { uint8_t *p; @@ -1735,7 +1741,7 @@ int ssl3_send_client_key_exchange(SSL *s) { } else if (alg_k & SSL_kECDHE) { const EC_GROUP *srvr_group = NULL; EC_KEY *tkey; - int field_size = 0, ecdh_len; + int ecdh_len; if (s->s3->tmp.peer_ecdh_tmp == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); @@ -1768,8 +1774,8 @@ int ssl3_send_client_key_exchange(SSL *s) { goto err; } - field_size = EC_GROUP_get_degree(srvr_group); - if (field_size <= 0) { + unsigned field_size = EC_GROUP_get_degree(srvr_group); + if (field_size == 0) { OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB); goto err; } @@ -2068,93 +2074,88 @@ int ssl3_send_client_certificate(SSL *s) { return ssl_do_write(s); } -int ssl3_send_next_proto(SSL *s) { - unsigned int len, padding_len; - uint8_t *d, *p; +int ssl3_send_next_proto(SSL *ssl) { + if (ssl->state == SSL3_ST_CW_NEXT_PROTO_B) { + return ssl_do_write(ssl); + } - if (s->state == SSL3_ST_CW_NEXT_PROTO_A) { - len = s->next_proto_negotiated_len; - padding_len = 32 - ((len + 2) % 32); + assert(ssl->state == SSL3_ST_CW_NEXT_PROTO_A); - d = p = ssl_handshake_start(s); - *(p++) = len; - memcpy(p, s->next_proto_negotiated, len); - p += len; - *(p++) = padding_len; - memset(p, 0, padding_len); - p += padding_len; + static const uint8_t kZero[32] = {0}; + size_t padding_len = 32 - ((ssl->next_proto_negotiated_len + 2) % 32); - if (!ssl_set_handshake_header(s, SSL3_MT_NEXT_PROTO, p - d)) { - return -1; - } - s->state = SSL3_ST_CW_NEXT_PROTO_B; + CBB cbb, child; + size_t length; + CBB_zero(&cbb); + if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl), + ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) || + !CBB_add_u8_length_prefixed(&cbb, &child) || + !CBB_add_bytes(&child, ssl->next_proto_negotiated, + ssl->next_proto_negotiated_len) || + !CBB_add_u8_length_prefixed(&cbb, &child) || + !CBB_add_bytes(&child, kZero, padding_len) || + !CBB_finish(&cbb, NULL, &length) || + !ssl_set_handshake_header(ssl, SSL3_MT_NEXT_PROTO, length)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + CBB_cleanup(&cbb); + return -1; } - return ssl_do_write(s); + ssl->state = SSL3_ST_CW_NEXT_PROTO_B; + return ssl_do_write(ssl); } -int ssl3_send_channel_id(SSL *s) { - uint8_t *d; - int ret = -1, public_key_len; - EVP_MD_CTX md_ctx; - ECDSA_SIG *sig = NULL; - uint8_t *public_key = NULL, *derp, *der_sig = NULL; +static int write_32_byte_big_endian(CBB *out, const BIGNUM *in) { + uint8_t *ptr; + return CBB_add_space(out, &ptr, 32) && + BN_bn2bin_padded(ptr, 32, in); +} - if (s->state != SSL3_ST_CW_CHANNEL_ID_A) { - return ssl_do_write(s); +int ssl3_send_channel_id(SSL *ssl) { + if (ssl->state == SSL3_ST_CW_CHANNEL_ID_B) { + return ssl_do_write(ssl); } - if (!s->tlsext_channel_id_private && s->ctx->channel_id_cb) { + assert(ssl->state == SSL3_ST_CW_CHANNEL_ID_A); + + if (ssl->tlsext_channel_id_private == NULL && + ssl->ctx->channel_id_cb != NULL) { EVP_PKEY *key = NULL; - s->ctx->channel_id_cb(s, &key); - if (key != NULL) { - s->tlsext_channel_id_private = key; + ssl->ctx->channel_id_cb(ssl, &key); + if (key != NULL && + !SSL_set1_tls_channel_id(ssl, key)) { + EVP_PKEY_free(key); + return -1; } + EVP_PKEY_free(key); } - if (!s->tlsext_channel_id_private) { - s->rwstate = SSL_CHANNEL_ID_LOOKUP; + if (ssl->tlsext_channel_id_private == NULL) { + ssl->rwstate = SSL_CHANNEL_ID_LOOKUP; return -1; } - s->rwstate = SSL_NOTHING; + ssl->rwstate = SSL_NOTHING; - if (EVP_PKEY_id(s->tlsext_channel_id_private) != EVP_PKEY_EC) { + if (EVP_PKEY_id(ssl->tlsext_channel_id_private) != EVP_PKEY_EC) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); return -1; } - EC_KEY *ec_key = s->tlsext_channel_id_private->pkey.ec; - - d = ssl_handshake_start(s); - s2n(TLSEXT_TYPE_channel_id, d); - s2n(TLSEXT_CHANNEL_ID_SIZE, d); - - EVP_MD_CTX_init(&md_ctx); - - public_key_len = i2o_ECPublicKey(ec_key, NULL); - if (public_key_len <= 0) { - OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY); - goto err; - } - /* i2o_ECPublicKey will produce an ANSI X9.62 public key which, for a - * P-256 key, is 0x04 (meaning uncompressed) followed by the x and y - * field elements as 32-byte, big-endian numbers. */ - if (public_key_len != 65) { - OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256); - goto err; - } - public_key = OPENSSL_malloc(public_key_len); - if (!public_key) { - OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + int ret = -1; + EC_KEY *ec_key = ssl->tlsext_channel_id_private->pkey.ec; + BIGNUM *x = BN_new(); + BIGNUM *y = BN_new(); + ECDSA_SIG *sig = NULL; + if (x == NULL || y == NULL || + !EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec_key), + EC_KEY_get0_public_key(ec_key), + x, y, NULL)) { goto err; } - derp = public_key; - i2o_ECPublicKey(ec_key, &derp); - uint8_t digest[EVP_MAX_MD_SIZE]; size_t digest_len; - if (!tls1_channel_id_hash(s, digest, &digest_len)) { + if (!tls1_channel_id_hash(ssl, digest, &digest_len)) { goto err; } @@ -2163,38 +2164,39 @@ int ssl3_send_channel_id(SSL *s) { goto err; } - /* The first byte of public_key will be 0x4, denoting an uncompressed key. */ - memcpy(d, public_key + 1, 64); - d += 64; - if (!BN_bn2bin_padded(d, 32, sig->r) || - !BN_bn2bin_padded(d + 32, 32, sig->s)) { + CBB cbb, child; + size_t length; + CBB_zero(&cbb); + if (!CBB_init_fixed(&cbb, ssl_handshake_start(ssl), + ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) || + !CBB_add_u16(&cbb, TLSEXT_TYPE_channel_id) || + !CBB_add_u16_length_prefixed(&cbb, &child) || + !write_32_byte_big_endian(&child, x) || + !write_32_byte_big_endian(&child, y) || + !write_32_byte_big_endian(&child, sig->r) || + !write_32_byte_big_endian(&child, sig->s) || + !CBB_finish(&cbb, NULL, &length) || + !ssl_set_handshake_header(ssl, SSL3_MT_ENCRYPTED_EXTENSIONS, length)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + CBB_cleanup(&cbb); goto err; } - 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); + ssl->state = SSL3_ST_CW_CHANNEL_ID_B; + ret = ssl_do_write(ssl); err: - EVP_MD_CTX_cleanup(&md_ctx); - OPENSSL_free(public_key); - OPENSSL_free(der_sig); + BN_free(x); + BN_free(y); ECDSA_SIG_free(sig); - return ret; } -int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) { - int i = 0; - if (s->ctx->client_cert_cb) { - i = s->ctx->client_cert_cb(s, px509, ppkey); +int ssl_do_client_cert_cb(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey) { + if (ssl->ctx->client_cert_cb == NULL) { + return 0; } - return i; + return ssl->ctx->client_cert_cb(ssl, out_x509, out_pkey); } int ssl3_verify_server_cert(SSL *s) { -- cgit v1.1