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/files/file_util.h"
12 #include "base/logging.h"
13 #include "base/sha1.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "crypto/sha2.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/test_data_directory.h"
18 #include "net/cert/asn1_util.h"
19 #include "net/cert/cert_status_flags.h"
20 #include "net/cert/cert_verifier.h"
21 #include "net/cert/cert_verify_result.h"
22 #include "net/cert/crl_set.h"
23 #include "net/cert/crl_set_storage.h"
24 #include "net/cert/test_root_certs.h"
25 #include "net/cert/x509_certificate.h"
26 #include "net/test/cert_test_util.h"
27 #include "net/test/test_certificate_data.h"
28 #include "testing/gtest/include/gtest/gtest.h"
31 #include "base/win/windows_version.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 bool SupportsAdditionalTrustAnchors() const override
{ return false; }
60 bool SupportsOCSPStapling() const override
{ return false; }
63 ~WellKnownCaCertVerifyProc() override
{}
66 int VerifyInternal(X509Certificate
* cert
,
67 const std::string
& hostname
,
68 const std::string
& ocsp_response
,
71 const CertificateList
& additional_trust_anchors
,
72 CertVerifyResult
* verify_result
) override
;
74 const bool is_well_known_
;
76 DISALLOW_COPY_AND_ASSIGN(WellKnownCaCertVerifyProc
);
79 int WellKnownCaCertVerifyProc::VerifyInternal(
80 X509Certificate
* cert
,
81 const std::string
& hostname
,
82 const std::string
& ocsp_response
,
85 const CertificateList
& additional_trust_anchors
,
86 CertVerifyResult
* verify_result
) {
87 verify_result
->is_issued_by_known_root
= is_well_known_
;
91 bool SupportsReturningVerifiedChain() {
92 #if defined(OS_ANDROID)
93 // Before API level 17, Android does not expose the APIs necessary to get at
94 // the verified certificate chain.
95 if (base::android::BuildInfo::GetInstance()->sdk_int() < 17)
101 bool SupportsDetectingKnownRoots() {
102 #if defined(OS_ANDROID)
103 // Before API level 17, Android does not expose the APIs necessary to get at
104 // the verified certificate chain and detect known roots.
105 if (base::android::BuildInfo::GetInstance()->sdk_int() < 17)
113 class CertVerifyProcTest
: public testing::Test
{
116 : verify_proc_(CertVerifyProc::CreateDefault()) {
118 ~CertVerifyProcTest() override
{}
121 bool SupportsAdditionalTrustAnchors() {
122 return verify_proc_
->SupportsAdditionalTrustAnchors();
125 int Verify(X509Certificate
* cert
,
126 const std::string
& hostname
,
129 const CertificateList
& additional_trust_anchors
,
130 CertVerifyResult
* verify_result
) {
131 return verify_proc_
->Verify(cert
, hostname
, std::string(), flags
, crl_set
,
132 additional_trust_anchors
, verify_result
);
135 const CertificateList empty_cert_list_
;
136 scoped_refptr
<CertVerifyProc
> verify_proc_
;
139 TEST_F(CertVerifyProcTest
, DISABLED_WithoutRevocationChecking
) {
140 // Check that verification without revocation checking works.
141 CertificateList certs
= CreateCertificateListFromFile(
142 GetTestCertsDirectory(),
143 "googlenew.chain.pem",
144 X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
146 X509Certificate::OSCertHandles intermediates
;
147 intermediates
.push_back(certs
[1]->os_cert_handle());
149 scoped_refptr
<X509Certificate
> google_full_chain
=
150 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
153 CertVerifyResult verify_result
;
155 Verify(google_full_chain
.get(),
163 #if defined(OS_ANDROID) || defined(USE_OPENSSL_CERTS)
164 // TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported.
165 #define MAYBE_EVVerification DISABLED_EVVerification
167 #define MAYBE_EVVerification EVVerification
169 TEST_F(CertVerifyProcTest
, MAYBE_EVVerification
) {
170 CertificateList certs
= CreateCertificateListFromFile(
171 GetTestCertsDirectory(),
173 X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
174 ASSERT_EQ(3U, certs
.size());
176 X509Certificate::OSCertHandles intermediates
;
177 intermediates
.push_back(certs
[1]->os_cert_handle());
178 intermediates
.push_back(certs
[2]->os_cert_handle());
180 scoped_refptr
<X509Certificate
> comodo_chain
=
181 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
184 scoped_refptr
<CRLSet
> crl_set(CRLSet::ForTesting(false, NULL
, ""));
185 CertVerifyResult verify_result
;
186 int flags
= CertVerifier::VERIFY_EV_CERT
;
187 int error
= Verify(comodo_chain
.get(),
193 EXPECT_EQ(OK
, error
);
194 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_IS_EV
);
197 TEST_F(CertVerifyProcTest
, PaypalNullCertParsing
) {
198 scoped_refptr
<X509Certificate
> paypal_null_cert(
199 X509Certificate::CreateFromBytes(
200 reinterpret_cast<const char*>(paypal_null_der
),
201 sizeof(paypal_null_der
)));
203 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), paypal_null_cert
.get());
205 const SHA1HashValue
& fingerprint
=
206 paypal_null_cert
->fingerprint();
207 for (size_t i
= 0; i
< 20; ++i
)
208 EXPECT_EQ(paypal_null_fingerprint
[i
], fingerprint
.data
[i
]);
211 CertVerifyResult verify_result
;
212 int error
= Verify(paypal_null_cert
.get(),
218 #if defined(USE_NSS_CERTS) || defined(OS_IOS) || defined(OS_ANDROID)
219 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID
, error
);
221 // TOOD(bulach): investigate why macosx and win aren't returning
222 // ERR_CERT_INVALID or ERR_CERT_COMMON_NAME_INVALID.
223 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID
, error
);
225 // Either the system crypto library should correctly report a certificate
226 // name mismatch, or our certificate blacklist should cause us to report an
227 // invalid certificate.
228 #if defined(USE_NSS_CERTS) || defined(OS_WIN) || defined(OS_IOS)
229 EXPECT_TRUE(verify_result
.cert_status
&
230 (CERT_STATUS_COMMON_NAME_INVALID
| CERT_STATUS_INVALID
));
234 // A regression test for http://crbug.com/31497.
235 #if defined(OS_ANDROID)
236 // Disabled on Android, as the Android verification libraries require an
237 // explicit policy to be specified, even when anyPolicy is permitted.
238 #define MAYBE_IntermediateCARequireExplicitPolicy \
239 DISABLED_IntermediateCARequireExplicitPolicy
241 #define MAYBE_IntermediateCARequireExplicitPolicy \
242 IntermediateCARequireExplicitPolicy
244 TEST_F(CertVerifyProcTest
, MAYBE_IntermediateCARequireExplicitPolicy
) {
245 base::FilePath certs_dir
= GetTestCertsDirectory();
247 CertificateList certs
= CreateCertificateListFromFile(
248 certs_dir
, "explicit-policy-chain.pem",
249 X509Certificate::FORMAT_AUTO
);
250 ASSERT_EQ(3U, certs
.size());
252 X509Certificate::OSCertHandles intermediates
;
253 intermediates
.push_back(certs
[1]->os_cert_handle());
255 scoped_refptr
<X509Certificate
> cert
=
256 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
258 ASSERT_TRUE(cert
.get());
260 ScopedTestRoot
scoped_root(certs
[2].get());
263 CertVerifyResult verify_result
;
264 int error
= Verify(cert
.get(),
265 "policy_test.example",
270 EXPECT_EQ(OK
, error
);
271 EXPECT_EQ(0u, verify_result
.cert_status
);
274 // Test for bug 58437.
275 // This certificate will expire on 2011-12-21. The test will still
276 // pass if error == ERR_CERT_DATE_INVALID.
277 // This test is DISABLED because it appears that we cannot do
278 // certificate revocation checking when running all of the net unit tests.
279 // This test passes when run individually, but when run with all of the net
280 // unit tests, the call to PKIXVerifyCert returns the NSS error -8180, which is
281 // SEC_ERROR_REVOKED_CERTIFICATE. This indicates a lack of revocation
282 // status, i.e. that the revocation check is failing for some reason.
283 TEST_F(CertVerifyProcTest
, DISABLED_GlobalSignR3EVTest
) {
284 base::FilePath certs_dir
= GetTestCertsDirectory();
286 scoped_refptr
<X509Certificate
> server_cert
=
287 ImportCertFromFile(certs_dir
, "2029_globalsign_com_cert.pem");
288 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
.get());
290 scoped_refptr
<X509Certificate
> intermediate_cert
=
291 ImportCertFromFile(certs_dir
, "globalsign_ev_sha256_ca_cert.pem");
292 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert
.get());
294 X509Certificate::OSCertHandles intermediates
;
295 intermediates
.push_back(intermediate_cert
->os_cert_handle());
296 scoped_refptr
<X509Certificate
> cert_chain
=
297 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
300 CertVerifyResult verify_result
;
301 int flags
= CertVerifier::VERIFY_REV_CHECKING_ENABLED
|
302 CertVerifier::VERIFY_EV_CERT
;
303 int error
= Verify(cert_chain
.get(),
304 "2029.globalsign.com",
310 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_IS_EV
);
312 EXPECT_EQ(ERR_CERT_DATE_INVALID
, error
);
315 // Test that verifying an ECDSA certificate doesn't crash on XP. (See
316 // crbug.com/144466).
317 TEST_F(CertVerifyProcTest
, ECDSA_RSA
) {
318 base::FilePath certs_dir
= GetTestCertsDirectory();
320 scoped_refptr
<X509Certificate
> cert
=
321 ImportCertFromFile(certs_dir
,
322 "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem");
324 CertVerifyResult verify_result
;
325 Verify(cert
.get(), "127.0.0.1", 0, NULL
, empty_cert_list_
, &verify_result
);
327 // We don't check verify_result because the certificate is signed by an
328 // unknown CA and will be considered invalid on XP because of the ECDSA
332 // Currently, only RSA and DSA keys are checked for weakness, and our example
333 // weak size is 768. These could change in the future.
335 // Note that this means there may be false negatives: keys for other
336 // algorithms and which are weak will pass this test.
337 static bool IsWeakKeyType(const std::string
& key_type
) {
338 size_t pos
= key_type
.find("-");
339 std::string size
= key_type
.substr(0, pos
);
340 std::string type
= key_type
.substr(pos
+ 1);
342 if (type
== "rsa" || type
== "dsa")
343 return size
== "768";
348 TEST_F(CertVerifyProcTest
, RejectWeakKeys
) {
349 base::FilePath certs_dir
= GetTestCertsDirectory();
350 typedef std::vector
<std::string
> Strings
;
353 // generate-weak-test-chains.sh currently has:
354 // key_types="768-rsa 1024-rsa 2048-rsa prime256v1-ecdsa"
355 // We must use the same key types here. The filenames generated look like:
356 // 2048-rsa-ee-by-768-rsa-intermediate.pem
357 key_types
.push_back("768-rsa");
358 key_types
.push_back("1024-rsa");
359 key_types
.push_back("2048-rsa");
361 bool use_ecdsa
= true;
363 use_ecdsa
= base::win::GetVersion() > base::win::VERSION_XP
;
367 key_types
.push_back("prime256v1-ecdsa");
369 // Add the root that signed the intermediates for this test.
370 scoped_refptr
<X509Certificate
> root_cert
=
371 ImportCertFromFile(certs_dir
, "2048-rsa-root.pem");
372 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), root_cert
.get());
373 ScopedTestRoot
scoped_root(root_cert
.get());
375 // Now test each chain.
376 for (Strings::const_iterator ee_type
= key_types
.begin();
377 ee_type
!= key_types
.end(); ++ee_type
) {
378 for (Strings::const_iterator signer_type
= key_types
.begin();
379 signer_type
!= key_types
.end(); ++signer_type
) {
380 std::string basename
= *ee_type
+ "-ee-by-" + *signer_type
+
382 SCOPED_TRACE(basename
);
383 scoped_refptr
<X509Certificate
> ee_cert
=
384 ImportCertFromFile(certs_dir
, basename
);
385 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), ee_cert
.get());
387 basename
= *signer_type
+ "-intermediate.pem";
388 scoped_refptr
<X509Certificate
> intermediate
=
389 ImportCertFromFile(certs_dir
, basename
);
390 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate
.get());
392 X509Certificate::OSCertHandles intermediates
;
393 intermediates
.push_back(intermediate
->os_cert_handle());
394 scoped_refptr
<X509Certificate
> cert_chain
=
395 X509Certificate::CreateFromHandle(ee_cert
->os_cert_handle(),
398 CertVerifyResult verify_result
;
399 int error
= Verify(cert_chain
.get(),
406 if (IsWeakKeyType(*ee_type
) || IsWeakKeyType(*signer_type
)) {
407 EXPECT_NE(OK
, error
);
408 EXPECT_EQ(CERT_STATUS_WEAK_KEY
,
409 verify_result
.cert_status
& CERT_STATUS_WEAK_KEY
);
410 EXPECT_NE(CERT_STATUS_INVALID
,
411 verify_result
.cert_status
& CERT_STATUS_INVALID
);
413 EXPECT_EQ(OK
, error
);
414 EXPECT_EQ(0U, verify_result
.cert_status
& CERT_STATUS_WEAK_KEY
);
420 // Regression test for http://crbug.com/108514.
421 #if defined(OS_MACOSX) && !defined(OS_IOS)
422 // Disabled on OS X - Security.framework doesn't ignore superflous certificates
423 // provided by servers. See CertVerifyProcTest.CybertrustGTERoot for further
425 #define MAYBE_ExtraneousMD5RootCert DISABLED_ExtraneousMD5RootCert
427 #define MAYBE_ExtraneousMD5RootCert ExtraneousMD5RootCert
429 TEST_F(CertVerifyProcTest
, MAYBE_ExtraneousMD5RootCert
) {
430 if (!SupportsReturningVerifiedChain()) {
431 LOG(INFO
) << "Skipping this test in this platform.";
435 base::FilePath certs_dir
= GetTestCertsDirectory();
437 scoped_refptr
<X509Certificate
> server_cert
=
438 ImportCertFromFile(certs_dir
, "cross-signed-leaf.pem");
439 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
.get());
441 scoped_refptr
<X509Certificate
> extra_cert
=
442 ImportCertFromFile(certs_dir
, "cross-signed-root-md5.pem");
443 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), extra_cert
.get());
445 scoped_refptr
<X509Certificate
> root_cert
=
446 ImportCertFromFile(certs_dir
, "cross-signed-root-sha256.pem");
447 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), root_cert
.get());
449 ScopedTestRoot
scoped_root(root_cert
.get());
451 X509Certificate::OSCertHandles intermediates
;
452 intermediates
.push_back(extra_cert
->os_cert_handle());
453 scoped_refptr
<X509Certificate
> cert_chain
=
454 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
457 CertVerifyResult verify_result
;
459 int error
= Verify(cert_chain
.get(),
465 EXPECT_EQ(OK
, error
);
467 // The extra MD5 root should be discarded
468 ASSERT_TRUE(verify_result
.verified_cert
.get());
470 verify_result
.verified_cert
->GetIntermediateCertificates().size());
471 EXPECT_TRUE(X509Certificate::IsSameOSCert(
472 verify_result
.verified_cert
->GetIntermediateCertificates().front(),
473 root_cert
->os_cert_handle()));
475 EXPECT_FALSE(verify_result
.has_md5
);
478 // Test for bug 94673.
479 TEST_F(CertVerifyProcTest
, GoogleDigiNotarTest
) {
480 base::FilePath certs_dir
= GetTestCertsDirectory();
482 scoped_refptr
<X509Certificate
> server_cert
=
483 ImportCertFromFile(certs_dir
, "google_diginotar.pem");
484 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
.get());
486 scoped_refptr
<X509Certificate
> intermediate_cert
=
487 ImportCertFromFile(certs_dir
, "diginotar_public_ca_2025.pem");
488 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert
.get());
490 X509Certificate::OSCertHandles intermediates
;
491 intermediates
.push_back(intermediate_cert
->os_cert_handle());
492 scoped_refptr
<X509Certificate
> cert_chain
=
493 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
496 CertVerifyResult verify_result
;
497 int flags
= CertVerifier::VERIFY_REV_CHECKING_ENABLED
;
498 int error
= Verify(cert_chain
.get(),
504 EXPECT_NE(OK
, error
);
506 // Now turn off revocation checking. Certificate verification should still
509 error
= Verify(cert_chain
.get(),
515 EXPECT_NE(OK
, error
);
518 TEST_F(CertVerifyProcTest
, DigiNotarCerts
) {
519 static const char* const kDigiNotarFilenames
[] = {
520 "diginotar_root_ca.pem",
521 "diginotar_cyber_ca.pem",
522 "diginotar_services_1024_ca.pem",
523 "diginotar_pkioverheid.pem",
524 "diginotar_pkioverheid_g2.pem",
528 base::FilePath certs_dir
= GetTestCertsDirectory();
530 for (size_t i
= 0; kDigiNotarFilenames
[i
]; i
++) {
531 scoped_refptr
<X509Certificate
> diginotar_cert
=
532 ImportCertFromFile(certs_dir
, kDigiNotarFilenames
[i
]);
533 std::string der_bytes
;
534 ASSERT_TRUE(X509Certificate::GetDEREncoded(
535 diginotar_cert
->os_cert_handle(), &der_bytes
));
537 base::StringPiece spki
;
538 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_bytes
, &spki
));
540 std::string spki_sha1
= base::SHA1HashString(spki
.as_string());
542 HashValueVector public_keys
;
543 HashValue
hash(HASH_VALUE_SHA1
);
544 ASSERT_EQ(hash
.size(), spki_sha1
.size());
545 memcpy(hash
.data(), spki_sha1
.data(), spki_sha1
.size());
546 public_keys
.push_back(hash
);
548 EXPECT_TRUE(CertVerifyProc::IsPublicKeyBlacklisted(public_keys
)) <<
549 "Public key not blocked for " << kDigiNotarFilenames
[i
];
553 TEST_F(CertVerifyProcTest
, NameConstraintsOk
) {
554 CertificateList ca_cert_list
=
555 CreateCertificateListFromFile(GetTestCertsDirectory(),
557 X509Certificate::FORMAT_AUTO
);
558 ASSERT_EQ(1U, ca_cert_list
.size());
559 ScopedTestRoot
test_root(ca_cert_list
[0].get());
561 CertificateList cert_list
= CreateCertificateListFromFile(
562 GetTestCertsDirectory(), "name_constraint_good.pem",
563 X509Certificate::FORMAT_AUTO
);
564 ASSERT_EQ(1U, cert_list
.size());
566 X509Certificate::OSCertHandles intermediates
;
567 scoped_refptr
<X509Certificate
> leaf
=
568 X509Certificate::CreateFromHandle(cert_list
[0]->os_cert_handle(),
572 CertVerifyResult verify_result
;
573 int error
= Verify(leaf
.get(),
579 EXPECT_EQ(OK
, error
);
580 EXPECT_EQ(0U, verify_result
.cert_status
);
583 TEST_F(CertVerifyProcTest
, NameConstraintsFailure
) {
584 if (!SupportsReturningVerifiedChain()) {
585 LOG(INFO
) << "Skipping this test in this platform.";
589 CertificateList ca_cert_list
=
590 CreateCertificateListFromFile(GetTestCertsDirectory(),
592 X509Certificate::FORMAT_AUTO
);
593 ASSERT_EQ(1U, ca_cert_list
.size());
594 ScopedTestRoot
test_root(ca_cert_list
[0].get());
596 CertificateList cert_list
= CreateCertificateListFromFile(
597 GetTestCertsDirectory(), "name_constraint_bad.pem",
598 X509Certificate::FORMAT_AUTO
);
599 ASSERT_EQ(1U, cert_list
.size());
601 X509Certificate::OSCertHandles intermediates
;
602 scoped_refptr
<X509Certificate
> leaf
=
603 X509Certificate::CreateFromHandle(cert_list
[0]->os_cert_handle(),
607 CertVerifyResult verify_result
;
608 int error
= Verify(leaf
.get(),
614 EXPECT_EQ(ERR_CERT_NAME_CONSTRAINT_VIOLATION
, error
);
615 EXPECT_EQ(CERT_STATUS_NAME_CONSTRAINT_VIOLATION
,
616 verify_result
.cert_status
& CERT_STATUS_NAME_CONSTRAINT_VIOLATION
);
619 TEST_F(CertVerifyProcTest
, TestHasTooLongValidity
) {
621 const char* const file
;
622 bool is_valid_too_long
;
624 {"twitter-chain.pem", false},
625 {"start_after_expiry.pem", true},
626 {"pre_br_validity_ok.pem", false},
627 {"pre_br_validity_bad_121.pem", true},
628 {"pre_br_validity_bad_2020.pem", true},
629 {"10_year_validity.pem", false},
630 {"11_year_validity.pem", true},
631 {"39_months_after_2015_04.pem", false},
632 {"40_months_after_2015_04.pem", true},
633 {"60_months_after_2012_07.pem", false},
634 {"61_months_after_2012_07.pem", true},
637 base::FilePath certs_dir
= GetTestCertsDirectory();
639 for (size_t i
= 0; i
< arraysize(tests
); ++i
) {
640 scoped_refptr
<X509Certificate
> certificate
=
641 ImportCertFromFile(certs_dir
, tests
[i
].file
);
642 SCOPED_TRACE(tests
[i
].file
);
643 ASSERT_TRUE(certificate
);
644 EXPECT_EQ(tests
[i
].is_valid_too_long
,
645 CertVerifyProc::HasTooLongValidity(*certificate
));
649 TEST_F(CertVerifyProcTest
, TestKnownRoot
) {
650 if (!SupportsDetectingKnownRoots()) {
651 LOG(INFO
) << "Skipping this test on this platform.";
655 base::FilePath certs_dir
= GetTestCertsDirectory();
656 CertificateList certs
= CreateCertificateListFromFile(
657 certs_dir
, "twitter-chain.pem", X509Certificate::FORMAT_AUTO
);
658 ASSERT_EQ(3U, certs
.size());
660 X509Certificate::OSCertHandles intermediates
;
661 intermediates
.push_back(certs
[1]->os_cert_handle());
663 scoped_refptr
<X509Certificate
> cert_chain
=
664 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
668 CertVerifyResult verify_result
;
669 // This will blow up, May 9th, 2016. Sorry! Please disable and file a bug
670 // against agl. See also PublicKeyHashes.
671 int error
= Verify(cert_chain
.get(), "twitter.com", flags
, NULL
,
672 empty_cert_list_
, &verify_result
);
673 EXPECT_EQ(OK
, error
);
674 EXPECT_TRUE(verify_result
.is_issued_by_known_root
);
677 TEST_F(CertVerifyProcTest
, PublicKeyHashes
) {
678 if (!SupportsReturningVerifiedChain()) {
679 LOG(INFO
) << "Skipping this test in this platform.";
683 base::FilePath certs_dir
= GetTestCertsDirectory();
684 CertificateList certs
= CreateCertificateListFromFile(
685 certs_dir
, "twitter-chain.pem", X509Certificate::FORMAT_AUTO
);
686 ASSERT_EQ(3U, certs
.size());
688 X509Certificate::OSCertHandles intermediates
;
689 intermediates
.push_back(certs
[1]->os_cert_handle());
691 scoped_refptr
<X509Certificate
> cert_chain
=
692 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
695 CertVerifyResult verify_result
;
697 // This will blow up, May 9th, 2016. Sorry! Please disable and file a bug
698 // against agl. See also TestKnownRoot.
699 int error
= Verify(cert_chain
.get(), "twitter.com", flags
, NULL
,
700 empty_cert_list_
, &verify_result
);
701 EXPECT_EQ(OK
, error
);
702 ASSERT_LE(3U, verify_result
.public_key_hashes
.size());
704 HashValueVector sha1_hashes
;
705 for (size_t i
= 0; i
< verify_result
.public_key_hashes
.size(); ++i
) {
706 if (verify_result
.public_key_hashes
[i
].tag
!= HASH_VALUE_SHA1
)
708 sha1_hashes
.push_back(verify_result
.public_key_hashes
[i
]);
710 ASSERT_LE(3u, sha1_hashes
.size());
712 for (size_t i
= 0; i
< 3; ++i
) {
713 EXPECT_EQ(HexEncode(kTwitterSPKIs
[i
], base::kSHA1Length
),
714 HexEncode(sha1_hashes
[i
].data(), base::kSHA1Length
));
717 HashValueVector sha256_hashes
;
718 for (size_t i
= 0; i
< verify_result
.public_key_hashes
.size(); ++i
) {
719 if (verify_result
.public_key_hashes
[i
].tag
!= HASH_VALUE_SHA256
)
721 sha256_hashes
.push_back(verify_result
.public_key_hashes
[i
]);
723 ASSERT_LE(3u, sha256_hashes
.size());
725 for (size_t i
= 0; i
< 3; ++i
) {
726 EXPECT_EQ(HexEncode(kTwitterSPKIsSHA256
[i
], crypto::kSHA256Length
),
727 HexEncode(sha256_hashes
[i
].data(), crypto::kSHA256Length
));
731 // A regression test for http://crbug.com/70293.
732 // The Key Usage extension in this RSA SSL server certificate does not have
733 // the keyEncipherment bit.
734 TEST_F(CertVerifyProcTest
, InvalidKeyUsage
) {
735 base::FilePath certs_dir
= GetTestCertsDirectory();
737 scoped_refptr
<X509Certificate
> server_cert
=
738 ImportCertFromFile(certs_dir
, "invalid_key_usage_cert.der");
739 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
.get());
742 CertVerifyResult verify_result
;
743 int error
= Verify(server_cert
.get(),
749 #if defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
750 // This certificate has two errors: "invalid key usage" and "untrusted CA".
751 // However, OpenSSL returns only one (the latter), and we can't detect
753 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID
, error
);
755 EXPECT_EQ(ERR_CERT_INVALID
, error
);
756 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_INVALID
);
758 // TODO(wtc): fix http://crbug.com/75520 to get all the certificate errors
760 #if !defined(USE_NSS_CERTS) && !defined(OS_IOS) && !defined(OS_ANDROID)
761 // The certificate is issued by an unknown CA.
762 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_AUTHORITY_INVALID
);
766 // Basic test for returning the chain in CertVerifyResult. Note that the
767 // returned chain may just be a reflection of the originally supplied chain;
768 // that is, if any errors occur, the default chain returned is an exact copy
769 // of the certificate to be verified. The remaining VerifyReturn* tests are
770 // used to ensure that the actual, verified chain is being returned by
772 TEST_F(CertVerifyProcTest
, VerifyReturnChainBasic
) {
773 if (!SupportsReturningVerifiedChain()) {
774 LOG(INFO
) << "Skipping this test in this platform.";
778 base::FilePath certs_dir
= GetTestCertsDirectory();
779 CertificateList certs
= CreateCertificateListFromFile(
780 certs_dir
, "x509_verify_results.chain.pem",
781 X509Certificate::FORMAT_AUTO
);
782 ASSERT_EQ(3U, certs
.size());
784 X509Certificate::OSCertHandles intermediates
;
785 intermediates
.push_back(certs
[1]->os_cert_handle());
786 intermediates
.push_back(certs
[2]->os_cert_handle());
788 ScopedTestRoot
scoped_root(certs
[2].get());
790 scoped_refptr
<X509Certificate
> google_full_chain
=
791 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
793 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), google_full_chain
.get());
794 ASSERT_EQ(2U, google_full_chain
->GetIntermediateCertificates().size());
796 CertVerifyResult verify_result
;
797 EXPECT_EQ(static_cast<X509Certificate
*>(NULL
),
798 verify_result
.verified_cert
.get());
799 int error
= Verify(google_full_chain
.get(),
805 EXPECT_EQ(OK
, error
);
806 ASSERT_NE(static_cast<X509Certificate
*>(NULL
),
807 verify_result
.verified_cert
.get());
809 EXPECT_NE(google_full_chain
, verify_result
.verified_cert
);
810 EXPECT_TRUE(X509Certificate::IsSameOSCert(
811 google_full_chain
->os_cert_handle(),
812 verify_result
.verified_cert
->os_cert_handle()));
813 const X509Certificate::OSCertHandles
& return_intermediates
=
814 verify_result
.verified_cert
->GetIntermediateCertificates();
815 ASSERT_EQ(2U, return_intermediates
.size());
816 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[0],
817 certs
[1]->os_cert_handle()));
818 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[1],
819 certs
[2]->os_cert_handle()));
822 // Test that certificates issued for 'intranet' names (that is, containing no
823 // known public registry controlled domain information) issued by well-known
824 // CAs are flagged appropriately, while certificates that are issued by
825 // internal CAs are not flagged.
826 TEST_F(CertVerifyProcTest
, IntranetHostsRejected
) {
827 if (!SupportsDetectingKnownRoots()) {
828 LOG(INFO
) << "Skipping this test in this platform.";
832 CertificateList cert_list
= CreateCertificateListFromFile(
833 GetTestCertsDirectory(), "reject_intranet_hosts.pem",
834 X509Certificate::FORMAT_AUTO
);
835 ASSERT_EQ(1U, cert_list
.size());
836 scoped_refptr
<X509Certificate
> cert(cert_list
[0]);
838 CertVerifyResult verify_result
;
841 // Intranet names for public CAs should be flagged:
842 verify_proc_
= new WellKnownCaCertVerifyProc(true);
844 Verify(cert
.get(), "intranet", 0, NULL
, empty_cert_list_
, &verify_result
);
845 EXPECT_EQ(OK
, error
);
846 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_NON_UNIQUE_NAME
);
848 // However, if the CA is not well known, these should not be flagged:
849 verify_proc_
= new WellKnownCaCertVerifyProc(false);
851 Verify(cert
.get(), "intranet", 0, NULL
, empty_cert_list_
, &verify_result
);
852 EXPECT_EQ(OK
, error
);
853 EXPECT_FALSE(verify_result
.cert_status
& CERT_STATUS_NON_UNIQUE_NAME
);
856 // Test that the certificate returned in CertVerifyResult is able to reorder
857 // certificates that are not ordered from end-entity to root. While this is
858 // a protocol violation if sent during a TLS handshake, if multiple sources
859 // of intermediate certificates are combined, it's possible that order may
860 // not be maintained.
861 TEST_F(CertVerifyProcTest
, VerifyReturnChainProperlyOrdered
) {
862 if (!SupportsReturningVerifiedChain()) {
863 LOG(INFO
) << "Skipping this test in this platform.";
867 base::FilePath certs_dir
= GetTestCertsDirectory();
868 CertificateList certs
= CreateCertificateListFromFile(
869 certs_dir
, "x509_verify_results.chain.pem",
870 X509Certificate::FORMAT_AUTO
);
871 ASSERT_EQ(3U, certs
.size());
873 // Construct the chain out of order.
874 X509Certificate::OSCertHandles intermediates
;
875 intermediates
.push_back(certs
[2]->os_cert_handle());
876 intermediates
.push_back(certs
[1]->os_cert_handle());
878 ScopedTestRoot
scoped_root(certs
[2].get());
880 scoped_refptr
<X509Certificate
> google_full_chain
=
881 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
883 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), google_full_chain
.get());
884 ASSERT_EQ(2U, google_full_chain
->GetIntermediateCertificates().size());
886 CertVerifyResult verify_result
;
887 EXPECT_EQ(static_cast<X509Certificate
*>(NULL
),
888 verify_result
.verified_cert
.get());
889 int error
= Verify(google_full_chain
.get(),
895 EXPECT_EQ(OK
, error
);
896 ASSERT_NE(static_cast<X509Certificate
*>(NULL
),
897 verify_result
.verified_cert
.get());
899 EXPECT_NE(google_full_chain
, verify_result
.verified_cert
);
900 EXPECT_TRUE(X509Certificate::IsSameOSCert(
901 google_full_chain
->os_cert_handle(),
902 verify_result
.verified_cert
->os_cert_handle()));
903 const X509Certificate::OSCertHandles
& return_intermediates
=
904 verify_result
.verified_cert
->GetIntermediateCertificates();
905 ASSERT_EQ(2U, return_intermediates
.size());
906 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[0],
907 certs
[1]->os_cert_handle()));
908 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[1],
909 certs
[2]->os_cert_handle()));
912 // Test that Verify() filters out certificates which are not related to
913 // or part of the certificate chain being verified.
914 TEST_F(CertVerifyProcTest
, VerifyReturnChainFiltersUnrelatedCerts
) {
915 if (!SupportsReturningVerifiedChain()) {
916 LOG(INFO
) << "Skipping this test in this platform.";
920 base::FilePath certs_dir
= GetTestCertsDirectory();
921 CertificateList certs
= CreateCertificateListFromFile(
922 certs_dir
, "x509_verify_results.chain.pem",
923 X509Certificate::FORMAT_AUTO
);
924 ASSERT_EQ(3U, certs
.size());
925 ScopedTestRoot
scoped_root(certs
[2].get());
927 scoped_refptr
<X509Certificate
> unrelated_certificate
=
928 ImportCertFromFile(certs_dir
, "duplicate_cn_1.pem");
929 scoped_refptr
<X509Certificate
> unrelated_certificate2
=
930 ImportCertFromFile(certs_dir
, "aia-cert.pem");
931 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), unrelated_certificate
.get());
932 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), unrelated_certificate2
.get());
934 // Interject unrelated certificates into the list of intermediates.
935 X509Certificate::OSCertHandles intermediates
;
936 intermediates
.push_back(unrelated_certificate
->os_cert_handle());
937 intermediates
.push_back(certs
[1]->os_cert_handle());
938 intermediates
.push_back(unrelated_certificate2
->os_cert_handle());
939 intermediates
.push_back(certs
[2]->os_cert_handle());
941 scoped_refptr
<X509Certificate
> google_full_chain
=
942 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
944 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), google_full_chain
.get());
945 ASSERT_EQ(4U, google_full_chain
->GetIntermediateCertificates().size());
947 CertVerifyResult verify_result
;
948 EXPECT_EQ(static_cast<X509Certificate
*>(NULL
),
949 verify_result
.verified_cert
.get());
950 int error
= Verify(google_full_chain
.get(),
956 EXPECT_EQ(OK
, error
);
957 ASSERT_NE(static_cast<X509Certificate
*>(NULL
),
958 verify_result
.verified_cert
.get());
960 EXPECT_NE(google_full_chain
, verify_result
.verified_cert
);
961 EXPECT_TRUE(X509Certificate::IsSameOSCert(
962 google_full_chain
->os_cert_handle(),
963 verify_result
.verified_cert
->os_cert_handle()));
964 const X509Certificate::OSCertHandles
& return_intermediates
=
965 verify_result
.verified_cert
->GetIntermediateCertificates();
966 ASSERT_EQ(2U, return_intermediates
.size());
967 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[0],
968 certs
[1]->os_cert_handle()));
969 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[1],
970 certs
[2]->os_cert_handle()));
973 TEST_F(CertVerifyProcTest
, AdditionalTrustAnchors
) {
974 if (!SupportsAdditionalTrustAnchors()) {
975 LOG(INFO
) << "Skipping this test in this platform.";
979 // |ca_cert| is the issuer of |cert|.
980 CertificateList ca_cert_list
= CreateCertificateListFromFile(
981 GetTestCertsDirectory(), "root_ca_cert.pem",
982 X509Certificate::FORMAT_AUTO
);
983 ASSERT_EQ(1U, ca_cert_list
.size());
984 scoped_refptr
<X509Certificate
> ca_cert(ca_cert_list
[0]);
986 CertificateList cert_list
= CreateCertificateListFromFile(
987 GetTestCertsDirectory(), "ok_cert.pem",
988 X509Certificate::FORMAT_AUTO
);
989 ASSERT_EQ(1U, cert_list
.size());
990 scoped_refptr
<X509Certificate
> cert(cert_list
[0]);
992 // Verification of |cert| fails when |ca_cert| is not in the trust anchors
995 CertVerifyResult verify_result
;
997 cert
.get(), "127.0.0.1", flags
, NULL
, empty_cert_list_
, &verify_result
);
998 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID
, error
);
999 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID
, verify_result
.cert_status
);
1000 EXPECT_FALSE(verify_result
.is_issued_by_additional_trust_anchor
);
1002 // Now add the |ca_cert| to the |trust_anchors|, and verification should pass.
1003 CertificateList trust_anchors
;
1004 trust_anchors
.push_back(ca_cert
);
1006 cert
.get(), "127.0.0.1", flags
, NULL
, trust_anchors
, &verify_result
);
1007 EXPECT_EQ(OK
, error
);
1008 EXPECT_EQ(0U, verify_result
.cert_status
);
1009 EXPECT_TRUE(verify_result
.is_issued_by_additional_trust_anchor
);
1011 // Clearing the |trust_anchors| makes verification fail again (the cache
1012 // should be skipped).
1014 cert
.get(), "127.0.0.1", flags
, NULL
, empty_cert_list_
, &verify_result
);
1015 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID
, error
);
1016 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID
, verify_result
.cert_status
);
1017 EXPECT_FALSE(verify_result
.is_issued_by_additional_trust_anchor
);
1020 // Tests that certificates issued by user-supplied roots are not flagged as
1021 // issued by a known root. This should pass whether or not the platform supports
1022 // detecting known roots.
1023 TEST_F(CertVerifyProcTest
, IsIssuedByKnownRootIgnoresTestRoots
) {
1024 // Load root_ca_cert.pem into the test root store.
1025 ScopedTestRoot
test_root(
1026 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem").get());
1028 scoped_refptr
<X509Certificate
> cert(
1029 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
1031 // Verification should pass.
1033 CertVerifyResult verify_result
;
1035 cert
.get(), "127.0.0.1", flags
, NULL
, empty_cert_list_
, &verify_result
);
1036 EXPECT_EQ(OK
, error
);
1037 EXPECT_EQ(0U, verify_result
.cert_status
);
1038 // But should not be marked as a known root.
1039 EXPECT_FALSE(verify_result
.is_issued_by_known_root
);
1042 #if defined(OS_MACOSX) && !defined(OS_IOS)
1043 // Tests that, on OS X, issues with a cross-certified Baltimore CyberTrust
1044 // Root can be successfully worked around once Apple completes removing the
1045 // older GTE CyberTrust Root from its trusted root store.
1047 // The issue is caused by servers supplying the cross-certified intermediate
1048 // (necessary for certain mobile platforms), which OS X does not recognize
1049 // as already existing within its trust store.
1050 TEST_F(CertVerifyProcTest
, CybertrustGTERoot
) {
1051 CertificateList certs
= CreateCertificateListFromFile(
1052 GetTestCertsDirectory(),
1053 "cybertrust_omniroot_chain.pem",
1054 X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
1055 ASSERT_EQ(2U, certs
.size());
1057 X509Certificate::OSCertHandles intermediates
;
1058 intermediates
.push_back(certs
[1]->os_cert_handle());
1060 scoped_refptr
<X509Certificate
> cybertrust_basic
=
1061 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
1063 ASSERT_TRUE(cybertrust_basic
.get());
1065 scoped_refptr
<X509Certificate
> baltimore_root
=
1066 ImportCertFromFile(GetTestCertsDirectory(),
1067 "cybertrust_baltimore_root.pem");
1068 ASSERT_TRUE(baltimore_root
.get());
1070 ScopedTestRoot
scoped_root(baltimore_root
.get());
1072 // Ensure that ONLY the Baltimore CyberTrust Root is trusted. This
1073 // simulates Keychain removing support for the GTE CyberTrust Root.
1074 TestRootCerts::GetInstance()->SetAllowSystemTrust(false);
1075 base::ScopedClosureRunner
reset_system_trust(
1076 base::Bind(&TestRootCerts::SetAllowSystemTrust
,
1077 base::Unretained(TestRootCerts::GetInstance()),
1080 // First, make sure a simple certificate chain from
1081 // EE -> Public SureServer SV -> Baltimore CyberTrust
1082 // works. Only the first two certificates are included in the chain.
1084 CertVerifyResult verify_result
;
1085 int error
= Verify(cybertrust_basic
.get(),
1086 "cacert.omniroot.com",
1091 EXPECT_EQ(OK
, error
);
1092 EXPECT_EQ(CERT_STATUS_SHA1_SIGNATURE_PRESENT
, verify_result
.cert_status
);
1094 // Attempt to verify with the first known cross-certified intermediate
1096 scoped_refptr
<X509Certificate
> baltimore_intermediate_1
=
1097 ImportCertFromFile(GetTestCertsDirectory(),
1098 "cybertrust_baltimore_cross_certified_1.pem");
1099 ASSERT_TRUE(baltimore_intermediate_1
.get());
1101 X509Certificate::OSCertHandles intermediate_chain_1
=
1102 cybertrust_basic
->GetIntermediateCertificates();
1103 intermediate_chain_1
.push_back(baltimore_intermediate_1
->os_cert_handle());
1105 scoped_refptr
<X509Certificate
> baltimore_chain_1
=
1106 X509Certificate::CreateFromHandle(cybertrust_basic
->os_cert_handle(),
1107 intermediate_chain_1
);
1108 error
= Verify(baltimore_chain_1
.get(),
1109 "cacert.omniroot.com",
1114 EXPECT_EQ(OK
, error
);
1115 EXPECT_EQ(CERT_STATUS_SHA1_SIGNATURE_PRESENT
, verify_result
.cert_status
);
1117 // Attempt to verify with the second known cross-certified intermediate
1119 scoped_refptr
<X509Certificate
> baltimore_intermediate_2
=
1120 ImportCertFromFile(GetTestCertsDirectory(),
1121 "cybertrust_baltimore_cross_certified_2.pem");
1122 ASSERT_TRUE(baltimore_intermediate_2
.get());
1124 X509Certificate::OSCertHandles intermediate_chain_2
=
1125 cybertrust_basic
->GetIntermediateCertificates();
1126 intermediate_chain_2
.push_back(baltimore_intermediate_2
->os_cert_handle());
1128 scoped_refptr
<X509Certificate
> baltimore_chain_2
=
1129 X509Certificate::CreateFromHandle(cybertrust_basic
->os_cert_handle(),
1130 intermediate_chain_2
);
1131 error
= Verify(baltimore_chain_2
.get(),
1132 "cacert.omniroot.com",
1137 EXPECT_EQ(OK
, error
);
1138 EXPECT_EQ(CERT_STATUS_SHA1_SIGNATURE_PRESENT
, verify_result
.cert_status
);
1140 // Attempt to verify when both a cross-certified intermediate AND
1141 // the legacy GTE root are provided.
1142 scoped_refptr
<X509Certificate
> cybertrust_root
=
1143 ImportCertFromFile(GetTestCertsDirectory(),
1144 "cybertrust_gte_root.pem");
1145 ASSERT_TRUE(cybertrust_root
.get());
1147 intermediate_chain_2
.push_back(cybertrust_root
->os_cert_handle());
1148 scoped_refptr
<X509Certificate
> baltimore_chain_with_root
=
1149 X509Certificate::CreateFromHandle(cybertrust_basic
->os_cert_handle(),
1150 intermediate_chain_2
);
1151 error
= Verify(baltimore_chain_with_root
.get(),
1152 "cacert.omniroot.com",
1157 EXPECT_EQ(OK
, error
);
1158 EXPECT_EQ(CERT_STATUS_SHA1_SIGNATURE_PRESENT
, verify_result
.cert_status
);
1160 TestRootCerts::GetInstance()->Clear();
1161 EXPECT_TRUE(TestRootCerts::GetInstance()->IsEmpty());
1165 #if defined(USE_NSS_CERTS) || defined(OS_IOS) || defined(OS_WIN) || \
1167 // Test that CRLSets are effective in making a certificate appear to be
1169 TEST_F(CertVerifyProcTest
, CRLSet
) {
1170 CertificateList ca_cert_list
=
1171 CreateCertificateListFromFile(GetTestCertsDirectory(),
1173 X509Certificate::FORMAT_AUTO
);
1174 ASSERT_EQ(1U, ca_cert_list
.size());
1175 ScopedTestRoot
test_root(ca_cert_list
[0].get());
1177 CertificateList cert_list
= CreateCertificateListFromFile(
1178 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO
);
1179 ASSERT_EQ(1U, cert_list
.size());
1180 scoped_refptr
<X509Certificate
> cert(cert_list
[0]);
1183 CertVerifyResult verify_result
;
1185 cert
.get(), "127.0.0.1", flags
, NULL
, empty_cert_list_
, &verify_result
);
1186 EXPECT_EQ(OK
, error
);
1187 EXPECT_EQ(0U, verify_result
.cert_status
);
1189 scoped_refptr
<CRLSet
> crl_set
;
1190 std::string crl_set_bytes
;
1192 // First test blocking by SPKI.
1193 EXPECT_TRUE(base::ReadFileToString(
1194 GetTestCertsDirectory().AppendASCII("crlset_by_leaf_spki.raw"),
1196 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes
, &crl_set
));
1198 error
= Verify(cert
.get(),
1204 EXPECT_EQ(ERR_CERT_REVOKED
, error
);
1206 // Second, test revocation by serial number of a cert directly under the
1208 crl_set_bytes
.clear();
1209 EXPECT_TRUE(base::ReadFileToString(
1210 GetTestCertsDirectory().AppendASCII("crlset_by_root_serial.raw"),
1212 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes
, &crl_set
));
1214 error
= Verify(cert
.get(),
1220 EXPECT_EQ(ERR_CERT_REVOKED
, error
);
1223 TEST_F(CertVerifyProcTest
, CRLSetLeafSerial
) {
1224 CertificateList ca_cert_list
=
1225 CreateCertificateListFromFile(GetTestCertsDirectory(),
1227 X509Certificate::FORMAT_AUTO
);
1228 ASSERT_EQ(1U, ca_cert_list
.size());
1229 ScopedTestRoot
test_root(ca_cert_list
[0].get());
1231 CertificateList intermediate_cert_list
=
1232 CreateCertificateListFromFile(GetTestCertsDirectory(),
1233 "quic_intermediate.crt",
1234 X509Certificate::FORMAT_AUTO
);
1235 ASSERT_EQ(1U, intermediate_cert_list
.size());
1236 X509Certificate::OSCertHandles intermediates
;
1237 intermediates
.push_back(intermediate_cert_list
[0]->os_cert_handle());
1239 CertificateList cert_list
= CreateCertificateListFromFile(
1240 GetTestCertsDirectory(), "quic_test.example.com.crt",
1241 X509Certificate::FORMAT_AUTO
);
1242 ASSERT_EQ(1U, cert_list
.size());
1244 scoped_refptr
<X509Certificate
> leaf
=
1245 X509Certificate::CreateFromHandle(cert_list
[0]->os_cert_handle(),
1249 CertVerifyResult verify_result
;
1250 int error
= Verify(leaf
.get(),
1256 EXPECT_EQ(OK
, error
);
1257 EXPECT_EQ(CERT_STATUS_SHA1_SIGNATURE_PRESENT
, verify_result
.cert_status
);
1259 // Test revocation by serial number of a certificate not under the root.
1260 scoped_refptr
<CRLSet
> crl_set
;
1261 std::string crl_set_bytes
;
1262 ASSERT_TRUE(base::ReadFileToString(
1263 GetTestCertsDirectory().AppendASCII("crlset_by_intermediate_serial.raw"),
1265 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes
, &crl_set
));
1267 error
= Verify(leaf
.get(),
1273 EXPECT_EQ(ERR_CERT_REVOKED
, error
);
1277 enum ExpectedAlgorithms
{
1278 EXPECT_MD2
= 1 << 0,
1279 EXPECT_MD4
= 1 << 1,
1280 EXPECT_MD5
= 1 << 2,
1281 EXPECT_SHA1
= 1 << 3
1284 struct WeakDigestTestData
{
1285 const char* root_cert_filename
;
1286 const char* intermediate_cert_filename
;
1287 const char* ee_cert_filename
;
1288 int expected_algorithms
;
1291 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
1292 // to output the parameter that was passed. Without this, it will simply
1293 // attempt to print out the first twenty bytes of the object, which depending
1294 // on platform and alignment, may result in an invalid read.
1295 void PrintTo(const WeakDigestTestData
& data
, std::ostream
* os
) {
1297 << (data
.root_cert_filename
? data
.root_cert_filename
: "none")
1298 << "; intermediate: " << data
.intermediate_cert_filename
1299 << "; end-entity: " << data
.ee_cert_filename
;
1302 class CertVerifyProcWeakDigestTest
1303 : public CertVerifyProcTest
,
1304 public testing::WithParamInterface
<WeakDigestTestData
> {
1306 CertVerifyProcWeakDigestTest() {}
1307 virtual ~CertVerifyProcWeakDigestTest() {}
1310 TEST_P(CertVerifyProcWeakDigestTest
, Verify
) {
1311 WeakDigestTestData data
= GetParam();
1312 base::FilePath certs_dir
= GetTestCertsDirectory();
1314 ScopedTestRoot test_root
;
1315 if (data
.root_cert_filename
) {
1316 scoped_refptr
<X509Certificate
> root_cert
=
1317 ImportCertFromFile(certs_dir
, data
.root_cert_filename
);
1318 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), root_cert
.get());
1319 test_root
.Reset(root_cert
.get());
1322 scoped_refptr
<X509Certificate
> intermediate_cert
=
1323 ImportCertFromFile(certs_dir
, data
.intermediate_cert_filename
);
1324 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert
.get());
1325 scoped_refptr
<X509Certificate
> ee_cert
=
1326 ImportCertFromFile(certs_dir
, data
.ee_cert_filename
);
1327 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), ee_cert
.get());
1329 X509Certificate::OSCertHandles intermediates
;
1330 intermediates
.push_back(intermediate_cert
->os_cert_handle());
1332 scoped_refptr
<X509Certificate
> ee_chain
=
1333 X509Certificate::CreateFromHandle(ee_cert
->os_cert_handle(),
1335 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), ee_chain
.get());
1338 CertVerifyResult verify_result
;
1339 int rv
= Verify(ee_chain
.get(),
1345 EXPECT_EQ(!!(data
.expected_algorithms
& EXPECT_MD2
), verify_result
.has_md2
);
1346 EXPECT_EQ(!!(data
.expected_algorithms
& EXPECT_MD4
), verify_result
.has_md4
);
1347 EXPECT_EQ(!!(data
.expected_algorithms
& EXPECT_MD5
), verify_result
.has_md5
);
1348 EXPECT_EQ(!!(data
.expected_algorithms
& EXPECT_SHA1
), verify_result
.has_sha1
);
1350 EXPECT_FALSE(verify_result
.is_issued_by_additional_trust_anchor
);
1352 // Ensure that MD4 and MD2 are tagged as invalid.
1353 if (data
.expected_algorithms
& (EXPECT_MD2
| EXPECT_MD4
)) {
1354 EXPECT_EQ(CERT_STATUS_INVALID
,
1355 verify_result
.cert_status
& CERT_STATUS_INVALID
);
1358 // Ensure that MD5 is flagged as weak.
1359 if (data
.expected_algorithms
& EXPECT_MD5
) {
1361 CERT_STATUS_WEAK_SIGNATURE_ALGORITHM
,
1362 verify_result
.cert_status
& CERT_STATUS_WEAK_SIGNATURE_ALGORITHM
);
1365 // If a root cert is present, then check that the chain was rejected if any
1366 // weak algorithms are present. This is only checked when a root cert is
1367 // present because the error reported for incomplete chains with weak
1368 // algorithms depends on which implementation was used to validate (NSS,
1369 // OpenSSL, CryptoAPI, Security.framework) and upon which weak algorithm
1370 // present (MD2, MD4, MD5).
1371 if (data
.root_cert_filename
) {
1372 if (data
.expected_algorithms
& (EXPECT_MD2
| EXPECT_MD4
)) {
1373 EXPECT_EQ(ERR_CERT_INVALID
, rv
);
1374 } else if (data
.expected_algorithms
& EXPECT_MD5
) {
1375 EXPECT_EQ(ERR_CERT_WEAK_SIGNATURE_ALGORITHM
, rv
);
1382 // Unlike TEST/TEST_F, which are macros that expand to further macros,
1383 // INSTANTIATE_TEST_CASE_P is a macro that expands directly to code that
1384 // stringizes the arguments. As a result, macros passed as parameters (such as
1385 // prefix or test_case_name) will not be expanded by the preprocessor. To work
1386 // around this, indirect the macro for INSTANTIATE_TEST_CASE_P, so that the
1387 // pre-processor will expand macros such as MAYBE_test_name before
1388 // instantiating the test.
1389 #define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
1390 INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator)
1392 // The signature algorithm of the root CA should not matter.
1393 const WeakDigestTestData kVerifyRootCATestData
[] = {
1394 { "weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem",
1395 "weak_digest_sha1_ee.pem", EXPECT_SHA1
},
1396 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1397 // MD4 is not supported by OS X / NSS
1398 { "weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem",
1399 "weak_digest_sha1_ee.pem", EXPECT_SHA1
},
1401 { "weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem",
1402 "weak_digest_sha1_ee.pem", EXPECT_SHA1
},
1404 INSTANTIATE_TEST_CASE_P(VerifyRoot
, CertVerifyProcWeakDigestTest
,
1405 testing::ValuesIn(kVerifyRootCATestData
));
1407 // The signature algorithm of intermediates should be properly detected.
1408 const WeakDigestTestData kVerifyIntermediateCATestData
[] = {
1409 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
1410 "weak_digest_sha1_ee.pem", EXPECT_MD5
| EXPECT_SHA1
},
1411 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1412 // MD4 is not supported by OS X / NSS
1413 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
1414 "weak_digest_sha1_ee.pem", EXPECT_MD4
| EXPECT_SHA1
},
1416 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
1417 "weak_digest_sha1_ee.pem", EXPECT_MD2
| EXPECT_SHA1
},
1419 // Disabled on NSS - MD4 is not supported, and MD2 and MD5 are disabled.
1420 #if defined(USE_NSS_CERTS) || defined(OS_IOS)
1421 #define MAYBE_VerifyIntermediate DISABLED_VerifyIntermediate
1423 #define MAYBE_VerifyIntermediate VerifyIntermediate
1425 WRAPPED_INSTANTIATE_TEST_CASE_P(
1426 MAYBE_VerifyIntermediate
,
1427 CertVerifyProcWeakDigestTest
,
1428 testing::ValuesIn(kVerifyIntermediateCATestData
));
1430 // The signature algorithm of end-entity should be properly detected.
1431 const WeakDigestTestData kVerifyEndEntityTestData
[] = {
1432 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1433 "weak_digest_md5_ee.pem", EXPECT_MD5
| EXPECT_SHA1
},
1434 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1435 // MD4 is not supported by OS X / NSS
1436 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1437 "weak_digest_md4_ee.pem", EXPECT_MD4
| EXPECT_SHA1
},
1439 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1440 "weak_digest_md2_ee.pem", EXPECT_MD2
| EXPECT_SHA1
},
1442 // Disabled on NSS - NSS caches chains/signatures in such a way that cannot
1443 // be cleared until NSS is cleanly shutdown, which is not presently supported
1445 #if defined(USE_NSS_CERTS) || defined(OS_IOS)
1446 #define MAYBE_VerifyEndEntity DISABLED_VerifyEndEntity
1448 #define MAYBE_VerifyEndEntity VerifyEndEntity
1450 WRAPPED_INSTANTIATE_TEST_CASE_P(MAYBE_VerifyEndEntity
,
1451 CertVerifyProcWeakDigestTest
,
1452 testing::ValuesIn(kVerifyEndEntityTestData
));
1454 // Incomplete chains should still report the status of the intermediate.
1455 const WeakDigestTestData kVerifyIncompleteIntermediateTestData
[] = {
1456 { NULL
, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem",
1457 EXPECT_MD5
| EXPECT_SHA1
},
1458 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1459 // MD4 is not supported by OS X / NSS
1460 { NULL
, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem",
1461 EXPECT_MD4
| EXPECT_SHA1
},
1463 { NULL
, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem",
1464 EXPECT_MD2
| EXPECT_SHA1
},
1466 // Disabled on NSS - libpkix does not return constructed chains on error,
1467 // preventing us from detecting/inspecting the verified chain.
1468 #if defined(USE_NSS_CERTS) || defined(OS_IOS)
1469 #define MAYBE_VerifyIncompleteIntermediate \
1470 DISABLED_VerifyIncompleteIntermediate
1472 #define MAYBE_VerifyIncompleteIntermediate VerifyIncompleteIntermediate
1474 WRAPPED_INSTANTIATE_TEST_CASE_P(
1475 MAYBE_VerifyIncompleteIntermediate
,
1476 CertVerifyProcWeakDigestTest
,
1477 testing::ValuesIn(kVerifyIncompleteIntermediateTestData
));
1479 // Incomplete chains should still report the status of the end-entity.
1480 const WeakDigestTestData kVerifyIncompleteEETestData
[] = {
1481 { NULL
, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem",
1482 EXPECT_MD5
| EXPECT_SHA1
},
1483 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1484 // MD4 is not supported by OS X / NSS
1485 { NULL
, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem",
1486 EXPECT_MD4
| EXPECT_SHA1
},
1488 { NULL
, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem",
1489 EXPECT_MD2
| EXPECT_SHA1
},
1491 // Disabled on NSS - libpkix does not return constructed chains on error,
1492 // preventing us from detecting/inspecting the verified chain.
1493 #if defined(USE_NSS_CERTS) || defined(OS_IOS)
1494 #define MAYBE_VerifyIncompleteEndEntity DISABLED_VerifyIncompleteEndEntity
1496 #define MAYBE_VerifyIncompleteEndEntity VerifyIncompleteEndEntity
1498 WRAPPED_INSTANTIATE_TEST_CASE_P(
1499 MAYBE_VerifyIncompleteEndEntity
,
1500 CertVerifyProcWeakDigestTest
,
1501 testing::ValuesIn(kVerifyIncompleteEETestData
));
1503 // Differing algorithms between the intermediate and the EE should still be
1505 const WeakDigestTestData kVerifyMixedTestData
[] = {
1506 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
1507 "weak_digest_md2_ee.pem", EXPECT_MD2
| EXPECT_MD5
},
1508 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
1509 "weak_digest_md5_ee.pem", EXPECT_MD2
| EXPECT_MD5
},
1510 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1511 // MD4 is not supported by OS X / NSS
1512 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
1513 "weak_digest_md2_ee.pem", EXPECT_MD2
| EXPECT_MD4
},
1516 // NSS does not support MD4 and does not enable MD2 by default, making all
1517 // permutations invalid.
1518 #if defined(USE_NSS_CERTS) || defined(OS_IOS)
1519 #define MAYBE_VerifyMixed DISABLED_VerifyMixed
1521 #define MAYBE_VerifyMixed VerifyMixed
1523 WRAPPED_INSTANTIATE_TEST_CASE_P(
1525 CertVerifyProcWeakDigestTest
,
1526 testing::ValuesIn(kVerifyMixedTestData
));
1528 // For the list of valid hostnames, see
1529 // net/cert/data/ssl/certificates/subjectAltName_sanity_check.pem
1530 static const struct CertVerifyProcNameData
{
1531 const char* hostname
;
1532 bool valid
; // Whether or not |hostname| matches a subjectAltName.
1533 } kVerifyNameData
[] = {
1534 { "127.0.0.1", false }, // Don't match the common name
1535 { "127.0.0.2", true }, // Matches the iPAddress SAN (IPv4)
1536 { "FE80:0:0:0:0:0:0:1", true }, // Matches the iPAddress SAN (IPv6)
1537 { "[FE80:0:0:0:0:0:0:1]", false }, // Should not match the iPAddress SAN
1538 { "FE80::1", true }, // Compressed form matches the iPAddress SAN (IPv6)
1539 { "::127.0.0.2", false }, // IPv6 mapped form should NOT match iPAddress SAN
1540 { "test.example", true }, // Matches the dNSName SAN
1541 { "test.example.", true }, // Matches the dNSName SAN (trailing . ignored)
1542 { "www.test.example", false }, // Should not match the dNSName SAN
1543 { "test..example", false }, // Should not match the dNSName SAN
1544 { "test.example..", false }, // Should not match the dNSName SAN
1545 { ".test.example.", false }, // Should not match the dNSName SAN
1546 { ".test.example", false }, // Should not match the dNSName SAN
1549 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
1550 // to output the parameter that was passed. Without this, it will simply
1551 // attempt to print out the first twenty bytes of the object, which depending
1552 // on platform and alignment, may result in an invalid read.
1553 void PrintTo(const CertVerifyProcNameData
& data
, std::ostream
* os
) {
1554 *os
<< "Hostname: " << data
.hostname
<< "; valid=" << data
.valid
;
1557 class CertVerifyProcNameTest
1558 : public CertVerifyProcTest
,
1559 public testing::WithParamInterface
<CertVerifyProcNameData
> {
1561 CertVerifyProcNameTest() {}
1562 virtual ~CertVerifyProcNameTest() {}
1565 TEST_P(CertVerifyProcNameTest
, VerifyCertName
) {
1566 CertVerifyProcNameData data
= GetParam();
1568 CertificateList cert_list
= CreateCertificateListFromFile(
1569 GetTestCertsDirectory(), "subjectAltName_sanity_check.pem",
1570 X509Certificate::FORMAT_AUTO
);
1571 ASSERT_EQ(1U, cert_list
.size());
1572 scoped_refptr
<X509Certificate
> cert(cert_list
[0]);
1574 ScopedTestRoot
scoped_root(cert
.get());
1576 CertVerifyResult verify_result
;
1577 int error
= Verify(cert
.get(), data
.hostname
, 0, NULL
, empty_cert_list_
,
1580 EXPECT_EQ(OK
, error
);
1581 EXPECT_FALSE(verify_result
.cert_status
& CERT_STATUS_COMMON_NAME_INVALID
);
1583 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID
, error
);
1584 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_COMMON_NAME_INVALID
);
1588 WRAPPED_INSTANTIATE_TEST_CASE_P(
1590 CertVerifyProcNameTest
,
1591 testing::ValuesIn(kVerifyNameData
));
1593 #if defined(OS_MACOSX) && !defined(OS_IOS)
1594 // Test that CertVerifyProcMac reacts appropriately when Apple's certificate
1595 // verifier rejects a certificate with a fatal error. This is a regression
1596 // test for https://crbug.com/472291.
1597 TEST_F(CertVerifyProcTest
, LargeKey
) {
1598 // Load root_ca_cert.pem into the test root store.
1599 ScopedTestRoot
test_root(
1600 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem").get());
1602 scoped_refptr
<X509Certificate
> cert(
1603 ImportCertFromFile(GetTestCertsDirectory(), "large_key.pem"));
1605 // Apple's verifier rejects this certificate as invalid because the
1606 // RSA key is too large. If a future version of OS X changes this,
1607 // large_key.pem may need to be regenerated with a larger key.
1609 CertVerifyResult verify_result
;
1610 int error
= Verify(cert
.get(), "127.0.0.1", flags
, NULL
, empty_cert_list_
,
1612 EXPECT_EQ(ERR_CERT_INVALID
, error
);
1613 EXPECT_EQ(CERT_STATUS_INVALID
, verify_result
.cert_status
);
1615 #endif // defined(OS_MACOSX) && !defined(OS_IOS)