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