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