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