Index: net/cert/internal/parsed_certificate_unittest.cc |
diff --git a/net/cert/internal/parsed_certificate_unittest.cc b/net/cert/internal/parsed_certificate_unittest.cc |
index db1b0ad845bdce2d76825ca3ef8e2c4913cc673a..bd9cb2cc3489452fa263ddae333ec16b7f7df579 100644 |
--- a/net/cert/internal/parsed_certificate_unittest.cc |
+++ b/net/cert/internal/parsed_certificate_unittest.cc |
@@ -24,7 +24,8 @@ std::string GetFilePath(const std::string& file_name) { |
// Returns nullptr if the certificate parsing failed, and verifies that any |
// errors match the ERRORS block in the .pem file. |
scoped_refptr<ParsedCertificate> ParseCertificateFromFile( |
- const std::string& file_name) { |
+ const std::string& file_name, |
+ const ParseCertificateOptions& options) { |
std::string data; |
std::string expected_errors; |
@@ -39,7 +40,7 @@ scoped_refptr<ParsedCertificate> ParseCertificateFromFile( |
scoped_refptr<ParsedCertificate> cert = ParsedCertificate::Create( |
bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new( |
reinterpret_cast<const uint8_t*>(data.data()), data.size(), nullptr)), |
- {}, &errors); |
+ options, &errors); |
EXPECT_EQ(expected_errors, errors.ToDebugString()) << "Test file: " |
<< test_file_path; |
@@ -63,7 +64,7 @@ der::Input DavidBenOid() { |
// Parses an Extension whose critical field is true (255). |
TEST(ParsedCertificateTest, ExtensionCritical) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("extension_critical.pem"); |
+ ParseCertificateFromFile("extension_critical.pem", {}); |
ASSERT_TRUE(cert); |
const uint8_t kExpectedValue[] = {0x30, 0x00}; |
@@ -79,7 +80,7 @@ TEST(ParsedCertificateTest, ExtensionCritical) { |
// Parses an Extension whose critical field is false (omitted). |
TEST(ParsedCertificateTest, ExtensionNotCritical) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("extension_not_critical.pem"); |
+ ParseCertificateFromFile("extension_not_critical.pem", {}); |
ASSERT_TRUE(cert); |
const uint8_t kExpectedValue[] = {0x30, 0x00}; |
@@ -96,40 +97,42 @@ TEST(ParsedCertificateTest, ExtensionNotCritical) { |
// however because critical has DEFAULT of false this is in fact invalid |
// DER-encoding. |
TEST(ParsedCertificateTest, ExtensionCritical0) { |
- ASSERT_FALSE(ParseCertificateFromFile("extension_critical_0.pem")); |
+ ASSERT_FALSE(ParseCertificateFromFile("extension_critical_0.pem", {})); |
} |
// Parses an Extension whose critical field is 3. Under DER-encoding BOOLEAN |
// values must an octet of either all zero bits, or all 1 bits, so this is not |
// valid. |
TEST(ParsedCertificateTest, ExtensionCritical3) { |
- ASSERT_FALSE(ParseCertificateFromFile("extension_critical_3.pem")); |
+ ASSERT_FALSE(ParseCertificateFromFile("extension_critical_3.pem", {})); |
} |
// Parses an Extensions that is an empty sequence. |
TEST(ParsedCertificateTest, ExtensionsEmptySequence) { |
- ASSERT_FALSE(ParseCertificateFromFile("extensions_empty_sequence.pem")); |
+ ASSERT_FALSE(ParseCertificateFromFile("extensions_empty_sequence.pem", {})); |
} |
// Parses an Extensions that is not a sequence. |
TEST(ParsedCertificateTest, ExtensionsNotSequence) { |
- ASSERT_FALSE(ParseCertificateFromFile("extensions_not_sequence.pem")); |
+ ASSERT_FALSE(ParseCertificateFromFile("extensions_not_sequence.pem", {})); |
} |
// Parses an Extensions that has data after the sequence. |
TEST(ParsedCertificateTest, ExtensionsDataAfterSequence) { |
- ASSERT_FALSE(ParseCertificateFromFile("extensions_data_after_sequence.pem")); |
+ ASSERT_FALSE( |
+ ParseCertificateFromFile("extensions_data_after_sequence.pem", {})); |
} |
// Parses an Extensions that contains duplicated key usages. |
TEST(ParsedCertificateTest, ExtensionsDuplicateKeyUsage) { |
- ASSERT_FALSE(ParseCertificateFromFile("extensions_duplicate_key_usage.pem")); |
+ ASSERT_FALSE( |
+ ParseCertificateFromFile("extensions_duplicate_key_usage.pem", {})); |
} |
// Parses an Extensions that contains an extended key usages. |
TEST(ParsedCertificateTest, ExtendedKeyUsage) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("extended_key_usage.pem"); |
+ ParseCertificateFromFile("extended_key_usage.pem", {}); |
ASSERT_TRUE(cert); |
ASSERT_EQ(4u, cert->extensions().size()); |
@@ -147,7 +150,7 @@ TEST(ParsedCertificateTest, ExtendedKeyUsage) { |
// Parses an Extensions that contains a key usage. |
TEST(ParsedCertificateTest, KeyUsage) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("key_usage.pem"); |
+ ParseCertificateFromFile("key_usage.pem", {}); |
ASSERT_TRUE(cert); |
ASSERT_TRUE(cert->has_key_usage()); |
@@ -164,7 +167,7 @@ TEST(ParsedCertificateTest, KeyUsage) { |
// Parses an Extensions that contains a policies extension. |
TEST(ParsedCertificateTest, Policies) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("policies.pem"); |
+ ParseCertificateFromFile("policies.pem", {}); |
ASSERT_TRUE(cert); |
ASSERT_EQ(4u, cert->extensions().size()); |
@@ -182,7 +185,7 @@ TEST(ParsedCertificateTest, Policies) { |
// Parses an Extensions that contains a subjectaltname extension. |
TEST(ParsedCertificateTest, SubjectAltName) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("subject_alt_name.pem"); |
+ ParseCertificateFromFile("subject_alt_name.pem", {}); |
ASSERT_TRUE(cert); |
ASSERT_TRUE(cert->has_subject_alt_names()); |
@@ -192,7 +195,7 @@ TEST(ParsedCertificateTest, SubjectAltName) { |
// real-world certificate. |
TEST(ParsedCertificateTest, ExtensionsReal) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("extensions_real.pem"); |
+ ParseCertificateFromFile("extensions_real.pem", {}); |
ASSERT_TRUE(cert); |
ASSERT_EQ(7u, cert->extensions().size()); |
@@ -213,7 +216,7 @@ TEST(ParsedCertificateTest, ExtensionsReal) { |
// Parses a BasicConstraints with no CA or pathlen. |
TEST(ParsedCertificateTest, BasicConstraintsNotCa) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("basic_constraints_not_ca.pem"); |
+ ParseCertificateFromFile("basic_constraints_not_ca.pem", {}); |
ASSERT_TRUE(cert); |
EXPECT_TRUE(cert->has_basic_constraints()); |
@@ -224,7 +227,7 @@ TEST(ParsedCertificateTest, BasicConstraintsNotCa) { |
// Parses a BasicConstraints with CA but no pathlen. |
TEST(ParsedCertificateTest, BasicConstraintsCaNoPath) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("basic_constraints_ca_no_path.pem"); |
+ ParseCertificateFromFile("basic_constraints_ca_no_path.pem", {}); |
ASSERT_TRUE(cert); |
EXPECT_TRUE(cert->has_basic_constraints()); |
@@ -235,7 +238,7 @@ TEST(ParsedCertificateTest, BasicConstraintsCaNoPath) { |
// Parses a BasicConstraints with CA and pathlen of 9. |
TEST(ParsedCertificateTest, BasicConstraintsCaPath9) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("basic_constraints_ca_path_9.pem"); |
+ ParseCertificateFromFile("basic_constraints_ca_path_9.pem", {}); |
ASSERT_TRUE(cert); |
EXPECT_TRUE(cert->has_basic_constraints()); |
@@ -247,7 +250,7 @@ TEST(ParsedCertificateTest, BasicConstraintsCaPath9) { |
// Parses a BasicConstraints with CA and pathlen of 255 (largest allowed size). |
TEST(ParsedCertificateTest, BasicConstraintsPathlen255) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("basic_constraints_pathlen_255.pem"); |
+ ParseCertificateFromFile("basic_constraints_pathlen_255.pem", {}); |
ASSERT_TRUE(cert); |
EXPECT_TRUE(cert->has_basic_constraints()); |
@@ -258,26 +261,28 @@ TEST(ParsedCertificateTest, BasicConstraintsPathlen255) { |
// Parses a BasicConstraints with CA and pathlen of 256 (too large). |
TEST(ParsedCertificateTest, BasicConstraintsPathlen256) { |
- ASSERT_FALSE(ParseCertificateFromFile("basic_constraints_pathlen_256.pem")); |
+ ASSERT_FALSE( |
+ ParseCertificateFromFile("basic_constraints_pathlen_256.pem", {})); |
} |
// Parses a BasicConstraints with CA and a negative pathlen. |
TEST(ParsedCertificateTest, BasicConstraintsNegativePath) { |
- ASSERT_FALSE(ParseCertificateFromFile("basic_constraints_negative_path.pem")); |
+ ASSERT_FALSE( |
+ ParseCertificateFromFile("basic_constraints_negative_path.pem", {})); |
} |
// Parses a BasicConstraints with CA and pathlen that is very large (and |
// couldn't fit in a 64-bit integer). |
TEST(ParsedCertificateTest, BasicConstraintsPathTooLarge) { |
ASSERT_FALSE( |
- ParseCertificateFromFile("basic_constraints_path_too_large.pem")); |
+ ParseCertificateFromFile("basic_constraints_path_too_large.pem", {})); |
} |
// Parses a BasicConstraints with CA explicitly set to false. This violates |
// DER-encoding rules, however is commonly used, so it is accepted. |
TEST(ParsedCertificateTest, BasicConstraintsCaFalse) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("basic_constraints_ca_false.pem"); |
+ ParseCertificateFromFile("basic_constraints_ca_false.pem", {}); |
ASSERT_TRUE(cert); |
EXPECT_TRUE(cert->has_basic_constraints()); |
@@ -289,7 +294,7 @@ TEST(ParsedCertificateTest, BasicConstraintsCaFalse) { |
// the end. |
TEST(ParsedCertificateTest, BasicConstraintsUnconsumedData) { |
ASSERT_FALSE( |
- ParseCertificateFromFile("basic_constraints_unconsumed_data.pem")); |
+ ParseCertificateFromFile("basic_constraints_unconsumed_data.pem", {})); |
} |
// Parses a BasicConstraints with CA omitted (false), but with a pathlen of 1. |
@@ -297,7 +302,7 @@ TEST(ParsedCertificateTest, BasicConstraintsUnconsumedData) { |
// BasicConstraints at a higher level. |
TEST(ParsedCertificateTest, BasicConstraintsPathLenButNotCa) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("basic_constraints_pathlen_not_ca.pem"); |
+ ParseCertificateFromFile("basic_constraints_pathlen_not_ca.pem", {}); |
ASSERT_TRUE(cert); |
EXPECT_TRUE(cert->has_basic_constraints()); |
@@ -310,7 +315,7 @@ TEST(ParsedCertificateTest, BasicConstraintsPathLenButNotCa) { |
// extension having requireExplicitPolicy:3. |
TEST(ParsedCertificateTest, PolicyConstraintsRequire) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("policy_constraints_require.pem"); |
+ ParseCertificateFromFile("policy_constraints_require.pem", {}); |
ASSERT_TRUE(cert); |
EXPECT_TRUE(cert->has_policy_constraints()); |
@@ -324,7 +329,7 @@ TEST(ParsedCertificateTest, PolicyConstraintsRequire) { |
// extension having inhibitPolicyMapping:1. |
TEST(ParsedCertificateTest, PolicyConstraintsInhibit) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("policy_constraints_inhibit.pem"); |
+ ParseCertificateFromFile("policy_constraints_inhibit.pem", {}); |
ASSERT_TRUE(cert); |
EXPECT_TRUE(cert->has_policy_constraints()); |
@@ -338,7 +343,7 @@ TEST(ParsedCertificateTest, PolicyConstraintsInhibit) { |
// extension having requireExplicitPolicy:5,inhibitPolicyMapping:2. |
TEST(ParsedCertificateTest, PolicyConstraintsInhibitRequire) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("policy_constraints_inhibit_require.pem"); |
+ ParseCertificateFromFile("policy_constraints_inhibit_require.pem", {}); |
ASSERT_TRUE(cert); |
EXPECT_TRUE(cert->has_policy_constraints()); |
@@ -352,8 +357,72 @@ TEST(ParsedCertificateTest, PolicyConstraintsInhibitRequire) { |
// extension with an empty sequence. |
TEST(ParsedCertificateTest, PolicyConstraintsEmpty) { |
scoped_refptr<ParsedCertificate> cert = |
- ParseCertificateFromFile("policy_constraints_empty.pem"); |
+ ParseCertificateFromFile("policy_constraints_empty.pem", {}); |
+ ASSERT_FALSE(cert); |
+} |
+ |
+// Tests a certificate with a serial number with a leading 0 padding byte in |
+// the encoding since it is not negative. |
+TEST(ParsedCertificateTest, SerialNumberZeroPadded) { |
+ scoped_refptr<ParsedCertificate> cert = |
+ ParseCertificateFromFile("serial_zero_padded.pem", {}); |
+ ASSERT_TRUE(cert); |
+ |
+ static const uint8_t expected_serial[3] = {0x00, 0x80, 0x01}; |
+ EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number); |
+} |
+ |
+// Tests a serial number where the MSB is >= 0x80, causing the encoded |
+// length to be 21 bytes long. This is an error, as RFC 5280 specifies a |
+// maximum of 20 bytes. |
+TEST(ParsedCertificateTest, SerialNumberZeroPadded21BytesLong) { |
+ scoped_refptr<ParsedCertificate> cert = |
+ ParseCertificateFromFile("serial_zero_padded_21_bytes.pem", {}); |
+ ASSERT_FALSE(cert); |
+ |
+ // Try again with allow_invalid_serial_numbers=true. Parsing should succeed. |
+ ParseCertificateOptions options; |
+ options.allow_invalid_serial_numbers = true; |
+ cert = ParseCertificateFromFile("serial_zero_padded_21_bytes.pem", options); |
+ ASSERT_TRUE(cert); |
+ |
+ static const uint8_t expected_serial[21] = { |
+ 0x00, 0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, |
+ 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13}; |
+ EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number); |
+} |
+ |
+// Tests a serial number which is negative. CAs are not supposed to include |
+// negative serial numbers, however RFC 5280 expects consumers to deal with it |
+// anyway. |
+TEST(ParsedCertificateTest, SerialNumberNegative) { |
+ scoped_refptr<ParsedCertificate> cert = |
+ ParseCertificateFromFile("serial_negative.pem", {}); |
+ ASSERT_TRUE(cert); |
+ |
+ static const uint8_t expected_serial[2] = {0x80, 0x01}; |
+ EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number); |
+} |
+ |
+// Tests a serial number which is very long. RFC 5280 specifies a maximum of 20 |
+// bytes. |
+TEST(ParsedCertificateTest, SerialNumber37BytesLong) { |
+ scoped_refptr<ParsedCertificate> cert = |
+ ParseCertificateFromFile("serial_37_bytes.pem", {}); |
ASSERT_FALSE(cert); |
+ |
+ // Try again with allow_invalid_serial_numbers=true. Parsing should succeed. |
+ ParseCertificateOptions options; |
+ options.allow_invalid_serial_numbers = true; |
+ cert = ParseCertificateFromFile("serial_37_bytes.pem", options); |
+ ASSERT_TRUE(cert); |
+ |
+ static const uint8_t expected_serial[37] = { |
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, |
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, |
+ 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, |
+ 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25}; |
+ EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number); |
} |
} // namespace |