1 // Copyright (c) 2012 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.
5 #include "net/cert/cert_verify_proc.h"
9 #include "base/callback_helpers.h"
10 #include "base/files/file_path.h"
11 #include "base/logging.h"
12 #include "base/sha1.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "crypto/sha2.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/test_data_directory.h"
17 #include "net/cert/asn1_util.h"
18 #include "net/cert/cert_status_flags.h"
19 #include "net/cert/cert_verifier.h"
20 #include "net/cert/cert_verify_result.h"
21 #include "net/cert/crl_set.h"
22 #include "net/cert/test_root_certs.h"
23 #include "net/cert/x509_certificate.h"
24 #include "net/test/cert_test_util.h"
25 #include "net/test/test_certificate_data.h"
26 #include "testing/gtest/include/gtest/gtest.h"
29 #include "base/win/windows_version.h"
30 #elif defined(OS_MACOSX) && !defined(OS_IOS)
31 #include "base/mac/mac_util.h"
32 #elif defined(OS_ANDROID)
33 #include "base/android/build_info.h"
36 using base::HexEncode;
42 // A certificate for www.paypal.com with a NULL byte in the common name.
43 // From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363
44 unsigned char paypal_null_fingerprint[] = {
45 0x4c, 0x88, 0x9e, 0x28, 0xd7, 0x7a, 0x44, 0x1e, 0x13, 0xf2, 0x6a, 0xba,
46 0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7
49 // Mock CertVerifyProc that will set |verify_result->is_issued_by_known_root|
50 // for all certificates that are Verified.
51 class WellKnownCaCertVerifyProc : public CertVerifyProc {
53 // Initialize a CertVerifyProc that will set
54 // |verify_result->is_issued_by_known_root| to |is_well_known|.
55 explicit WellKnownCaCertVerifyProc(bool is_well_known)
56 : is_well_known_(is_well_known) {}
58 // CertVerifyProc implementation:
59 virtual bool SupportsAdditionalTrustAnchors() const OVERRIDE { return false; }
62 virtual ~WellKnownCaCertVerifyProc() {}
65 virtual int VerifyInternal(X509Certificate* cert,
66 const std::string& hostname,
69 const CertificateList& additional_trust_anchors,
70 CertVerifyResult* verify_result) OVERRIDE;
72 const bool is_well_known_;
74 DISALLOW_COPY_AND_ASSIGN(WellKnownCaCertVerifyProc);
77 int WellKnownCaCertVerifyProc::VerifyInternal(
78 X509Certificate* cert,
79 const std::string& hostname,
82 const CertificateList& additional_trust_anchors,
83 CertVerifyResult* verify_result) {
84 verify_result->is_issued_by_known_root = is_well_known_;
88 bool SupportsReturningVerifiedChain() {
89 #if defined(OS_ANDROID)
90 // Before API level 17, Android does not expose the APIs necessary to get at
91 // the verified certificate chain.
92 if (base::android::BuildInfo::GetInstance()->sdk_int() < 17)
98 bool SupportsDetectingKnownRoots() {
99 #if defined(OS_ANDROID)
100 // Before API level 17, Android does not expose the APIs necessary to get at
101 // the verified certificate chain and detect known roots.
102 if (base::android::BuildInfo::GetInstance()->sdk_int() < 17)
110 class CertVerifyProcTest : public testing::Test {
113 : verify_proc_(CertVerifyProc::CreateDefault()) {
115 virtual ~CertVerifyProcTest() {}
118 bool SupportsAdditionalTrustAnchors() {
119 return verify_proc_->SupportsAdditionalTrustAnchors();
122 int Verify(X509Certificate* cert,
123 const std::string& hostname,
126 const CertificateList& additional_trust_anchors,
127 CertVerifyResult* verify_result) {
128 return verify_proc_->Verify(cert, hostname, flags, crl_set,
129 additional_trust_anchors, verify_result);
132 const CertificateList empty_cert_list_;
133 scoped_refptr<CertVerifyProc> verify_proc_;
136 TEST_F(CertVerifyProcTest, DISABLED_WithoutRevocationChecking) {
137 // Check that verification without revocation checking works.
138 CertificateList certs = CreateCertificateListFromFile(
139 GetTestCertsDirectory(),
140 "googlenew.chain.pem",
141 X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
143 X509Certificate::OSCertHandles intermediates;
144 intermediates.push_back(certs[1]->os_cert_handle());
146 scoped_refptr<X509Certificate> google_full_chain =
147 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
150 CertVerifyResult verify_result;
152 Verify(google_full_chain.get(),
160 #if defined(OS_ANDROID) || defined(USE_OPENSSL_CERTS)
161 // TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported.
162 #define MAYBE_EVVerification DISABLED_EVVerification
164 #define MAYBE_EVVerification EVVerification
166 TEST_F(CertVerifyProcTest, MAYBE_EVVerification) {
167 CertificateList certs = CreateCertificateListFromFile(
168 GetTestCertsDirectory(),
170 X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
171 ASSERT_EQ(3U, certs.size());
173 X509Certificate::OSCertHandles intermediates;
174 intermediates.push_back(certs[1]->os_cert_handle());
175 intermediates.push_back(certs[2]->os_cert_handle());
177 scoped_refptr<X509Certificate> comodo_chain =
178 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
181 scoped_refptr<CRLSet> crl_set(CRLSet::ForTesting(false, NULL, ""));
182 CertVerifyResult verify_result;
183 int flags = CertVerifier::VERIFY_EV_CERT;
184 int error = Verify(comodo_chain.get(),
190 EXPECT_EQ(OK, error);
191 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
194 TEST_F(CertVerifyProcTest, PaypalNullCertParsing) {
195 scoped_refptr<X509Certificate> paypal_null_cert(
196 X509Certificate::CreateFromBytes(
197 reinterpret_cast<const char*>(paypal_null_der),
198 sizeof(paypal_null_der)));
200 ASSERT_NE(static_cast<X509Certificate*>(NULL), paypal_null_cert);
202 const SHA1HashValue& fingerprint =
203 paypal_null_cert->fingerprint();
204 for (size_t i = 0; i < 20; ++i)
205 EXPECT_EQ(paypal_null_fingerprint[i], fingerprint.data[i]);
208 CertVerifyResult verify_result;
209 int error = Verify(paypal_null_cert.get(),
215 #if defined(USE_NSS) || defined(OS_IOS) || defined(OS_ANDROID)
216 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
218 // TOOD(bulach): investigate why macosx and win aren't returning
219 // ERR_CERT_INVALID or ERR_CERT_COMMON_NAME_INVALID.
220 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
222 // Either the system crypto library should correctly report a certificate
223 // name mismatch, or our certificate blacklist should cause us to report an
224 // invalid certificate.
225 #if defined(USE_NSS) || defined(OS_WIN) || defined(OS_IOS)
226 EXPECT_TRUE(verify_result.cert_status &
227 (CERT_STATUS_COMMON_NAME_INVALID | CERT_STATUS_INVALID));
231 // A regression test for http://crbug.com/31497.
232 #if defined(OS_ANDROID)
233 // Disabled on Android, as the Android verification libraries require an
234 // explicit policy to be specified, even when anyPolicy is permitted.
235 #define MAYBE_IntermediateCARequireExplicitPolicy \
236 DISABLED_IntermediateCARequireExplicitPolicy
238 #define MAYBE_IntermediateCARequireExplicitPolicy \
239 IntermediateCARequireExplicitPolicy
241 TEST_F(CertVerifyProcTest, MAYBE_IntermediateCARequireExplicitPolicy) {
242 base::FilePath certs_dir = GetTestCertsDirectory();
244 CertificateList certs = CreateCertificateListFromFile(
245 certs_dir, "explicit-policy-chain.pem",
246 X509Certificate::FORMAT_AUTO);
247 ASSERT_EQ(3U, certs.size());
249 X509Certificate::OSCertHandles intermediates;
250 intermediates.push_back(certs[1]->os_cert_handle());
252 scoped_refptr<X509Certificate> cert =
253 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
255 ASSERT_TRUE(cert.get());
257 ScopedTestRoot scoped_root(certs[2].get());
260 CertVerifyResult verify_result;
261 int error = Verify(cert.get(),
262 "policy_test.example",
267 EXPECT_EQ(OK, error);
268 EXPECT_EQ(0u, verify_result.cert_status);
271 // Test for bug 58437.
272 // This certificate will expire on 2011-12-21. The test will still
273 // pass if error == ERR_CERT_DATE_INVALID.
274 // This test is DISABLED because it appears that we cannot do
275 // certificate revocation checking when running all of the net unit tests.
276 // This test passes when run individually, but when run with all of the net
277 // unit tests, the call to PKIXVerifyCert returns the NSS error -8180, which is
278 // SEC_ERROR_REVOKED_CERTIFICATE. This indicates a lack of revocation
279 // status, i.e. that the revocation check is failing for some reason.
280 TEST_F(CertVerifyProcTest, DISABLED_GlobalSignR3EVTest) {
281 base::FilePath certs_dir = GetTestCertsDirectory();
283 scoped_refptr<X509Certificate> server_cert =
284 ImportCertFromFile(certs_dir, "2029_globalsign_com_cert.pem");
285 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
287 scoped_refptr<X509Certificate> intermediate_cert =
288 ImportCertFromFile(certs_dir, "globalsign_ev_sha256_ca_cert.pem");
289 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
291 X509Certificate::OSCertHandles intermediates;
292 intermediates.push_back(intermediate_cert->os_cert_handle());
293 scoped_refptr<X509Certificate> cert_chain =
294 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
297 CertVerifyResult verify_result;
298 int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED |
299 CertVerifier::VERIFY_EV_CERT;
300 int error = Verify(cert_chain.get(),
301 "2029.globalsign.com",
307 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
309 EXPECT_EQ(ERR_CERT_DATE_INVALID, error);
312 // Test that verifying an ECDSA certificate doesn't crash on XP. (See
313 // crbug.com/144466).
314 TEST_F(CertVerifyProcTest, ECDSA_RSA) {
315 base::FilePath certs_dir = GetTestCertsDirectory();
317 scoped_refptr<X509Certificate> cert =
318 ImportCertFromFile(certs_dir,
319 "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem");
321 CertVerifyResult verify_result;
322 Verify(cert.get(), "127.0.0.1", 0, NULL, empty_cert_list_, &verify_result);
324 // We don't check verify_result because the certificate is signed by an
325 // unknown CA and will be considered invalid on XP because of the ECDSA
329 // Currently, only RSA and DSA keys are checked for weakness, and our example
330 // weak size is 768. These could change in the future.
332 // Note that this means there may be false negatives: keys for other
333 // algorithms and which are weak will pass this test.
334 static bool IsWeakKeyType(const std::string& key_type) {
335 size_t pos = key_type.find("-");
336 std::string size = key_type.substr(0, pos);
337 std::string type = key_type.substr(pos + 1);
339 if (type == "rsa" || type == "dsa")
340 return size == "768";
345 TEST_F(CertVerifyProcTest, RejectWeakKeys) {
346 base::FilePath certs_dir = GetTestCertsDirectory();
347 typedef std::vector<std::string> Strings;
350 // generate-weak-test-chains.sh currently has:
351 // key_types="768-rsa 1024-rsa 2048-rsa prime256v1-ecdsa"
352 // We must use the same key types here. The filenames generated look like:
353 // 2048-rsa-ee-by-768-rsa-intermediate.pem
354 key_types.push_back("768-rsa");
355 key_types.push_back("1024-rsa");
356 key_types.push_back("2048-rsa");
358 bool use_ecdsa = true;
360 use_ecdsa = base::win::GetVersion() > base::win::VERSION_XP;
364 key_types.push_back("prime256v1-ecdsa");
366 // Add the root that signed the intermediates for this test.
367 scoped_refptr<X509Certificate> root_cert =
368 ImportCertFromFile(certs_dir, "2048-rsa-root.pem");
369 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert);
370 ScopedTestRoot scoped_root(root_cert.get());
372 // Now test each chain.
373 for (Strings::const_iterator ee_type = key_types.begin();
374 ee_type != key_types.end(); ++ee_type) {
375 for (Strings::const_iterator signer_type = key_types.begin();
376 signer_type != key_types.end(); ++signer_type) {
377 std::string basename = *ee_type + "-ee-by-" + *signer_type +
379 SCOPED_TRACE(basename);
380 scoped_refptr<X509Certificate> ee_cert =
381 ImportCertFromFile(certs_dir, basename);
382 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert);
384 basename = *signer_type + "-intermediate.pem";
385 scoped_refptr<X509Certificate> intermediate =
386 ImportCertFromFile(certs_dir, basename);
387 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate);
389 X509Certificate::OSCertHandles intermediates;
390 intermediates.push_back(intermediate->os_cert_handle());
391 scoped_refptr<X509Certificate> cert_chain =
392 X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(),
395 CertVerifyResult verify_result;
396 int error = Verify(cert_chain.get(),
403 if (IsWeakKeyType(*ee_type) || IsWeakKeyType(*signer_type)) {
404 EXPECT_NE(OK, error);
405 EXPECT_EQ(CERT_STATUS_WEAK_KEY,
406 verify_result.cert_status & CERT_STATUS_WEAK_KEY);
407 EXPECT_NE(CERT_STATUS_INVALID,
408 verify_result.cert_status & CERT_STATUS_INVALID);
410 EXPECT_EQ(OK, error);
411 EXPECT_EQ(0U, verify_result.cert_status & CERT_STATUS_WEAK_KEY);
417 // Regression test for http://crbug.com/108514.
418 #if defined(OS_MACOSX) && !defined(OS_IOS)
419 // Disabled on OS X - Security.framework doesn't ignore superflous certificates
420 // provided by servers. See CertVerifyProcTest.CybertrustGTERoot for further
422 #define MAYBE_ExtraneousMD5RootCert DISABLED_ExtraneousMD5RootCert
424 #define MAYBE_ExtraneousMD5RootCert ExtraneousMD5RootCert
426 TEST_F(CertVerifyProcTest, MAYBE_ExtraneousMD5RootCert) {
427 if (!SupportsReturningVerifiedChain()) {
428 LOG(INFO) << "Skipping this test in this platform.";
432 base::FilePath certs_dir = GetTestCertsDirectory();
434 scoped_refptr<X509Certificate> server_cert =
435 ImportCertFromFile(certs_dir, "cross-signed-leaf.pem");
436 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
438 scoped_refptr<X509Certificate> extra_cert =
439 ImportCertFromFile(certs_dir, "cross-signed-root-md5.pem");
440 ASSERT_NE(static_cast<X509Certificate*>(NULL), extra_cert.get());
442 scoped_refptr<X509Certificate> root_cert =
443 ImportCertFromFile(certs_dir, "cross-signed-root-sha1.pem");
444 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert.get());
446 ScopedTestRoot scoped_root(root_cert.get());
448 X509Certificate::OSCertHandles intermediates;
449 intermediates.push_back(extra_cert->os_cert_handle());
450 scoped_refptr<X509Certificate> cert_chain =
451 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
454 CertVerifyResult verify_result;
456 int error = Verify(cert_chain.get(),
462 EXPECT_EQ(OK, error);
464 // The extra MD5 root should be discarded
465 ASSERT_TRUE(verify_result.verified_cert.get());
467 verify_result.verified_cert->GetIntermediateCertificates().size());
468 EXPECT_TRUE(X509Certificate::IsSameOSCert(
469 verify_result.verified_cert->GetIntermediateCertificates().front(),
470 root_cert->os_cert_handle()));
472 EXPECT_FALSE(verify_result.has_md5);
475 // Test for bug 94673.
476 TEST_F(CertVerifyProcTest, GoogleDigiNotarTest) {
477 base::FilePath certs_dir = GetTestCertsDirectory();
479 scoped_refptr<X509Certificate> server_cert =
480 ImportCertFromFile(certs_dir, "google_diginotar.pem");
481 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
483 scoped_refptr<X509Certificate> intermediate_cert =
484 ImportCertFromFile(certs_dir, "diginotar_public_ca_2025.pem");
485 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
487 X509Certificate::OSCertHandles intermediates;
488 intermediates.push_back(intermediate_cert->os_cert_handle());
489 scoped_refptr<X509Certificate> cert_chain =
490 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
493 CertVerifyResult verify_result;
494 int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED;
495 int error = Verify(cert_chain.get(),
501 EXPECT_NE(OK, error);
503 // Now turn off revocation checking. Certificate verification should still
506 error = Verify(cert_chain.get(),
512 EXPECT_NE(OK, error);
515 TEST_F(CertVerifyProcTest, DigiNotarCerts) {
516 static const char* const kDigiNotarFilenames[] = {
517 "diginotar_root_ca.pem",
518 "diginotar_cyber_ca.pem",
519 "diginotar_services_1024_ca.pem",
520 "diginotar_pkioverheid.pem",
521 "diginotar_pkioverheid_g2.pem",
525 base::FilePath certs_dir = GetTestCertsDirectory();
527 for (size_t i = 0; kDigiNotarFilenames[i]; i++) {
528 scoped_refptr<X509Certificate> diginotar_cert =
529 ImportCertFromFile(certs_dir, kDigiNotarFilenames[i]);
530 std::string der_bytes;
531 ASSERT_TRUE(X509Certificate::GetDEREncoded(
532 diginotar_cert->os_cert_handle(), &der_bytes));
534 base::StringPiece spki;
535 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_bytes, &spki));
537 std::string spki_sha1 = base::SHA1HashString(spki.as_string());
539 HashValueVector public_keys;
540 HashValue hash(HASH_VALUE_SHA1);
541 ASSERT_EQ(hash.size(), spki_sha1.size());
542 memcpy(hash.data(), spki_sha1.data(), spki_sha1.size());
543 public_keys.push_back(hash);
545 EXPECT_TRUE(CertVerifyProc::IsPublicKeyBlacklisted(public_keys)) <<
546 "Public key not blocked for " << kDigiNotarFilenames[i];
550 TEST_F(CertVerifyProcTest, NameConstraintsOk) {
551 CertificateList ca_cert_list =
552 CreateCertificateListFromFile(GetTestCertsDirectory(),
554 X509Certificate::FORMAT_AUTO);
555 ASSERT_EQ(1U, ca_cert_list.size());
556 ScopedTestRoot test_root(ca_cert_list[0]);
558 CertificateList cert_list = CreateCertificateListFromFile(
559 GetTestCertsDirectory(), "name_constraint_ok.crt",
560 X509Certificate::FORMAT_AUTO);
561 ASSERT_EQ(1U, cert_list.size());
563 X509Certificate::OSCertHandles intermediates;
564 scoped_refptr<X509Certificate> leaf =
565 X509Certificate::CreateFromHandle(cert_list[0]->os_cert_handle(),
569 CertVerifyResult verify_result;
570 int error = Verify(leaf.get(),
576 EXPECT_EQ(OK, error);
577 EXPECT_EQ(0U, verify_result.cert_status);
580 TEST_F(CertVerifyProcTest, NameConstraintsFailure) {
581 if (!SupportsReturningVerifiedChain()) {
582 LOG(INFO) << "Skipping this test in this platform.";
586 CertificateList ca_cert_list =
587 CreateCertificateListFromFile(GetTestCertsDirectory(),
589 X509Certificate::FORMAT_AUTO);
590 ASSERT_EQ(1U, ca_cert_list.size());
591 ScopedTestRoot test_root(ca_cert_list[0]);
593 CertificateList cert_list = CreateCertificateListFromFile(
594 GetTestCertsDirectory(), "name_constraint_bad.crt",
595 X509Certificate::FORMAT_AUTO);
596 ASSERT_EQ(1U, cert_list.size());
598 X509Certificate::OSCertHandles intermediates;
599 scoped_refptr<X509Certificate> leaf =
600 X509Certificate::CreateFromHandle(cert_list[0]->os_cert_handle(),
604 CertVerifyResult verify_result;
605 int error = Verify(leaf.get(),
611 EXPECT_EQ(ERR_CERT_NAME_CONSTRAINT_VIOLATION, error);
612 EXPECT_EQ(CERT_STATUS_NAME_CONSTRAINT_VIOLATION,
613 verify_result.cert_status & CERT_STATUS_NAME_CONSTRAINT_VIOLATION);
616 TEST_F(CertVerifyProcTest, TestKnownRoot) {
617 if (!SupportsDetectingKnownRoots()) {
618 LOG(INFO) << "Skipping this test in this platform.";
622 base::FilePath certs_dir = GetTestCertsDirectory();
623 CertificateList certs = CreateCertificateListFromFile(
624 certs_dir, "satveda.pem", X509Certificate::FORMAT_AUTO);
625 ASSERT_EQ(2U, certs.size());
627 X509Certificate::OSCertHandles intermediates;
628 intermediates.push_back(certs[1]->os_cert_handle());
630 scoped_refptr<X509Certificate> cert_chain =
631 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
635 CertVerifyResult verify_result;
636 // This will blow up, May 24th, 2019. Sorry! Please disable and file a bug
637 // against agl. See also PublicKeyHashes.
638 int error = Verify(cert_chain.get(),
644 EXPECT_EQ(OK, error);
645 EXPECT_EQ(0U, verify_result.cert_status);
646 EXPECT_TRUE(verify_result.is_issued_by_known_root);
649 // The certse.pem certificate has been revoked. crbug.com/259723.
650 TEST_F(CertVerifyProcTest, PublicKeyHashes) {
651 if (!SupportsReturningVerifiedChain()) {
652 LOG(INFO) << "Skipping this test in this platform.";
656 base::FilePath certs_dir = GetTestCertsDirectory();
657 CertificateList certs = CreateCertificateListFromFile(
658 certs_dir, "satveda.pem", X509Certificate::FORMAT_AUTO);
659 ASSERT_EQ(2U, certs.size());
661 X509Certificate::OSCertHandles intermediates;
662 intermediates.push_back(certs[1]->os_cert_handle());
664 scoped_refptr<X509Certificate> cert_chain =
665 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
668 CertVerifyResult verify_result;
670 // This will blow up, May 24th, 2019. Sorry! Please disable and file a bug
671 // against agl. See also TestKnownRoot.
672 int error = Verify(cert_chain.get(),
678 EXPECT_EQ(OK, error);
679 EXPECT_EQ(0U, verify_result.cert_status);
680 ASSERT_LE(2U, verify_result.public_key_hashes.size());
682 HashValueVector sha1_hashes;
683 for (size_t i = 0; i < verify_result.public_key_hashes.size(); ++i) {
684 if (verify_result.public_key_hashes[i].tag != HASH_VALUE_SHA1)
686 sha1_hashes.push_back(verify_result.public_key_hashes[i]);
688 ASSERT_LE(2u, sha1_hashes.size());
690 for (size_t i = 0; i < 2; ++i) {
691 EXPECT_EQ(HexEncode(kSatvedaSPKIs[i], base::kSHA1Length),
692 HexEncode(sha1_hashes[i].data(), base::kSHA1Length));
695 HashValueVector sha256_hashes;
696 for (size_t i = 0; i < verify_result.public_key_hashes.size(); ++i) {
697 if (verify_result.public_key_hashes[i].tag != HASH_VALUE_SHA256)
699 sha256_hashes.push_back(verify_result.public_key_hashes[i]);
701 ASSERT_LE(2u, sha256_hashes.size());
703 for (size_t i = 0; i < 2; ++i) {
704 EXPECT_EQ(HexEncode(kSatvedaSPKIsSHA256[i], crypto::kSHA256Length),
705 HexEncode(sha256_hashes[i].data(), crypto::kSHA256Length));
709 // A regression test for http://crbug.com/70293.
710 // The Key Usage extension in this RSA SSL server certificate does not have
711 // the keyEncipherment bit.
712 TEST_F(CertVerifyProcTest, InvalidKeyUsage) {
713 base::FilePath certs_dir = GetTestCertsDirectory();
715 scoped_refptr<X509Certificate> server_cert =
716 ImportCertFromFile(certs_dir, "invalid_key_usage_cert.der");
717 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
720 CertVerifyResult verify_result;
721 int error = Verify(server_cert.get(),
727 #if defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
728 // This certificate has two errors: "invalid key usage" and "untrusted CA".
729 // However, OpenSSL returns only one (the latter), and we can't detect
731 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
733 EXPECT_EQ(ERR_CERT_INVALID, error);
734 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
736 // TODO(wtc): fix http://crbug.com/75520 to get all the certificate errors
738 #if !defined(USE_NSS) && !defined(OS_IOS) && !defined(OS_ANDROID)
739 // The certificate is issued by an unknown CA.
740 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
744 // Basic test for returning the chain in CertVerifyResult. Note that the
745 // returned chain may just be a reflection of the originally supplied chain;
746 // that is, if any errors occur, the default chain returned is an exact copy
747 // of the certificate to be verified. The remaining VerifyReturn* tests are
748 // used to ensure that the actual, verified chain is being returned by
750 TEST_F(CertVerifyProcTest, VerifyReturnChainBasic) {
751 if (!SupportsReturningVerifiedChain()) {
752 LOG(INFO) << "Skipping this test in this platform.";
756 base::FilePath certs_dir = GetTestCertsDirectory();
757 CertificateList certs = CreateCertificateListFromFile(
758 certs_dir, "x509_verify_results.chain.pem",
759 X509Certificate::FORMAT_AUTO);
760 ASSERT_EQ(3U, certs.size());
762 X509Certificate::OSCertHandles intermediates;
763 intermediates.push_back(certs[1]->os_cert_handle());
764 intermediates.push_back(certs[2]->os_cert_handle());
766 ScopedTestRoot scoped_root(certs[2].get());
768 scoped_refptr<X509Certificate> google_full_chain =
769 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
771 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain);
772 ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size());
774 CertVerifyResult verify_result;
775 EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
776 int error = Verify(google_full_chain.get(),
782 EXPECT_EQ(OK, error);
783 ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
785 EXPECT_NE(google_full_chain, verify_result.verified_cert);
786 EXPECT_TRUE(X509Certificate::IsSameOSCert(
787 google_full_chain->os_cert_handle(),
788 verify_result.verified_cert->os_cert_handle()));
789 const X509Certificate::OSCertHandles& return_intermediates =
790 verify_result.verified_cert->GetIntermediateCertificates();
791 ASSERT_EQ(2U, return_intermediates.size());
792 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
793 certs[1]->os_cert_handle()));
794 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
795 certs[2]->os_cert_handle()));
798 // Test that certificates issued for 'intranet' names (that is, containing no
799 // known public registry controlled domain information) issued by well-known
800 // CAs are flagged appropriately, while certificates that are issued by
801 // internal CAs are not flagged.
802 TEST_F(CertVerifyProcTest, IntranetHostsRejected) {
803 if (!SupportsDetectingKnownRoots()) {
804 LOG(INFO) << "Skipping this test in this platform.";
808 CertificateList cert_list = CreateCertificateListFromFile(
809 GetTestCertsDirectory(), "ok_cert.pem",
810 X509Certificate::FORMAT_AUTO);
811 ASSERT_EQ(1U, cert_list.size());
812 scoped_refptr<X509Certificate> cert(cert_list[0]);
814 CertVerifyResult verify_result;
817 // Intranet names for public CAs should be flagged:
818 verify_proc_ = new WellKnownCaCertVerifyProc(true);
820 Verify(cert.get(), "intranet", 0, NULL, empty_cert_list_, &verify_result);
821 EXPECT_EQ(OK, error);
822 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
824 // However, if the CA is not well known, these should not be flagged:
825 verify_proc_ = new WellKnownCaCertVerifyProc(false);
827 Verify(cert.get(), "intranet", 0, NULL, empty_cert_list_, &verify_result);
828 EXPECT_EQ(OK, error);
829 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
832 // Test that the certificate returned in CertVerifyResult is able to reorder
833 // certificates that are not ordered from end-entity to root. While this is
834 // a protocol violation if sent during a TLS handshake, if multiple sources
835 // of intermediate certificates are combined, it's possible that order may
836 // not be maintained.
837 TEST_F(CertVerifyProcTest, VerifyReturnChainProperlyOrdered) {
838 if (!SupportsReturningVerifiedChain()) {
839 LOG(INFO) << "Skipping this test in this platform.";
843 base::FilePath certs_dir = GetTestCertsDirectory();
844 CertificateList certs = CreateCertificateListFromFile(
845 certs_dir, "x509_verify_results.chain.pem",
846 X509Certificate::FORMAT_AUTO);
847 ASSERT_EQ(3U, certs.size());
849 // Construct the chain out of order.
850 X509Certificate::OSCertHandles intermediates;
851 intermediates.push_back(certs[2]->os_cert_handle());
852 intermediates.push_back(certs[1]->os_cert_handle());
854 ScopedTestRoot scoped_root(certs[2].get());
856 scoped_refptr<X509Certificate> google_full_chain =
857 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
859 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain);
860 ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size());
862 CertVerifyResult verify_result;
863 EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
864 int error = Verify(google_full_chain.get(),
870 EXPECT_EQ(OK, error);
871 ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
873 EXPECT_NE(google_full_chain, verify_result.verified_cert);
874 EXPECT_TRUE(X509Certificate::IsSameOSCert(
875 google_full_chain->os_cert_handle(),
876 verify_result.verified_cert->os_cert_handle()));
877 const X509Certificate::OSCertHandles& return_intermediates =
878 verify_result.verified_cert->GetIntermediateCertificates();
879 ASSERT_EQ(2U, return_intermediates.size());
880 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
881 certs[1]->os_cert_handle()));
882 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
883 certs[2]->os_cert_handle()));
886 // Test that Verify() filters out certificates which are not related to
887 // or part of the certificate chain being verified.
888 TEST_F(CertVerifyProcTest, VerifyReturnChainFiltersUnrelatedCerts) {
889 if (!SupportsReturningVerifiedChain()) {
890 LOG(INFO) << "Skipping this test in this platform.";
894 base::FilePath certs_dir = GetTestCertsDirectory();
895 CertificateList certs = CreateCertificateListFromFile(
896 certs_dir, "x509_verify_results.chain.pem",
897 X509Certificate::FORMAT_AUTO);
898 ASSERT_EQ(3U, certs.size());
899 ScopedTestRoot scoped_root(certs[2].get());
901 scoped_refptr<X509Certificate> unrelated_certificate =
902 ImportCertFromFile(certs_dir, "duplicate_cn_1.pem");
903 scoped_refptr<X509Certificate> unrelated_certificate2 =
904 ImportCertFromFile(certs_dir, "aia-cert.pem");
905 ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_certificate);
906 ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_certificate2);
908 // Interject unrelated certificates into the list of intermediates.
909 X509Certificate::OSCertHandles intermediates;
910 intermediates.push_back(unrelated_certificate->os_cert_handle());
911 intermediates.push_back(certs[1]->os_cert_handle());
912 intermediates.push_back(unrelated_certificate2->os_cert_handle());
913 intermediates.push_back(certs[2]->os_cert_handle());
915 scoped_refptr<X509Certificate> google_full_chain =
916 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
918 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain);
919 ASSERT_EQ(4U, google_full_chain->GetIntermediateCertificates().size());
921 CertVerifyResult verify_result;
922 EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
923 int error = Verify(google_full_chain.get(),
929 EXPECT_EQ(OK, error);
930 ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
932 EXPECT_NE(google_full_chain, verify_result.verified_cert);
933 EXPECT_TRUE(X509Certificate::IsSameOSCert(
934 google_full_chain->os_cert_handle(),
935 verify_result.verified_cert->os_cert_handle()));
936 const X509Certificate::OSCertHandles& return_intermediates =
937 verify_result.verified_cert->GetIntermediateCertificates();
938 ASSERT_EQ(2U, return_intermediates.size());
939 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
940 certs[1]->os_cert_handle()));
941 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
942 certs[2]->os_cert_handle()));
945 TEST_F(CertVerifyProcTest, AdditionalTrustAnchors) {
946 if (!SupportsAdditionalTrustAnchors()) {
947 LOG(INFO) << "Skipping this test in this platform.";
951 // |ca_cert| is the issuer of |cert|.
952 CertificateList ca_cert_list = CreateCertificateListFromFile(
953 GetTestCertsDirectory(), "root_ca_cert.pem",
954 X509Certificate::FORMAT_AUTO);
955 ASSERT_EQ(1U, ca_cert_list.size());
956 scoped_refptr<X509Certificate> ca_cert(ca_cert_list[0]);
958 CertificateList cert_list = CreateCertificateListFromFile(
959 GetTestCertsDirectory(), "ok_cert.pem",
960 X509Certificate::FORMAT_AUTO);
961 ASSERT_EQ(1U, cert_list.size());
962 scoped_refptr<X509Certificate> cert(cert_list[0]);
964 // Verification of |cert| fails when |ca_cert| is not in the trust anchors
967 CertVerifyResult verify_result;
969 cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result);
970 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
971 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
972 EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
974 // Now add the |ca_cert| to the |trust_anchors|, and verification should pass.
975 CertificateList trust_anchors;
976 trust_anchors.push_back(ca_cert);
978 cert.get(), "127.0.0.1", flags, NULL, trust_anchors, &verify_result);
979 EXPECT_EQ(OK, error);
980 EXPECT_EQ(0U, verify_result.cert_status);
981 EXPECT_TRUE(verify_result.is_issued_by_additional_trust_anchor);
983 // Clearing the |trust_anchors| makes verification fail again (the cache
984 // should be skipped).
986 cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result);
987 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
988 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
989 EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
992 // Tests that certificates issued by user-supplied roots are not flagged as
993 // issued by a known root. This should pass whether or not the platform supports
994 // detecting known roots.
995 TEST_F(CertVerifyProcTest, IsIssuedByKnownRootIgnoresTestRoots) {
996 // Load root_ca_cert.pem into the test root store.
997 TestRootCerts* root_certs = TestRootCerts::GetInstance();
998 root_certs->AddFromFile(
999 GetTestCertsDirectory().AppendASCII("root_ca_cert.pem"));
1001 CertificateList cert_list = CreateCertificateListFromFile(
1002 GetTestCertsDirectory(), "ok_cert.pem",
1003 X509Certificate::FORMAT_AUTO);
1004 ASSERT_EQ(1U, cert_list.size());
1005 scoped_refptr<X509Certificate> cert(cert_list[0]);
1007 // Verification should pass.
1009 CertVerifyResult verify_result;
1011 cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result);
1012 EXPECT_EQ(OK, error);
1013 EXPECT_EQ(0U, verify_result.cert_status);
1014 // But should not be marked as a known root.
1015 EXPECT_FALSE(verify_result.is_issued_by_known_root);
1017 root_certs->Clear();
1018 EXPECT_TRUE(root_certs->IsEmpty());
1021 #if defined(OS_MACOSX) && !defined(OS_IOS)
1022 // Tests that, on OS X, issues with a cross-certified Baltimore CyberTrust
1023 // Root can be successfully worked around once Apple completes removing the
1024 // older GTE CyberTrust Root from its trusted root store.
1026 // The issue is caused by servers supplying the cross-certified intermediate
1027 // (necessary for certain mobile platforms), which OS X does not recognize
1028 // as already existing within its trust store.
1029 TEST_F(CertVerifyProcTest, CybertrustGTERoot) {
1030 CertificateList certs = CreateCertificateListFromFile(
1031 GetTestCertsDirectory(),
1032 "cybertrust_omniroot_chain.pem",
1033 X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
1034 ASSERT_EQ(2U, certs.size());
1036 X509Certificate::OSCertHandles intermediates;
1037 intermediates.push_back(certs[1]->os_cert_handle());
1039 scoped_refptr<X509Certificate> cybertrust_basic =
1040 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
1042 ASSERT_TRUE(cybertrust_basic.get());
1044 scoped_refptr<X509Certificate> baltimore_root =
1045 ImportCertFromFile(GetTestCertsDirectory(),
1046 "cybertrust_baltimore_root.pem");
1047 ASSERT_TRUE(baltimore_root.get());
1049 ScopedTestRoot scoped_root(baltimore_root.get());
1051 // Ensure that ONLY the Baltimore CyberTrust Root is trusted. This
1052 // simulates Keychain removing support for the GTE CyberTrust Root.
1053 TestRootCerts::GetInstance()->SetAllowSystemTrust(false);
1054 base::ScopedClosureRunner reset_system_trust(
1055 base::Bind(&TestRootCerts::SetAllowSystemTrust,
1056 base::Unretained(TestRootCerts::GetInstance()),
1059 // First, make sure a simple certificate chain from
1060 // EE -> Public SureServer SV -> Baltimore CyberTrust
1061 // works. Only the first two certificates are included in the chain.
1063 CertVerifyResult verify_result;
1064 int error = Verify(cybertrust_basic.get(),
1065 "cacert.omniroot.com",
1070 EXPECT_EQ(OK, error);
1071 EXPECT_EQ(0U, verify_result.cert_status);
1073 // Attempt to verify with the first known cross-certified intermediate
1075 scoped_refptr<X509Certificate> baltimore_intermediate_1 =
1076 ImportCertFromFile(GetTestCertsDirectory(),
1077 "cybertrust_baltimore_cross_certified_1.pem");
1078 ASSERT_TRUE(baltimore_intermediate_1.get());
1080 X509Certificate::OSCertHandles intermediate_chain_1 =
1081 cybertrust_basic->GetIntermediateCertificates();
1082 intermediate_chain_1.push_back(baltimore_intermediate_1->os_cert_handle());
1084 scoped_refptr<X509Certificate> baltimore_chain_1 =
1085 X509Certificate::CreateFromHandle(cybertrust_basic->os_cert_handle(),
1086 intermediate_chain_1);
1087 error = Verify(baltimore_chain_1.get(),
1088 "cacert.omniroot.com",
1093 EXPECT_EQ(OK, error);
1094 EXPECT_EQ(0U, verify_result.cert_status);
1096 // Attempt to verify with the second known cross-certified intermediate
1098 scoped_refptr<X509Certificate> baltimore_intermediate_2 =
1099 ImportCertFromFile(GetTestCertsDirectory(),
1100 "cybertrust_baltimore_cross_certified_2.pem");
1101 ASSERT_TRUE(baltimore_intermediate_2.get());
1103 X509Certificate::OSCertHandles intermediate_chain_2 =
1104 cybertrust_basic->GetIntermediateCertificates();
1105 intermediate_chain_2.push_back(baltimore_intermediate_2->os_cert_handle());
1107 scoped_refptr<X509Certificate> baltimore_chain_2 =
1108 X509Certificate::CreateFromHandle(cybertrust_basic->os_cert_handle(),
1109 intermediate_chain_2);
1110 error = Verify(baltimore_chain_2.get(),
1111 "cacert.omniroot.com",
1116 EXPECT_EQ(OK, error);
1117 EXPECT_EQ(0U, verify_result.cert_status);
1119 // Attempt to verify when both a cross-certified intermediate AND
1120 // the legacy GTE root are provided.
1121 scoped_refptr<X509Certificate> cybertrust_root =
1122 ImportCertFromFile(GetTestCertsDirectory(),
1123 "cybertrust_gte_root.pem");
1124 ASSERT_TRUE(cybertrust_root.get());
1126 intermediate_chain_2.push_back(cybertrust_root->os_cert_handle());
1127 scoped_refptr<X509Certificate> baltimore_chain_with_root =
1128 X509Certificate::CreateFromHandle(cybertrust_basic->os_cert_handle(),
1129 intermediate_chain_2);
1130 error = Verify(baltimore_chain_with_root.get(),
1131 "cacert.omniroot.com",
1136 EXPECT_EQ(OK, error);
1137 EXPECT_EQ(0U, verify_result.cert_status);
1139 TestRootCerts::GetInstance()->Clear();
1140 EXPECT_TRUE(TestRootCerts::GetInstance()->IsEmpty());
1144 #if defined(USE_NSS) || defined(OS_IOS) || defined(OS_WIN) || defined(OS_MACOSX)
1145 static const uint8 kCRLSetLeafSPKIBlocked[] = {
1146 0x8e, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
1147 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
1148 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
1149 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
1150 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
1151 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
1152 0x30, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
1153 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x43, 0x38, 0x4d, 0x4a, 0x46, 0x55, 0x55,
1154 0x5a, 0x38, 0x43, 0x79, 0x54, 0x2b, 0x4e, 0x57, 0x64, 0x68, 0x69, 0x7a, 0x51,
1155 0x68, 0x54, 0x49, 0x65, 0x46, 0x49, 0x37, 0x76, 0x41, 0x77, 0x7a, 0x64, 0x54,
1156 0x79, 0x52, 0x59, 0x45, 0x6e, 0x78, 0x6c, 0x33, 0x62, 0x67, 0x3d, 0x22, 0x5d,
1160 static const uint8 kCRLSetLeafSerialBlocked[] = {
1161 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
1162 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
1163 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
1164 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
1165 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
1166 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
1167 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
1168 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x0f, 0x87, 0xe4, 0xc7, 0x75, 0xea,
1169 0x46, 0x7e, 0xf3, 0xfd, 0x82, 0xb7, 0x46, 0x7b, 0x10, 0xda, 0xc5, 0xbf, 0xd8,
1170 0xd1, 0x29, 0xb2, 0xc6, 0xac, 0x7f, 0x51, 0x42, 0x15, 0x28, 0x51, 0x06, 0x7f,
1171 0x01, 0x00, 0x00, 0x00, // number of serials
1172 0x01, 0xed, // serial 0xed
1175 static const uint8 kCRLSetQUICSerialBlocked[] = {
1176 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
1177 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
1178 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
1179 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
1180 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
1181 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
1182 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
1183 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d,
1184 // Issuer SPKI SHA-256 hash:
1185 0xe4, 0x3a, 0xa3, 0xdb, 0x98, 0x31, 0x61, 0x05, 0xdd, 0x57, 0x6d, 0xc6, 0x2f,
1186 0x71, 0x26, 0xba, 0xdd, 0xf4, 0x98, 0x3e, 0x62, 0x22, 0xf8, 0xf9, 0xe4, 0x18,
1187 0x62, 0x77, 0x79, 0xdb, 0x9b, 0x31,
1188 0x01, 0x00, 0x00, 0x00, // number of serials
1189 0x01, 0x03, // serial 3
1192 // Test that CRLSets are effective in making a certificate appear to be
1194 TEST_F(CertVerifyProcTest, CRLSet) {
1195 CertificateList ca_cert_list =
1196 CreateCertificateListFromFile(GetTestCertsDirectory(),
1198 X509Certificate::FORMAT_AUTO);
1199 ASSERT_EQ(1U, ca_cert_list.size());
1200 ScopedTestRoot test_root(ca_cert_list[0]);
1202 CertificateList cert_list = CreateCertificateListFromFile(
1203 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO);
1204 ASSERT_EQ(1U, cert_list.size());
1205 scoped_refptr<X509Certificate> cert(cert_list[0]);
1208 CertVerifyResult verify_result;
1210 cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result);
1211 EXPECT_EQ(OK, error);
1212 EXPECT_EQ(0U, verify_result.cert_status);
1214 // First test blocking by SPKI.
1215 base::StringPiece crl_set_bytes(
1216 reinterpret_cast<const char*>(kCRLSetLeafSPKIBlocked),
1217 sizeof(kCRLSetLeafSPKIBlocked));
1218 scoped_refptr<CRLSet> crl_set;
1219 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
1221 error = Verify(cert.get(),
1227 EXPECT_EQ(ERR_CERT_REVOKED, error);
1229 // Second, test revocation by serial number of a cert directly under the
1232 base::StringPiece(reinterpret_cast<const char*>(kCRLSetLeafSerialBlocked),
1233 sizeof(kCRLSetLeafSerialBlocked));
1234 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
1236 error = Verify(cert.get(),
1242 EXPECT_EQ(ERR_CERT_REVOKED, error);
1245 TEST_F(CertVerifyProcTest, CRLSetLeafSerial) {
1246 CertificateList ca_cert_list =
1247 CreateCertificateListFromFile(GetTestCertsDirectory(),
1249 X509Certificate::FORMAT_AUTO);
1250 ASSERT_EQ(1U, ca_cert_list.size());
1251 ScopedTestRoot test_root(ca_cert_list[0]);
1253 CertificateList intermediate_cert_list =
1254 CreateCertificateListFromFile(GetTestCertsDirectory(),
1255 "quic_intermediate.crt",
1256 X509Certificate::FORMAT_AUTO);
1257 ASSERT_EQ(1U, intermediate_cert_list.size());
1258 X509Certificate::OSCertHandles intermediates;
1259 intermediates.push_back(intermediate_cert_list[0]->os_cert_handle());
1261 CertificateList cert_list = CreateCertificateListFromFile(
1262 GetTestCertsDirectory(), "quic_test.example.com.crt",
1263 X509Certificate::FORMAT_AUTO);
1264 ASSERT_EQ(1U, cert_list.size());
1266 scoped_refptr<X509Certificate> leaf =
1267 X509Certificate::CreateFromHandle(cert_list[0]->os_cert_handle(),
1271 CertVerifyResult verify_result;
1272 int error = Verify(leaf.get(),
1278 EXPECT_EQ(OK, error);
1279 EXPECT_EQ(0U, verify_result.cert_status);
1281 // Test revocation by serial number of a certificate not under the root.
1282 scoped_refptr<CRLSet> crl_set;
1283 base::StringPiece crl_set_bytes =
1284 base::StringPiece(reinterpret_cast<const char*>(kCRLSetQUICSerialBlocked),
1285 sizeof(kCRLSetQUICSerialBlocked));
1286 ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
1288 error = Verify(leaf.get(),
1294 EXPECT_EQ(ERR_CERT_REVOKED, error);
1298 struct WeakDigestTestData {
1299 const char* root_cert_filename;
1300 const char* intermediate_cert_filename;
1301 const char* ee_cert_filename;
1302 bool expected_has_md5;
1303 bool expected_has_md4;
1304 bool expected_has_md2;
1307 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
1308 // to output the parameter that was passed. Without this, it will simply
1309 // attempt to print out the first twenty bytes of the object, which depending
1310 // on platform and alignment, may result in an invalid read.
1311 void PrintTo(const WeakDigestTestData& data, std::ostream* os) {
1313 << (data.root_cert_filename ? data.root_cert_filename : "none")
1314 << "; intermediate: " << data.intermediate_cert_filename
1315 << "; end-entity: " << data.ee_cert_filename;
1318 class CertVerifyProcWeakDigestTest
1319 : public CertVerifyProcTest,
1320 public testing::WithParamInterface<WeakDigestTestData> {
1322 CertVerifyProcWeakDigestTest() {}
1323 virtual ~CertVerifyProcWeakDigestTest() {}
1326 TEST_P(CertVerifyProcWeakDigestTest, Verify) {
1327 WeakDigestTestData data = GetParam();
1328 base::FilePath certs_dir = GetTestCertsDirectory();
1330 ScopedTestRoot test_root;
1331 if (data.root_cert_filename) {
1332 scoped_refptr<X509Certificate> root_cert =
1333 ImportCertFromFile(certs_dir, data.root_cert_filename);
1334 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert);
1335 test_root.Reset(root_cert.get());
1338 scoped_refptr<X509Certificate> intermediate_cert =
1339 ImportCertFromFile(certs_dir, data.intermediate_cert_filename);
1340 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
1341 scoped_refptr<X509Certificate> ee_cert =
1342 ImportCertFromFile(certs_dir, data.ee_cert_filename);
1343 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert);
1345 X509Certificate::OSCertHandles intermediates;
1346 intermediates.push_back(intermediate_cert->os_cert_handle());
1348 scoped_refptr<X509Certificate> ee_chain =
1349 X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(),
1351 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_chain);
1354 CertVerifyResult verify_result;
1355 int rv = Verify(ee_chain.get(),
1361 EXPECT_EQ(data.expected_has_md5, verify_result.has_md5);
1362 EXPECT_EQ(data.expected_has_md4, verify_result.has_md4);
1363 EXPECT_EQ(data.expected_has_md2, verify_result.has_md2);
1364 EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
1366 // Ensure that MD4 and MD2 are tagged as invalid.
1367 if (data.expected_has_md4 || data.expected_has_md2) {
1368 EXPECT_EQ(CERT_STATUS_INVALID,
1369 verify_result.cert_status & CERT_STATUS_INVALID);
1372 // Ensure that MD5 is flagged as weak.
1373 if (data.expected_has_md5) {
1375 CERT_STATUS_WEAK_SIGNATURE_ALGORITHM,
1376 verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
1379 // If a root cert is present, then check that the chain was rejected if any
1380 // weak algorithms are present. This is only checked when a root cert is
1381 // present because the error reported for incomplete chains with weak
1382 // algorithms depends on which implementation was used to validate (NSS,
1383 // OpenSSL, CryptoAPI, Security.framework) and upon which weak algorithm
1384 // present (MD2, MD4, MD5).
1385 if (data.root_cert_filename) {
1386 if (data.expected_has_md4 || data.expected_has_md2) {
1387 EXPECT_EQ(ERR_CERT_INVALID, rv);
1388 } else if (data.expected_has_md5) {
1389 EXPECT_EQ(ERR_CERT_WEAK_SIGNATURE_ALGORITHM, rv);
1396 // Unlike TEST/TEST_F, which are macros that expand to further macros,
1397 // INSTANTIATE_TEST_CASE_P is a macro that expands directly to code that
1398 // stringizes the arguments. As a result, macros passed as parameters (such as
1399 // prefix or test_case_name) will not be expanded by the preprocessor. To work
1400 // around this, indirect the macro for INSTANTIATE_TEST_CASE_P, so that the
1401 // pre-processor will expand macros such as MAYBE_test_name before
1402 // instantiating the test.
1403 #define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
1404 INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator)
1406 // The signature algorithm of the root CA should not matter.
1407 const WeakDigestTestData kVerifyRootCATestData[] = {
1408 { "weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem",
1409 "weak_digest_sha1_ee.pem", false, false, false },
1410 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1411 // MD4 is not supported by OS X / NSS
1412 { "weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem",
1413 "weak_digest_sha1_ee.pem", false, false, false },
1415 { "weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem",
1416 "weak_digest_sha1_ee.pem", false, false, false },
1418 INSTANTIATE_TEST_CASE_P(VerifyRoot, CertVerifyProcWeakDigestTest,
1419 testing::ValuesIn(kVerifyRootCATestData));
1421 // The signature algorithm of intermediates should be properly detected.
1422 const WeakDigestTestData kVerifyIntermediateCATestData[] = {
1423 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
1424 "weak_digest_sha1_ee.pem", true, false, false },
1425 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1426 // MD4 is not supported by OS X / NSS
1427 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
1428 "weak_digest_sha1_ee.pem", false, true, false },
1430 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
1431 "weak_digest_sha1_ee.pem", false, false, true },
1433 // Disabled on NSS - MD4 is not supported, and MD2 and MD5 are disabled.
1434 #if defined(USE_NSS) || defined(OS_IOS)
1435 #define MAYBE_VerifyIntermediate DISABLED_VerifyIntermediate
1437 #define MAYBE_VerifyIntermediate VerifyIntermediate
1439 WRAPPED_INSTANTIATE_TEST_CASE_P(
1440 MAYBE_VerifyIntermediate,
1441 CertVerifyProcWeakDigestTest,
1442 testing::ValuesIn(kVerifyIntermediateCATestData));
1444 // The signature algorithm of end-entity should be properly detected.
1445 const WeakDigestTestData kVerifyEndEntityTestData[] = {
1446 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1447 "weak_digest_md5_ee.pem", true, false, false },
1448 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1449 // MD4 is not supported by OS X / NSS
1450 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1451 "weak_digest_md4_ee.pem", false, true, false },
1453 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1454 "weak_digest_md2_ee.pem", false, false, true },
1456 // Disabled on NSS - NSS caches chains/signatures in such a way that cannot
1457 // be cleared until NSS is cleanly shutdown, which is not presently supported
1459 #if defined(USE_NSS) || defined(OS_IOS)
1460 #define MAYBE_VerifyEndEntity DISABLED_VerifyEndEntity
1462 #define MAYBE_VerifyEndEntity VerifyEndEntity
1464 WRAPPED_INSTANTIATE_TEST_CASE_P(MAYBE_VerifyEndEntity,
1465 CertVerifyProcWeakDigestTest,
1466 testing::ValuesIn(kVerifyEndEntityTestData));
1468 // Incomplete chains should still report the status of the intermediate.
1469 const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] = {
1470 { NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem",
1471 true, false, false },
1472 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1473 // MD4 is not supported by OS X / NSS
1474 { NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem",
1475 false, true, false },
1477 { NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem",
1478 false, false, true },
1480 // Disabled on NSS - libpkix does not return constructed chains on error,
1481 // preventing us from detecting/inspecting the verified chain.
1482 #if defined(USE_NSS) || defined(OS_IOS)
1483 #define MAYBE_VerifyIncompleteIntermediate \
1484 DISABLED_VerifyIncompleteIntermediate
1486 #define MAYBE_VerifyIncompleteIntermediate VerifyIncompleteIntermediate
1488 WRAPPED_INSTANTIATE_TEST_CASE_P(
1489 MAYBE_VerifyIncompleteIntermediate,
1490 CertVerifyProcWeakDigestTest,
1491 testing::ValuesIn(kVerifyIncompleteIntermediateTestData));
1493 // Incomplete chains should still report the status of the end-entity.
1494 const WeakDigestTestData kVerifyIncompleteEETestData[] = {
1495 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem",
1496 true, false, false },
1497 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1498 // MD4 is not supported by OS X / NSS
1499 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem",
1500 false, true, false },
1502 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem",
1503 false, false, true },
1505 // Disabled on NSS - libpkix does not return constructed chains on error,
1506 // preventing us from detecting/inspecting the verified chain.
1507 #if defined(USE_NSS) || defined(OS_IOS)
1508 #define MAYBE_VerifyIncompleteEndEntity DISABLED_VerifyIncompleteEndEntity
1510 #define MAYBE_VerifyIncompleteEndEntity VerifyIncompleteEndEntity
1512 WRAPPED_INSTANTIATE_TEST_CASE_P(
1513 MAYBE_VerifyIncompleteEndEntity,
1514 CertVerifyProcWeakDigestTest,
1515 testing::ValuesIn(kVerifyIncompleteEETestData));
1517 // Differing algorithms between the intermediate and the EE should still be
1519 const WeakDigestTestData kVerifyMixedTestData[] = {
1520 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
1521 "weak_digest_md2_ee.pem", true, false, true },
1522 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
1523 "weak_digest_md5_ee.pem", true, false, true },
1524 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1525 // MD4 is not supported by OS X / NSS
1526 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
1527 "weak_digest_md2_ee.pem", false, true, true },
1530 // NSS does not support MD4 and does not enable MD2 by default, making all
1531 // permutations invalid.
1532 #if defined(USE_NSS) || defined(OS_IOS)
1533 #define MAYBE_VerifyMixed DISABLED_VerifyMixed
1535 #define MAYBE_VerifyMixed VerifyMixed
1537 WRAPPED_INSTANTIATE_TEST_CASE_P(
1539 CertVerifyProcWeakDigestTest,
1540 testing::ValuesIn(kVerifyMixedTestData));
1542 // For the list of valid hostnames, see
1543 // net/cert/data/ssl/certificates/subjectAltName_sanity_check.pem
1544 static const struct CertVerifyProcNameData {
1545 const char* hostname;
1546 bool valid; // Whether or not |hostname| matches a subjectAltName.
1547 } kVerifyNameData[] = {
1548 { "127.0.0.1", false }, // Don't match the common name
1549 { "127.0.0.2", true }, // Matches the iPAddress SAN (IPv4)
1550 { "FE80:0:0:0:0:0:0:1", true }, // Matches the iPAddress SAN (IPv6)
1551 { "[FE80:0:0:0:0:0:0:1]", false }, // Should not match the iPAddress SAN
1552 { "FE80::1", true }, // Compressed form matches the iPAddress SAN (IPv6)
1553 { "::127.0.0.2", false }, // IPv6 mapped form should NOT match iPAddress SAN
1554 { "test.example", true }, // Matches the dNSName SAN
1555 { "test.example.", true }, // Matches the dNSName SAN (trailing . ignored)
1556 { "www.test.example", false }, // Should not match the dNSName SAN
1557 { "test..example", false }, // Should not match the dNSName SAN
1558 { "test.example..", false }, // Should not match the dNSName SAN
1559 { ".test.example.", false }, // Should not match the dNSName SAN
1560 { ".test.example", false }, // Should not match the dNSName SAN
1563 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
1564 // to output the parameter that was passed. Without this, it will simply
1565 // attempt to print out the first twenty bytes of the object, which depending
1566 // on platform and alignment, may result in an invalid read.
1567 void PrintTo(const CertVerifyProcNameData& data, std::ostream* os) {
1568 *os << "Hostname: " << data.hostname << "; valid=" << data.valid;
1571 class CertVerifyProcNameTest
1572 : public CertVerifyProcTest,
1573 public testing::WithParamInterface<CertVerifyProcNameData> {
1575 CertVerifyProcNameTest() {}
1576 virtual ~CertVerifyProcNameTest() {}
1579 TEST_P(CertVerifyProcNameTest, VerifyCertName) {
1580 CertVerifyProcNameData data = GetParam();
1582 CertificateList cert_list = CreateCertificateListFromFile(
1583 GetTestCertsDirectory(), "subjectAltName_sanity_check.pem",
1584 X509Certificate::FORMAT_AUTO);
1585 ASSERT_EQ(1U, cert_list.size());
1586 scoped_refptr<X509Certificate> cert(cert_list[0]);
1588 ScopedTestRoot scoped_root(cert.get());
1590 CertVerifyResult verify_result;
1591 int error = Verify(cert.get(), data.hostname, 0, NULL, empty_cert_list_,
1594 EXPECT_EQ(OK, error);
1595 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID);
1597 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
1598 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID);
1602 WRAPPED_INSTANTIATE_TEST_CASE_P(
1604 CertVerifyProcNameTest,
1605 testing::ValuesIn(kVerifyNameData));