| Index: net/cert/internal/parse_certificate_unittest.cc
|
| diff --git a/net/cert/internal/parse_certificate_unittest.cc b/net/cert/internal/parse_certificate_unittest.cc
|
| index ebdec7b849659c071b0b512af0319d9876a86daa..82e6db5f4937226c766c50af970eacb598a126b0 100644
|
| --- a/net/cert/internal/parse_certificate_unittest.cc
|
| +++ b/net/cert/internal/parse_certificate_unittest.cc
|
| @@ -122,8 +122,11 @@ TEST(ParseCertificateTest, AlgorithmNotSequence) {
|
| // Loads tbsCertificate data and expectations from the PEM file |file_name|.
|
| // Verifies that parsing the TBSCertificate succeeds, and each parsed field
|
| // matches the expectations.
|
| -void EnsureParsingTbsSucceeds(const std::string& file_name,
|
| - CertificateVersion expected_version) {
|
| +//
|
| +// TODO(eroman): Get rid of the |expected_version| parameter -- this should be
|
| +// encoded in the test expectations file.
|
| +void RunTbsCertificateTestGivenVersion(const std::string& file_name,
|
| + CertificateVersion expected_version) {
|
| std::string data;
|
| std::string expected_serial_number;
|
| std::string expected_signature_algorithm;
|
| @@ -135,26 +138,39 @@ void EnsureParsingTbsSucceeds(const std::string& file_name,
|
| std::string expected_issuer_unique_id;
|
| std::string expected_subject_unique_id;
|
| std::string expected_extensions;
|
| + std::string expected_errors;
|
|
|
| // Read the certificate data and test expectations from a single PEM file.
|
| const PemBlockMapping mappings[] = {
|
| {"TBS CERTIFICATE", &data},
|
| - {"SIGNATURE ALGORITHM", &expected_signature_algorithm},
|
| - {"SERIAL NUMBER", &expected_serial_number},
|
| - {"ISSUER", &expected_issuer},
|
| - {"VALIDITY NOTBEFORE", &expected_validity_not_before},
|
| - {"VALIDITY NOTAFTER", &expected_validity_not_after},
|
| - {"SUBJECT", &expected_subject},
|
| - {"SPKI", &expected_spki},
|
| + {"SIGNATURE ALGORITHM", &expected_signature_algorithm, true},
|
| + {"SERIAL NUMBER", &expected_serial_number, true},
|
| + {"ISSUER", &expected_issuer, true},
|
| + {"VALIDITY NOTBEFORE", &expected_validity_not_before, true},
|
| + {"VALIDITY NOTAFTER", &expected_validity_not_after, true},
|
| + {"SUBJECT", &expected_subject, true},
|
| + {"SPKI", &expected_spki, true},
|
| {"ISSUER UNIQUE ID", &expected_issuer_unique_id, true},
|
| {"SUBJECT UNIQUE ID", &expected_subject_unique_id, true},
|
| {"EXTENSIONS", &expected_extensions, true},
|
| + {"ERRORS", &expected_errors, true},
|
| };
|
| - ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));
|
| + std::string test_file_path = GetFilePath(file_name);
|
| + ASSERT_TRUE(ReadTestDataFromPemFile(test_file_path, mappings));
|
| +
|
| + bool expected_result = !expected_spki.empty();
|
|
|
| - // Parsing the TBSCertificate should succeed.
|
| ParsedTbsCertificate parsed;
|
| - ASSERT_TRUE(ParseTbsCertificate(der::Input(&data), {}, &parsed));
|
| + CertErrors errors;
|
| + bool actual_result =
|
| + ParseTbsCertificate(der::Input(&data), {}, &parsed, &errors);
|
| +
|
| + EXPECT_EQ(expected_result, actual_result);
|
| + EXPECT_EQ(expected_errors, errors.ToDebugString()) << "Test file: "
|
| + << test_file_path;
|
| +
|
| + if (!expected_result || !actual_result)
|
| + return;
|
|
|
| // Ensure that the ParsedTbsCertificate matches expectations.
|
| EXPECT_EQ(expected_version, parsed.version);
|
| @@ -184,30 +200,18 @@ void EnsureParsingTbsSucceeds(const std::string& file_name,
|
| EXPECT_EQ(!expected_extensions.empty(), parsed.has_extensions);
|
| }
|
|
|
| -// Loads certificate data from the PEM file |file_name| and verifies that the
|
| -// Certificate parsing succeed, however the TBSCertificate parsing fails.
|
| -void EnsureParsingTbsFails(const std::string& file_name) {
|
| - std::string data;
|
| -
|
| - const PemBlockMapping mappings[] = {
|
| - {"TBS CERTIFICATE", &data},
|
| - };
|
| -
|
| - ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings));
|
| -
|
| - // Parsing the TBSCertificate should fail.
|
| - ParsedTbsCertificate parsed;
|
| - ASSERT_FALSE(ParseTbsCertificate(der::Input(&data), {}, &parsed));
|
| +void RunTbsCertificateTest(const std::string& file_name) {
|
| + RunTbsCertificateTestGivenVersion(file_name, CertificateVersion::V3);
|
| }
|
|
|
| // Tests parsing a TBSCertificate for v3 that contains no optional fields.
|
| TEST(ParseTbsCertificateTest, Version3NoOptionals) {
|
| - EnsureParsingTbsSucceeds("tbs_v3_no_optionals.pem", CertificateVersion::V3);
|
| + RunTbsCertificateTest("tbs_v3_no_optionals.pem");
|
| }
|
|
|
| // Tests parsing a TBSCertificate for v3 that contains extensions.
|
| TEST(ParseTbsCertificateTest, Version3WithExtensions) {
|
| - EnsureParsingTbsSucceeds("tbs_v3_extensions.pem", CertificateVersion::V3);
|
| + RunTbsCertificateTest("tbs_v3_extensions.pem");
|
| }
|
|
|
| // Tests parsing a TBSCertificate for v3 that contains no optional fields, and
|
| @@ -216,115 +220,111 @@ TEST(ParseTbsCertificateTest, Version3WithExtensions) {
|
| // CAs are not supposed to include negative serial numbers, however RFC 5280
|
| // expects consumers to deal with it anyway).
|
| TEST(ParseTbsCertificateTest, NegativeSerialNumber) {
|
| - EnsureParsingTbsSucceeds("tbs_negative_serial_number.pem",
|
| - CertificateVersion::V3);
|
| + RunTbsCertificateTest("tbs_negative_serial_number.pem");
|
| }
|
|
|
| // Tests parsing a TBSCertificate with a serial number that is 21 octets long
|
| // (and the first byte is 0).
|
| TEST(ParseTbCertificateTest, SerialNumber21OctetsLeading0) {
|
| - EnsureParsingTbsFails("tbs_serial_number_21_octets_leading_0.pem");
|
| + RunTbsCertificateTest("tbs_serial_number_21_octets_leading_0.pem");
|
| }
|
|
|
| // Tests parsing a TBSCertificate with a serial number that is 26 octets long
|
| // (and does not contain a leading 0).
|
| TEST(ParseTbsCertificateTest, SerialNumber26Octets) {
|
| - EnsureParsingTbsFails("tbs_serial_number_26_octets.pem");
|
| + RunTbsCertificateTest("tbs_serial_number_26_octets.pem");
|
| }
|
|
|
| // Tests parsing a TBSCertificate which lacks a version number (causing it to
|
| // default to v1).
|
| TEST(ParseTbsCertificateTest, Version1) {
|
| - EnsureParsingTbsSucceeds("tbs_v1.pem", CertificateVersion::V1);
|
| + RunTbsCertificateTestGivenVersion("tbs_v1.pem", CertificateVersion::V1);
|
| }
|
|
|
| // The version was set to v1 explicitly rather than omitting the version field.
|
| TEST(ParseTbsCertificateTest, ExplicitVersion1) {
|
| - EnsureParsingTbsFails("tbs_explicit_v1.pem");
|
| + RunTbsCertificateTest("tbs_explicit_v1.pem");
|
| }
|
|
|
| // Extensions are not defined in version 1.
|
| TEST(ParseTbsCertificateTest, Version1WithExtensions) {
|
| - EnsureParsingTbsFails("tbs_v1_extensions.pem");
|
| + RunTbsCertificateTest("tbs_v1_extensions.pem");
|
| }
|
|
|
| // Extensions are not defined in version 2.
|
| TEST(ParseTbsCertificateTest, Version2WithExtensions) {
|
| - EnsureParsingTbsFails("tbs_v2_extensions.pem");
|
| + RunTbsCertificateTest("tbs_v2_extensions.pem");
|
| }
|
|
|
| // A boring version 2 certificate with none of the optional fields.
|
| TEST(ParseTbsCertificateTest, Version2NoOptionals) {
|
| - EnsureParsingTbsSucceeds("tbs_v2_no_optionals.pem", CertificateVersion::V2);
|
| + RunTbsCertificateTestGivenVersion("tbs_v2_no_optionals.pem",
|
| + CertificateVersion::V2);
|
| }
|
|
|
| // A version 2 certificate with an issuer unique ID field.
|
| TEST(ParseTbsCertificateTest, Version2IssuerUniqueId) {
|
| - EnsureParsingTbsSucceeds("tbs_v2_issuer_unique_id.pem",
|
| - CertificateVersion::V2);
|
| + RunTbsCertificateTestGivenVersion("tbs_v2_issuer_unique_id.pem",
|
| + CertificateVersion::V2);
|
| }
|
|
|
| // A version 2 certificate with both a issuer and subject unique ID field.
|
| TEST(ParseTbsCertificateTest, Version2IssuerAndSubjectUniqueId) {
|
| - EnsureParsingTbsSucceeds("tbs_v2_issuer_and_subject_unique_id.pem",
|
| - CertificateVersion::V2);
|
| + RunTbsCertificateTestGivenVersion("tbs_v2_issuer_and_subject_unique_id.pem",
|
| + CertificateVersion::V2);
|
| }
|
|
|
| // A version 3 certificate with all of the optional fields (issuer unique id,
|
| // subject unique id, and extensions).
|
| TEST(ParseTbsCertificateTest, Version3AllOptionals) {
|
| - EnsureParsingTbsSucceeds("tbs_v3_all_optionals.pem", CertificateVersion::V3);
|
| + RunTbsCertificateTest("tbs_v3_all_optionals.pem");
|
| }
|
|
|
| // The version was set to v4, which is unrecognized.
|
| TEST(ParseTbsCertificateTest, Version4) {
|
| - EnsureParsingTbsFails("tbs_v4.pem");
|
| + RunTbsCertificateTest("tbs_v4.pem");
|
| }
|
|
|
| // Tests that extraneous data after extensions in a v3 is rejected.
|
| TEST(ParseTbsCertificateTest, Version3DataAfterExtensions) {
|
| - EnsureParsingTbsFails("tbs_v3_data_after_extensions.pem");
|
| + RunTbsCertificateTest("tbs_v3_data_after_extensions.pem");
|
| }
|
|
|
| // Tests using a real-world certificate (whereas the other tests are fabricated
|
| // (and in fact invalid) data.
|
| TEST(ParseTbsCertificateTest, Version3Real) {
|
| - EnsureParsingTbsSucceeds("tbs_v3_real.pem", CertificateVersion::V3);
|
| + RunTbsCertificateTest("tbs_v3_real.pem");
|
| }
|
|
|
| // Parses a TBSCertificate whose "validity" field expresses both notBefore
|
| // and notAfter using UTCTime.
|
| TEST(ParseTbsCertificateTest, ValidityBothUtcTime) {
|
| - EnsureParsingTbsSucceeds("tbs_validity_both_utc_time.pem",
|
| - CertificateVersion::V3);
|
| + RunTbsCertificateTest("tbs_validity_both_utc_time.pem");
|
| }
|
|
|
| // Parses a TBSCertificate whose "validity" field expresses both notBefore
|
| // and notAfter using GeneralizedTime.
|
| TEST(ParseTbsCertificateTest, ValidityBothGeneralizedTime) {
|
| - EnsureParsingTbsSucceeds("tbs_validity_both_generalized_time.pem",
|
| - CertificateVersion::V3);
|
| + RunTbsCertificateTest("tbs_validity_both_generalized_time.pem");
|
| }
|
|
|
| // Parses a TBSCertificate whose "validity" field expresses notBefore using
|
| // UTCTime and notAfter using GeneralizedTime.
|
| TEST(ParseTbsCertificateTest, ValidityUTCTimeAndGeneralizedTime) {
|
| - EnsureParsingTbsSucceeds("tbs_validity_utc_time_and_generalized_time.pem",
|
| - CertificateVersion::V3);
|
| + RunTbsCertificateTest("tbs_validity_utc_time_and_generalized_time.pem");
|
| }
|
|
|
| // Parses a TBSCertificate whose validity" field expresses notBefore using
|
| // GeneralizedTime and notAfter using UTCTime. Also of interest, notBefore >
|
| // notAfter. Parsing will succeed, however no time can satisfy this constraint.
|
| TEST(ParseTbsCertificateTest, ValidityGeneralizedTimeAndUTCTime) {
|
| - EnsureParsingTbsSucceeds("tbs_validity_generalized_time_and_utc_time.pem",
|
| - CertificateVersion::V3);
|
| + RunTbsCertificateTest("tbs_validity_generalized_time_and_utc_time.pem");
|
| }
|
|
|
| // Parses a TBSCertificate whose "validity" field does not strictly follow
|
| // the DER rules (and fails to be parsed).
|
| TEST(ParseTbsCertificateTest, ValidityRelaxed) {
|
| - EnsureParsingTbsFails("tbs_validity_relaxed.pem");
|
| + RunTbsCertificateTest("tbs_validity_relaxed.pem");
|
| }
|
|
|
| // Reads a PEM file containing a block "EXTENSION". This input will be
|
|
|