Test the implicit cleanup feature of X509_sign_ctx, etc.
The *_sign_ctx APIs implicitly call EVP_MD_CTX_cleanup on return, on
both success and failure. Some callers rely on this to avoid a memory
leak. An earlier iteration of this patch set accidentally broke this.
Add a test so we catch this.
Change-Id: I241b9161606f91adfbc37064304b815145703659
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/81807
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc
index cfb6823..94aeb4e 100644
--- a/crypto/x509/x509_test.cc
+++ b/crypto/x509/x509_test.cc
@@ -2197,7 +2197,7 @@
ASSERT_TRUE(SignatureRoundTrips(md_ctx.get(), pkey.get()));
// RSA-PSS with salt length matching hash length should work when passing in
- // -1 or the value explicitly.
+ // |RSA_PSS_SALTLEN_DIGEST| or the value explicitly.
md_ctx.Reset();
EVP_PKEY_CTX *pkey_ctx;
ASSERT_TRUE(EVP_DigestSignInit(md_ctx.get(), &pkey_ctx, EVP_sha256(), NULL,
@@ -2543,6 +2543,75 @@
}
}
+// The |*_sign_ctx| APIs implicitly call |EVP_MD_CTX_cleanup| on return, on both
+// success and failure. Some callers rely on this to avoid a memory leak. These
+// tests rely on ASan to detect leaks. Test failure by using unsupported RSA-PSS
+// parameters.
+TEST(X509Test, SignImplicitCleanup) {
+ bssl::UniquePtr<EVP_PKEY> pkey(PrivateKeyFromPEM(kRSAKey));
+ ASSERT_TRUE(pkey);
+
+ bssl::UniquePtr<X509> cert = CertFromPEM(kLeafPEM);
+ ASSERT_TRUE(cert);
+ {
+ EVP_MD_CTX ctx;
+ EVP_MD_CTX_init(&ctx);
+ ASSERT_TRUE(
+ EVP_DigestSignInit(&ctx, nullptr, EVP_sha256(), nullptr, pkey.get()));
+ EXPECT_TRUE(X509_sign_ctx(cert.get(), &ctx));
+ }
+ {
+ EVP_MD_CTX ctx;
+ EVP_MD_CTX_init(&ctx);
+ EVP_PKEY_CTX *pkey_ctx;
+ ASSERT_TRUE(
+ EVP_DigestSignInit(&ctx, &pkey_ctx, EVP_sha256(), nullptr, pkey.get()));
+ ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING));
+ ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, 33));
+ EXPECT_FALSE(X509_sign_ctx(cert.get(), &ctx));
+ }
+
+ bssl::UniquePtr<X509_CRL> crl = CRLFromPEM(kBasicCRL);
+ ASSERT_TRUE(crl);
+ {
+ EVP_MD_CTX ctx;
+ EVP_MD_CTX_init(&ctx);
+ ASSERT_TRUE(
+ EVP_DigestSignInit(&ctx, nullptr, EVP_sha256(), nullptr, pkey.get()));
+ EXPECT_TRUE(X509_CRL_sign_ctx(crl.get(), &ctx));
+ }
+ {
+ EVP_MD_CTX ctx;
+ EVP_MD_CTX_init(&ctx);
+ EVP_PKEY_CTX *pkey_ctx;
+ ASSERT_TRUE(
+ EVP_DigestSignInit(&ctx, &pkey_ctx, EVP_sha256(), nullptr, pkey.get()));
+ ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING));
+ ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, 33));
+ EXPECT_FALSE(X509_CRL_sign_ctx(crl.get(), &ctx));
+ }
+
+ bssl::UniquePtr<X509_REQ> csr = CSRFromPEM(kTestCSR);
+ ASSERT_TRUE(csr);
+ {
+ EVP_MD_CTX ctx;
+ EVP_MD_CTX_init(&ctx);
+ ASSERT_TRUE(
+ EVP_DigestSignInit(&ctx, nullptr, EVP_sha256(), nullptr, pkey.get()));
+ EXPECT_TRUE(X509_REQ_sign_ctx(csr.get(), &ctx));
+ }
+ {
+ EVP_MD_CTX ctx;
+ EVP_MD_CTX_init(&ctx);
+ EVP_PKEY_CTX *pkey_ctx;
+ ASSERT_TRUE(
+ EVP_DigestSignInit(&ctx, &pkey_ctx, EVP_sha256(), nullptr, pkey.get()));
+ ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING));
+ ASSERT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, 33));
+ EXPECT_FALSE(X509_REQ_sign_ctx(csr.get(), &ctx));
+ }
+}
+
TEST(X509Test, Ed25519Sign) {
uint8_t pub_bytes[32], priv_bytes[64];
ED25519_keypair(pub_bytes, priv_bytes);