update master-with-bazel from master branch

This commit is contained in:
BoringSSL Robot
2024-02-23 16:37:48 +00:00
6 changed files with 142 additions and 44 deletions
+28 -10
View File
@@ -848,15 +848,22 @@ OPENSSL_EXPORT void SSL_CTX_set0_buffer_pool(SSL_CTX *ctx,
// the wire) but does not include the leaf. Both client and server certificates
// use these functions.
//
// Prefer to configure the certificate before the private key. If configured in
// the other order, inconsistent private keys will be silently dropped, rather
// than return an error. Additionally, overwriting a previously-configured
// certificate and key pair only works if the certificate is configured first.
//
// Certificates and keys may be configured before the handshake or dynamically
// in the early callback and certificate callback.
// SSL_CTX_use_certificate sets |ctx|'s leaf certificate to |x509|. It returns
// one on success and zero on failure.
// one on success and zero on failure. If |ctx| has a private key which is
// inconsistent with |x509|, the private key is silently dropped.
OPENSSL_EXPORT int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x509);
// SSL_use_certificate sets |ssl|'s leaf certificate to |x509|. It returns one
// on success and zero on failure.
// on success and zero on failure. If |ssl| has a private key which is
// inconsistent with |x509|, the private key is silently dropped.
OPENSSL_EXPORT int SSL_use_certificate(SSL *ssl, X509 *x509);
// SSL_CTX_use_PrivateKey sets |ctx|'s private key to |pkey|. It returns one on
@@ -990,14 +997,6 @@ SSL_get0_peer_delegation_algorithms(const SSL *ssl,
// chain of |ssl|.
OPENSSL_EXPORT void SSL_certs_clear(SSL *ssl);
// SSL_CTX_check_private_key returns one if the certificate and private key
// configured in |ctx| are consistent and zero otherwise.
OPENSSL_EXPORT int SSL_CTX_check_private_key(const SSL_CTX *ctx);
// SSL_check_private_key returns one if the certificate and private key
// configured in |ssl| are consistent and zero otherwise.
OPENSSL_EXPORT int SSL_check_private_key(const SSL *ssl);
// SSL_CTX_get0_certificate returns |ctx|'s leaf certificate.
OPENSSL_EXPORT X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx);
@@ -5317,6 +5316,25 @@ OPENSSL_EXPORT int SSL_set1_curves_list(SSL *ssl, const char *curves);
// returns this value, but we define this constant for compatibility.
#define TLSEXT_nid_unknown 0x1000000
// SSL_CTX_check_private_key returns one if |ctx| has both a certificate and
// private key, and zero otherwise.
//
// This function does not check consistency because the library checks when the
// certificate and key are individually configured. However, if the private key
// is configured before the certificate, inconsistent private keys are silently
// dropped. Some callers are inadvertently relying on this function to detect
// when this happens.
//
// Instead, callers should configure the certificate first, then the private
// key, checking for errors in each. This function is then unnecessary.
OPENSSL_EXPORT int SSL_CTX_check_private_key(const SSL_CTX *ctx);
// SSL_check_private_key returns one if |ssl| has both a certificate and private
// key, and zero otherwise.
//
// See discussion in |SSL_CTX_check_private_key|.
OPENSSL_EXPORT int SSL_check_private_key(const SSL *ssl);
// Compliance policy configurations
//
-1
View File
@@ -3202,7 +3202,6 @@ bool ssl_is_key_type_supported(int key_type);
// message on the error queue.
bool ssl_compare_public_and_private_key(const EVP_PKEY *pubkey,
const EVP_PKEY *privkey);
bool ssl_cert_check_private_key(const CERT *cert, const EVP_PKEY *privkey);
bool ssl_get_new_session(SSL_HANDSHAKE *hs);
bool ssl_encrypt_ticket(SSL_HANDSHAKE *hs, CBB *out,
const SSL_SESSION *session);
-24
View File
@@ -493,30 +493,6 @@ bool ssl_compare_public_and_private_key(const EVP_PKEY *pubkey,
return false;
}
bool ssl_cert_check_private_key(const CERT *cert, const EVP_PKEY *privkey) {
if (privkey == nullptr) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
return false;
}
if (cert->chain == nullptr ||
sk_CRYPTO_BUFFER_value(cert->chain.get(), 0) == nullptr) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
return false;
}
CBS cert_cbs;
CRYPTO_BUFFER_init_CBS(sk_CRYPTO_BUFFER_value(cert->chain.get(), 0),
&cert_cbs);
UniquePtr<EVP_PKEY> pubkey = ssl_cert_parse_pubkey(&cert_cbs);
if (!pubkey) {
OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
return false;
}
return ssl_compare_public_and_private_key(pubkey.get(), privkey);
}
bool ssl_cert_check_key_usage(const CBS *in, enum ssl_key_usage_t bit) {
CBS buf = *in;
+23 -4
View File
@@ -1724,17 +1724,36 @@ int SSL_has_pending(const SSL *ssl) {
return SSL_pending(ssl) != 0 || !ssl->s3->read_buffer.empty();
}
static bool has_cert_and_key(const CERT *cert) {
// TODO(davidben): If |cert->key_method| is set, that should be fine too.
if (cert->privatekey == nullptr) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
return false;
}
if (cert->chain == nullptr ||
sk_CRYPTO_BUFFER_value(cert->chain.get(), 0) == nullptr) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
return false;
}
return true;
}
int SSL_CTX_check_private_key(const SSL_CTX *ctx) {
return ssl_cert_check_private_key(ctx->cert.get(),
ctx->cert->privatekey.get());
// There is no need to actually check consistency because inconsistent values
// can never be configured.
return has_cert_and_key(ctx->cert.get());
}
int SSL_check_private_key(const SSL *ssl) {
if (!ssl->config) {
return 0;
}
return ssl_cert_check_private_key(ssl->config->cert.get(),
ssl->config->cert->privatekey.get());
// There is no need to actually check consistency because inconsistent values
// can never be configured.
return has_cert_and_key(ssl->config->cert.get());
}
long SSL_get_default_timeout(const SSL *ssl) {
+15 -5
View File
@@ -83,11 +83,21 @@ static bool ssl_set_pkey(CERT *cert, EVP_PKEY *pkey) {
return false;
}
if (cert->chain != nullptr &&
sk_CRYPTO_BUFFER_value(cert->chain.get(), 0) != nullptr &&
// Sanity-check that the private key and the certificate match.
!ssl_cert_check_private_key(cert, pkey)) {
return false;
// If the leaf certificate has been configured, check it matches.
const CRYPTO_BUFFER *leaf = cert->chain != nullptr
? sk_CRYPTO_BUFFER_value(cert->chain.get(), 0)
: nullptr;
if (leaf != nullptr) {
CBS cert_cbs;
CRYPTO_BUFFER_init_CBS(leaf, &cert_cbs);
UniquePtr<EVP_PKEY> pubkey = ssl_cert_parse_pubkey(&cert_cbs);
if (!pubkey) {
OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
return false;
}
if (!ssl_compare_public_and_private_key(pubkey.get(), pkey)) {
return false;
}
}
cert->privatekey = UpRef(pkey);
+76
View File
@@ -4556,6 +4556,82 @@ TEST(SSLTest, SetChainAndKeyMismatch) {
ERR_clear_error();
}
TEST(SSLTest, CertThenKeyMismatch) {
bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
ASSERT_TRUE(ctx);
bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
ASSERT_TRUE(key);
bssl::UniquePtr<X509> leaf = GetChainTestCertificate();
ASSERT_TRUE(leaf);
// There is no key or certificate, so |SSL_CTX_check_private_key| fails.
EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
// With only a certificate, |SSL_CTX_check_private_key| still fails.
ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf.get()));
EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
// The private key does not match the certificate, so it should fail.
EXPECT_FALSE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
// Checking the private key fails, but this is really because there is still
// no private key.
EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
EXPECT_EQ(nullptr, SSL_CTX_get0_privatekey(ctx.get()));
}
TEST(SSLTest, KeyThenCertMismatch) {
bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
ASSERT_TRUE(ctx);
bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
ASSERT_TRUE(key);
bssl::UniquePtr<X509> leaf = GetChainTestCertificate();
ASSERT_TRUE(leaf);
// There is no key or certificate, so |SSL_CTX_check_private_key| fails.
EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
// With only a key, |SSL_CTX_check_private_key| still fails.
ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
// If configuring a certificate that doesn't match the key, configuration
// actually succeeds. We just silently drop the private key.
ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf.get()));
EXPECT_EQ(nullptr, SSL_CTX_get0_privatekey(ctx.get()));
// Some callers configure the private key, then the certificate, and then
// expect |SSL_CTX_check_private_key| to check consistency. It does, but only
// by way of noticing there is no private key. The actual consistency check
// happened in |SSL_CTX_use_certificate|.
EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
}
TEST(SSLTest, OverrideCertAndKey) {
// It is possible to override an existing certificate by configuring
// certificate, then key, due to |SSL_CTX_use_certificate|'s above silent
// dropping behavior.
bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
ASSERT_TRUE(ctx);
bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
ASSERT_TRUE(key);
bssl::UniquePtr<X509> leaf = GetTestCertificate();
ASSERT_TRUE(leaf);
bssl::UniquePtr<EVP_PKEY> key2 = GetChainTestKey();
ASSERT_TRUE(key2);
bssl::UniquePtr<X509> leaf2 = GetChainTestCertificate();
ASSERT_TRUE(leaf2);
ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf.get()));
ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf2.get()));
ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key2.get()));
}
TEST(SSLTest, SetChainAndKeyCtx) {
bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
ASSERT_TRUE(client_ctx);