Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(947)

Unified Diff: net/cert/internal/parsed_certificate_unittest.cc

Issue 2881023003: X509CertificateBytes: Allow invalid serial numbers for now. (Closed)
Patch Set: review changes 2 Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/cert/internal/parse_certificate_unittest.cc ('k') | net/cert/x509_certificate_bytes.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « net/cert/internal/parse_certificate_unittest.cc ('k') | net/cert/x509_certificate_bytes.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698