Skip to content

Commit

Permalink
fix certificate parsing when set with ASN1
Browse files Browse the repository at this point in the history
  • Loading branch information
samuel40791765 committed Jul 5, 2023
1 parent 95c9cb4 commit 1b6e672
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
40 changes: 40 additions & 0 deletions ssl/ssl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4842,6 +4842,46 @@ TEST(SSLTest, GetCertificateExData) {
EXPECT_EQ(ex_data3, ex_data);
}

TEST(SSLTest, GetCertificateASN1) {
bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
ASSERT_TRUE(ctx);
bssl::UniquePtr<X509> cert = GetTestCertificate();
ASSERT_TRUE(cert);

// Concert cert to ASN1 to pass in.
uint8_t *der = nullptr;
size_t der_len = i2d_X509(cert.get(), &der);
bssl::UniquePtr<uint8_t> free_der(der);

ASSERT_TRUE(SSL_CTX_use_certificate_ASN1(ctx.get(), der_len, der));
bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
ASSERT_TRUE(ssl);

X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
ASSERT_TRUE(cert2);

X509 *cert3 = SSL_get_certificate(ssl.get());
ASSERT_TRUE(cert3);

// The old and new certificates must be identical.
EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
EXPECT_EQ(0, X509_cmp(cert.get(), cert3));

uint8_t *der2 = nullptr;
long der2_len = i2d_X509(cert2, &der2);
ASSERT_LT(0, der2_len);
bssl::UniquePtr<uint8_t> free_der2(der2);

uint8_t *der3 = nullptr;
long der3_len = i2d_X509(cert3, &der3);
ASSERT_LT(0, der3_len);
bssl::UniquePtr<uint8_t> free_der3(der3);

// They must also encode identically.
EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
}

TEST(SSLTest, SetChainAndKeyMismatch) {
bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
ASSERT_TRUE(ctx);
Expand Down
25 changes: 25 additions & 0 deletions ssl/ssl_x509.cc
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,32 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) {
return ssl_use_certificate(ctx->cert.get(), x);
}

// ssl_cert_cache_leaf_cert sets |cert->x509_leaf|, if currently NULL, from the
// first element of |cert->chain|. This is the case when certs are set with
// |SSL_CTX_use_certificate_ASN1| or |SSL_use_certificate_ASN1| in AWS-LC.
static int ssl_cert_cache_leaf_cert(CERT *cert) {
assert(cert->x509_method);

if (cert->x509_leaf != NULL ||
cert->chain == NULL) {
return 1;
}

CRYPTO_BUFFER *leaf = sk_CRYPTO_BUFFER_value(cert->chain.get(), 0);
if (!leaf) {
return 1;
}

cert->x509_leaf = X509_parse_from_buffer(leaf);
return cert->x509_leaf != NULL;
}

static X509 *ssl_cert_get0_leaf(CERT *cert) {
if (cert->x509_leaf == NULL &&
!ssl_cert_cache_leaf_cert(cert)) {
return NULL;
}

return cert->x509_leaf;
}

Expand Down

0 comments on commit 1b6e672

Please sign in to comment.