Просмотр исходного кода

Use handshake parameters to decide if cert/key are available

Whether the host has a valid certificate or private key may depend on
the handshake parameters and not just its configuration. For example,
negotiating the delegated credential extension (see
https://tools.ietf.org/html/draft-ietf-tls-subcerts) requires an
alternate private key for the handshake.

Change-Id: I11cea1d11e731aa4018d980c010b8d8ebaa64c31
Reviewed-on: https://boringssl-review.googlesource.com/c/33664
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
kris/onging/CECPQ3_patch15
Christopher Patton 6 лет назад
committed by CQ bot account: commit-bot@chromium.org
Родитель
Сommit
9cde848bd1
9 измененных файлов: 24 добавлений и 22 удалений
  1. +3
    -3
      ssl/handshake_client.cc
  2. +3
    -3
      ssl/handshake_server.cc
  3. +3
    -3
      ssl/internal.h
  4. +6
    -6
      ssl/ssl_cert.cc
  5. +3
    -2
      ssl/ssl_privkey.cc
  6. +3
    -2
      ssl/ssl_x509.cc
  7. +1
    -1
      ssl/tls13_both.cc
  8. +1
    -1
      ssl/tls13_client.cc
  9. +1
    -1
      ssl/tls13_server.cc

+ 3
- 3
ssl/handshake_client.cc Просмотреть файл

@@ -1219,7 +1219,7 @@ static enum ssl_hs_wait_t do_send_client_certificate(SSL_HANDSHAKE *hs) {
}
}

