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