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/file_util.h"
11 #include "base/files/file_path.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_MACOSX) && !defined(OS_IOS)
33 #include "base/mac/mac_util.h"
34 #elif defined(OS_ANDROID)
35 #include "base/android/build_info.h"
38 using base::HexEncode
;
44 // A certificate for www.paypal.com with a NULL byte in the common name.
45 // From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363
46 unsigned char paypal_null_fingerprint
[] = {
47 0x4c, 0x88, 0x9e, 0x28, 0xd7, 0x7a, 0x44, 0x1e, 0x13, 0xf2, 0x6a, 0xba,
48 0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7
51 // Mock CertVerifyProc that will set |verify_result->is_issued_by_known_root|
52 // for all certificates that are Verified.
53 class WellKnownCaCertVerifyProc
: public CertVerifyProc
{
55 // Initialize a CertVerifyProc that will set
56 // |verify_result->is_issued_by_known_root| to |is_well_known|.
57 explicit WellKnownCaCertVerifyProc(bool is_well_known
)
58 : is_well_known_(is_well_known
) {}
60 // CertVerifyProc implementation:
61 virtual bool SupportsAdditionalTrustAnchors() const OVERRIDE
{ return false; }
64 virtual ~WellKnownCaCertVerifyProc() {}
67 virtual int VerifyInternal(X509Certificate
* cert
,
68 const std::string
& hostname
,
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
,
84 const CertificateList
& additional_trust_anchors
,
85 CertVerifyResult
* verify_result
) {
86 verify_result
->is_issued_by_known_root
= is_well_known_
;
90 bool SupportsReturningVerifiedChain() {
91 #if defined(OS_ANDROID)
92 // Before API level 17, Android does not expose the APIs necessary to get at
93 // the verified certificate chain.
94 if (base::android::BuildInfo::GetInstance()->sdk_int() < 17)
100 bool SupportsDetectingKnownRoots() {
101 #if defined(OS_ANDROID)
102 // Before API level 17, Android does not expose the APIs necessary to get at
103 // the verified certificate chain and detect known roots.
104 if (base::android::BuildInfo::GetInstance()->sdk_int() < 17)
112 class CertVerifyProcTest
: public testing::Test
{
115 : verify_proc_(CertVerifyProc::CreateDefault()) {
117 virtual ~CertVerifyProcTest() {}
120 bool SupportsAdditionalTrustAnchors() {
121 return verify_proc_
->SupportsAdditionalTrustAnchors();
124 int Verify(X509Certificate
* cert
,
125 const std::string
& hostname
,
128 const CertificateList
& additional_trust_anchors
,
129 CertVerifyResult
* verify_result
) {
130 return verify_proc_
->Verify(cert
, hostname
, flags
, crl_set
,
131 additional_trust_anchors
, verify_result
);
134 const CertificateList empty_cert_list_
;
135 scoped_refptr
<CertVerifyProc
> verify_proc_
;
138 TEST_F(CertVerifyProcTest
, DISABLED_WithoutRevocationChecking
) {
139 // Check that verification without revocation checking works.
140 CertificateList certs
= CreateCertificateListFromFile(
141 GetTestCertsDirectory(),
142 "googlenew.chain.pem",
143 X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
145 X509Certificate::OSCertHandles intermediates
;
146 intermediates
.push_back(certs
[1]->os_cert_handle());
148 scoped_refptr
<X509Certificate
> google_full_chain
=
149 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
152 CertVerifyResult verify_result
;
154 Verify(google_full_chain
.get(),
162 #if defined(OS_ANDROID) || defined(USE_OPENSSL_CERTS)
163 // TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported.
164 #define MAYBE_EVVerification DISABLED_EVVerification
166 #define MAYBE_EVVerification EVVerification
168 TEST_F(CertVerifyProcTest
, MAYBE_EVVerification
) {
169 CertificateList certs
= CreateCertificateListFromFile(
170 GetTestCertsDirectory(),
172 X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
173 ASSERT_EQ(3U, certs
.size());
175 X509Certificate::OSCertHandles intermediates
;
176 intermediates
.push_back(certs
[1]->os_cert_handle());
177 intermediates
.push_back(certs
[2]->os_cert_handle());
179 scoped_refptr
<X509Certificate
> comodo_chain
=
180 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
183 scoped_refptr
<CRLSet
> crl_set(CRLSet::ForTesting(false, NULL
, ""));
184 CertVerifyResult verify_result
;
185 int flags
= CertVerifier::VERIFY_EV_CERT
;
186 int error
= Verify(comodo_chain
.get(),
192 EXPECT_EQ(OK
, error
);
193 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_IS_EV
);
196 TEST_F(CertVerifyProcTest
, PaypalNullCertParsing
) {
197 scoped_refptr
<X509Certificate
> paypal_null_cert(
198 X509Certificate::CreateFromBytes(
199 reinterpret_cast<const char*>(paypal_null_der
),
200 sizeof(paypal_null_der
)));
202 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), paypal_null_cert
.get());
204 const SHA1HashValue
& fingerprint
=
205 paypal_null_cert
->fingerprint();
206 for (size_t i
= 0; i
< 20; ++i
)
207 EXPECT_EQ(paypal_null_fingerprint
[i
], fingerprint
.data
[i
]);
210 CertVerifyResult verify_result
;
211 int error
= Verify(paypal_null_cert
.get(),
217 #if defined(USE_NSS) || defined(OS_IOS) || defined(OS_ANDROID)
218 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID
, error
);
220 // TOOD(bulach): investigate why macosx and win aren't returning
221 // ERR_CERT_INVALID or ERR_CERT_COMMON_NAME_INVALID.
222 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID
, error
);
224 // Either the system crypto library should correctly report a certificate
225 // name mismatch, or our certificate blacklist should cause us to report an
226 // invalid certificate.
227 #if defined(USE_NSS) || defined(OS_WIN) || defined(OS_IOS)
228 EXPECT_TRUE(verify_result
.cert_status
&
229 (CERT_STATUS_COMMON_NAME_INVALID
| CERT_STATUS_INVALID
));
233 // A regression test for http://crbug.com/31497.
234 #if defined(OS_ANDROID)
235 // Disabled on Android, as the Android verification libraries require an
236 // explicit policy to be specified, even when anyPolicy is permitted.
237 #define MAYBE_IntermediateCARequireExplicitPolicy \
238 DISABLED_IntermediateCARequireExplicitPolicy
240 #define MAYBE_IntermediateCARequireExplicitPolicy \
241 IntermediateCARequireExplicitPolicy
243 TEST_F(CertVerifyProcTest
, MAYBE_IntermediateCARequireExplicitPolicy
) {
244 base::FilePath certs_dir
= GetTestCertsDirectory();
246 CertificateList certs
= CreateCertificateListFromFile(
247 certs_dir
, "explicit-policy-chain.pem",
248 X509Certificate::FORMAT_AUTO
);
249 ASSERT_EQ(3U, certs
.size());
251 X509Certificate::OSCertHandles intermediates
;
252 intermediates
.push_back(certs
[1]->os_cert_handle());
254 scoped_refptr
<X509Certificate
> cert
=
255 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
257 ASSERT_TRUE(cert
.get());
259 ScopedTestRoot
scoped_root(certs
[2].get());
262 CertVerifyResult verify_result
;
263 int error
= Verify(cert
.get(),
264 "policy_test.example",
269 EXPECT_EQ(OK
, error
);
270 EXPECT_EQ(0u, verify_result
.cert_status
);
273 // Test for bug 58437.
274 // This certificate will expire on 2011-12-21. The test will still
275 // pass if error == ERR_CERT_DATE_INVALID.
276 // This test is DISABLED because it appears that we cannot do
277 // certificate revocation checking when running all of the net unit tests.
278 // This test passes when run individually, but when run with all of the net
279 // unit tests, the call to PKIXVerifyCert returns the NSS error -8180, which is
280 // SEC_ERROR_REVOKED_CERTIFICATE. This indicates a lack of revocation
281 // status, i.e. that the revocation check is failing for some reason.
282 TEST_F(CertVerifyProcTest
, DISABLED_GlobalSignR3EVTest
) {
283 base::FilePath certs_dir
= GetTestCertsDirectory();
285 scoped_refptr
<X509Certificate
> server_cert
=
286 ImportCertFromFile(certs_dir
, "2029_globalsign_com_cert.pem");
287 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
.get());
289 scoped_refptr
<X509Certificate
> intermediate_cert
=
290 ImportCertFromFile(certs_dir
, "globalsign_ev_sha256_ca_cert.pem");
291 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert
.get());
293 X509Certificate::OSCertHandles intermediates
;
294 intermediates
.push_back(intermediate_cert
->os_cert_handle());
295 scoped_refptr
<X509Certificate
> cert_chain
=
296 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
299 CertVerifyResult verify_result
;
300 int flags
= CertVerifier::VERIFY_REV_CHECKING_ENABLED
|
301 CertVerifier::VERIFY_EV_CERT
;
302 int error
= Verify(cert_chain
.get(),
303 "2029.globalsign.com",
309 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_IS_EV
);
311 EXPECT_EQ(ERR_CERT_DATE_INVALID
, error
);
314 // Test that verifying an ECDSA certificate doesn't crash on XP. (See
315 // crbug.com/144466).
316 TEST_F(CertVerifyProcTest
, ECDSA_RSA
) {
317 base::FilePath certs_dir
= GetTestCertsDirectory();
319 scoped_refptr
<X509Certificate
> cert
=
320 ImportCertFromFile(certs_dir
,
321 "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem");
323 CertVerifyResult verify_result
;
324 Verify(cert
.get(), "127.0.0.1", 0, NULL
, empty_cert_list_
, &verify_result
);
326 // We don't check verify_result because the certificate is signed by an
327 // unknown CA and will be considered invalid on XP because of the ECDSA
331 // Currently, only RSA and DSA keys are checked for weakness, and our example
332 // weak size is 768. These could change in the future.
334 // Note that this means there may be false negatives: keys for other
335 // algorithms and which are weak will pass this test.
336 static bool IsWeakKeyType(const std::string
& key_type
) {
337 size_t pos
= key_type
.find("-");
338 std::string size
= key_type
.substr(0, pos
);
339 std::string type
= key_type
.substr(pos
+ 1);
341 if (type
== "rsa" || type
== "dsa")
342 return size
== "768";
347 TEST_F(CertVerifyProcTest
, RejectWeakKeys
) {
348 base::FilePath certs_dir
= GetTestCertsDirectory();
349 typedef std::vector
<std::string
> Strings
;
352 // generate-weak-test-chains.sh currently has:
353 // key_types="768-rsa 1024-rsa 2048-rsa prime256v1-ecdsa"
354 // We must use the same key types here. The filenames generated look like:
355 // 2048-rsa-ee-by-768-rsa-intermediate.pem
356 key_types
.push_back("768-rsa");
357 key_types
.push_back("1024-rsa");
358 key_types
.push_back("2048-rsa");
360 bool use_ecdsa
= true;
362 use_ecdsa
= base::win::GetVersion() > base::win::VERSION_XP
;
366 key_types
.push_back("prime256v1-ecdsa");
368 // Add the root that signed the intermediates for this test.
369 scoped_refptr
<X509Certificate
> root_cert
=
370 ImportCertFromFile(certs_dir
, "2048-rsa-root.pem");
371 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), root_cert
.get());
372 ScopedTestRoot
scoped_root(root_cert
.get());
374 // Now test each chain.
375 for (Strings::const_iterator ee_type
= key_types
.begin();
376 ee_type
!= key_types
.end(); ++ee_type
) {
377 for (Strings::const_iterator signer_type
= key_types
.begin();
378 signer_type
!= key_types
.end(); ++signer_type
) {
379 std::string basename
= *ee_type
+ "-ee-by-" + *signer_type
+
381 SCOPED_TRACE(basename
);
382 scoped_refptr
<X509Certificate
> ee_cert
=
383 ImportCertFromFile(certs_dir
, basename
);
384 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), ee_cert
.get());
386 basename
= *signer_type
+ "-intermediate.pem";
387 scoped_refptr
<X509Certificate
> intermediate
=
388 ImportCertFromFile(certs_dir
, basename
);
389 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate
.get());
391 X509Certificate::OSCertHandles intermediates
;
392 intermediates
.push_back(intermediate
->os_cert_handle());
393 scoped_refptr
<X509Certificate
> cert_chain
=
394 X509Certificate::CreateFromHandle(ee_cert
->os_cert_handle(),
397 CertVerifyResult verify_result
;
398 int error
= Verify(cert_chain
.get(),
405 if (IsWeakKeyType(*ee_type
) || IsWeakKeyType(*signer_type
)) {
406 EXPECT_NE(OK
, error
);
407 EXPECT_EQ(CERT_STATUS_WEAK_KEY
,
408 verify_result
.cert_status
& CERT_STATUS_WEAK_KEY
);
409 EXPECT_NE(CERT_STATUS_INVALID
,
410 verify_result
.cert_status
& CERT_STATUS_INVALID
);
412 EXPECT_EQ(OK
, error
);
413 EXPECT_EQ(0U, verify_result
.cert_status
& CERT_STATUS_WEAK_KEY
);
419 // Regression test for http://crbug.com/108514.
420 #if defined(OS_MACOSX) && !defined(OS_IOS)
421 // Disabled on OS X - Security.framework doesn't ignore superflous certificates
422 // provided by servers. See CertVerifyProcTest.CybertrustGTERoot for further
424 #define MAYBE_ExtraneousMD5RootCert DISABLED_ExtraneousMD5RootCert
426 #define MAYBE_ExtraneousMD5RootCert ExtraneousMD5RootCert
428 TEST_F(CertVerifyProcTest
, MAYBE_ExtraneousMD5RootCert
) {
429 if (!SupportsReturningVerifiedChain()) {
430 LOG(INFO
) << "Skipping this test in this platform.";
434 base::FilePath certs_dir
= GetTestCertsDirectory();
436 scoped_refptr
<X509Certificate
> server_cert
=
437 ImportCertFromFile(certs_dir
, "cross-signed-leaf.pem");
438 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
.get());
440 scoped_refptr
<X509Certificate
> extra_cert
=
441 ImportCertFromFile(certs_dir
, "cross-signed-root-md5.pem");
442 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), extra_cert
.get());
444 scoped_refptr
<X509Certificate
> root_cert
=
445 ImportCertFromFile(certs_dir
, "cross-signed-root-sha1.pem");
446 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), root_cert
.get());
448 ScopedTestRoot
scoped_root(root_cert
.get());
450 X509Certificate::OSCertHandles intermediates
;
451 intermediates
.push_back(extra_cert
->os_cert_handle());
452 scoped_refptr
<X509Certificate
> cert_chain
=
453 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
456 CertVerifyResult verify_result
;
458 int error
= Verify(cert_chain
.get(),
464 EXPECT_EQ(OK
, error
);
466 // The extra MD5 root should be discarded
467 ASSERT_TRUE(verify_result
.verified_cert
.get());
469 verify_result
.verified_cert
->GetIntermediateCertificates().size());
470 EXPECT_TRUE(X509Certificate::IsSameOSCert(
471 verify_result
.verified_cert
->GetIntermediateCertificates().front(),
472 root_cert
->os_cert_handle()));
474 EXPECT_FALSE(verify_result
.has_md5
);
477 // Test for bug 94673.
478 TEST_F(CertVerifyProcTest
, GoogleDigiNotarTest
) {
479 base::FilePath certs_dir
= GetTestCertsDirectory();
481 scoped_refptr
<X509Certificate
> server_cert
=
482 ImportCertFromFile(certs_dir
, "google_diginotar.pem");
483 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
.get());
485 scoped_refptr
<X509Certificate
> intermediate_cert
=
486 ImportCertFromFile(certs_dir
, "diginotar_public_ca_2025.pem");
487 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert
.get());
489 X509Certificate::OSCertHandles intermediates
;
490 intermediates
.push_back(intermediate_cert
->os_cert_handle());
491 scoped_refptr
<X509Certificate
> cert_chain
=
492 X509Certificate::CreateFromHandle(server_cert
->os_cert_handle(),
495 CertVerifyResult verify_result
;
496 int flags
= CertVerifier::VERIFY_REV_CHECKING_ENABLED
;
497 int error
= Verify(cert_chain
.get(),
503 EXPECT_NE(OK
, error
);
505 // Now turn off revocation checking. Certificate verification should still
508 error
= Verify(cert_chain
.get(),
514 EXPECT_NE(OK
, error
);
517 TEST_F(CertVerifyProcTest
, DigiNotarCerts
) {
518 static const char* const kDigiNotarFilenames
[] = {
519 "diginotar_root_ca.pem",
520 "diginotar_cyber_ca.pem",
521 "diginotar_services_1024_ca.pem",
522 "diginotar_pkioverheid.pem",
523 "diginotar_pkioverheid_g2.pem",
527 base::FilePath certs_dir
= GetTestCertsDirectory();
529 for (size_t i
= 0; kDigiNotarFilenames
[i
]; i
++) {
530 scoped_refptr
<X509Certificate
> diginotar_cert
=
531 ImportCertFromFile(certs_dir
, kDigiNotarFilenames
[i
]);
532 std::string der_bytes
;
533 ASSERT_TRUE(X509Certificate::GetDEREncoded(
534 diginotar_cert
->os_cert_handle(), &der_bytes
));
536 base::StringPiece spki
;
537 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_bytes
, &spki
));
539 std::string spki_sha1
= base::SHA1HashString(spki
.as_string());
541 HashValueVector public_keys
;
542 HashValue
hash(HASH_VALUE_SHA1
);
543 ASSERT_EQ(hash
.size(), spki_sha1
.size());
544 memcpy(hash
.data(), spki_sha1
.data(), spki_sha1
.size());
545 public_keys
.push_back(hash
);
547 EXPECT_TRUE(CertVerifyProc::IsPublicKeyBlacklisted(public_keys
)) <<
548 "Public key not blocked for " << kDigiNotarFilenames
[i
];
552 TEST_F(CertVerifyProcTest
, NameConstraintsOk
) {
553 CertificateList ca_cert_list
=
554 CreateCertificateListFromFile(GetTestCertsDirectory(),
556 X509Certificate::FORMAT_AUTO
);
557 ASSERT_EQ(1U, ca_cert_list
.size());
558 ScopedTestRoot
test_root(ca_cert_list
[0].get());
560 CertificateList cert_list
= CreateCertificateListFromFile(
561 GetTestCertsDirectory(), "name_constraint_ok.crt",
562 X509Certificate::FORMAT_AUTO
);
563 ASSERT_EQ(1U, cert_list
.size());
565 X509Certificate::OSCertHandles intermediates
;
566 scoped_refptr
<X509Certificate
> leaf
=
567 X509Certificate::CreateFromHandle(cert_list
[0]->os_cert_handle(),
571 CertVerifyResult verify_result
;
572 int error
= Verify(leaf
.get(),
578 EXPECT_EQ(OK
, error
);
579 EXPECT_EQ(0U, verify_result
.cert_status
);
582 TEST_F(CertVerifyProcTest
, NameConstraintsFailure
) {
583 if (!SupportsReturningVerifiedChain()) {
584 LOG(INFO
) << "Skipping this test in this platform.";
588 CertificateList ca_cert_list
=
589 CreateCertificateListFromFile(GetTestCertsDirectory(),
591 X509Certificate::FORMAT_AUTO
);
592 ASSERT_EQ(1U, ca_cert_list
.size());
593 ScopedTestRoot
test_root(ca_cert_list
[0].get());
595 CertificateList cert_list
= CreateCertificateListFromFile(
596 GetTestCertsDirectory(), "name_constraint_bad.crt",
597 X509Certificate::FORMAT_AUTO
);
598 ASSERT_EQ(1U, cert_list
.size());
600 X509Certificate::OSCertHandles intermediates
;
601 scoped_refptr
<X509Certificate
> leaf
=
602 X509Certificate::CreateFromHandle(cert_list
[0]->os_cert_handle(),
606 CertVerifyResult verify_result
;
607 int error
= Verify(leaf
.get(),
613 EXPECT_EQ(ERR_CERT_NAME_CONSTRAINT_VIOLATION
, error
);
614 EXPECT_EQ(CERT_STATUS_NAME_CONSTRAINT_VIOLATION
,
615 verify_result
.cert_status
& CERT_STATUS_NAME_CONSTRAINT_VIOLATION
);
618 TEST_F(CertVerifyProcTest
, TestKnownRoot
) {
619 if (!SupportsDetectingKnownRoots()) {
620 LOG(INFO
) << "Skipping this test in this platform.";
624 base::FilePath certs_dir
= GetTestCertsDirectory();
625 CertificateList certs
= CreateCertificateListFromFile(
626 certs_dir
, "satveda.pem", X509Certificate::FORMAT_AUTO
);
627 ASSERT_EQ(2U, certs
.size());
629 X509Certificate::OSCertHandles intermediates
;
630 intermediates
.push_back(certs
[1]->os_cert_handle());
632 scoped_refptr
<X509Certificate
> cert_chain
=
633 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
637 CertVerifyResult verify_result
;
638 // This will blow up, May 24th, 2019. Sorry! Please disable and file a bug
639 // against agl. See also PublicKeyHashes.
640 int error
= Verify(cert_chain
.get(),
646 EXPECT_EQ(OK
, error
);
647 EXPECT_EQ(0U, verify_result
.cert_status
);
648 EXPECT_TRUE(verify_result
.is_issued_by_known_root
);
651 // The certse.pem certificate has been revoked. crbug.com/259723.
652 TEST_F(CertVerifyProcTest
, PublicKeyHashes
) {
653 if (!SupportsReturningVerifiedChain()) {
654 LOG(INFO
) << "Skipping this test in this platform.";
658 base::FilePath certs_dir
= GetTestCertsDirectory();
659 CertificateList certs
= CreateCertificateListFromFile(
660 certs_dir
, "satveda.pem", X509Certificate::FORMAT_AUTO
);
661 ASSERT_EQ(2U, certs
.size());
663 X509Certificate::OSCertHandles intermediates
;
664 intermediates
.push_back(certs
[1]->os_cert_handle());
666 scoped_refptr
<X509Certificate
> cert_chain
=
667 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
670 CertVerifyResult verify_result
;
672 // This will blow up, May 24th, 2019. Sorry! Please disable and file a bug
673 // against agl. See also TestKnownRoot.
674 int error
= Verify(cert_chain
.get(),
680 EXPECT_EQ(OK
, error
);
681 EXPECT_EQ(0U, verify_result
.cert_status
);
682 ASSERT_LE(2U, verify_result
.public_key_hashes
.size());
684 HashValueVector sha1_hashes
;
685 for (size_t i
= 0; i
< verify_result
.public_key_hashes
.size(); ++i
) {
686 if (verify_result
.public_key_hashes
[i
].tag
!= HASH_VALUE_SHA1
)
688 sha1_hashes
.push_back(verify_result
.public_key_hashes
[i
]);
690 ASSERT_LE(2u, sha1_hashes
.size());
692 for (size_t i
= 0; i
< 2; ++i
) {
693 EXPECT_EQ(HexEncode(kSatvedaSPKIs
[i
], base::kSHA1Length
),
694 HexEncode(sha1_hashes
[i
].data(), base::kSHA1Length
));
697 HashValueVector sha256_hashes
;
698 for (size_t i
= 0; i
< verify_result
.public_key_hashes
.size(); ++i
) {
699 if (verify_result
.public_key_hashes
[i
].tag
!= HASH_VALUE_SHA256
)
701 sha256_hashes
.push_back(verify_result
.public_key_hashes
[i
]);
703 ASSERT_LE(2u, sha256_hashes
.size());
705 for (size_t i
= 0; i
< 2; ++i
) {
706 EXPECT_EQ(HexEncode(kSatvedaSPKIsSHA256
[i
], crypto::kSHA256Length
),
707 HexEncode(sha256_hashes
[i
].data(), crypto::kSHA256Length
));
711 // A regression test for http://crbug.com/70293.
712 // The Key Usage extension in this RSA SSL server certificate does not have
713 // the keyEncipherment bit.
714 TEST_F(CertVerifyProcTest
, InvalidKeyUsage
) {
715 base::FilePath certs_dir
= GetTestCertsDirectory();
717 scoped_refptr
<X509Certificate
> server_cert
=
718 ImportCertFromFile(certs_dir
, "invalid_key_usage_cert.der");
719 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), server_cert
.get());
722 CertVerifyResult verify_result
;
723 int error
= Verify(server_cert
.get(),
729 #if defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
730 // This certificate has two errors: "invalid key usage" and "untrusted CA".
731 // However, OpenSSL returns only one (the latter), and we can't detect
733 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID
, error
);
735 EXPECT_EQ(ERR_CERT_INVALID
, error
);
736 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_INVALID
);
738 // TODO(wtc): fix http://crbug.com/75520 to get all the certificate errors
740 #if !defined(USE_NSS) && !defined(OS_IOS) && !defined(OS_ANDROID)
741 // The certificate is issued by an unknown CA.
742 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_AUTHORITY_INVALID
);
746 // Basic test for returning the chain in CertVerifyResult. Note that the
747 // returned chain may just be a reflection of the originally supplied chain;
748 // that is, if any errors occur, the default chain returned is an exact copy
749 // of the certificate to be verified. The remaining VerifyReturn* tests are
750 // used to ensure that the actual, verified chain is being returned by
752 TEST_F(CertVerifyProcTest
, VerifyReturnChainBasic
) {
753 if (!SupportsReturningVerifiedChain()) {
754 LOG(INFO
) << "Skipping this test in this platform.";
758 base::FilePath certs_dir
= GetTestCertsDirectory();
759 CertificateList certs
= CreateCertificateListFromFile(
760 certs_dir
, "x509_verify_results.chain.pem",
761 X509Certificate::FORMAT_AUTO
);
762 ASSERT_EQ(3U, certs
.size());
764 X509Certificate::OSCertHandles intermediates
;
765 intermediates
.push_back(certs
[1]->os_cert_handle());
766 intermediates
.push_back(certs
[2]->os_cert_handle());
768 ScopedTestRoot
scoped_root(certs
[2].get());
770 scoped_refptr
<X509Certificate
> google_full_chain
=
771 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
773 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), google_full_chain
.get());
774 ASSERT_EQ(2U, google_full_chain
->GetIntermediateCertificates().size());
776 CertVerifyResult verify_result
;
777 EXPECT_EQ(static_cast<X509Certificate
*>(NULL
),
778 verify_result
.verified_cert
.get());
779 int error
= Verify(google_full_chain
.get(),
785 EXPECT_EQ(OK
, error
);
786 ASSERT_NE(static_cast<X509Certificate
*>(NULL
),
787 verify_result
.verified_cert
.get());
789 EXPECT_NE(google_full_chain
, verify_result
.verified_cert
);
790 EXPECT_TRUE(X509Certificate::IsSameOSCert(
791 google_full_chain
->os_cert_handle(),
792 verify_result
.verified_cert
->os_cert_handle()));
793 const X509Certificate::OSCertHandles
& return_intermediates
=
794 verify_result
.verified_cert
->GetIntermediateCertificates();
795 ASSERT_EQ(2U, return_intermediates
.size());
796 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[0],
797 certs
[1]->os_cert_handle()));
798 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[1],
799 certs
[2]->os_cert_handle()));
802 // Test that certificates issued for 'intranet' names (that is, containing no
803 // known public registry controlled domain information) issued by well-known
804 // CAs are flagged appropriately, while certificates that are issued by
805 // internal CAs are not flagged.
806 TEST_F(CertVerifyProcTest
, IntranetHostsRejected
) {
807 if (!SupportsDetectingKnownRoots()) {
808 LOG(INFO
) << "Skipping this test in this platform.";
812 CertificateList cert_list
= CreateCertificateListFromFile(
813 GetTestCertsDirectory(), "ok_cert.pem",
814 X509Certificate::FORMAT_AUTO
);
815 ASSERT_EQ(1U, cert_list
.size());
816 scoped_refptr
<X509Certificate
> cert(cert_list
[0]);
818 CertVerifyResult verify_result
;
821 // Intranet names for public CAs should be flagged:
822 verify_proc_
= new WellKnownCaCertVerifyProc(true);
824 Verify(cert
.get(), "intranet", 0, NULL
, empty_cert_list_
, &verify_result
);
825 EXPECT_EQ(OK
, error
);
826 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_NON_UNIQUE_NAME
);
828 // However, if the CA is not well known, these should not be flagged:
829 verify_proc_
= new WellKnownCaCertVerifyProc(false);
831 Verify(cert
.get(), "intranet", 0, NULL
, empty_cert_list_
, &verify_result
);
832 EXPECT_EQ(OK
, error
);
833 EXPECT_FALSE(verify_result
.cert_status
& CERT_STATUS_NON_UNIQUE_NAME
);
836 // Test that the certificate returned in CertVerifyResult is able to reorder
837 // certificates that are not ordered from end-entity to root. While this is
838 // a protocol violation if sent during a TLS handshake, if multiple sources
839 // of intermediate certificates are combined, it's possible that order may
840 // not be maintained.
841 TEST_F(CertVerifyProcTest
, VerifyReturnChainProperlyOrdered
) {
842 if (!SupportsReturningVerifiedChain()) {
843 LOG(INFO
) << "Skipping this test in this platform.";
847 base::FilePath certs_dir
= GetTestCertsDirectory();
848 CertificateList certs
= CreateCertificateListFromFile(
849 certs_dir
, "x509_verify_results.chain.pem",
850 X509Certificate::FORMAT_AUTO
);
851 ASSERT_EQ(3U, certs
.size());
853 // Construct the chain out of order.
854 X509Certificate::OSCertHandles intermediates
;
855 intermediates
.push_back(certs
[2]->os_cert_handle());
856 intermediates
.push_back(certs
[1]->os_cert_handle());
858 ScopedTestRoot
scoped_root(certs
[2].get());
860 scoped_refptr
<X509Certificate
> google_full_chain
=
861 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
863 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), google_full_chain
.get());
864 ASSERT_EQ(2U, google_full_chain
->GetIntermediateCertificates().size());
866 CertVerifyResult verify_result
;
867 EXPECT_EQ(static_cast<X509Certificate
*>(NULL
),
868 verify_result
.verified_cert
.get());
869 int error
= Verify(google_full_chain
.get(),
875 EXPECT_EQ(OK
, error
);
876 ASSERT_NE(static_cast<X509Certificate
*>(NULL
),
877 verify_result
.verified_cert
.get());
879 EXPECT_NE(google_full_chain
, verify_result
.verified_cert
);
880 EXPECT_TRUE(X509Certificate::IsSameOSCert(
881 google_full_chain
->os_cert_handle(),
882 verify_result
.verified_cert
->os_cert_handle()));
883 const X509Certificate::OSCertHandles
& return_intermediates
=
884 verify_result
.verified_cert
->GetIntermediateCertificates();
885 ASSERT_EQ(2U, return_intermediates
.size());
886 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[0],
887 certs
[1]->os_cert_handle()));
888 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[1],
889 certs
[2]->os_cert_handle()));
892 // Test that Verify() filters out certificates which are not related to
893 // or part of the certificate chain being verified.
894 TEST_F(CertVerifyProcTest
, VerifyReturnChainFiltersUnrelatedCerts
) {
895 if (!SupportsReturningVerifiedChain()) {
896 LOG(INFO
) << "Skipping this test in this platform.";
900 base::FilePath certs_dir
= GetTestCertsDirectory();
901 CertificateList certs
= CreateCertificateListFromFile(
902 certs_dir
, "x509_verify_results.chain.pem",
903 X509Certificate::FORMAT_AUTO
);
904 ASSERT_EQ(3U, certs
.size());
905 ScopedTestRoot
scoped_root(certs
[2].get());
907 scoped_refptr
<X509Certificate
> unrelated_certificate
=
908 ImportCertFromFile(certs_dir
, "duplicate_cn_1.pem");
909 scoped_refptr
<X509Certificate
> unrelated_certificate2
=
910 ImportCertFromFile(certs_dir
, "aia-cert.pem");
911 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), unrelated_certificate
.get());
912 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), unrelated_certificate2
.get());
914 // Interject unrelated certificates into the list of intermediates.
915 X509Certificate::OSCertHandles intermediates
;
916 intermediates
.push_back(unrelated_certificate
->os_cert_handle());
917 intermediates
.push_back(certs
[1]->os_cert_handle());
918 intermediates
.push_back(unrelated_certificate2
->os_cert_handle());
919 intermediates
.push_back(certs
[2]->os_cert_handle());
921 scoped_refptr
<X509Certificate
> google_full_chain
=
922 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
924 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), google_full_chain
.get());
925 ASSERT_EQ(4U, google_full_chain
->GetIntermediateCertificates().size());
927 CertVerifyResult verify_result
;
928 EXPECT_EQ(static_cast<X509Certificate
*>(NULL
),
929 verify_result
.verified_cert
.get());
930 int error
= Verify(google_full_chain
.get(),
936 EXPECT_EQ(OK
, error
);
937 ASSERT_NE(static_cast<X509Certificate
*>(NULL
),
938 verify_result
.verified_cert
.get());
940 EXPECT_NE(google_full_chain
, verify_result
.verified_cert
);
941 EXPECT_TRUE(X509Certificate::IsSameOSCert(
942 google_full_chain
->os_cert_handle(),
943 verify_result
.verified_cert
->os_cert_handle()));
944 const X509Certificate::OSCertHandles
& return_intermediates
=
945 verify_result
.verified_cert
->GetIntermediateCertificates();
946 ASSERT_EQ(2U, return_intermediates
.size());
947 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[0],
948 certs
[1]->os_cert_handle()));
949 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates
[1],
950 certs
[2]->os_cert_handle()));
953 TEST_F(CertVerifyProcTest
, AdditionalTrustAnchors
) {
954 if (!SupportsAdditionalTrustAnchors()) {
955 LOG(INFO
) << "Skipping this test in this platform.";
959 // |ca_cert| is the issuer of |cert|.
960 CertificateList ca_cert_list
= CreateCertificateListFromFile(
961 GetTestCertsDirectory(), "root_ca_cert.pem",
962 X509Certificate::FORMAT_AUTO
);
963 ASSERT_EQ(1U, ca_cert_list
.size());
964 scoped_refptr
<X509Certificate
> ca_cert(ca_cert_list
[0]);
966 CertificateList cert_list
= CreateCertificateListFromFile(
967 GetTestCertsDirectory(), "ok_cert.pem",
968 X509Certificate::FORMAT_AUTO
);
969 ASSERT_EQ(1U, cert_list
.size());
970 scoped_refptr
<X509Certificate
> cert(cert_list
[0]);
972 // Verification of |cert| fails when |ca_cert| is not in the trust anchors
975 CertVerifyResult verify_result
;
977 cert
.get(), "127.0.0.1", flags
, NULL
, empty_cert_list_
, &verify_result
);
978 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID
, error
);
979 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID
, verify_result
.cert_status
);
980 EXPECT_FALSE(verify_result
.is_issued_by_additional_trust_anchor
);
982 // Now add the |ca_cert| to the |trust_anchors|, and verification should pass.
983 CertificateList trust_anchors
;
984 trust_anchors
.push_back(ca_cert
);
986 cert
.get(), "127.0.0.1", flags
, NULL
, trust_anchors
, &verify_result
);
987 EXPECT_EQ(OK
, error
);
988 EXPECT_EQ(0U, verify_result
.cert_status
);
989 EXPECT_TRUE(verify_result
.is_issued_by_additional_trust_anchor
);
991 // Clearing the |trust_anchors| makes verification fail again (the cache
992 // should be skipped).
994 cert
.get(), "127.0.0.1", flags
, NULL
, empty_cert_list_
, &verify_result
);
995 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID
, error
);
996 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID
, verify_result
.cert_status
);
997 EXPECT_FALSE(verify_result
.is_issued_by_additional_trust_anchor
);
1000 // Tests that certificates issued by user-supplied roots are not flagged as
1001 // issued by a known root. This should pass whether or not the platform supports
1002 // detecting known roots.
1003 TEST_F(CertVerifyProcTest
, IsIssuedByKnownRootIgnoresTestRoots
) {
1004 // Load root_ca_cert.pem into the test root store.
1005 TestRootCerts
* root_certs
= TestRootCerts::GetInstance();
1006 root_certs
->AddFromFile(
1007 GetTestCertsDirectory().AppendASCII("root_ca_cert.pem"));
1009 CertificateList cert_list
= CreateCertificateListFromFile(
1010 GetTestCertsDirectory(), "ok_cert.pem",
1011 X509Certificate::FORMAT_AUTO
);
1012 ASSERT_EQ(1U, cert_list
.size());
1013 scoped_refptr
<X509Certificate
> cert(cert_list
[0]);
1015 // Verification should pass.
1017 CertVerifyResult verify_result
;
1019 cert
.get(), "127.0.0.1", flags
, NULL
, empty_cert_list_
, &verify_result
);
1020 EXPECT_EQ(OK
, error
);
1021 EXPECT_EQ(0U, verify_result
.cert_status
);
1022 // But should not be marked as a known root.
1023 EXPECT_FALSE(verify_result
.is_issued_by_known_root
);
1025 root_certs
->Clear();
1026 EXPECT_TRUE(root_certs
->IsEmpty());
1029 #if defined(OS_MACOSX) && !defined(OS_IOS)
1030 // Tests that, on OS X, issues with a cross-certified Baltimore CyberTrust
1031 // Root can be successfully worked around once Apple completes removing the
1032 // older GTE CyberTrust Root from its trusted root store.
1034 // The issue is caused by servers supplying the cross-certified intermediate
1035 // (necessary for certain mobile platforms), which OS X does not recognize
1036 // as already existing within its trust store.
1037 TEST_F(CertVerifyProcTest
, CybertrustGTERoot
) {
1038 CertificateList certs
= CreateCertificateListFromFile(
1039 GetTestCertsDirectory(),
1040 "cybertrust_omniroot_chain.pem",
1041 X509Certificate::FORMAT_PEM_CERT_SEQUENCE
);
1042 ASSERT_EQ(2U, certs
.size());
1044 X509Certificate::OSCertHandles intermediates
;
1045 intermediates
.push_back(certs
[1]->os_cert_handle());
1047 scoped_refptr
<X509Certificate
> cybertrust_basic
=
1048 X509Certificate::CreateFromHandle(certs
[0]->os_cert_handle(),
1050 ASSERT_TRUE(cybertrust_basic
.get());
1052 scoped_refptr
<X509Certificate
> baltimore_root
=
1053 ImportCertFromFile(GetTestCertsDirectory(),
1054 "cybertrust_baltimore_root.pem");
1055 ASSERT_TRUE(baltimore_root
.get());
1057 ScopedTestRoot
scoped_root(baltimore_root
.get());
1059 // Ensure that ONLY the Baltimore CyberTrust Root is trusted. This
1060 // simulates Keychain removing support for the GTE CyberTrust Root.
1061 TestRootCerts::GetInstance()->SetAllowSystemTrust(false);
1062 base::ScopedClosureRunner
reset_system_trust(
1063 base::Bind(&TestRootCerts::SetAllowSystemTrust
,
1064 base::Unretained(TestRootCerts::GetInstance()),
1067 // First, make sure a simple certificate chain from
1068 // EE -> Public SureServer SV -> Baltimore CyberTrust
1069 // works. Only the first two certificates are included in the chain.
1071 CertVerifyResult verify_result
;
1072 int error
= Verify(cybertrust_basic
.get(),
1073 "cacert.omniroot.com",
1078 EXPECT_EQ(OK
, error
);
1079 EXPECT_EQ(0U, verify_result
.cert_status
);
1081 // Attempt to verify with the first known cross-certified intermediate
1083 scoped_refptr
<X509Certificate
> baltimore_intermediate_1
=
1084 ImportCertFromFile(GetTestCertsDirectory(),
1085 "cybertrust_baltimore_cross_certified_1.pem");
1086 ASSERT_TRUE(baltimore_intermediate_1
.get());
1088 X509Certificate::OSCertHandles intermediate_chain_1
=
1089 cybertrust_basic
->GetIntermediateCertificates();
1090 intermediate_chain_1
.push_back(baltimore_intermediate_1
->os_cert_handle());
1092 scoped_refptr
<X509Certificate
> baltimore_chain_1
=
1093 X509Certificate::CreateFromHandle(cybertrust_basic
->os_cert_handle(),
1094 intermediate_chain_1
);
1095 error
= Verify(baltimore_chain_1
.get(),
1096 "cacert.omniroot.com",
1101 EXPECT_EQ(OK
, error
);
1102 EXPECT_EQ(0U, verify_result
.cert_status
);
1104 // Attempt to verify with the second known cross-certified intermediate
1106 scoped_refptr
<X509Certificate
> baltimore_intermediate_2
=
1107 ImportCertFromFile(GetTestCertsDirectory(),
1108 "cybertrust_baltimore_cross_certified_2.pem");
1109 ASSERT_TRUE(baltimore_intermediate_2
.get());
1111 X509Certificate::OSCertHandles intermediate_chain_2
=
1112 cybertrust_basic
->GetIntermediateCertificates();
1113 intermediate_chain_2
.push_back(baltimore_intermediate_2
->os_cert_handle());
1115 scoped_refptr
<X509Certificate
> baltimore_chain_2
=
1116 X509Certificate::CreateFromHandle(cybertrust_basic
->os_cert_handle(),
1117 intermediate_chain_2
);
1118 error
= Verify(baltimore_chain_2
.get(),
1119 "cacert.omniroot.com",
1124 EXPECT_EQ(OK
, error
);
1125 EXPECT_EQ(0U, verify_result
.cert_status
);
1127 // Attempt to verify when both a cross-certified intermediate AND
1128 // the legacy GTE root are provided.
1129 scoped_refptr
<X509Certificate
> cybertrust_root
=
1130 ImportCertFromFile(GetTestCertsDirectory(),
1131 "cybertrust_gte_root.pem");
1132 ASSERT_TRUE(cybertrust_root
.get());
1134 intermediate_chain_2
.push_back(cybertrust_root
->os_cert_handle());
1135 scoped_refptr
<X509Certificate
> baltimore_chain_with_root
=
1136 X509Certificate::CreateFromHandle(cybertrust_basic
->os_cert_handle(),
1137 intermediate_chain_2
);
1138 error
= Verify(baltimore_chain_with_root
.get(),
1139 "cacert.omniroot.com",
1144 EXPECT_EQ(OK
, error
);
1145 EXPECT_EQ(0U, verify_result
.cert_status
);
1147 TestRootCerts::GetInstance()->Clear();
1148 EXPECT_TRUE(TestRootCerts::GetInstance()->IsEmpty());
1152 #if defined(USE_NSS) || defined(OS_IOS) || defined(OS_WIN) || defined(OS_MACOSX)
1153 static const uint8 kCRLSetLeafSPKIBlocked
[] = {
1154 0x8e, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
1155 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
1156 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
1157 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
1158 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
1159 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
1160 0x30, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
1161 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x43, 0x38, 0x4d, 0x4a, 0x46, 0x55, 0x55,
1162 0x5a, 0x38, 0x43, 0x79, 0x54, 0x2b, 0x4e, 0x57, 0x64, 0x68, 0x69, 0x7a, 0x51,
1163 0x68, 0x54, 0x49, 0x65, 0x46, 0x49, 0x37, 0x76, 0x41, 0x77, 0x7a, 0x64, 0x54,
1164 0x79, 0x52, 0x59, 0x45, 0x6e, 0x78, 0x6c, 0x33, 0x62, 0x67, 0x3d, 0x22, 0x5d,
1168 static const uint8 kCRLSetLeafSerialBlocked
[] = {
1169 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
1170 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
1171 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
1172 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
1173 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
1174 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
1175 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
1176 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x0f, 0x87, 0xe4, 0xc7, 0x75, 0xea,
1177 0x46, 0x7e, 0xf3, 0xfd, 0x82, 0xb7, 0x46, 0x7b, 0x10, 0xda, 0xc5, 0xbf, 0xd8,
1178 0xd1, 0x29, 0xb2, 0xc6, 0xac, 0x7f, 0x51, 0x42, 0x15, 0x28, 0x51, 0x06, 0x7f,
1179 0x01, 0x00, 0x00, 0x00, // number of serials
1180 0x01, 0xed, // serial 0xed
1183 static const uint8 kCRLSetQUICSerialBlocked
[] = {
1184 0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
1185 0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
1186 0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
1187 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
1188 0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
1189 0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
1190 0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
1191 0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d,
1192 // Issuer SPKI SHA-256 hash:
1193 0xe4, 0x3a, 0xa3, 0xdb, 0x98, 0x31, 0x61, 0x05, 0xdd, 0x57, 0x6d, 0xc6, 0x2f,
1194 0x71, 0x26, 0xba, 0xdd, 0xf4, 0x98, 0x3e, 0x62, 0x22, 0xf8, 0xf9, 0xe4, 0x18,
1195 0x62, 0x77, 0x79, 0xdb, 0x9b, 0x31,
1196 0x01, 0x00, 0x00, 0x00, // number of serials
1197 0x01, 0x03, // serial 3
1200 // Test that CRLSets are effective in making a certificate appear to be
1202 TEST_F(CertVerifyProcTest
, CRLSet
) {
1203 CertificateList ca_cert_list
=
1204 CreateCertificateListFromFile(GetTestCertsDirectory(),
1206 X509Certificate::FORMAT_AUTO
);
1207 ASSERT_EQ(1U, ca_cert_list
.size());
1208 ScopedTestRoot
test_root(ca_cert_list
[0].get());
1210 CertificateList cert_list
= CreateCertificateListFromFile(
1211 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO
);
1212 ASSERT_EQ(1U, cert_list
.size());
1213 scoped_refptr
<X509Certificate
> cert(cert_list
[0]);
1216 CertVerifyResult verify_result
;
1218 cert
.get(), "127.0.0.1", flags
, NULL
, empty_cert_list_
, &verify_result
);
1219 EXPECT_EQ(OK
, error
);
1220 EXPECT_EQ(0U, verify_result
.cert_status
);
1222 // First test blocking by SPKI.
1223 base::StringPiece
crl_set_bytes(
1224 reinterpret_cast<const char*>(kCRLSetLeafSPKIBlocked
),
1225 sizeof(kCRLSetLeafSPKIBlocked
));
1226 scoped_refptr
<CRLSet
> crl_set
;
1227 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes
, &crl_set
));
1229 error
= Verify(cert
.get(),
1235 EXPECT_EQ(ERR_CERT_REVOKED
, error
);
1237 // Second, test revocation by serial number of a cert directly under the
1240 base::StringPiece(reinterpret_cast<const char*>(kCRLSetLeafSerialBlocked
),
1241 sizeof(kCRLSetLeafSerialBlocked
));
1242 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes
, &crl_set
));
1244 error
= Verify(cert
.get(),
1250 EXPECT_EQ(ERR_CERT_REVOKED
, error
);
1253 TEST_F(CertVerifyProcTest
, CRLSetLeafSerial
) {
1254 CertificateList ca_cert_list
=
1255 CreateCertificateListFromFile(GetTestCertsDirectory(),
1257 X509Certificate::FORMAT_AUTO
);
1258 ASSERT_EQ(1U, ca_cert_list
.size());
1259 ScopedTestRoot
test_root(ca_cert_list
[0].get());
1261 CertificateList intermediate_cert_list
=
1262 CreateCertificateListFromFile(GetTestCertsDirectory(),
1263 "quic_intermediate.crt",
1264 X509Certificate::FORMAT_AUTO
);
1265 ASSERT_EQ(1U, intermediate_cert_list
.size());
1266 X509Certificate::OSCertHandles intermediates
;
1267 intermediates
.push_back(intermediate_cert_list
[0]->os_cert_handle());
1269 CertificateList cert_list
= CreateCertificateListFromFile(
1270 GetTestCertsDirectory(), "quic_test.example.com.crt",
1271 X509Certificate::FORMAT_AUTO
);
1272 ASSERT_EQ(1U, cert_list
.size());
1274 scoped_refptr
<X509Certificate
> leaf
=
1275 X509Certificate::CreateFromHandle(cert_list
[0]->os_cert_handle(),
1279 CertVerifyResult verify_result
;
1280 int error
= Verify(leaf
.get(),
1286 EXPECT_EQ(OK
, error
);
1287 EXPECT_EQ(0U, verify_result
.cert_status
);
1289 // Test revocation by serial number of a certificate not under the root.
1290 scoped_refptr
<CRLSet
> crl_set
;
1291 base::StringPiece crl_set_bytes
=
1292 base::StringPiece(reinterpret_cast<const char*>(kCRLSetQUICSerialBlocked
),
1293 sizeof(kCRLSetQUICSerialBlocked
));
1294 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes
, &crl_set
));
1296 error
= Verify(leaf
.get(),
1302 EXPECT_EQ(ERR_CERT_REVOKED
, error
);
1306 struct WeakDigestTestData
{
1307 const char* root_cert_filename
;
1308 const char* intermediate_cert_filename
;
1309 const char* ee_cert_filename
;
1310 bool expected_has_md5
;
1311 bool expected_has_md4
;
1312 bool expected_has_md2
;
1315 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
1316 // to output the parameter that was passed. Without this, it will simply
1317 // attempt to print out the first twenty bytes of the object, which depending
1318 // on platform and alignment, may result in an invalid read.
1319 void PrintTo(const WeakDigestTestData
& data
, std::ostream
* os
) {
1321 << (data
.root_cert_filename
? data
.root_cert_filename
: "none")
1322 << "; intermediate: " << data
.intermediate_cert_filename
1323 << "; end-entity: " << data
.ee_cert_filename
;
1326 class CertVerifyProcWeakDigestTest
1327 : public CertVerifyProcTest
,
1328 public testing::WithParamInterface
<WeakDigestTestData
> {
1330 CertVerifyProcWeakDigestTest() {}
1331 virtual ~CertVerifyProcWeakDigestTest() {}
1334 TEST_P(CertVerifyProcWeakDigestTest
, Verify
) {
1335 WeakDigestTestData data
= GetParam();
1336 base::FilePath certs_dir
= GetTestCertsDirectory();
1338 ScopedTestRoot test_root
;
1339 if (data
.root_cert_filename
) {
1340 scoped_refptr
<X509Certificate
> root_cert
=
1341 ImportCertFromFile(certs_dir
, data
.root_cert_filename
);
1342 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), root_cert
.get());
1343 test_root
.Reset(root_cert
.get());
1346 scoped_refptr
<X509Certificate
> intermediate_cert
=
1347 ImportCertFromFile(certs_dir
, data
.intermediate_cert_filename
);
1348 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), intermediate_cert
.get());
1349 scoped_refptr
<X509Certificate
> ee_cert
=
1350 ImportCertFromFile(certs_dir
, data
.ee_cert_filename
);
1351 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), ee_cert
.get());
1353 X509Certificate::OSCertHandles intermediates
;
1354 intermediates
.push_back(intermediate_cert
->os_cert_handle());
1356 scoped_refptr
<X509Certificate
> ee_chain
=
1357 X509Certificate::CreateFromHandle(ee_cert
->os_cert_handle(),
1359 ASSERT_NE(static_cast<X509Certificate
*>(NULL
), ee_chain
.get());
1362 CertVerifyResult verify_result
;
1363 int rv
= Verify(ee_chain
.get(),
1369 EXPECT_EQ(data
.expected_has_md5
, verify_result
.has_md5
);
1370 EXPECT_EQ(data
.expected_has_md4
, verify_result
.has_md4
);
1371 EXPECT_EQ(data
.expected_has_md2
, verify_result
.has_md2
);
1372 EXPECT_FALSE(verify_result
.is_issued_by_additional_trust_anchor
);
1374 // Ensure that MD4 and MD2 are tagged as invalid.
1375 if (data
.expected_has_md4
|| data
.expected_has_md2
) {
1376 EXPECT_EQ(CERT_STATUS_INVALID
,
1377 verify_result
.cert_status
& CERT_STATUS_INVALID
);
1380 // Ensure that MD5 is flagged as weak.
1381 if (data
.expected_has_md5
) {
1383 CERT_STATUS_WEAK_SIGNATURE_ALGORITHM
,
1384 verify_result
.cert_status
& CERT_STATUS_WEAK_SIGNATURE_ALGORITHM
);
1387 // If a root cert is present, then check that the chain was rejected if any
1388 // weak algorithms are present. This is only checked when a root cert is
1389 // present because the error reported for incomplete chains with weak
1390 // algorithms depends on which implementation was used to validate (NSS,
1391 // OpenSSL, CryptoAPI, Security.framework) and upon which weak algorithm
1392 // present (MD2, MD4, MD5).
1393 if (data
.root_cert_filename
) {
1394 if (data
.expected_has_md4
|| data
.expected_has_md2
) {
1395 EXPECT_EQ(ERR_CERT_INVALID
, rv
);
1396 } else if (data
.expected_has_md5
) {
1397 EXPECT_EQ(ERR_CERT_WEAK_SIGNATURE_ALGORITHM
, rv
);
1404 // Unlike TEST/TEST_F, which are macros that expand to further macros,
1405 // INSTANTIATE_TEST_CASE_P is a macro that expands directly to code that
1406 // stringizes the arguments. As a result, macros passed as parameters (such as
1407 // prefix or test_case_name) will not be expanded by the preprocessor. To work
1408 // around this, indirect the macro for INSTANTIATE_TEST_CASE_P, so that the
1409 // pre-processor will expand macros such as MAYBE_test_name before
1410 // instantiating the test.
1411 #define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
1412 INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator)
1414 // The signature algorithm of the root CA should not matter.
1415 const WeakDigestTestData kVerifyRootCATestData
[] = {
1416 { "weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem",
1417 "weak_digest_sha1_ee.pem", false, false, false },
1418 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1419 // MD4 is not supported by OS X / NSS
1420 { "weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem",
1421 "weak_digest_sha1_ee.pem", false, false, false },
1423 { "weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem",
1424 "weak_digest_sha1_ee.pem", false, false, false },
1426 INSTANTIATE_TEST_CASE_P(VerifyRoot
, CertVerifyProcWeakDigestTest
,
1427 testing::ValuesIn(kVerifyRootCATestData
));
1429 // The signature algorithm of intermediates should be properly detected.
1430 const WeakDigestTestData kVerifyIntermediateCATestData
[] = {
1431 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
1432 "weak_digest_sha1_ee.pem", true, false, false },
1433 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1434 // MD4 is not supported by OS X / NSS
1435 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
1436 "weak_digest_sha1_ee.pem", false, true, false },
1438 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
1439 "weak_digest_sha1_ee.pem", false, false, true },
1441 // Disabled on NSS - MD4 is not supported, and MD2 and MD5 are disabled.
1442 #if defined(USE_NSS) || defined(OS_IOS)
1443 #define MAYBE_VerifyIntermediate DISABLED_VerifyIntermediate
1445 #define MAYBE_VerifyIntermediate VerifyIntermediate
1447 WRAPPED_INSTANTIATE_TEST_CASE_P(
1448 MAYBE_VerifyIntermediate
,
1449 CertVerifyProcWeakDigestTest
,
1450 testing::ValuesIn(kVerifyIntermediateCATestData
));
1452 // The signature algorithm of end-entity should be properly detected.
1453 const WeakDigestTestData kVerifyEndEntityTestData
[] = {
1454 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1455 "weak_digest_md5_ee.pem", true, false, false },
1456 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1457 // MD4 is not supported by OS X / NSS
1458 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1459 "weak_digest_md4_ee.pem", false, true, false },
1461 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1462 "weak_digest_md2_ee.pem", false, false, true },
1464 // Disabled on NSS - NSS caches chains/signatures in such a way that cannot
1465 // be cleared until NSS is cleanly shutdown, which is not presently supported
1467 #if defined(USE_NSS) || defined(OS_IOS)
1468 #define MAYBE_VerifyEndEntity DISABLED_VerifyEndEntity
1470 #define MAYBE_VerifyEndEntity VerifyEndEntity
1472 WRAPPED_INSTANTIATE_TEST_CASE_P(MAYBE_VerifyEndEntity
,
1473 CertVerifyProcWeakDigestTest
,
1474 testing::ValuesIn(kVerifyEndEntityTestData
));
1476 // Incomplete chains should still report the status of the intermediate.
1477 const WeakDigestTestData kVerifyIncompleteIntermediateTestData
[] = {
1478 { NULL
, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem",
1479 true, false, false },
1480 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1481 // MD4 is not supported by OS X / NSS
1482 { NULL
, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem",
1483 false, true, false },
1485 { NULL
, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem",
1486 false, false, true },
1488 // Disabled on NSS - libpkix does not return constructed chains on error,
1489 // preventing us from detecting/inspecting the verified chain.
1490 #if defined(USE_NSS) || defined(OS_IOS)
1491 #define MAYBE_VerifyIncompleteIntermediate \
1492 DISABLED_VerifyIncompleteIntermediate
1494 #define MAYBE_VerifyIncompleteIntermediate VerifyIncompleteIntermediate
1496 WRAPPED_INSTANTIATE_TEST_CASE_P(
1497 MAYBE_VerifyIncompleteIntermediate
,
1498 CertVerifyProcWeakDigestTest
,
1499 testing::ValuesIn(kVerifyIncompleteIntermediateTestData
));
1501 // Incomplete chains should still report the status of the end-entity.
1502 const WeakDigestTestData kVerifyIncompleteEETestData
[] = {
1503 { NULL
, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem",
1504 true, false, false },
1505 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1506 // MD4 is not supported by OS X / NSS
1507 { NULL
, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem",
1508 false, true, false },
1510 { NULL
, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem",
1511 false, false, true },
1513 // Disabled on NSS - libpkix does not return constructed chains on error,
1514 // preventing us from detecting/inspecting the verified chain.
1515 #if defined(USE_NSS) || defined(OS_IOS)
1516 #define MAYBE_VerifyIncompleteEndEntity DISABLED_VerifyIncompleteEndEntity
1518 #define MAYBE_VerifyIncompleteEndEntity VerifyIncompleteEndEntity
1520 WRAPPED_INSTANTIATE_TEST_CASE_P(
1521 MAYBE_VerifyIncompleteEndEntity
,
1522 CertVerifyProcWeakDigestTest
,
1523 testing::ValuesIn(kVerifyIncompleteEETestData
));
1525 // Differing algorithms between the intermediate and the EE should still be
1527 const WeakDigestTestData kVerifyMixedTestData
[] = {
1528 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
1529 "weak_digest_md2_ee.pem", true, false, true },
1530 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
1531 "weak_digest_md5_ee.pem", true, false, true },
1532 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1533 // MD4 is not supported by OS X / NSS
1534 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
1535 "weak_digest_md2_ee.pem", false, true, true },
1538 // NSS does not support MD4 and does not enable MD2 by default, making all
1539 // permutations invalid.
1540 #if defined(USE_NSS) || defined(OS_IOS)
1541 #define MAYBE_VerifyMixed DISABLED_VerifyMixed
1543 #define MAYBE_VerifyMixed VerifyMixed
1545 WRAPPED_INSTANTIATE_TEST_CASE_P(
1547 CertVerifyProcWeakDigestTest
,
1548 testing::ValuesIn(kVerifyMixedTestData
));
1550 // For the list of valid hostnames, see
1551 // net/cert/data/ssl/certificates/subjectAltName_sanity_check.pem
1552 static const struct CertVerifyProcNameData
{
1553 const char* hostname
;
1554 bool valid
; // Whether or not |hostname| matches a subjectAltName.
1555 } kVerifyNameData
[] = {
1556 { "127.0.0.1", false }, // Don't match the common name
1557 { "127.0.0.2", true }, // Matches the iPAddress SAN (IPv4)
1558 { "FE80:0:0:0:0:0:0:1", true }, // Matches the iPAddress SAN (IPv6)
1559 { "[FE80:0:0:0:0:0:0:1]", false }, // Should not match the iPAddress SAN
1560 { "FE80::1", true }, // Compressed form matches the iPAddress SAN (IPv6)
1561 { "::127.0.0.2", false }, // IPv6 mapped form should NOT match iPAddress SAN
1562 { "test.example", true }, // Matches the dNSName SAN
1563 { "test.example.", true }, // Matches the dNSName SAN (trailing . ignored)
1564 { "www.test.example", false }, // Should not match the dNSName SAN
1565 { "test..example", false }, // Should not match the dNSName SAN
1566 { "test.example..", false }, // Should not match the dNSName SAN
1567 { ".test.example.", false }, // Should not match the dNSName SAN
1568 { ".test.example", false }, // Should not match the dNSName SAN
1571 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
1572 // to output the parameter that was passed. Without this, it will simply
1573 // attempt to print out the first twenty bytes of the object, which depending
1574 // on platform and alignment, may result in an invalid read.
1575 void PrintTo(const CertVerifyProcNameData
& data
, std::ostream
* os
) {
1576 *os
<< "Hostname: " << data
.hostname
<< "; valid=" << data
.valid
;
1579 class CertVerifyProcNameTest
1580 : public CertVerifyProcTest
,
1581 public testing::WithParamInterface
<CertVerifyProcNameData
> {
1583 CertVerifyProcNameTest() {}
1584 virtual ~CertVerifyProcNameTest() {}
1587 TEST_P(CertVerifyProcNameTest
, VerifyCertName
) {
1588 CertVerifyProcNameData data
= GetParam();
1590 CertificateList cert_list
= CreateCertificateListFromFile(
1591 GetTestCertsDirectory(), "subjectAltName_sanity_check.pem",
1592 X509Certificate::FORMAT_AUTO
);
1593 ASSERT_EQ(1U, cert_list
.size());
1594 scoped_refptr
<X509Certificate
> cert(cert_list
[0]);
1596 ScopedTestRoot
scoped_root(cert
.get());
1598 CertVerifyResult verify_result
;
1599 int error
= Verify(cert
.get(), data
.hostname
, 0, NULL
, empty_cert_list_
,
1602 EXPECT_EQ(OK
, error
);
1603 EXPECT_FALSE(verify_result
.cert_status
& CERT_STATUS_COMMON_NAME_INVALID
);
1605 EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID
, error
);
1606 EXPECT_TRUE(verify_result
.cert_status
& CERT_STATUS_COMMON_NAME_INVALID
);
1610 WRAPPED_INSTANTIATE_TEST_CASE_P(
1612 CertVerifyProcNameTest
,
1613 testing::ValuesIn(kVerifyNameData
));