Index: net/cert/internal/verify_certificate_chain_unittest.cc |
diff --git a/net/cert/internal/verify_certificate_chain_unittest.cc b/net/cert/internal/verify_certificate_chain_unittest.cc |
index 9103f12f3df0298ae230c4f5392d87f32e607e35..f14300ce4d796b1388d7a584b9c864332b2f9f3e 100644 |
--- a/net/cert/internal/verify_certificate_chain_unittest.cc |
+++ b/net/cert/internal/verify_certificate_chain_unittest.cc |
@@ -4,254 +4,41 @@ |
#include "net/cert/internal/verify_certificate_chain.h" |
-#include "base/base_paths.h" |
-#include "base/files/file_util.h" |
-#include "base/path_service.h" |
-#include "base/strings/string_split.h" |
-#include "base/strings/string_util.h" |
-#include "base/strings/stringprintf.h" |
-#include "net/cert/internal/parsed_certificate.h" |
#include "net/cert/internal/signature_policy.h" |
-#include "net/cert/internal/test_helpers.h" |
#include "net/cert/internal/trust_store.h" |
-#include "net/cert/pem_tokenizer.h" |
-#include "net/der/input.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
+#include "net/cert/internal/verify_certificate_chain_typed_unittest.h" |
namespace net { |
namespace { |
-// Reads a data file from the unit-test data. |
-std::string ReadTestFileToString(const std::string& file_name) { |
- // Compute the full path, relative to the src/ directory. |
- base::FilePath src_root; |
- PathService::Get(base::DIR_SOURCE_ROOT, &src_root); |
- base::FilePath filepath = src_root.AppendASCII( |
- std::string("net/data/verify_certificate_chain_unittest/") + file_name); |
+class VerifyCertificateChainAssumingTrustedRootDelegate { |
+ public: |
+ static void Verify(const std::vector<scoped_refptr<ParsedCertificate>>& chain, |
+ const std::vector<scoped_refptr<ParsedCertificate>>& roots, |
+ const der::GeneralizedTime& time, |
+ bool expected_result) { |
+ TrustStore trust_store; |
+ ASSERT_EQ(1U, roots.size()); |
+ trust_store.AddTrustedCertificate(roots[0]); |
- // Read the full contents of the file. |
- std::string file_data; |
- if (!base::ReadFileToString(filepath, &file_data)) { |
- ADD_FAILURE() << "Couldn't read file: " << filepath.value(); |
- return std::string(); |
- } |
- |
- return file_data; |
-} |
- |
-// Reads a test case from |file_name|. Test cases are comprised of a |
-// certificate chain, trust store, a timestamp to validate at, and the |
-// expected result of verification. |
-void ReadTestFromFile(const std::string& file_name, |
- std::vector<std::string>* chain, |
- TrustStore* trust_store, |
- der::GeneralizedTime* time, |
- bool* verify_result) { |
- chain->clear(); |
- trust_store->Clear(); |
- |
- std::string file_data = ReadTestFileToString(file_name); |
- |
- std::vector<std::string> pem_headers; |
- |
- const char kCertificateHeader[] = "CERTIFICATE"; |
- const char kTrustedCertificateHeader[] = "TRUSTED_CERTIFICATE"; |
- const char kTimeHeader[] = "TIME"; |
- const char kResultHeader[] = "VERIFY_RESULT"; |
- |
- pem_headers.push_back(kCertificateHeader); |
- pem_headers.push_back(kTrustedCertificateHeader); |
- pem_headers.push_back(kTimeHeader); |
- pem_headers.push_back(kResultHeader); |
- |
- bool has_time = false; |
- bool has_result = false; |
- |
- PEMTokenizer pem_tokenizer(file_data, pem_headers); |
- while (pem_tokenizer.GetNext()) { |
- const std::string& block_type = pem_tokenizer.block_type(); |
- const std::string& block_data = pem_tokenizer.data(); |
- |
- if (block_type == kCertificateHeader) { |
- chain->push_back(block_data); |
- } else if (block_type == kTrustedCertificateHeader) { |
- scoped_refptr<ParsedCertificate> cert( |
- ParsedCertificate::CreateFromCertificateCopy(block_data, {})); |
- ASSERT_TRUE(cert); |
- trust_store->AddTrustedCertificate(std::move(cert)); |
- } else if (block_type == kTimeHeader) { |
- ASSERT_FALSE(has_time) << "Duplicate " << kTimeHeader; |
- has_time = true; |
- ASSERT_TRUE(der::ParseUTCTime(der::Input(&block_data), time)); |
- } else if (block_type == kResultHeader) { |
- ASSERT_FALSE(has_result) << "Duplicate " << kResultHeader; |
- ASSERT_TRUE(block_data == "SUCCESS" || block_data == "FAIL") |
- << "Unrecognized result: " << block_data; |
- has_result = true; |
- *verify_result = block_data == "SUCCESS"; |
- } |
- } |
- |
- ASSERT_TRUE(has_time); |
- ASSERT_TRUE(has_result); |
-} |
+ std::vector<scoped_refptr<ParsedCertificate>> full_chain(chain); |
+ full_chain.push_back(roots[0]); |
-void RunTest(const char* file_name) { |
- std::vector<std::string> chain; |
- TrustStore trust_store; |
- der::GeneralizedTime time; |
- bool expected_result; |
+ SimpleSignaturePolicy signature_policy(1024); |
- ReadTestFromFile(file_name, &chain, &trust_store, &time, &expected_result); |
+ bool result = VerifyCertificateChainAssumingTrustedRoot( |
+ full_chain, trust_store, &signature_policy, time); |
- std::vector<scoped_refptr<net::ParsedCertificate>> input_chain; |
- for (const auto& cert_der : chain) { |
- ASSERT_TRUE(net::ParsedCertificate::CreateAndAddToVector( |
- reinterpret_cast<const uint8_t*>(cert_der.data()), cert_der.size(), |
- net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, {}, |
- &input_chain)); |
+ ASSERT_EQ(expected_result, result); |
} |
- |
- SimpleSignaturePolicy signature_policy(1024); |
- |
- std::vector<scoped_refptr<ParsedCertificate>> trusted_chain; |
- bool result = VerifyCertificateChain(input_chain, trust_store, |
- &signature_policy, time, &trusted_chain); |
- if (result) { |
- ASSERT_EQ(trusted_chain.size(), input_chain.size() + 1); |
- ASSERT_TRUE(std::equal(input_chain.begin(), input_chain.end(), |
- trusted_chain.begin())); |
- ASSERT_TRUE(trust_store.IsTrustedCertificate(trusted_chain.back().get())); |
- } else { |
- ASSERT_EQ(trusted_chain.size(), 0u); |
- } |
- |
- ASSERT_EQ(expected_result, result); |
-} |
- |
-TEST(VerifyCertificateChainTest, TargetAndIntermediary) { |
- RunTest("target-and-intermediary.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, UnknownRoot) { |
- RunTest("unknown-root.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, IntermediaryLacksBasicConstraints) { |
- RunTest("intermediary-lacks-basic-constraints.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, IntermediaryBasicConstraintsCaFalse) { |
- RunTest("intermediary-basic-constraints-ca-false.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, IntermediaryBasicConstraintsNotCritical) { |
- RunTest("intermediary-basic-constraints-not-critical.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, IntermediaryLacksSigningKeyUsage) { |
- RunTest("intermediary-lacks-signing-key-usage.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, IntermediaryUnknownCriticalExtension) { |
- RunTest("intermediary-unknown-critical-extension.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, IntermediaryUnknownNonCriticalExtension) { |
- RunTest("intermediary-unknown-non-critical-extension.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, ViolatesBasicConstraintsPathlen0) { |
- RunTest("violates-basic-constraints-pathlen-0.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, BasicConstraintsPathlen0SelfIssued) { |
- RunTest("basic-constraints-pathlen-0-self-issued.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, TargetSignedWithMd5) { |
- RunTest("target-signed-with-md5.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, IntermediarySignedWithMd5) { |
- RunTest("intermediary-signed-with-md5.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, TargetWrongSignature) { |
- RunTest("target-wrong-signature.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, TargetSignedBy512bitRsa) { |
- RunTest("target-signed-by-512bit-rsa.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, TargetSignedUsingEcdsa) { |
- RunTest("target-signed-using-ecdsa.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, ExpiredIntermediary) { |
- RunTest("expired-intermediary.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, ExpiredTarget) { |
- RunTest("expired-target.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, ExpiredTargetNotBefore) { |
- RunTest("expired-target-notBefore.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, ExpiredRoot) { |
- RunTest("expired-root.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, TargetNotEndEntity) { |
- RunTest("target-not-end-entity.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, TargetHasKeyCertSignButNotCa) { |
- RunTest("target-has-keycertsign-but-not-ca.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, TargetHasPathlenButNotCa) { |
- RunTest("target-has-pathlen-but-not-ca.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, TargetUnknownCriticalExtension) { |
- RunTest("target-unknown-critical-extension.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, IssuerAndSubjectNotByteForByteEqual) { |
- RunTest("issuer-and-subject-not-byte-for-byte-equal.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, IssuerAndSubjectNotByteForByteEqualAnchor) { |
- RunTest("issuer-and-subject-not-byte-for-byte-equal-anchor.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, ViolatesPathlen1Root) { |
- RunTest("violates-pathlen-1-root.pem"); |
-} |
- |
-TEST(VerifyCertificateChainTest, NonSelfSignedRoot) { |
- RunTest("non-self-signed-root.pem"); |
-} |
- |
-// Tests that verifying a chain with no certificates fails. |
-TEST(VerifyCertificateChainTest, EmptyChainIsInvalid) { |
- TrustStore trust_store; |
- der::GeneralizedTime time; |
- std::vector<scoped_refptr<ParsedCertificate>> chain; |
- SimpleSignaturePolicy signature_policy(2048); |
- |
- ASSERT_FALSE(VerifyCertificateChain(chain, trust_store, &signature_policy, |
- time, nullptr)); |
-} |
- |
-// TODO(eroman): Add test that invalidate validity dates where the day or month |
-// ordinal not in range, like "March 39, 2016" are rejected. |
+}; |
} // namespace |
+INSTANTIATE_TYPED_TEST_CASE_P( |
+ VerifyCertificateChainAssumingTrustedRoot, |
+ VerifyCertificateChainSingleRootTest, |
+ VerifyCertificateChainAssumingTrustedRootDelegate); |
+ |
} // namespace net |