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