if (!ssl_has_certificate(hs->config)) {
if (!ssl_has_certificate(hs)) {
// Without a client certificate, the handshake buffer may be released.
hs->transcript.FreeBuffer();
}
@@ -1386,12 +1386,12 @@ static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) {
static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;

if (!hs->cert_request || !ssl_has_certificate(hs->config)) {
if (!hs->cert_request || !ssl_has_certificate(hs)) {
hs->state = state_send_client_finished;
return ssl_hs_ok;
}

assert(ssl_has_private_key(hs->config));
assert(ssl_has_private_key(hs));
ScopedCBB cbb;
CBB body, child;
if (!ssl->method->init_message(ssl, cbb.get(), &body,


+ 3
- 3
ssl/handshake_server.cc Просмотреть файл

@@ -303,7 +303,7 @@ static void ssl_get_compatible_server_ciphers(SSL_HANDSHAKE *hs,
uint32_t mask_k = 0;
uint32_t mask_a = 0;

if (ssl_has_certificate(hs->config)) {
if (ssl_has_certificate(hs)) {
mask_a |= ssl_cipher_auth_mask_for_key(hs->local_pubkey.get());
if (EVP_PKEY_id(hs->local_pubkey.get()) == EVP_PKEY_RSA) {
mask_k |= SSL_kRSA;
@@ -868,7 +868,7 @@ static enum ssl_hs_wait_t do_send_server_certificate(SSL_HANDSHAKE *hs) {
ScopedCBB cbb;

if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
if (!ssl_has_certificate(hs->config)) {
if (!ssl_has_certificate(hs)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
return ssl_hs_error;
}
@@ -974,7 +974,7 @@ static enum ssl_hs_wait_t do_send_server_key_exchange(SSL_HANDSHAKE *hs) {

// Add a signature.
if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
if (!ssl_has_private_key(hs->config)) {
if (!ssl_has_private_key(hs)) {
ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}


+ 3
- 3
ssl/internal.h Просмотреть файл

@@ -919,8 +919,8 @@ enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert,

// Private key operations.

// ssl_has_private_key returns whether |cfg| has a private key configured.
bool ssl_has_private_key(const SSL_CONFIG *cfg);
// ssl_has_private_key returns whether |hs| has a private key configured.
bool ssl_has_private_key(const SSL_HANDSHAKE *hs);

// ssl_private_key_* perform the corresponding operation on
// |SSL_PRIVATE_KEY_METHOD|. If there is a custom private key configured, they
@@ -1173,7 +1173,7 @@ int ssl_write_buffer_flush(SSL *ssl);

// ssl_has_certificate returns whether a certificate and private key are
// configured.
bool ssl_has_certificate(const SSL_CONFIG *cfg);
bool ssl_has_certificate(const SSL_HANDSHAKE *hs);

// ssl_parse_cert_chain parses a certificate list from |cbs| in the format used
// by a TLS Certificate message. On success, it advances |cbs| and returns


+ 6
- 6
ssl/ssl_cert.cc Просмотреть файл

@@ -324,10 +324,10 @@ bool ssl_set_cert(CERT *cert, UniquePtr<CRYPTO_BUFFER> buffer) {
return true;
}

bool ssl_has_certificate(const SSL_CONFIG *cfg) {
return cfg->cert->chain != nullptr &&
sk_CRYPTO_BUFFER_value(cfg->cert->chain.get(), 0) != nullptr &&
ssl_has_private_key(cfg);
bool ssl_has_certificate(const SSL_HANDSHAKE *hs) {
return hs->config->cert->chain != nullptr &&
sk_CRYPTO_BUFFER_value(hs->config->cert->chain.get(), 0) != nullptr &&
ssl_has_private_key(hs);
}

bool ssl_parse_cert_chain(uint8_t *out_alert,
@@ -395,7 +395,7 @@ bool ssl_parse_cert_chain(uint8_t *out_alert,
}

bool ssl_add_cert_chain(SSL_HANDSHAKE *hs, CBB *cbb) {
if (!ssl_has_certificate(hs->config)) {
if (!ssl_has_certificate(hs)) {
return CBB_add_u24(cbb, 0);
}

@@ -728,7 +728,7 @@ bool ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey,

bool ssl_on_certificate_selected(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
if (!ssl_has_certificate(hs->config)) {
if (!ssl_has_certificate(hs)) {
// Nothing to do.
return true;
}


+ 3
- 2
ssl/ssl_privkey.cc Просмотреть файл

@@ -133,8 +133,9 @@ static const SSL_SIGNATURE_ALGORITHM *get_signature_algorithm(uint16_t sigalg) {
return NULL;
}

bool ssl_has_private_key(const SSL_CONFIG *cfg) {
return cfg->cert->privatekey != nullptr || cfg->cert->key_method != nullptr;
bool ssl_has_private_key(const SSL_HANDSHAKE *hs) {
return (hs->config->cert->privatekey != nullptr ||
hs->config->cert->key_method != nullptr);
}

static bool pkey_supports_algorithm(const SSL *ssl, EVP_PKEY *pkey,


+ 3
- 2
ssl/ssl_x509.cc Просмотреть файл

@@ -448,7 +448,7 @@ static int ssl_crypto_x509_ssl_auto_chain_if_needed(SSL_HANDSHAKE *hs) {
// Only build a chain if there are no intermediates configured and the feature
// isn't disabled.
if ((hs->ssl->mode & SSL_MODE_NO_AUTO_CHAIN) ||
!ssl_has_certificate(hs->config) || hs->config->cert->chain == NULL ||
!ssl_has_certificate(hs) || hs->config->cert->chain == NULL ||
sk_CRYPTO_BUFFER_num(hs->config->cert->chain.get()) > 1) {
return 1;
}
@@ -1223,7 +1223,8 @@ static int do_client_cert_cb(SSL *ssl, void *arg) {
assert(ssl->config);
return -1;
}
if (ssl_has_certificate(ssl->config.get()) ||

if (ssl_has_certificate(ssl->s3->hs.get()) ||
ssl->ctx->client_cert_cb == NULL) {
return 1;
}


+ 1
- 1
ssl/tls13_both.cc Просмотреть файл

@@ -441,7 +441,7 @@ bool tls13_add_certificate(SSL_HANDSHAKE *hs) {
return false;
}

if (!ssl_has_certificate(hs->config)) {
if (!ssl_has_certificate(hs)) {
return ssl_add_message_cbb(ssl, cbb.get());
}



+ 1
- 1
ssl/tls13_client.cc Просмотреть файл

@@ -685,7 +685,7 @@ static enum ssl_hs_wait_t do_send_client_certificate(SSL_HANDSHAKE *hs) {

static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs) {
// Don't send CertificateVerify if there is no certificate.
if (!ssl_has_certificate(hs->config)) {
if (!ssl_has_certificate(hs)) {
hs->tls13_state = state_complete_second_flight;
return ssl_hs_ok;
}


+ 1
- 1
ssl/tls13_server.cc Просмотреть файл

@@ -662,7 +662,7 @@ static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) {

// Send the server Certificate message, if necessary.
if (!ssl->s3->session_reused) {
if (!ssl_has_certificate(hs->config)) {
if (!ssl_has_certificate(hs)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
return ssl_hs_error;
}


Загрузка…
Отмена
Сохранить