2016-07-11 18:19:03 +01:00
|
|
|
/* Copyright (c) 2016, Google Inc.
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
|
|
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
|
|
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
|
|
|
|
Move libssl's internals into the bssl namespace.
This is horrible, but everything else I tried was worse. The goal with
this CL is to take the extern "C" out of ssl/internal.h and move most
symbols to namespace bssl, so we can start using C++ helpers and
destructors without worry.
Complications:
- Public API functions must be extern "C" and match their declaration in
ssl.h, which is unnamespaced. C++ really does not want you to
interleave namespaced and unnamespaced things. One can actually write
a namespaced extern "C" function, but this means, from C++'s
perspective, the function is namespaced. Trying to namespace the
public header would worked but ended up too deep a rabbithole.
- Our STACK_OF macros do not work right in namespaces.
- The typedefs for our exposed but opaque types are visible in the
header files and copied into consuming projects as forward
declarations. We ultimately want to give SSL a destructor, but
clobbering an unnamespaced ssl_st::~ssl_st seems bad manners.
- MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL.
This CL opts for:
- ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This
informs the public headers to create forward declarations which are
compatible with our namespaces.
- For now, C++-defined type FOO ends up at bssl::FOO with a typedef
outside. Later I imagine we'll rename many of them.
- Internal functions get namespace bssl, so we stop worrying about
stomping the tls1_prf symbol. Exported C functions are stuck as they
are. Rather than try anything weird, bite the bullet and reorder files
which have a mix of public and private functions. I expect that over
time, the public functions will become fairly small as we move logic
to more idiomatic C++.
Files without any public C functions can just be written normally.
- To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle
in advance of them being made idiomatic C++.
Bug: 132
Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581
Reviewed-on: https://boringssl-review.googlesource.com/18124
Reviewed-by: David Benjamin <davidben@google.com>
2017-07-18 21:34:25 +01:00
|
|
|
#define BORINGSSL_INTERNAL_CXX_TYPES
|
|
|
|
|
2016-07-11 18:19:03 +01:00
|
|
|
#include <openssl/ssl.h>
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <openssl/bytestring.h>
|
|
|
|
#include <openssl/err.h>
|
|
|
|
#include <openssl/hkdf.h>
|
|
|
|
#include <openssl/mem.h>
|
|
|
|
#include <openssl/stack.h>
|
|
|
|
#include <openssl/x509.h>
|
|
|
|
|
2016-11-13 01:32:10 +00:00
|
|
|
#include "../crypto/internal.h"
|
2016-07-11 18:19:03 +01:00
|
|
|
#include "internal.h"
|
|
|
|
|
|
|
|
|
Move libssl's internals into the bssl namespace.
This is horrible, but everything else I tried was worse. The goal with
this CL is to take the extern "C" out of ssl/internal.h and move most
symbols to namespace bssl, so we can start using C++ helpers and
destructors without worry.
Complications:
- Public API functions must be extern "C" and match their declaration in
ssl.h, which is unnamespaced. C++ really does not want you to
interleave namespaced and unnamespaced things. One can actually write
a namespaced extern "C" function, but this means, from C++'s
perspective, the function is namespaced. Trying to namespace the
public header would worked but ended up too deep a rabbithole.
- Our STACK_OF macros do not work right in namespaces.
- The typedefs for our exposed but opaque types are visible in the
header files and copied into consuming projects as forward
declarations. We ultimately want to give SSL a destructor, but
clobbering an unnamespaced ssl_st::~ssl_st seems bad manners.
- MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL.
This CL opts for:
- ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This
informs the public headers to create forward declarations which are
compatible with our namespaces.
- For now, C++-defined type FOO ends up at bssl::FOO with a typedef
outside. Later I imagine we'll rename many of them.
- Internal functions get namespace bssl, so we stop worrying about
stomping the tls1_prf symbol. Exported C functions are stuck as they
are. Rather than try anything weird, bite the bullet and reorder files
which have a mix of public and private functions. I expect that over
time, the public functions will become fairly small as we move logic
to more idiomatic C++.
Files without any public C functions can just be written normally.
- To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle
in advance of them being made idiomatic C++.
Bug: 132
Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581
Reviewed-on: https://boringssl-review.googlesource.com/18124
Reviewed-by: David Benjamin <davidben@google.com>
2017-07-18 21:34:25 +01:00
|
|
|
namespace bssl {
|
|
|
|
|
2016-08-16 16:25:03 +01:00
|
|
|
/* kMaxKeyUpdates is the number of consecutive KeyUpdates that will be
|
|
|
|
* processed. Without this limit an attacker could force unbounded processing
|
|
|
|
* without being able to return application data. */
|
|
|
|
static const uint8_t kMaxKeyUpdates = 32;
|
|
|
|
|
2016-12-19 18:19:29 +00:00
|
|
|
int tls13_handshake(SSL_HANDSHAKE *hs, int *out_early_return) {
|
2016-11-14 01:32:04 +00:00
|
|
|
SSL *const ssl = hs->ssl;
|
2016-07-11 18:19:03 +01:00
|
|
|
for (;;) {
|
|
|
|
/* Resolve the operation the handshake was waiting on. */
|
|
|
|
switch (hs->wait) {
|
|
|
|
case ssl_hs_error:
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
|
|
|
|
return -1;
|
|
|
|
|
2016-07-18 21:25:05 +01:00
|
|
|
case ssl_hs_flush:
|
|
|
|
case ssl_hs_flush_and_read_message: {
|
2017-01-01 22:41:30 +00:00
|
|
|
int ret = ssl->method->flush_flight(ssl);
|
2016-07-11 18:19:03 +01:00
|
|
|
if (ret <= 0) {
|
|
|
|
return ret;
|
|
|
|
}
|
2016-07-18 21:25:05 +01:00
|
|
|
if (hs->wait != ssl_hs_flush_and_read_message) {
|
|
|
|
break;
|
|
|
|
}
|
2016-07-22 16:39:29 +01:00
|
|
|
ssl->method->expect_flight(ssl);
|
2016-07-18 21:25:05 +01:00
|
|
|
hs->wait = ssl_hs_read_message;
|
2017-07-17 19:10:46 +01:00
|
|
|
SSL_FALLTHROUGH;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
|
|
|
|
2016-07-18 21:25:05 +01:00
|
|
|
case ssl_hs_read_message: {
|
2017-01-21 19:49:39 +00:00
|
|
|
int ret = ssl->method->ssl_get_message(ssl);
|
2016-07-11 18:19:03 +01:00
|
|
|
if (ret <= 0) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2017-06-13 17:45:25 +01:00
|
|
|
case ssl_hs_read_change_cipher_spec: {
|
|
|
|
int ret = ssl->method->read_change_cipher_spec(ssl);
|
|
|
|
if (ret <= 0) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2017-01-11 16:34:52 +00:00
|
|
|
case ssl_hs_read_end_of_early_data: {
|
2016-12-19 18:19:29 +00:00
|
|
|
if (ssl->s3->hs->can_early_read) {
|
|
|
|
/* While we are processing early data, the handshake returns early. */
|
|
|
|
*out_early_return = 1;
|
|
|
|
return 1;
|
2017-01-11 16:34:52 +00:00
|
|
|
}
|
2016-12-19 18:19:29 +00:00
|
|
|
hs->wait = ssl_hs_ok;
|
2017-01-11 16:34:52 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-07-11 18:19:03 +01:00
|
|
|
case ssl_hs_x509_lookup:
|
|
|
|
ssl->rwstate = SSL_X509_LOOKUP;
|
|
|
|
hs->wait = ssl_hs_ok;
|
|
|
|
return -1;
|
|
|
|
|
2016-09-24 00:25:11 +01:00
|
|
|
case ssl_hs_channel_id_lookup:
|
|
|
|
ssl->rwstate = SSL_CHANNEL_ID_LOOKUP;
|
|
|
|
hs->wait = ssl_hs_ok;
|
|
|
|
return -1;
|
|
|
|
|
2016-07-11 18:19:03 +01:00
|
|
|
case ssl_hs_private_key_operation:
|
|
|
|
ssl->rwstate = SSL_PRIVATE_KEY_OPERATION;
|
|
|
|
hs->wait = ssl_hs_ok;
|
|
|
|
return -1;
|
|
|
|
|
2017-03-10 22:47:18 +00:00
|
|
|
case ssl_hs_pending_ticket:
|
|
|
|
ssl->rwstate = SSL_PENDING_TICKET;
|
|
|
|
hs->wait = ssl_hs_ok;
|
|
|
|
return -1;
|
|
|
|
|
2017-07-11 21:13:10 +01:00
|
|
|
case ssl_hs_certificate_verify:
|
|
|
|
ssl->rwstate = SSL_CERTIFICATE_VERIFY;
|
|
|
|
hs->wait = ssl_hs_ok;
|
|
|
|
return -1;
|
|
|
|
|
2017-03-09 19:56:07 +00:00
|
|
|
case ssl_hs_early_data_rejected:
|
|
|
|
ssl->rwstate = SSL_EARLY_DATA_REJECTED;
|
|
|
|
/* Cause |SSL_write| to start failing immediately. */
|
|
|
|
hs->can_early_write = 0;
|
|
|
|
return -1;
|
|
|
|
|
2016-07-11 18:19:03 +01:00
|
|
|
case ssl_hs_ok:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Run the state machine again. */
|
2016-11-14 01:32:04 +00:00
|
|
|
hs->wait = hs->do_tls13_handshake(hs);
|
2016-07-11 18:19:03 +01:00
|
|
|
if (hs->wait == ssl_hs_error) {
|
|
|
|
/* Don't loop around to avoid a stray |SSL_R_SSL_HANDSHAKE_FAILURE| the
|
|
|
|
* first time around. */
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (hs->wait == ssl_hs_ok) {
|
|
|
|
/* The handshake has completed. */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Otherwise, loop to the beginning and resolve what was blocking the
|
|
|
|
* handshake. */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-24 00:25:11 +01:00
|
|
|
int tls13_get_cert_verify_signature_input(
|
2017-01-12 18:17:07 +00:00
|
|
|
SSL_HANDSHAKE *hs, uint8_t **out, size_t *out_len,
|
2016-09-24 00:25:11 +01:00
|
|
|
enum ssl_cert_verify_context_t cert_verify_context) {
|
2016-07-11 18:19:03 +01:00
|
|
|
CBB cbb;
|
|
|
|
if (!CBB_init(&cbb, 64 + 33 + 1 + 2 * EVP_MAX_MD_SIZE)) {
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 64; i++) {
|
|
|
|
if (!CBB_add_u8(&cbb, 0x20)) {
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-24 00:25:11 +01:00
|
|
|
const uint8_t *context;
|
|
|
|
size_t context_len;
|
|
|
|
if (cert_verify_context == ssl_cert_verify_server) {
|
2016-07-11 18:19:03 +01:00
|
|
|
/* Include the NUL byte. */
|
|
|
|
static const char kContext[] = "TLS 1.3, server CertificateVerify";
|
2016-09-24 00:25:11 +01:00
|
|
|
context = (const uint8_t *)kContext;
|
|
|
|
context_len = sizeof(kContext);
|
|
|
|
} else if (cert_verify_context == ssl_cert_verify_client) {
|
2016-07-11 18:19:03 +01:00
|
|
|
static const char kContext[] = "TLS 1.3, client CertificateVerify";
|
2016-09-24 00:25:11 +01:00
|
|
|
context = (const uint8_t *)kContext;
|
|
|
|
context_len = sizeof(kContext);
|
|
|
|
} else if (cert_verify_context == ssl_cert_verify_channel_id) {
|
|
|
|
static const char kContext[] = "TLS 1.3, Channel ID";
|
|
|
|
context = (const uint8_t *)kContext;
|
|
|
|
context_len = sizeof(kContext);
|
|
|
|
} else {
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!CBB_add_bytes(&cbb, context, context_len)) {
|
|
|
|
goto err;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
|
|
|
|
2016-11-01 17:39:36 +00:00
|
|
|
uint8_t context_hash[EVP_MAX_MD_SIZE];
|
|
|
|
size_t context_hash_len;
|
2017-01-12 18:17:07 +00:00
|
|
|
if (!SSL_TRANSCRIPT_get_hash(&hs->transcript, context_hash,
|
|
|
|
&context_hash_len) ||
|
2016-11-01 17:39:36 +00:00
|
|
|
!CBB_add_bytes(&cbb, context_hash, context_hash_len) ||
|
2016-07-11 18:19:03 +01:00
|
|
|
!CBB_finish(&cbb, out, out_len)) {
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
err:
|
|
|
|
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
|
|
|
|
CBB_cleanup(&cbb);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-12-12 19:46:09 +00:00
|
|
|
int tls13_process_certificate(SSL_HANDSHAKE *hs, int allow_anonymous) {
|
|
|
|
SSL *const ssl = hs->ssl;
|
2016-11-01 17:39:36 +00:00
|
|
|
CBS cbs, context, certificate_list;
|
2016-07-11 18:19:03 +01:00
|
|
|
CBS_init(&cbs, ssl->init_msg, ssl->init_num);
|
|
|
|
if (!CBS_get_u8_length_prefixed(&cbs, &context) ||
|
|
|
|
CBS_len(&context) != 0) {
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-02 01:16:31 +01:00
|
|
|
const int retain_sha256 =
|
2016-11-17 01:53:09 +00:00
|
|
|
ssl->server && ssl->retain_only_sha256_of_client_certs;
|
2016-07-11 18:19:03 +01:00
|
|
|
int ret = 0;
|
2016-11-01 17:39:36 +00:00
|
|
|
|
2016-12-12 19:46:09 +00:00
|
|
|
EVP_PKEY *pkey = NULL;
|
2016-12-12 19:06:16 +00:00
|
|
|
STACK_OF(CRYPTO_BUFFER) *certs = sk_CRYPTO_BUFFER_new_null();
|
|
|
|
if (certs == NULL) {
|
2016-11-01 17:39:36 +00:00
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
|
|
|
|
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
|
2016-07-11 18:19:03 +01:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2016-11-01 17:39:36 +00:00
|
|
|
if (!CBS_get_u24_length_prefixed(&cbs, &certificate_list)) {
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (CBS_len(&certificate_list) > 0) {
|
|
|
|
CBS certificate, extensions;
|
|
|
|
if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) ||
|
2016-12-12 19:06:16 +00:00
|
|
|
!CBS_get_u16_length_prefixed(&certificate_list, &extensions) ||
|
|
|
|
CBS_len(&certificate) == 0) {
|
2016-11-01 17:39:36 +00:00
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2016-12-12 19:46:09 +00:00
|
|
|
if (sk_CRYPTO_BUFFER_num(certs) == 0) {
|
|
|
|
pkey = ssl_cert_parse_pubkey(&certificate);
|
|
|
|
if (pkey == NULL) {
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
|
|
|
|
goto err;
|
|
|
|
}
|
2016-12-12 20:05:53 +00:00
|
|
|
/* TLS 1.3 always uses certificate keys for signing thus the correct
|
|
|
|
* keyUsage is enforced. */
|
|
|
|
if (!ssl_cert_check_digital_signature_key_usage(&certificate)) {
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
|
|
|
|
goto err;
|
|
|
|
}
|
2016-12-12 19:46:09 +00:00
|
|
|
|
|
|
|
if (retain_sha256) {
|
|
|
|
/* Retain the hash of the leaf certificate if requested. */
|
|
|
|
SHA256(CBS_data(&certificate), CBS_len(&certificate),
|
2017-02-10 01:01:26 +00:00
|
|
|
hs->new_session->peer_sha256);
|
2016-12-12 19:46:09 +00:00
|
|
|
}
|
2016-11-01 17:39:36 +00:00
|
|
|
}
|
|
|
|
|
2016-12-12 19:16:44 +00:00
|
|
|
CRYPTO_BUFFER *buf =
|
|
|
|
CRYPTO_BUFFER_new_from_CBS(&certificate, ssl->ctx->pool);
|
2016-12-12 19:06:16 +00:00
|
|
|
if (buf == NULL ||
|
|
|
|
!sk_CRYPTO_BUFFER_push(certs, buf)) {
|
|
|
|
CRYPTO_BUFFER_free(buf);
|
2016-11-01 17:39:36 +00:00
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
|
|
|
|
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Parse out the extensions. */
|
|
|
|
int have_status_request = 0, have_sct = 0;
|
|
|
|
CBS status_request, sct;
|
2016-11-13 01:32:10 +00:00
|
|
|
const SSL_EXTENSION_TYPE ext_types[] = {
|
|
|
|
{TLSEXT_TYPE_status_request, &have_status_request, &status_request},
|
|
|
|
{TLSEXT_TYPE_certificate_timestamp, &have_sct, &sct},
|
|
|
|
};
|
|
|
|
|
2017-02-08 21:33:15 +00:00
|
|
|
uint8_t alert = SSL_AD_DECODE_ERROR;
|
2016-11-13 01:32:10 +00:00
|
|
|
if (!ssl_parse_extensions(&extensions, &alert, ext_types,
|
2016-12-07 20:29:45 +00:00
|
|
|
OPENSSL_ARRAY_SIZE(ext_types),
|
|
|
|
0 /* reject unknown */)) {
|
2016-11-13 01:32:10 +00:00
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
|
|
|
|
goto err;
|
2016-11-01 17:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* All Certificate extensions are parsed, but only the leaf extensions are
|
|
|
|
* stored. */
|
|
|
|
if (have_status_request) {
|
|
|
|
if (ssl->server || !ssl->ocsp_stapling_enabled) {
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t status_type;
|
|
|
|
CBS ocsp_response;
|
|
|
|
if (!CBS_get_u8(&status_request, &status_type) ||
|
|
|
|
status_type != TLSEXT_STATUSTYPE_ocsp ||
|
|
|
|
!CBS_get_u24_length_prefixed(&status_request, &ocsp_response) ||
|
|
|
|
CBS_len(&ocsp_response) == 0 ||
|
|
|
|
CBS_len(&status_request) != 0) {
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2016-12-12 19:06:16 +00:00
|
|
|
if (sk_CRYPTO_BUFFER_num(certs) == 1 &&
|
2017-02-10 01:01:26 +00:00
|
|
|
!CBS_stow(&ocsp_response, &hs->new_session->ocsp_response,
|
|
|
|
&hs->new_session->ocsp_response_length)) {
|
2016-11-01 17:39:36 +00:00
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (have_sct) {
|
|
|
|
if (ssl->server || !ssl->signed_cert_timestamps_enabled) {
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2016-11-17 21:21:27 +00:00
|
|
|
if (!ssl_is_sct_list_valid(&sct)) {
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
|
2016-11-01 17:39:36 +00:00
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2016-12-12 19:06:16 +00:00
|
|
|
if (sk_CRYPTO_BUFFER_num(certs) == 1 &&
|
2017-02-10 01:01:26 +00:00
|
|
|
!CBS_stow(
|
|
|
|
&sct, &hs->new_session->tlsext_signed_cert_timestamp_list,
|
|
|
|
&hs->new_session->tlsext_signed_cert_timestamp_list_length)) {
|
2016-11-01 17:39:36 +00:00
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-11 18:19:03 +01:00
|
|
|
if (CBS_len(&cbs) != 0) {
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2016-12-12 19:46:09 +00:00
|
|
|
EVP_PKEY_free(hs->peer_pubkey);
|
|
|
|
hs->peer_pubkey = pkey;
|
|
|
|
pkey = NULL;
|
|
|
|
|
2017-02-10 01:01:26 +00:00
|
|
|
sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free);
|
|
|
|
hs->new_session->certs = certs;
|
2016-12-12 19:06:16 +00:00
|
|
|
certs = NULL;
|
|
|
|
|
2017-02-10 01:01:26 +00:00
|
|
|
if (!ssl->ctx->x509_method->session_cache_objects(hs->new_session)) {
|
2016-12-12 19:06:16 +00:00
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2017-02-10 01:01:26 +00:00
|
|
|
if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) {
|
2016-08-02 01:16:31 +01:00
|
|
|
if (!allow_anonymous) {
|
2016-07-11 18:19:03 +01:00
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
|
2016-10-08 01:51:43 +01:00
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED);
|
2016-07-11 18:19:03 +01:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2016-08-02 00:16:46 +01:00
|
|
|
/* OpenSSL returns X509_V_OK when no certificates are requested. This is
|
2016-08-18 21:40:28 +01:00
|
|
|
* classed by them as a bug, but it's assumed by at least NGINX. */
|
2017-02-10 01:01:26 +00:00
|
|
|
hs->new_session->verify_result = X509_V_OK;
|
2016-08-02 00:16:46 +01:00
|
|
|
|
2016-07-11 18:19:03 +01:00
|
|
|
/* No certificate, so nothing more to do. */
|
|
|
|
ret = 1;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2017-02-10 01:01:26 +00:00
|
|
|
hs->new_session->peer_sha256_valid = retain_sha256;
|
2016-07-11 18:19:03 +01:00
|
|
|
ret = 1;
|
|
|
|
|
|
|
|
err:
|
2016-12-12 19:06:16 +00:00
|
|
|
sk_CRYPTO_BUFFER_pop_free(certs, CRYPTO_BUFFER_free);
|
2016-12-12 19:46:09 +00:00
|
|
|
EVP_PKEY_free(pkey);
|
2016-07-11 18:19:03 +01:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-12-12 19:46:09 +00:00
|
|
|
int tls13_process_certificate_verify(SSL_HANDSHAKE *hs) {
|
|
|
|
SSL *const ssl = hs->ssl;
|
|
|
|
if (hs->peer_pubkey == NULL) {
|
2017-07-13 03:43:42 +01:00
|
|
|
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
|
|
|
|
return 0;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
CBS cbs, signature;
|
|
|
|
uint16_t signature_algorithm;
|
|
|
|
CBS_init(&cbs, ssl->init_msg, ssl->init_num);
|
|
|
|
if (!CBS_get_u16(&cbs, &signature_algorithm) ||
|
|
|
|
!CBS_get_u16_length_prefixed(&cbs, &signature) ||
|
|
|
|
CBS_len(&cbs) != 0) {
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
2017-07-13 03:43:42 +01:00
|
|
|
return 0;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
|
|
|
|
2017-06-16 03:43:04 +01:00
|
|
|
uint8_t alert = SSL_AD_DECODE_ERROR;
|
|
|
|
if (!tls12_check_peer_sigalg(ssl, &alert, signature_algorithm)) {
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
|
2017-07-13 03:43:42 +01:00
|
|
|
return 0;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
2017-02-10 01:01:26 +00:00
|
|
|
hs->new_session->peer_signature_algorithm = signature_algorithm;
|
2016-07-11 18:19:03 +01:00
|
|
|
|
2017-07-13 03:43:42 +01:00
|
|
|
uint8_t *msg = NULL;
|
|
|
|
size_t msg_len;
|
2016-09-24 00:25:11 +01:00
|
|
|
if (!tls13_get_cert_verify_signature_input(
|
2017-01-12 18:17:07 +00:00
|
|
|
hs, &msg, &msg_len,
|
2016-09-24 00:25:11 +01:00
|
|
|
ssl->server ? ssl_cert_verify_client : ssl_cert_verify_server)) {
|
2016-07-11 18:19:03 +01:00
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
|
2017-07-13 03:43:42 +01:00
|
|
|
return 0;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
Move libssl's internals into the bssl namespace.
This is horrible, but everything else I tried was worse. The goal with
this CL is to take the extern "C" out of ssl/internal.h and move most
symbols to namespace bssl, so we can start using C++ helpers and
destructors without worry.
Complications:
- Public API functions must be extern "C" and match their declaration in
ssl.h, which is unnamespaced. C++ really does not want you to
interleave namespaced and unnamespaced things. One can actually write
a namespaced extern "C" function, but this means, from C++'s
perspective, the function is namespaced. Trying to namespace the
public header would worked but ended up too deep a rabbithole.
- Our STACK_OF macros do not work right in namespaces.
- The typedefs for our exposed but opaque types are visible in the
header files and copied into consuming projects as forward
declarations. We ultimately want to give SSL a destructor, but
clobbering an unnamespaced ssl_st::~ssl_st seems bad manners.
- MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL.
This CL opts for:
- ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This
informs the public headers to create forward declarations which are
compatible with our namespaces.
- For now, C++-defined type FOO ends up at bssl::FOO with a typedef
outside. Later I imagine we'll rename many of them.
- Internal functions get namespace bssl, so we stop worrying about
stomping the tls1_prf symbol. Exported C functions are stuck as they
are. Rather than try anything weird, bite the bullet and reorder files
which have a mix of public and private functions. I expect that over
time, the public functions will become fairly small as we move logic
to more idiomatic C++.
Files without any public C functions can just be written normally.
- To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle
in advance of them being made idiomatic C++.
Bug: 132
Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581
Reviewed-on: https://boringssl-review.googlesource.com/18124
Reviewed-by: David Benjamin <davidben@google.com>
2017-07-18 21:34:25 +01:00
|
|
|
UniquePtr<uint8_t> free_msg(msg);
|
2016-07-11 18:19:03 +01:00
|
|
|
|
|
|
|
int sig_ok =
|
|
|
|
ssl_public_key_verify(ssl, CBS_data(&signature), CBS_len(&signature),
|
2016-12-12 19:46:09 +00:00
|
|
|
signature_algorithm, hs->peer_pubkey, msg, msg_len);
|
2016-08-19 19:51:10 +01:00
|
|
|
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
|
|
|
|
sig_ok = 1;
|
|
|
|
ERR_clear_error();
|
|
|
|
#endif
|
2016-07-11 18:19:03 +01:00
|
|
|
if (!sig_ok) {
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
|
2017-07-13 03:43:42 +01:00
|
|
|
return 0;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
|
|
|
|
2017-07-13 03:43:42 +01:00
|
|
|
return 1;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
|
|
|
|
2017-03-26 04:24:23 +01:00
|
|
|
int tls13_process_finished(SSL_HANDSHAKE *hs, int use_saved_value) {
|
2016-11-17 07:43:08 +00:00
|
|
|
SSL *const ssl = hs->ssl;
|
2017-03-26 04:24:23 +01:00
|
|
|
uint8_t verify_data_buf[EVP_MAX_MD_SIZE];
|
|
|
|
const uint8_t *verify_data;
|
2016-07-11 18:19:03 +01:00
|
|
|
size_t verify_data_len;
|
2017-03-26 04:24:23 +01:00
|
|
|
if (use_saved_value) {
|
|
|
|
assert(ssl->server);
|
|
|
|
verify_data = hs->expected_client_finished;
|
|
|
|
verify_data_len = hs->hash_len;
|
|
|
|
} else {
|
|
|
|
if (!tls13_finished_mac(hs, verify_data_buf, &verify_data_len,
|
|
|
|
!ssl->server)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
verify_data = verify_data_buf;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
|
|
|
|
2016-08-19 19:51:10 +01:00
|
|
|
int finished_ok =
|
|
|
|
ssl->init_num == verify_data_len &&
|
|
|
|
CRYPTO_memcmp(verify_data, ssl->init_msg, verify_data_len) == 0;
|
|
|
|
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
|
|
|
|
finished_ok = 1;
|
|
|
|
#endif
|
|
|
|
if (!finished_ok) {
|
2016-07-11 18:19:03 +01:00
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-01-13 00:46:50 +00:00
|
|
|
int tls13_add_certificate(SSL_HANDSHAKE *hs) {
|
2016-11-17 07:43:08 +00:00
|
|
|
SSL *const ssl = hs->ssl;
|
Move libssl's internals into the bssl namespace.
This is horrible, but everything else I tried was worse. The goal with
this CL is to take the extern "C" out of ssl/internal.h and move most
symbols to namespace bssl, so we can start using C++ helpers and
destructors without worry.
Complications:
- Public API functions must be extern "C" and match their declaration in
ssl.h, which is unnamespaced. C++ really does not want you to
interleave namespaced and unnamespaced things. One can actually write
a namespaced extern "C" function, but this means, from C++'s
perspective, the function is namespaced. Trying to namespace the
public header would worked but ended up too deep a rabbithole.
- Our STACK_OF macros do not work right in namespaces.
- The typedefs for our exposed but opaque types are visible in the
header files and copied into consuming projects as forward
declarations. We ultimately want to give SSL a destructor, but
clobbering an unnamespaced ssl_st::~ssl_st seems bad manners.
- MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL.
This CL opts for:
- ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This
informs the public headers to create forward declarations which are
compatible with our namespaces.
- For now, C++-defined type FOO ends up at bssl::FOO with a typedef
outside. Later I imagine we'll rename many of them.
- Internal functions get namespace bssl, so we stop worrying about
stomping the tls1_prf symbol. Exported C functions are stuck as they
are. Rather than try anything weird, bite the bullet and reorder files
which have a mix of public and private functions. I expect that over
time, the public functions will become fairly small as we move logic
to more idiomatic C++.
Files without any public C functions can just be written normally.
- To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle
in advance of them being made idiomatic C++.
Bug: 132
Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581
Reviewed-on: https://boringssl-review.googlesource.com/18124
Reviewed-by: David Benjamin <davidben@google.com>
2017-07-18 21:34:25 +01:00
|
|
|
ScopedCBB cbb;
|
2017-07-13 03:43:42 +01:00
|
|
|
CBB body, certificate_list;
|
|
|
|
if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CERTIFICATE) ||
|
2016-08-18 07:32:23 +01:00
|
|
|
/* The request context is always empty in the handshake. */
|
|
|
|
!CBB_add_u8(&body, 0) ||
|
2016-11-01 17:39:36 +00:00
|
|
|
!CBB_add_u24_length_prefixed(&body, &certificate_list)) {
|
|
|
|
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
|
2017-07-13 03:43:42 +01:00
|
|
|
return 0;
|
2016-11-01 17:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!ssl_has_certificate(ssl)) {
|
2017-07-13 03:43:42 +01:00
|
|
|
return ssl_add_message_cbb(ssl, cbb.get());
|
2016-11-01 17:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CERT *cert = ssl->cert;
|
2017-01-24 21:59:42 +00:00
|
|
|
CRYPTO_BUFFER *leaf_buf = sk_CRYPTO_BUFFER_value(cert->chain, 0);
|
2016-11-01 17:39:36 +00:00
|
|
|
CBB leaf, extensions;
|
|
|
|
if (!CBB_add_u24_length_prefixed(&certificate_list, &leaf) ||
|
2017-01-24 21:59:42 +00:00
|
|
|
!CBB_add_bytes(&leaf, CRYPTO_BUFFER_data(leaf_buf),
|
|
|
|
CRYPTO_BUFFER_len(leaf_buf)) ||
|
2016-11-01 17:39:36 +00:00
|
|
|
!CBB_add_u16_length_prefixed(&certificate_list, &extensions)) {
|
|
|
|
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
|
2017-07-13 03:43:42 +01:00
|
|
|
return 0;
|
2016-11-01 17:39:36 +00:00
|
|
|
}
|
|
|
|
|
2017-02-14 23:34:54 +00:00
|
|
|
if (hs->scts_requested && ssl->cert->signed_cert_timestamp_list != NULL) {
|
2016-11-01 17:39:36 +00:00
|
|
|
CBB contents;
|
|
|
|
if (!CBB_add_u16(&extensions, TLSEXT_TYPE_certificate_timestamp) ||
|
|
|
|
!CBB_add_u16_length_prefixed(&extensions, &contents) ||
|
2017-02-14 23:34:54 +00:00
|
|
|
!CBB_add_bytes(
|
|
|
|
&contents,
|
|
|
|
CRYPTO_BUFFER_data(ssl->cert->signed_cert_timestamp_list),
|
|
|
|
CRYPTO_BUFFER_len(ssl->cert->signed_cert_timestamp_list)) ||
|
2016-11-18 19:05:00 +00:00
|
|
|
!CBB_flush(&extensions)) {
|
2016-11-01 17:39:36 +00:00
|
|
|
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
|
2017-07-13 03:43:42 +01:00
|
|
|
return 0;
|
2016-11-01 17:39:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-17 07:43:08 +00:00
|
|
|
if (hs->ocsp_stapling_requested &&
|
2017-02-14 23:34:54 +00:00
|
|
|
ssl->cert->ocsp_response != NULL) {
|
2016-11-01 17:39:36 +00:00
|
|
|
CBB contents, ocsp_response;
|
|
|
|
if (!CBB_add_u16(&extensions, TLSEXT_TYPE_status_request) ||
|
|
|
|
!CBB_add_u16_length_prefixed(&extensions, &contents) ||
|
|
|
|
!CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) ||
|
|
|
|
!CBB_add_u24_length_prefixed(&contents, &ocsp_response) ||
|
2017-02-14 23:34:54 +00:00
|
|
|
!CBB_add_bytes(&ocsp_response,
|
|
|
|
CRYPTO_BUFFER_data(ssl->cert->ocsp_response),
|
|
|
|
CRYPTO_BUFFER_len(ssl->cert->ocsp_response)) ||
|
2016-11-18 19:05:00 +00:00
|
|
|
!CBB_flush(&extensions)) {
|
2016-11-01 17:39:36 +00:00
|
|
|
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
|
2017-07-13 03:43:42 +01:00
|
|
|
return 0;
|
2016-11-01 17:39:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-24 21:59:42 +00:00
|
|
|
for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cert->chain); i++) {
|
|
|
|
CRYPTO_BUFFER *cert_buf = sk_CRYPTO_BUFFER_value(cert->chain, i);
|
2016-11-01 17:39:36 +00:00
|
|
|
CBB child;
|
|
|
|
if (!CBB_add_u24_length_prefixed(&certificate_list, &child) ||
|
2017-01-24 21:59:42 +00:00
|
|
|
!CBB_add_bytes(&child, CRYPTO_BUFFER_data(cert_buf),
|
|
|
|
CRYPTO_BUFFER_len(cert_buf)) ||
|
2016-11-01 17:39:36 +00:00
|
|
|
!CBB_add_u16(&certificate_list, 0 /* no extensions */)) {
|
|
|
|
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
|
2017-07-13 03:43:42 +01:00
|
|
|
return 0;
|
2016-11-01 17:39:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-13 03:43:42 +01:00
|
|
|
return ssl_add_message_cbb(ssl, cbb.get());
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
|
|
|
|
2017-06-17 18:20:59 +01:00
|
|
|
enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs) {
|
2016-11-17 07:43:08 +00:00
|
|
|
SSL *const ssl = hs->ssl;
|
2016-07-11 18:19:03 +01:00
|
|
|
uint16_t signature_algorithm;
|
2016-11-17 08:20:47 +00:00
|
|
|
if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) {
|
2017-07-13 03:43:42 +01:00
|
|
|
return ssl_private_key_failure;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
2017-07-13 03:43:42 +01:00
|
|
|
|
Move libssl's internals into the bssl namespace.
This is horrible, but everything else I tried was worse. The goal with
this CL is to take the extern "C" out of ssl/internal.h and move most
symbols to namespace bssl, so we can start using C++ helpers and
destructors without worry.
Complications:
- Public API functions must be extern "C" and match their declaration in
ssl.h, which is unnamespaced. C++ really does not want you to
interleave namespaced and unnamespaced things. One can actually write
a namespaced extern "C" function, but this means, from C++'s
perspective, the function is namespaced. Trying to namespace the
public header would worked but ended up too deep a rabbithole.
- Our STACK_OF macros do not work right in namespaces.
- The typedefs for our exposed but opaque types are visible in the
header files and copied into consuming projects as forward
declarations. We ultimately want to give SSL a destructor, but
clobbering an unnamespaced ssl_st::~ssl_st seems bad manners.
- MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL.
This CL opts for:
- ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This
informs the public headers to create forward declarations which are
compatible with our namespaces.
- For now, C++-defined type FOO ends up at bssl::FOO with a typedef
outside. Later I imagine we'll rename many of them.
- Internal functions get namespace bssl, so we stop worrying about
stomping the tls1_prf symbol. Exported C functions are stuck as they
are. Rather than try anything weird, bite the bullet and reorder files
which have a mix of public and private functions. I expect that over
time, the public functions will become fairly small as we move logic
to more idiomatic C++.
Files without any public C functions can just be written normally.
- To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle
in advance of them being made idiomatic C++.
Bug: 132
Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581
Reviewed-on: https://boringssl-review.googlesource.com/18124
Reviewed-by: David Benjamin <davidben@google.com>
2017-07-18 21:34:25 +01:00
|
|
|
ScopedCBB cbb;
|
2017-07-13 03:43:42 +01:00
|
|
|
CBB body;
|
|
|
|
if (!ssl->method->init_message(ssl, cbb.get(), &body,
|
2016-07-11 18:19:03 +01:00
|
|
|
SSL3_MT_CERTIFICATE_VERIFY) ||
|
|
|
|
!CBB_add_u16(&body, signature_algorithm)) {
|
|
|
|
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
|
2017-07-13 03:43:42 +01:00
|
|
|
return ssl_private_key_failure;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Sign the digest. */
|
|
|
|
CBB child;
|
2017-03-30 21:51:53 +01:00
|
|
|
const size_t max_sig_len = EVP_PKEY_size(hs->local_pubkey);
|
2016-07-11 18:19:03 +01:00
|
|
|
uint8_t *sig;
|
|
|
|
size_t sig_len;
|
|
|
|
if (!CBB_add_u16_length_prefixed(&body, &child) ||
|
|
|
|
!CBB_reserve(&child, &sig, max_sig_len)) {
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
|
2017-07-13 03:43:42 +01:00
|
|
|
return ssl_private_key_failure;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
|
|
|
|
2017-07-13 03:43:42 +01:00
|
|
|
uint8_t *msg = NULL;
|
|
|
|
size_t msg_len;
|
2017-06-17 18:20:59 +01:00
|
|
|
if (!tls13_get_cert_verify_signature_input(
|
|
|
|
hs, &msg, &msg_len,
|
|
|
|
ssl->server ? ssl_cert_verify_server : ssl_cert_verify_client)) {
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
|
2017-07-13 03:43:42 +01:00
|
|
|
return ssl_private_key_failure;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
Move libssl's internals into the bssl namespace.
This is horrible, but everything else I tried was worse. The goal with
this CL is to take the extern "C" out of ssl/internal.h and move most
symbols to namespace bssl, so we can start using C++ helpers and
destructors without worry.
Complications:
- Public API functions must be extern "C" and match their declaration in
ssl.h, which is unnamespaced. C++ really does not want you to
interleave namespaced and unnamespaced things. One can actually write
a namespaced extern "C" function, but this means, from C++'s
perspective, the function is namespaced. Trying to namespace the
public header would worked but ended up too deep a rabbithole.
- Our STACK_OF macros do not work right in namespaces.
- The typedefs for our exposed but opaque types are visible in the
header files and copied into consuming projects as forward
declarations. We ultimately want to give SSL a destructor, but
clobbering an unnamespaced ssl_st::~ssl_st seems bad manners.
- MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL.
This CL opts for:
- ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This
informs the public headers to create forward declarations which are
compatible with our namespaces.
- For now, C++-defined type FOO ends up at bssl::FOO with a typedef
outside. Later I imagine we'll rename many of them.
- Internal functions get namespace bssl, so we stop worrying about
stomping the tls1_prf symbol. Exported C functions are stuck as they
are. Rather than try anything weird, bite the bullet and reorder files
which have a mix of public and private functions. I expect that over
time, the public functions will become fairly small as we move logic
to more idiomatic C++.
Files without any public C functions can just be written normally.
- To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle
in advance of them being made idiomatic C++.
Bug: 132
Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581
Reviewed-on: https://boringssl-review.googlesource.com/18124
Reviewed-by: David Benjamin <davidben@google.com>
2017-07-18 21:34:25 +01:00
|
|
|
UniquePtr<uint8_t> free_msg(msg);
|
2016-07-11 18:19:03 +01:00
|
|
|
|
2017-06-17 18:20:59 +01:00
|
|
|
enum ssl_private_key_result_t sign_result = ssl_private_key_sign(
|
|
|
|
hs, sig, &sig_len, max_sig_len, signature_algorithm, msg, msg_len);
|
2016-07-11 18:19:03 +01:00
|
|
|
if (sign_result != ssl_private_key_success) {
|
2017-07-13 03:43:42 +01:00
|
|
|
return sign_result;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!CBB_did_write(&child, sig_len) ||
|
2017-07-13 03:43:42 +01:00
|
|
|
!ssl_add_message_cbb(ssl, cbb.get())) {
|
|
|
|
return ssl_private_key_failure;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
|
|
|
|
2017-07-13 03:43:42 +01:00
|
|
|
return ssl_private_key_success;
|
2016-07-11 18:19:03 +01:00
|
|
|
}
|
|
|
|
|
2017-01-13 00:46:50 +00:00
|
|
|
int tls13_add_finished(SSL_HANDSHAKE *hs) {
|
2016-11-17 07:43:08 +00:00
|
|
|
SSL *const ssl = hs->ssl;
|
2016-07-11 18:19:03 +01:00
|
|
|
size_t verify_data_len;
|
|
|
|
uint8_t verify_data[EVP_MAX_MD_SIZE];
|
|
|
|
|
2016-11-17 07:43:08 +00:00
|
|
|
if (!tls13_finished_mac(hs, verify_data, &verify_data_len, ssl->server)) {
|
2016-07-11 18:19:03 +01:00
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CBB cbb, body;
|
|
|
|
if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_FINISHED) ||
|
|
|
|
!CBB_add_bytes(&body, verify_data, verify_data_len) ||
|
Don't use the buffer BIO in TLS.
On the TLS side, we introduce a running buffer of ciphertext. Queuing up
pending data consists of encrypting the record into the buffer. This
effectively reimplements what the buffer BIO was doing previously, but
this resizes to fit the whole flight.
As part of this, rename all the functions to add to the pending flight
to be more uniform. This CL proposes "add_foo" to add to the pending
flight and "flush_flight" to drain it.
We add an add_alert hook for alerts but, for now, only the SSL 3.0
warning alert (sent mid-handshake) uses this mechanism. Later work will
push this down to the rest of the write path so closure alerts use it
too, as in DTLS. The intended end state is that all the ssl_buffer.c and
wpend_ret logic will only be used for application data and eventually
optionally replaced by the in-place API, while all "incidental" data
will be handled internally.
For now, the two buffers are mutually exclusive. Moving closure alerts
to "incidentals" will change this, but flushing application data early
is tricky due to wpend_ret. (If we call ssl_write_buffer_flush,
do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That
too is all left alone in this change.
To keep the diff down, write_message is retained for now and will be
removed from the state machines in a follow-up change.
BUG=72
Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d
Reviewed-on: https://boringssl-review.googlesource.com/13224
Reviewed-by: Adam Langley <agl@google.com>
2017-01-03 23:37:41 +00:00
|
|
|
!ssl_add_message_cbb(ssl, &cbb)) {
|
2016-07-11 18:19:03 +01:00
|
|
|
CBB_cleanup(&cbb);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2016-07-26 17:39:22 +01:00
|
|
|
|
2016-07-26 17:27:38 +01:00
|
|
|
static int tls13_receive_key_update(SSL *ssl) {
|
2016-10-03 17:25:56 +01:00
|
|
|
CBS cbs;
|
|
|
|
uint8_t key_update_request;
|
|
|
|
CBS_init(&cbs, ssl->init_msg, ssl->init_num);
|
|
|
|
if (!CBS_get_u8(&cbs, &key_update_request) ||
|
|
|
|
CBS_len(&cbs) != 0 ||
|
|
|
|
(key_update_request != SSL_KEY_UPDATE_NOT_REQUESTED &&
|
|
|
|
key_update_request != SSL_KEY_UPDATE_REQUESTED)) {
|
2016-07-26 17:27:38 +01:00
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-04-06 17:54:12 +01:00
|
|
|
if (!tls13_rotate_traffic_key(ssl, evp_aead_open)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Acknowledge the KeyUpdate */
|
|
|
|
if (key_update_request == SSL_KEY_UPDATE_REQUESTED &&
|
|
|
|
!ssl->s3->key_update_pending) {
|
|
|
|
CBB cbb, body;
|
|
|
|
if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_KEY_UPDATE) ||
|
|
|
|
!CBB_add_u8(&body, SSL_KEY_UPDATE_NOT_REQUESTED) ||
|
|
|
|
!ssl_add_message_cbb(ssl, &cbb) ||
|
|
|
|
!tls13_rotate_traffic_key(ssl, evp_aead_seal)) {
|
|
|
|
CBB_cleanup(&cbb);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Suppress KeyUpdate acknowledgments until this change is written to the
|
|
|
|
* wire. This prevents us from accumulating write obligations when read and
|
|
|
|
* write progress at different rates. See draft-ietf-tls-tls13-18, section
|
|
|
|
* 4.5.3. */
|
|
|
|
ssl->s3->key_update_pending = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
2016-07-26 17:27:38 +01:00
|
|
|
}
|
|
|
|
|
2016-07-26 17:39:22 +01:00
|
|
|
int tls13_post_handshake(SSL *ssl) {
|
2016-07-26 17:27:38 +01:00
|
|
|
if (ssl->s3->tmp.message_type == SSL3_MT_KEY_UPDATE) {
|
2016-08-16 16:25:03 +01:00
|
|
|
ssl->s3->key_update_count++;
|
|
|
|
if (ssl->s3->key_update_count > kMaxKeyUpdates) {
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_KEY_UPDATES);
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-07-26 17:27:38 +01:00
|
|
|
return tls13_receive_key_update(ssl);
|
|
|
|
}
|
|
|
|
|
2016-08-16 16:25:03 +01:00
|
|
|
ssl->s3->key_update_count = 0;
|
|
|
|
|
2016-07-26 17:39:22 +01:00
|
|
|
if (ssl->s3->tmp.message_type == SSL3_MT_NEW_SESSION_TICKET &&
|
|
|
|
!ssl->server) {
|
2016-07-27 16:10:52 +01:00
|
|
|
return tls13_process_new_session_ticket(ssl);
|
2016-07-26 17:39:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
|
|
|
|
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
|
|
|
|
return 0;
|
|
|
|
}
|
Move libssl's internals into the bssl namespace.
This is horrible, but everything else I tried was worse. The goal with
this CL is to take the extern "C" out of ssl/internal.h and move most
symbols to namespace bssl, so we can start using C++ helpers and
destructors without worry.
Complications:
- Public API functions must be extern "C" and match their declaration in
ssl.h, which is unnamespaced. C++ really does not want you to
interleave namespaced and unnamespaced things. One can actually write
a namespaced extern "C" function, but this means, from C++'s
perspective, the function is namespaced. Trying to namespace the
public header would worked but ended up too deep a rabbithole.
- Our STACK_OF macros do not work right in namespaces.
- The typedefs for our exposed but opaque types are visible in the
header files and copied into consuming projects as forward
declarations. We ultimately want to give SSL a destructor, but
clobbering an unnamespaced ssl_st::~ssl_st seems bad manners.
- MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL.
This CL opts for:
- ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This
informs the public headers to create forward declarations which are
compatible with our namespaces.
- For now, C++-defined type FOO ends up at bssl::FOO with a typedef
outside. Later I imagine we'll rename many of them.
- Internal functions get namespace bssl, so we stop worrying about
stomping the tls1_prf symbol. Exported C functions are stuck as they
are. Rather than try anything weird, bite the bullet and reorder files
which have a mix of public and private functions. I expect that over
time, the public functions will become fairly small as we move logic
to more idiomatic C++.
Files without any public C functions can just be written normally.
- To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle
in advance of them being made idiomatic C++.
Bug: 132
Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581
Reviewed-on: https://boringssl-review.googlesource.com/18124
Reviewed-by: David Benjamin <davidben@google.com>
2017-07-18 21:34:25 +01:00
|
|
|
|
|
|
|
} // namespace bssl
|