• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "parsed_certificate.h"
6 
7 #include "cert_errors.h"
8 #include "parse_certificate.h"
9 #include "test_helpers.h"
10 #include "input.h"
11 #include <gtest/gtest.h>
12 #include <openssl/pool.h>
13 
14 // TODO(eroman): Add tests for parsing of policy mappings.
15 
16 namespace bssl {
17 
18 namespace {
19 
GetFilePath(const std::string & file_name)20 std::string GetFilePath(const std::string& file_name) {
21   return std::string("testdata/parse_certificate_unittest/") + file_name;
22 }
23 
24 // Reads and parses a certificate from the PEM file |file_name|.
25 //
26 // Returns nullptr if the certificate parsing failed, and verifies that any
27 // errors match the ERRORS block in the .pem file.
ParseCertificateFromFile(const std::string & file_name,const ParseCertificateOptions & options)28 std::shared_ptr<const ParsedCertificate> ParseCertificateFromFile(
29     const std::string& file_name,
30     const ParseCertificateOptions& options) {
31   std::string data;
32   std::string expected_errors;
33 
34   // Read the certificate data and error expectations from a single PEM file.
35   const PemBlockMapping mappings[] = {
36       {"CERTIFICATE", &data},
37       {"ERRORS", &expected_errors, true /*optional*/},
38   };
39   std::string test_file_path = GetFilePath(file_name);
40   EXPECT_TRUE(ReadTestDataFromPemFile(test_file_path, mappings));
41 
42   CertErrors errors;
43   std::shared_ptr<const ParsedCertificate> cert = ParsedCertificate::Create(
44       bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
45           reinterpret_cast<const uint8_t*>(data.data()), data.size(), nullptr)),
46       options, &errors);
47 
48   // The errors are baselined for |!allow_invalid_serial_numbers|. So if
49   // requesting a non-default option skip the error checks.
50   // TODO(eroman): This is ugly.
51   if (!options.allow_invalid_serial_numbers)
52     VerifyCertErrors(expected_errors, errors, test_file_path);
53 
54   // Every parse failure being tested should emit error information.
55   if (!cert) {
56     EXPECT_FALSE(errors.ToDebugString().empty());
57   }
58 
59   return cert;
60 }
61 
DavidBenOid()62 der::Input DavidBenOid() {
63   // This OID corresponds with
64   // 1.2.840.113554.4.1.72585.0 (https://davidben.net/oid)
65   static const uint8_t kOid[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12,
66                                  0x04, 0x01, 0x84, 0xb7, 0x09, 0x00};
67   return der::Input(kOid);
68 }
69 
70 // Parses an Extension whose critical field is true (255).
TEST(ParsedCertificateTest,ExtensionCritical)71 TEST(ParsedCertificateTest, ExtensionCritical) {
72   std::shared_ptr<const ParsedCertificate> cert =
73       ParseCertificateFromFile("extension_critical.pem", {});
74   ASSERT_TRUE(cert);
75 
76   const uint8_t kExpectedValue[] = {0x30, 0x00};
77 
78   ParsedExtension extension;
79   ASSERT_TRUE(cert->GetExtension(DavidBenOid(), &extension));
80 
81   EXPECT_TRUE(extension.critical);
82   EXPECT_EQ(DavidBenOid(), extension.oid);
83   EXPECT_EQ(der::Input(kExpectedValue), extension.value);
84 }
85 
86 // Parses an Extension whose critical field is false (omitted).
TEST(ParsedCertificateTest,ExtensionNotCritical)87 TEST(ParsedCertificateTest, ExtensionNotCritical) {
88   std::shared_ptr<const ParsedCertificate> cert =
89       ParseCertificateFromFile("extension_not_critical.pem", {});
90   ASSERT_TRUE(cert);
91 
92   const uint8_t kExpectedValue[] = {0x30, 0x00};
93 
94   ParsedExtension extension;
95   ASSERT_TRUE(cert->GetExtension(DavidBenOid(), &extension));
96 
97   EXPECT_FALSE(extension.critical);
98   EXPECT_EQ(DavidBenOid(), extension.oid);
99   EXPECT_EQ(der::Input(kExpectedValue), extension.value);
100 }
101 
102 // Parses an Extension whose critical field is 0. This is in one sense FALSE,
103 // however because critical has DEFAULT of false this is in fact invalid
104 // DER-encoding.
TEST(ParsedCertificateTest,ExtensionCritical0)105 TEST(ParsedCertificateTest, ExtensionCritical0) {
106   ASSERT_FALSE(ParseCertificateFromFile("extension_critical_0.pem", {}));
107 }
108 
109 // Parses an Extension whose critical field is 3. Under DER-encoding BOOLEAN
110 // values must an octet of either all zero bits, or all 1 bits, so this is not
111 // valid.
TEST(ParsedCertificateTest,ExtensionCritical3)112 TEST(ParsedCertificateTest, ExtensionCritical3) {
113   ASSERT_FALSE(ParseCertificateFromFile("extension_critical_3.pem", {}));
114 }
115 
116 // Parses an Extensions that is an empty sequence.
TEST(ParsedCertificateTest,ExtensionsEmptySequence)117 TEST(ParsedCertificateTest, ExtensionsEmptySequence) {
118   ASSERT_FALSE(ParseCertificateFromFile("extensions_empty_sequence.pem", {}));
119 }
120 
121 // Parses an Extensions that is not a sequence.
TEST(ParsedCertificateTest,ExtensionsNotSequence)122 TEST(ParsedCertificateTest, ExtensionsNotSequence) {
123   ASSERT_FALSE(ParseCertificateFromFile("extensions_not_sequence.pem", {}));
124 }
125 
126 // Parses an Extensions that has data after the sequence.
TEST(ParsedCertificateTest,ExtensionsDataAfterSequence)127 TEST(ParsedCertificateTest, ExtensionsDataAfterSequence) {
128   ASSERT_FALSE(
129       ParseCertificateFromFile("extensions_data_after_sequence.pem", {}));
130 }
131 
132 // Parses an Extensions that contains duplicated key usages.
TEST(ParsedCertificateTest,ExtensionsDuplicateKeyUsage)133 TEST(ParsedCertificateTest, ExtensionsDuplicateKeyUsage) {
134   ASSERT_FALSE(
135       ParseCertificateFromFile("extensions_duplicate_key_usage.pem", {}));
136 }
137 
138 // Parses a certificate with a bad key usage extension (BIT STRING with zero
139 // elements).
TEST(ParsedCertificateTest,BadKeyUsage)140 TEST(ParsedCertificateTest, BadKeyUsage) {
141   ASSERT_FALSE(ParseCertificateFromFile("bad_key_usage.pem", {}));
142 }
143 
144 // Parses a certificate that has a PolicyQualifierInfo that is missing the
145 // qualifier field.
TEST(ParsedCertificateTest,BadPolicyQualifiers)146 TEST(ParsedCertificateTest, BadPolicyQualifiers) {
147   ASSERT_FALSE(ParseCertificateFromFile("bad_policy_qualifiers.pem", {}));
148 }
149 
150 // Parses a certificate that uses an unknown signature algorithm OID (00).
TEST(ParsedCertificateTest,BadSignatureAlgorithmOid)151 TEST(ParsedCertificateTest, BadSignatureAlgorithmOid) {
152   std::shared_ptr<const ParsedCertificate> cert =
153       ParseCertificateFromFile("bad_signature_algorithm_oid.pem", {});
154   ASSERT_TRUE(cert);
155   ASSERT_FALSE(cert->signature_algorithm());
156 }
157 
158 //  The validity encodes time as UTCTime but following the BER rules rather than
159 //  DER rules (i.e. YYMMDDHHMMZ instead of YYMMDDHHMMSSZ).
TEST(ParsedCertificateTest,BadValidity)160 TEST(ParsedCertificateTest, BadValidity) {
161   ASSERT_FALSE(ParseCertificateFromFile("bad_validity.pem", {}));
162 }
163 
164 // The signature algorithm contains an unexpected parameters field.
TEST(ParsedCertificateTest,FailedSignatureAlgorithm)165 TEST(ParsedCertificateTest, FailedSignatureAlgorithm) {
166   std::shared_ptr<const ParsedCertificate> cert =
167       ParseCertificateFromFile("failed_signature_algorithm.pem", {});
168   ASSERT_TRUE(cert);
169   ASSERT_FALSE(cert->signature_algorithm());
170 }
171 
TEST(ParsedCertificateTest,IssuerBadPrintableString)172 TEST(ParsedCertificateTest, IssuerBadPrintableString) {
173   ASSERT_FALSE(ParseCertificateFromFile("issuer_bad_printable_string.pem", {}));
174 }
175 
TEST(ParsedCertificateTest,NameConstraintsBadIp)176 TEST(ParsedCertificateTest, NameConstraintsBadIp) {
177   ASSERT_FALSE(ParseCertificateFromFile("name_constraints_bad_ip.pem", {}));
178 }
179 
TEST(ParsedCertificateTest,PolicyQualifiersEmptySequence)180 TEST(ParsedCertificateTest, PolicyQualifiersEmptySequence) {
181   ASSERT_FALSE(
182       ParseCertificateFromFile("policy_qualifiers_empty_sequence.pem", {}));
183 }
184 
TEST(ParsedCertificateTest,SubjectBlankSubjectAltNameNotCritical)185 TEST(ParsedCertificateTest, SubjectBlankSubjectAltNameNotCritical) {
186   ASSERT_FALSE(ParseCertificateFromFile(
187       "subject_blank_subjectaltname_not_critical.pem", {}));
188 }
189 
TEST(ParsedCertificateTest,SubjectNotAscii)190 TEST(ParsedCertificateTest, SubjectNotAscii) {
191   ASSERT_FALSE(ParseCertificateFromFile("subject_not_ascii.pem", {}));
192 }
193 
TEST(ParsedCertificateTest,SubjectNotPrintableString)194 TEST(ParsedCertificateTest, SubjectNotPrintableString) {
195   ASSERT_FALSE(
196       ParseCertificateFromFile("subject_not_printable_string.pem", {}));
197 }
198 
TEST(ParsedCertificateTest,SubjectAltNameBadIp)199 TEST(ParsedCertificateTest, SubjectAltNameBadIp) {
200   ASSERT_FALSE(ParseCertificateFromFile("subjectaltname_bad_ip.pem", {}));
201 }
202 
TEST(ParsedCertificateTest,SubjectAltNameDnsNotAscii)203 TEST(ParsedCertificateTest, SubjectAltNameDnsNotAscii) {
204   ASSERT_FALSE(
205       ParseCertificateFromFile("subjectaltname_dns_not_ascii.pem", {}));
206 }
207 
TEST(ParsedCertificateTest,SubjectAltNameGeneralNamesEmptySequence)208 TEST(ParsedCertificateTest, SubjectAltNameGeneralNamesEmptySequence) {
209   ASSERT_FALSE(ParseCertificateFromFile(
210       "subjectaltname_general_names_empty_sequence.pem", {}));
211 }
212 
TEST(ParsedCertificateTest,SubjectAltNameTrailingData)213 TEST(ParsedCertificateTest, SubjectAltNameTrailingData) {
214   ASSERT_FALSE(
215       ParseCertificateFromFile("subjectaltname_trailing_data.pem", {}));
216 }
217 
TEST(ParsedCertificateTest,V1ExplicitVersion)218 TEST(ParsedCertificateTest, V1ExplicitVersion) {
219   ASSERT_FALSE(ParseCertificateFromFile("v1_explicit_version.pem", {}));
220 }
221 
222 // Parses an Extensions that contains an extended key usages.
TEST(ParsedCertificateTest,ExtendedKeyUsage)223 TEST(ParsedCertificateTest, ExtendedKeyUsage) {
224   std::shared_ptr<const ParsedCertificate> cert =
225       ParseCertificateFromFile("extended_key_usage.pem", {});
226   ASSERT_TRUE(cert);
227 
228   ASSERT_EQ(4u, cert->extensions().size());
229 
230   ParsedExtension extension;
231   ASSERT_TRUE(cert->GetExtension(der::Input(kExtKeyUsageOid), &extension));
232 
233   EXPECT_FALSE(extension.critical);
234   EXPECT_EQ(45u, extension.value.Length());
235 
236   EXPECT_TRUE(cert->has_extended_key_usage());
237   EXPECT_EQ(4u, cert->extended_key_usage().size());
238 }
239 
240 // Parses an Extensions that contains a key usage.
TEST(ParsedCertificateTest,KeyUsage)241 TEST(ParsedCertificateTest, KeyUsage) {
242   std::shared_ptr<const ParsedCertificate> cert =
243       ParseCertificateFromFile("key_usage.pem", {});
244   ASSERT_TRUE(cert);
245 
246   ASSERT_TRUE(cert->has_key_usage());
247 
248   EXPECT_EQ(5u, cert->key_usage().unused_bits());
249   const uint8_t kExpectedBytes[] = {0xA0};
250   EXPECT_EQ(der::Input(kExpectedBytes), cert->key_usage().bytes());
251 
252   EXPECT_TRUE(cert->key_usage().AssertsBit(0));
253   EXPECT_FALSE(cert->key_usage().AssertsBit(1));
254   EXPECT_TRUE(cert->key_usage().AssertsBit(2));
255 }
256 
257 // Parses an Extensions that contains a policies extension.
TEST(ParsedCertificateTest,Policies)258 TEST(ParsedCertificateTest, Policies) {
259   std::shared_ptr<const ParsedCertificate> cert =
260       ParseCertificateFromFile("policies.pem", {});
261   ASSERT_TRUE(cert);
262 
263   ASSERT_EQ(4u, cert->extensions().size());
264 
265   ParsedExtension extension;
266   ASSERT_TRUE(
267       cert->GetExtension(der::Input(kCertificatePoliciesOid), &extension));
268 
269   EXPECT_FALSE(extension.critical);
270   EXPECT_EQ(95u, extension.value.Length());
271 
272   EXPECT_TRUE(cert->has_policy_oids());
273   EXPECT_EQ(2u, cert->policy_oids().size());
274 }
275 
276 // Parses an Extensions that contains a subjectaltname extension.
TEST(ParsedCertificateTest,SubjectAltName)277 TEST(ParsedCertificateTest, SubjectAltName) {
278   std::shared_ptr<const ParsedCertificate> cert =
279       ParseCertificateFromFile("subject_alt_name.pem", {});
280   ASSERT_TRUE(cert);
281 
282   ASSERT_TRUE(cert->has_subject_alt_names());
283 }
284 
285 // Parses an Extensions that contains multiple extensions, sourced from a
286 // real-world certificate.
TEST(ParsedCertificateTest,ExtensionsReal)287 TEST(ParsedCertificateTest, ExtensionsReal) {
288   std::shared_ptr<const ParsedCertificate> cert =
289       ParseCertificateFromFile("extensions_real.pem", {});
290   ASSERT_TRUE(cert);
291 
292   ASSERT_EQ(7u, cert->extensions().size());
293 
294   EXPECT_TRUE(cert->has_key_usage());
295   EXPECT_TRUE(cert->has_basic_constraints());
296   EXPECT_TRUE(cert->has_authority_info_access());
297   EXPECT_TRUE(cert->has_policy_oids());
298 
299   ASSERT_TRUE(cert->authority_key_identifier());
300   ASSERT_TRUE(cert->authority_key_identifier()->key_identifier);
301   EXPECT_FALSE(cert->authority_key_identifier()->authority_cert_issuer);
302   EXPECT_FALSE(cert->authority_key_identifier()->authority_cert_serial_number);
303   const uint8_t expected_authority_key_identifier[] = {
304       0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64,
305       0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e,
306   };
307   EXPECT_EQ(der::Input(expected_authority_key_identifier),
308             cert->authority_key_identifier()->key_identifier);
309 
310   ASSERT_TRUE(cert->subject_key_identifier());
311   const uint8_t expected_subject_key_identifier[] = {
312       0x4a, 0xdd, 0x06, 0x16, 0x1b, 0xbc, 0xf6, 0x68, 0xb5, 0x76,
313       0xf5, 0x81, 0xb6, 0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f};
314   EXPECT_EQ(der::Input(expected_subject_key_identifier),
315             cert->subject_key_identifier());
316 
317   ParsedExtension extension;
318   ASSERT_TRUE(
319       cert->GetExtension(der::Input(kCertificatePoliciesOid), &extension));
320 
321   EXPECT_FALSE(extension.critical);
322   EXPECT_EQ(16u, extension.value.Length());
323 
324   // TODO(eroman): Verify the other extensions' values.
325 }
326 
327 // Parses a BasicConstraints with no CA or pathlen.
TEST(ParsedCertificateTest,BasicConstraintsNotCa)328 TEST(ParsedCertificateTest, BasicConstraintsNotCa) {
329   std::shared_ptr<const ParsedCertificate> cert =
330       ParseCertificateFromFile("basic_constraints_not_ca.pem", {});
331   ASSERT_TRUE(cert);
332 
333   EXPECT_TRUE(cert->has_basic_constraints());
334   EXPECT_FALSE(cert->basic_constraints().is_ca);
335   EXPECT_FALSE(cert->basic_constraints().has_path_len);
336 }
337 
338 // Parses a BasicConstraints with CA but no pathlen.
TEST(ParsedCertificateTest,BasicConstraintsCaNoPath)339 TEST(ParsedCertificateTest, BasicConstraintsCaNoPath) {
340   std::shared_ptr<const ParsedCertificate> cert =
341       ParseCertificateFromFile("basic_constraints_ca_no_path.pem", {});
342   ASSERT_TRUE(cert);
343 
344   EXPECT_TRUE(cert->has_basic_constraints());
345   EXPECT_TRUE(cert->basic_constraints().is_ca);
346   EXPECT_FALSE(cert->basic_constraints().has_path_len);
347 }
348 
349 // Parses a BasicConstraints with CA and pathlen of 9.
TEST(ParsedCertificateTest,BasicConstraintsCaPath9)350 TEST(ParsedCertificateTest, BasicConstraintsCaPath9) {
351   std::shared_ptr<const ParsedCertificate> cert =
352       ParseCertificateFromFile("basic_constraints_ca_path_9.pem", {});
353   ASSERT_TRUE(cert);
354 
355   EXPECT_TRUE(cert->has_basic_constraints());
356   EXPECT_TRUE(cert->basic_constraints().is_ca);
357   EXPECT_TRUE(cert->basic_constraints().has_path_len);
358   EXPECT_EQ(9u, cert->basic_constraints().path_len);
359 }
360 
361 // Parses a BasicConstraints with CA and pathlen of 255 (largest allowed size).
TEST(ParsedCertificateTest,BasicConstraintsPathlen255)362 TEST(ParsedCertificateTest, BasicConstraintsPathlen255) {
363   std::shared_ptr<const ParsedCertificate> cert =
364       ParseCertificateFromFile("basic_constraints_pathlen_255.pem", {});
365   ASSERT_TRUE(cert);
366 
367   EXPECT_TRUE(cert->has_basic_constraints());
368   EXPECT_TRUE(cert->basic_constraints().is_ca);
369   EXPECT_TRUE(cert->basic_constraints().has_path_len);
370   EXPECT_EQ(255, cert->basic_constraints().path_len);
371 }
372 
373 // Parses a BasicConstraints with CA and pathlen of 256 (too large).
TEST(ParsedCertificateTest,BasicConstraintsPathlen256)374 TEST(ParsedCertificateTest, BasicConstraintsPathlen256) {
375   ASSERT_FALSE(
376       ParseCertificateFromFile("basic_constraints_pathlen_256.pem", {}));
377 }
378 
379 // Parses a BasicConstraints with CA and a negative pathlen.
TEST(ParsedCertificateTest,BasicConstraintsNegativePath)380 TEST(ParsedCertificateTest, BasicConstraintsNegativePath) {
381   ASSERT_FALSE(
382       ParseCertificateFromFile("basic_constraints_negative_path.pem", {}));
383 }
384 
385 // Parses a BasicConstraints with CA and pathlen that is very large (and
386 // couldn't fit in a 64-bit integer).
TEST(ParsedCertificateTest,BasicConstraintsPathTooLarge)387 TEST(ParsedCertificateTest, BasicConstraintsPathTooLarge) {
388   ASSERT_FALSE(
389       ParseCertificateFromFile("basic_constraints_path_too_large.pem", {}));
390 }
391 
392 // Parses a BasicConstraints with CA explicitly set to false. This violates
393 // DER-encoding rules, however is commonly used, so it is accepted.
TEST(ParsedCertificateTest,BasicConstraintsCaFalse)394 TEST(ParsedCertificateTest, BasicConstraintsCaFalse) {
395   std::shared_ptr<const ParsedCertificate> cert =
396       ParseCertificateFromFile("basic_constraints_ca_false.pem", {});
397   ASSERT_TRUE(cert);
398 
399   EXPECT_TRUE(cert->has_basic_constraints());
400   EXPECT_FALSE(cert->basic_constraints().is_ca);
401   EXPECT_FALSE(cert->basic_constraints().has_path_len);
402 }
403 
404 // Parses a BasicConstraints with CA set to true and an unexpected NULL at
405 // the end.
TEST(ParsedCertificateTest,BasicConstraintsUnconsumedData)406 TEST(ParsedCertificateTest, BasicConstraintsUnconsumedData) {
407   ASSERT_FALSE(
408       ParseCertificateFromFile("basic_constraints_unconsumed_data.pem", {}));
409 }
410 
411 // Parses a BasicConstraints with CA omitted (false), but with a pathlen of 1.
412 // This is valid DER for the ASN.1, however is not valid when interpreting the
413 // BasicConstraints at a higher level.
TEST(ParsedCertificateTest,BasicConstraintsPathLenButNotCa)414 TEST(ParsedCertificateTest, BasicConstraintsPathLenButNotCa) {
415   std::shared_ptr<const ParsedCertificate> cert =
416       ParseCertificateFromFile("basic_constraints_pathlen_not_ca.pem", {});
417   ASSERT_TRUE(cert);
418 
419   EXPECT_TRUE(cert->has_basic_constraints());
420   EXPECT_FALSE(cert->basic_constraints().is_ca);
421   EXPECT_TRUE(cert->basic_constraints().has_path_len);
422   EXPECT_EQ(1u, cert->basic_constraints().path_len);
423 }
424 
425 // Tests parsing a certificate that contains a policyConstraints
426 // extension having requireExplicitPolicy:3.
TEST(ParsedCertificateTest,PolicyConstraintsRequire)427 TEST(ParsedCertificateTest, PolicyConstraintsRequire) {
428   std::shared_ptr<const ParsedCertificate> cert =
429       ParseCertificateFromFile("policy_constraints_require.pem", {});
430   ASSERT_TRUE(cert);
431 
432   EXPECT_TRUE(cert->has_policy_constraints());
433   EXPECT_TRUE(cert->policy_constraints().require_explicit_policy.has_value());
434   EXPECT_EQ(3, cert->policy_constraints().require_explicit_policy.value());
435   EXPECT_FALSE(cert->policy_constraints().inhibit_policy_mapping.has_value());
436 }
437 
438 // Tests parsing a certificate that contains a policyConstraints
439 // extension having inhibitPolicyMapping:1.
TEST(ParsedCertificateTest,PolicyConstraintsInhibit)440 TEST(ParsedCertificateTest, PolicyConstraintsInhibit) {
441   std::shared_ptr<const ParsedCertificate> cert =
442       ParseCertificateFromFile("policy_constraints_inhibit.pem", {});
443   ASSERT_TRUE(cert);
444 
445   EXPECT_TRUE(cert->has_policy_constraints());
446   EXPECT_FALSE(cert->policy_constraints().require_explicit_policy.has_value());
447   EXPECT_TRUE(cert->policy_constraints().inhibit_policy_mapping.has_value());
448   EXPECT_EQ(1, cert->policy_constraints().inhibit_policy_mapping.value());
449 }
450 
451 // Tests parsing a certificate that contains a policyConstraints
452 // extension having requireExplicitPolicy:5,inhibitPolicyMapping:2.
TEST(ParsedCertificateTest,PolicyConstraintsInhibitRequire)453 TEST(ParsedCertificateTest, PolicyConstraintsInhibitRequire) {
454   std::shared_ptr<const ParsedCertificate> cert =
455       ParseCertificateFromFile("policy_constraints_inhibit_require.pem", {});
456   ASSERT_TRUE(cert);
457 
458   EXPECT_TRUE(cert->has_policy_constraints());
459   EXPECT_TRUE(cert->policy_constraints().require_explicit_policy.has_value());
460   EXPECT_EQ(5, cert->policy_constraints().require_explicit_policy.value());
461   EXPECT_TRUE(cert->policy_constraints().inhibit_policy_mapping.has_value());
462   EXPECT_EQ(2, cert->policy_constraints().inhibit_policy_mapping.value());
463 }
464 
465 // Tests parsing a certificate that has a policyConstraints
466 // extension with an empty sequence.
TEST(ParsedCertificateTest,PolicyConstraintsEmpty)467 TEST(ParsedCertificateTest, PolicyConstraintsEmpty) {
468   std::shared_ptr<const ParsedCertificate> cert =
469       ParseCertificateFromFile("policy_constraints_empty.pem", {});
470   ASSERT_FALSE(cert);
471 }
472 
473 // Tests a certificate with a serial number with a leading 0 padding byte in
474 // the encoding since it is not negative.
TEST(ParsedCertificateTest,SerialNumberZeroPadded)475 TEST(ParsedCertificateTest, SerialNumberZeroPadded) {
476   std::shared_ptr<const ParsedCertificate> cert =
477       ParseCertificateFromFile("serial_zero_padded.pem", {});
478   ASSERT_TRUE(cert);
479 
480   static const uint8_t expected_serial[3] = {0x00, 0x80, 0x01};
481   EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number);
482 }
483 
484 // Tests a serial number where the MSB is >= 0x80, causing the encoded
485 // length to be 21 bytes long. This is an error, as RFC 5280 specifies a
486 // maximum of 20 bytes.
TEST(ParsedCertificateTest,SerialNumberZeroPadded21BytesLong)487 TEST(ParsedCertificateTest, SerialNumberZeroPadded21BytesLong) {
488   std::shared_ptr<const ParsedCertificate> cert =
489       ParseCertificateFromFile("serial_zero_padded_21_bytes.pem", {});
490   ASSERT_FALSE(cert);
491 
492   // Try again with allow_invalid_serial_numbers=true. Parsing should succeed.
493   ParseCertificateOptions options;
494   options.allow_invalid_serial_numbers = true;
495   cert = ParseCertificateFromFile("serial_zero_padded_21_bytes.pem", options);
496   ASSERT_TRUE(cert);
497 
498   static const uint8_t expected_serial[21] = {
499       0x00, 0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
500       0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13};
501   EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number);
502 }
503 
504 // Tests a serial number which is negative.  CAs are not supposed to include
505 // negative serial numbers, however RFC 5280 expects consumers to deal with it
506 // anyway.
TEST(ParsedCertificateTest,SerialNumberNegative)507 TEST(ParsedCertificateTest, SerialNumberNegative) {
508   std::shared_ptr<const ParsedCertificate> cert =
509       ParseCertificateFromFile("serial_negative.pem", {});
510   ASSERT_TRUE(cert);
511 
512   static const uint8_t expected_serial[2] = {0x80, 0x01};
513   EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number);
514 }
515 
516 // Tests a serial number which is very long. RFC 5280 specifies a maximum of 20
517 // bytes.
TEST(ParsedCertificateTest,SerialNumber37BytesLong)518 TEST(ParsedCertificateTest, SerialNumber37BytesLong) {
519   std::shared_ptr<const ParsedCertificate> cert =
520       ParseCertificateFromFile("serial_37_bytes.pem", {});
521   ASSERT_FALSE(cert);
522 
523   // Try again with allow_invalid_serial_numbers=true. Parsing should succeed.
524   ParseCertificateOptions options;
525   options.allow_invalid_serial_numbers = true;
526   cert = ParseCertificateFromFile("serial_37_bytes.pem", options);
527   ASSERT_TRUE(cert);
528 
529   static const uint8_t expected_serial[37] = {
530       0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
531       0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
532       0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
533       0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25};
534   EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number);
535 }
536 
537 // Tests a serial number which is zero. RFC 5280 says they should be positive,
538 // however also recommends supporting non-positive ones, so parsing here
539 // is expected to succeed.
TEST(ParsedCertificateTest,SerialNumberZero)540 TEST(ParsedCertificateTest, SerialNumberZero) {
541   std::shared_ptr<const ParsedCertificate> cert =
542       ParseCertificateFromFile("serial_zero.pem", {});
543   ASSERT_TRUE(cert);
544 
545   static const uint8_t expected_serial[] = {0x00};
546   EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number);
547 }
548 
549 // Tests a serial number which not a number (NULL).
TEST(ParsedCertificateTest,SerialNotNumber)550 TEST(ParsedCertificateTest, SerialNotNumber) {
551   std::shared_ptr<const ParsedCertificate> cert =
552       ParseCertificateFromFile("serial_not_number.pem", {});
553   ASSERT_FALSE(cert);
554 }
555 
556 // Tests a serial number which uses a non-minimal INTEGER encoding
TEST(ParsedCertificateTest,SerialNotMinimal)557 TEST(ParsedCertificateTest, SerialNotMinimal) {
558   std::shared_ptr<const ParsedCertificate> cert =
559       ParseCertificateFromFile("serial_not_minimal.pem", {});
560   ASSERT_FALSE(cert);
561 }
562 
563 // Tests parsing a certificate that has an inhibitAnyPolicy extension.
TEST(ParsedCertificateTest,InhibitAnyPolicy)564 TEST(ParsedCertificateTest, InhibitAnyPolicy) {
565   std::shared_ptr<const ParsedCertificate> cert =
566       ParseCertificateFromFile("inhibit_any_policy.pem", {});
567   ASSERT_TRUE(cert);
568 
569   ParsedExtension extension;
570   ASSERT_TRUE(cert->GetExtension(der::Input(kInhibitAnyPolicyOid), &extension));
571 
572   std::optional<uint8_t> skip_count = ParseInhibitAnyPolicy(extension.value);
573   ASSERT_TRUE(skip_count.has_value());
574   EXPECT_EQ(3, skip_count.value());
575 }
576 
577 // Tests a subjectKeyIdentifier that is not an OCTET_STRING.
TEST(ParsedCertificateTest,SubjectKeyIdentifierNotOctetString)578 TEST(ParsedCertificateTest, SubjectKeyIdentifierNotOctetString) {
579   std::shared_ptr<const ParsedCertificate> cert = ParseCertificateFromFile(
580       "subject_key_identifier_not_octet_string.pem", {});
581   ASSERT_FALSE(cert);
582 }
583 
584 // Tests an authorityKeyIdentifier that is not a SEQUENCE.
TEST(ParsedCertificateTest,AuthourityKeyIdentifierNotSequence)585 TEST(ParsedCertificateTest, AuthourityKeyIdentifierNotSequence) {
586   std::shared_ptr<const ParsedCertificate> cert =
587       ParseCertificateFromFile("authority_key_identifier_not_sequence.pem", {});
588   ASSERT_FALSE(cert);
589 }
590 
591 }  // namespace
592 
593 }  // namespace net
594