summaryrefslogtreecommitdiff
path: root/src/crypto/x509/x509_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/x509/x509_test.cc')
-rw-r--r--src/crypto/x509/x509_test.cc122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/crypto/x509/x509_test.cc b/src/crypto/x509/x509_test.cc
index 9ed1b52a..bf0b29a2 100644
--- a/src/crypto/x509/x509_test.cc
+++ b/src/crypto/x509/x509_test.cc
@@ -1549,3 +1549,125 @@ TEST(X509Test, MismatchAlgorithms) {
EXPECT_EQ(ERR_LIB_X509, ERR_GET_LIB(err));
EXPECT_EQ(X509_R_SIGNATURE_ALGORITHM_MISMATCH, ERR_GET_REASON(err));
}
+
+TEST(X509Test, PEMX509Info) {
+ std::string cert = kRootCAPEM;
+ auto cert_obj = CertFromPEM(kRootCAPEM);
+ ASSERT_TRUE(cert_obj);
+
+ std::string rsa = kRSAKey;
+ auto rsa_obj = PrivateKeyFromPEM(kRSAKey);
+ ASSERT_TRUE(rsa_obj);
+
+ std::string crl = kBasicCRL;
+ auto crl_obj = CRLFromPEM(kBasicCRL);
+ ASSERT_TRUE(crl_obj);
+
+ std::string unknown =
+ "-----BEGIN UNKNOWN-----\n"
+ "AAAA\n"
+ "-----END UNKNOWN-----\n";
+
+ std::string invalid =
+ "-----BEGIN CERTIFICATE-----\n"
+ "AAAA\n"
+ "-----END CERTIFICATE-----\n";
+
+ // Each X509_INFO contains at most one certificate, CRL, etc. The format
+ // creates a new X509_INFO when a repeated type is seen.
+ std::string pem =
+ // The first few entries have one of everything in different orders.
+ cert + rsa + crl +
+ rsa + crl + cert +
+ // Unknown types are ignored.
+ crl + unknown + cert + rsa +
+ // Seeing a new certificate starts a new entry, so now we have a bunch of
+ // certificate-only entries.
+ cert + cert + cert +
+ // The key folds into the certificate's entry.
+ cert + rsa +
+ // Doubled keys also start new entries.
+ rsa + rsa + rsa + rsa + crl +
+ // As do CRLs.
+ crl + crl;
+
+ const struct ExpectedInfo {
+ const X509 *cert;
+ const EVP_PKEY *key;
+ const X509_CRL *crl;
+ } kExpected[] = {
+ {cert_obj.get(), rsa_obj.get(), crl_obj.get()},
+ {cert_obj.get(), rsa_obj.get(), crl_obj.get()},
+ {cert_obj.get(), rsa_obj.get(), crl_obj.get()},
+ {cert_obj.get(), nullptr, nullptr},
+ {cert_obj.get(), nullptr, nullptr},
+ {cert_obj.get(), nullptr, nullptr},
+ {cert_obj.get(), rsa_obj.get(), nullptr},
+ {nullptr, rsa_obj.get(), nullptr},
+ {nullptr, rsa_obj.get(), nullptr},
+ {nullptr, rsa_obj.get(), nullptr},
+ {nullptr, rsa_obj.get(), crl_obj.get()},
+ {nullptr, nullptr, crl_obj.get()},
+ {nullptr, nullptr, crl_obj.get()},
+ };
+
+ auto check_info = [](const ExpectedInfo *expected, const X509_INFO *info) {
+ if (expected->cert != nullptr) {
+ EXPECT_EQ(0, X509_cmp(expected->cert, info->x509));
+ } else {
+ EXPECT_EQ(nullptr, info->x509);
+ }
+ if (expected->crl != nullptr) {
+ EXPECT_EQ(0, X509_CRL_cmp(expected->crl, info->crl));
+ } else {
+ EXPECT_EQ(nullptr, info->crl);
+ }
+ if (expected->key != nullptr) {
+ ASSERT_NE(nullptr, info->x_pkey);
+ // EVP_PKEY_cmp returns one if the keys are equal.
+ EXPECT_EQ(1, EVP_PKEY_cmp(expected->key, info->x_pkey->dec_pkey));
+ } else {
+ EXPECT_EQ(nullptr, info->x_pkey);
+ }
+ };
+
+ bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem.data(), pem.size()));
+ ASSERT_TRUE(bio);
+ bssl::UniquePtr<STACK_OF(X509_INFO)> infos(
+ PEM_X509_INFO_read_bio(bio.get(), nullptr, nullptr, nullptr));
+ ASSERT_TRUE(infos);
+ ASSERT_EQ(OPENSSL_ARRAY_SIZE(kExpected), sk_X509_INFO_num(infos.get()));
+ for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kExpected); i++) {
+ SCOPED_TRACE(i);
+ check_info(&kExpected[i], sk_X509_INFO_value(infos.get(), i));
+ }
+
+ // Passing an existing stack appends to it.
+ bio.reset(BIO_new_mem_buf(pem.data(), pem.size()));
+ ASSERT_TRUE(bio);
+ ASSERT_EQ(infos.get(),
+ PEM_X509_INFO_read_bio(bio.get(), infos.get(), nullptr, nullptr));
+ ASSERT_EQ(2 * OPENSSL_ARRAY_SIZE(kExpected), sk_X509_INFO_num(infos.get()));
+ for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kExpected); i++) {
+ SCOPED_TRACE(i);
+ check_info(&kExpected[i], sk_X509_INFO_value(infos.get(), i));
+ check_info(
+ &kExpected[i],
+ sk_X509_INFO_value(infos.get(), i + OPENSSL_ARRAY_SIZE(kExpected)));
+ }
+
+ // Gracefully handle errors in both the append and fresh cases.
+ std::string bad_pem = cert + cert + invalid;
+
+ bio.reset(BIO_new_mem_buf(bad_pem.data(), bad_pem.size()));
+ ASSERT_TRUE(bio);
+ bssl::UniquePtr<STACK_OF(X509_INFO)> infos2(
+ PEM_X509_INFO_read_bio(bio.get(), nullptr, nullptr, nullptr));
+ EXPECT_FALSE(infos2);
+
+ bio.reset(BIO_new_mem_buf(bad_pem.data(), bad_pem.size()));
+ ASSERT_TRUE(bio);
+ EXPECT_FALSE(
+ PEM_X509_INFO_read_bio(bio.get(), infos.get(), nullptr, nullptr));
+ EXPECT_EQ(2 * OPENSSL_ARRAY_SIZE(kExpected), sk_X509_INFO_num(infos.get()));
+}