Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: net/cert/cert_verify_proc_mac_unittest.cc

Issue 2670643008: Move CertVerifyProcMac unit-tests to their own file. (Closed)
Patch Set: Rebase + add missing include Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/cert/cert_verify_proc_mac.h ('k') | net/cert/cert_verify_proc_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/cert/cert_verify_proc.h" 5 #include "net/cert/cert_verify_proc_mac.h"
6 6
7 #include <vector>
8
9 #include "base/callback_helpers.h"
10 #include "base/files/file_path.h" 7 #include "base/files/file_path.h"
11 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
12 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/mac/mac_util.h"
13 #include "base/macros.h" 11 #include "base/macros.h"
14 #include "base/sha1.h" 12 #include "base/memory/ptr_util.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/test/histogram_tester.h"
17 #include "base/test/scoped_feature_list.h"
18 #include "build/build_config.h"
19 #include "crypto/sha2.h"
20 #include "net/base/net_errors.h" 13 #include "net/base/net_errors.h"
21 #include "net/cert/asn1_util.h"
22 #include "net/cert/cert_status_flags.h"
23 #include "net/cert/cert_verifier.h" 14 #include "net/cert/cert_verifier.h"
24 #include "net/cert/cert_verify_result.h" 15 #include "net/cert/cert_verify_result.h"
25 #include "net/cert/crl_set.h" 16 #include "net/cert/crl_set.h"
26 #include "net/cert/crl_set_storage.h" 17 #include "net/cert/crl_set_storage.h"
18 #include "net/cert/test_keychain_search_list_mac.h"
27 #include "net/cert/test_root_certs.h" 19 #include "net/cert/test_root_certs.h"
28 #include "net/cert/x509_certificate.h" 20 #include "net/cert/x509_certificate.h"
29 #include "net/test/cert_test_util.h" 21 #include "net/test/cert_test_util.h"
30 #include "net/test/gtest_util.h" 22 #include "net/test/gtest_util.h"
31 #include "net/test/test_certificate_data.h"
32 #include "net/test/test_data_directory.h" 23 #include "net/test/test_data_directory.h"
33 #include "testing/gmock/include/gmock/gmock.h" 24 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h" 25 #include "testing/gtest/include/gtest/gtest.h"
35 26
36 #if defined(OS_ANDROID)
37 #include "base/android/build_info.h"
38 #endif
39
40 #if defined(OS_MACOSX) && !defined(OS_IOS)
41 #include "base/mac/mac_util.h"
42 #include "net/cert/test_keychain_search_list_mac.h"
43 #endif
44
45 #if defined(OS_WIN)
46 #include "base/win/windows_version.h"
47 #endif
48
49 using net::test::IsError; 27 using net::test::IsError;
50 using net::test::IsOk; 28 using net::test::IsOk;
51 29
52 using base::HexEncode;
53
54 namespace net { 30 namespace net {
55 31
56 namespace { 32 namespace {
57 33
58 const char kTLSFeatureExtensionHistogram[] =
59 "Net.Certificate.TLSFeatureExtensionWithPrivateRoot";
60 const char kTLSFeatureExtensionOCSPHistogram[] =
61 "Net.Certificate.TLSFeatureExtensionWithPrivateRootHasOCSP";
62
63 // Mock CertVerifyProc that sets the CertVerifyResult to a given value for
64 // all certificates that are Verify()'d
65 class MockCertVerifyProc : public CertVerifyProc {
66 public:
67 explicit MockCertVerifyProc(const CertVerifyResult& result)
68 : result_(result) {}
69 // CertVerifyProc implementation:
70 bool SupportsAdditionalTrustAnchors() const override { return false; }
71 bool SupportsOCSPStapling() const override { return false; }
72
73 protected:
74 ~MockCertVerifyProc() override {}
75
76 private:
77 int VerifyInternal(X509Certificate* cert,
78 const std::string& hostname,
79 const std::string& ocsp_response,
80 int flags,
81 CRLSet* crl_set,
82 const CertificateList& additional_trust_anchors,
83 CertVerifyResult* verify_result) override;
84
85 const CertVerifyResult result_;
86
87 DISALLOW_COPY_AND_ASSIGN(MockCertVerifyProc);
88 };
89
90 int MockCertVerifyProc::VerifyInternal(
91 X509Certificate* cert,
92 const std::string& hostname,
93 const std::string& ocsp_response,
94 int flags,
95 CRLSet* crl_set,
96 const CertificateList& additional_trust_anchors,
97 CertVerifyResult* verify_result) {
98 *verify_result = result_;
99 verify_result->verified_cert = cert;
100 return OK;
101 }
102
103 // This enum identifies a concrete implemenation of CertVerifyProc.
104 //
105 // The type is erased by CertVerifyProc::CreateDefault(), however
106 // needs to be known for some of the test expectations.
107 enum CertVerifyProcType {
108 CERT_VERIFY_PROC_NSS,
109 CERT_VERIFY_PROC_OPENSSL,
110 CERT_VERIFY_PROC_ANDROID,
111 CERT_VERIFY_PROC_IOS,
112 CERT_VERIFY_PROC_MAC,
113 CERT_VERIFY_PROC_WIN,
114 };
115
116 // Returns the CertVerifyProcType corresponding to what
117 // CertVerifyProc::CreateDefault() returns. This needs to be kept in sync with
118 // CreateDefault().
119 CertVerifyProcType GetDefaultCertVerifyProcType() {
120 #if defined(USE_NSS_CERTS)
121 return CERT_VERIFY_PROC_NSS;
122 #elif defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
123 return CERT_VERIFY_PROC_OPENSSL;
124 #elif defined(OS_ANDROID)
125 return CERT_VERIFY_PROC_ANDROID;
126 #elif defined(OS_IOS)
127 return CERT_VERIFY_PROC_IOS;
128 #elif defined(OS_MACOSX)
129 return CERT_VERIFY_PROC_MAC;
130 #elif defined(OS_WIN)
131 return CERT_VERIFY_PROC_WIN;
132 #else
133 // Will fail to compile.
134 #endif
135 }
136
137 // Whether the test is running within the iphone simulator.
138 const bool kTargetIsIphoneSimulator =
139 #if TARGET_IPHONE_SIMULATOR
140 true;
141 #else
142 false;
143 #endif
144
145 // Template helper to load a series of certificate files into a CertificateList.
146 // Like CertTestUtil's CreateCertificateListFromFile, except it can load a
147 // series of individual certificates (to make the tests clearer).
148 template <size_t N>
149 void LoadCertificateFiles(const char* const (&cert_files)[N],
150 CertificateList* certs) {
151 certs->clear();
152 for (size_t i = 0; i < N; ++i) {
153 SCOPED_TRACE(cert_files[i]);
154 scoped_refptr<X509Certificate> cert = CreateCertificateChainFromFile(
155 GetTestCertsDirectory(), cert_files[i], X509Certificate::FORMAT_AUTO);
156 ASSERT_TRUE(cert);
157 certs->push_back(cert);
158 }
159 }
160
161 // Returns a textual description of the CertVerifyProc implementation
162 // that is being tested, used to give better names to parameterized
163 // tests.
164 std::string VerifyProcTypeToName(
165 const testing::TestParamInfo<CertVerifyProcType>& params) {
166 switch (params.param) {
167 case CERT_VERIFY_PROC_NSS:
168 return "CertVerifyProcNSS";
169 case CERT_VERIFY_PROC_OPENSSL:
170 return "CertVerifyProcOpenSSL";
171 case CERT_VERIFY_PROC_ANDROID:
172 return "CertVerifyProcAndroid";
173 case CERT_VERIFY_PROC_IOS:
174 return "CertVerifyProcIOS";
175 case CERT_VERIFY_PROC_MAC:
176 return "CertVerifyProcMac";
177 case CERT_VERIFY_PROC_WIN:
178 return "CertVerifyProcWin";
179 }
180
181 return nullptr;
182 }
183
184 // The set of all CertVerifyProcTypes that tests should be
185 // parameterized on.
186 const std::vector<CertVerifyProcType> kAllCertVerifiers = {
187 GetDefaultCertVerifyProcType()};
188
189 } // namespace
190
191 // This fixture is for tests that apply to concrete implementations of
192 // CertVerifyProc. It will be run for all of the concrete
193 // CertVerifyProc types.
194 //
195 // It is called "Internal" as it tests the internal methods like
196 // "VerifyInternal()".
197 class CertVerifyProcInternalTest
198 : public testing::TestWithParam<CertVerifyProcType> {
199 protected:
200 void SetUp() override {
201 EXPECT_EQ(verify_proc_type(), GetDefaultCertVerifyProcType());
202 verify_proc_ = CertVerifyProc::CreateDefault();
203 }
204
205 int Verify(X509Certificate* cert,
206 const std::string& hostname,
207 int flags,
208 CRLSet* crl_set,
209 const CertificateList& additional_trust_anchors,
210 CertVerifyResult* verify_result) {
211 return verify_proc_->Verify(cert, hostname, std::string(), flags, crl_set,
212 additional_trust_anchors, verify_result);
213 }
214
215 CertVerifyProcType verify_proc_type() const { return GetParam(); }
216
217 bool SupportsAdditionalTrustAnchors() const {
218 return verify_proc_->SupportsAdditionalTrustAnchors();
219 }
220
221 bool SupportsReturningVerifiedChain() const {
222 #if defined(OS_ANDROID)
223 // Before API level 17, Android does not expose the APIs necessary to get at
224 // the verified certificate chain.
225 if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID &&
226 base::android::BuildInfo::GetInstance()->sdk_int() < 17)
227 return false;
228 #endif
229 return true;
230 }
231
232 bool SupportsDetectingKnownRoots() const {
233 #if defined(OS_ANDROID)
234 // Before API level 17, Android does not expose the APIs necessary to get at
235 // the verified certificate chain and detect known roots.
236 if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID)
237 return base::android::BuildInfo::GetInstance()->sdk_int() >= 17;
238 #endif
239
240 // iOS does not expose the APIs necessary to get the known system roots.
241 if (verify_proc_type() == CERT_VERIFY_PROC_IOS)
242 return false;
243
244 return true;
245 }
246
247 bool WeakKeysAreInvalid() const {
248 #if defined(OS_MACOSX) && !defined(OS_IOS)
249 // Starting with Mac OS 10.12, certs with weak keys are treated as
250 // (recoverable) invalid certificate errors.
251 if (verify_proc_type() == CERT_VERIFY_PROC_MAC &&
252 base::mac::IsAtLeastOS10_12()) {
253 return true;
254 }
255 #endif
256 return false;
257 }
258
259 bool SupportsCRLSet() const {
260 return verify_proc_type() == CERT_VERIFY_PROC_NSS ||
261 verify_proc_type() == CERT_VERIFY_PROC_WIN ||
262 verify_proc_type() == CERT_VERIFY_PROC_MAC;
263 }
264
265 bool SupportsCRLSetsInPathBuilding() const {
266 return verify_proc_type() == CERT_VERIFY_PROC_WIN ||
267 verify_proc_type() == CERT_VERIFY_PROC_NSS;
268 }
269
270 CertVerifyProc* verify_proc() const { return verify_proc_.get(); }
271
272 private:
273 scoped_refptr<CertVerifyProc> verify_proc_;
274 };
275
276 INSTANTIATE_TEST_CASE_P(,
277 CertVerifyProcInternalTest,
278 testing::ValuesIn(kAllCertVerifiers),
279 VerifyProcTypeToName);
280
281 // TODO(rsleevi): Reenable this test once comodo.chaim.pem is no longer
282 // expired, http://crbug.com/502818
283 TEST_P(CertVerifyProcInternalTest, DISABLED_EVVerification) {
284 if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID ||
285 verify_proc_type() == CERT_VERIFY_PROC_OPENSSL) {
286 // TODO(jnd): http://crbug.com/117478 - EV verification is not yet
287 // supported.
288 LOG(INFO) << "Skipping test as EV verification is not yet supported";
289 return;
290 }
291
292 CertificateList certs =
293 CreateCertificateListFromFile(GetTestCertsDirectory(), "comodo.chain.pem",
294 X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
295 ASSERT_EQ(3U, certs.size());
296
297 X509Certificate::OSCertHandles intermediates;
298 intermediates.push_back(certs[1]->os_cert_handle());
299 intermediates.push_back(certs[2]->os_cert_handle());
300
301 scoped_refptr<X509Certificate> comodo_chain =
302 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
303 intermediates);
304
305 scoped_refptr<CRLSet> crl_set(CRLSet::ForTesting(false, NULL, ""));
306 CertVerifyResult verify_result;
307 int flags = CertVerifier::VERIFY_EV_CERT;
308 int error = Verify(comodo_chain.get(), "comodo.com", flags, crl_set.get(),
309 CertificateList(), &verify_result);
310 EXPECT_THAT(error, IsOk());
311 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
312 }
313
314 // TODO(crbug.com/605457): the test expectation was incorrect on some
315 // configurations, so disable the test until it is fixed (better to have
316 // a bug to track a failing test than a false sense of security due to
317 // false positive).
318 TEST_P(CertVerifyProcInternalTest, DISABLED_PaypalNullCertParsing) {
319 // A certificate for www.paypal.com with a NULL byte in the common name.
320 // From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363
321 SHA256HashValue paypal_null_fingerprint = {{0x00}};
322
323 scoped_refptr<X509Certificate> paypal_null_cert(
324 X509Certificate::CreateFromBytes(
325 reinterpret_cast<const char*>(paypal_null_der),
326 sizeof(paypal_null_der)));
327
328 ASSERT_NE(static_cast<X509Certificate*>(NULL), paypal_null_cert.get());
329
330 EXPECT_EQ(paypal_null_fingerprint, X509Certificate::CalculateFingerprint256(
331 paypal_null_cert->os_cert_handle()));
332
333 int flags = 0;
334 CertVerifyResult verify_result;
335 int error = Verify(paypal_null_cert.get(), "www.paypal.com", flags, NULL,
336 CertificateList(), &verify_result);
337
338 if (verify_proc_type() == CERT_VERIFY_PROC_NSS ||
339 verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
340 EXPECT_THAT(error, IsError(ERR_CERT_COMMON_NAME_INVALID));
341 } else if (verify_proc_type() == CERT_VERIFY_PROC_IOS &&
342 kTargetIsIphoneSimulator) {
343 // iOS returns a ERR_CERT_INVALID error on the simulator, while returning
344 // ERR_CERT_AUTHORITY_INVALID on the real device.
345 EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
346 } else {
347 // TOOD(bulach): investigate why macosx and win aren't returning
348 // ERR_CERT_INVALID or ERR_CERT_COMMON_NAME_INVALID.
349 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
350 }
351
352 // Either the system crypto library should correctly report a certificate
353 // name mismatch, or our certificate blacklist should cause us to report an
354 // invalid certificate.
355 if (verify_proc_type() == CERT_VERIFY_PROC_NSS ||
356 verify_proc_type() == CERT_VERIFY_PROC_WIN) {
357 EXPECT_TRUE(verify_result.cert_status &
358 (CERT_STATUS_COMMON_NAME_INVALID | CERT_STATUS_INVALID));
359 }
360
361 // TODO(crbug.com/649017): What expectations to use for the other verifiers?
362 }
363
364 // A regression test for http://crbug.com/31497.
365 TEST_P(CertVerifyProcInternalTest, IntermediateCARequireExplicitPolicy) {
366 if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID) {
367 // Disabled on Android, as the Android verification libraries require an
368 // explicit policy to be specified, even when anyPolicy is permitted.
369 LOG(INFO) << "Skipping test on Android";
370 return;
371 }
372
373 base::FilePath certs_dir = GetTestCertsDirectory();
374
375 CertificateList certs = CreateCertificateListFromFile(
376 certs_dir, "explicit-policy-chain.pem", X509Certificate::FORMAT_AUTO);
377 ASSERT_EQ(3U, certs.size());
378
379 X509Certificate::OSCertHandles intermediates;
380 intermediates.push_back(certs[1]->os_cert_handle());
381
382 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
383 certs[0]->os_cert_handle(), intermediates);
384 ASSERT_TRUE(cert.get());
385
386 ScopedTestRoot scoped_root(certs[2].get());
387
388 int flags = 0;
389 CertVerifyResult verify_result;
390 int error = Verify(cert.get(), "policy_test.example", flags, NULL,
391 CertificateList(), &verify_result);
392 EXPECT_THAT(error, IsOk());
393 EXPECT_EQ(0u, verify_result.cert_status);
394 }
395
396 TEST_P(CertVerifyProcInternalTest, RejectExpiredCert) {
397 base::FilePath certs_dir = GetTestCertsDirectory();
398
399 // Load root_ca_cert.pem into the test root store.
400 ScopedTestRoot test_root(
401 ImportCertFromFile(certs_dir, "root_ca_cert.pem").get());
402
403 CertificateList certs = CreateCertificateListFromFile(
404 certs_dir, "expired_cert.pem", X509Certificate::FORMAT_AUTO);
405 ASSERT_EQ(1U, certs.size());
406
407 X509Certificate::OSCertHandles intermediates;
408 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
409 certs[0]->os_cert_handle(), intermediates);
410
411 int flags = 0;
412 CertVerifyResult verify_result;
413 int error = Verify(cert.get(), "127.0.0.1", flags, NULL, CertificateList(),
414 &verify_result);
415 EXPECT_THAT(error, IsError(ERR_CERT_DATE_INVALID));
416 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_DATE_INVALID);
417 }
418
419 // Currently, only RSA and DSA keys are checked for weakness, and our example
420 // weak size is 768. These could change in the future.
421 //
422 // Note that this means there may be false negatives: keys for other
423 // algorithms and which are weak will pass this test.
424 static bool IsWeakKeyType(const std::string& key_type) {
425 size_t pos = key_type.find("-");
426 std::string size = key_type.substr(0, pos);
427 std::string type = key_type.substr(pos + 1);
428
429 if (type == "rsa" || type == "dsa")
430 return size == "768";
431
432 return false;
433 }
434
435 TEST_P(CertVerifyProcInternalTest, RejectWeakKeys) {
436 base::FilePath certs_dir = GetTestCertsDirectory();
437 typedef std::vector<std::string> Strings;
438 Strings key_types;
439
440 // generate-weak-test-chains.sh currently has:
441 // key_types="768-rsa 1024-rsa 2048-rsa prime256v1-ecdsa"
442 // We must use the same key types here. The filenames generated look like:
443 // 2048-rsa-ee-by-768-rsa-intermediate.pem
444 key_types.push_back("768-rsa");
445 key_types.push_back("1024-rsa");
446 key_types.push_back("2048-rsa");
447 key_types.push_back("prime256v1-ecdsa");
448
449 // Add the root that signed the intermediates for this test.
450 scoped_refptr<X509Certificate> root_cert =
451 ImportCertFromFile(certs_dir, "2048-rsa-root.pem");
452 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert.get());
453 ScopedTestRoot scoped_root(root_cert.get());
454
455 // Now test each chain.
456 for (Strings::const_iterator ee_type = key_types.begin();
457 ee_type != key_types.end(); ++ee_type) {
458 for (Strings::const_iterator signer_type = key_types.begin();
459 signer_type != key_types.end(); ++signer_type) {
460 std::string basename =
461 *ee_type + "-ee-by-" + *signer_type + "-intermediate.pem";
462 SCOPED_TRACE(basename);
463 scoped_refptr<X509Certificate> ee_cert =
464 ImportCertFromFile(certs_dir, basename);
465 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert.get());
466
467 basename = *signer_type + "-intermediate.pem";
468 scoped_refptr<X509Certificate> intermediate =
469 ImportCertFromFile(certs_dir, basename);
470 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate.get());
471
472 X509Certificate::OSCertHandles intermediates;
473 intermediates.push_back(intermediate->os_cert_handle());
474 scoped_refptr<X509Certificate> cert_chain =
475 X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(),
476 intermediates);
477
478 CertVerifyResult verify_result;
479 int error = Verify(cert_chain.get(), "127.0.0.1", 0, NULL,
480 CertificateList(), &verify_result);
481
482 if (IsWeakKeyType(*ee_type) || IsWeakKeyType(*signer_type)) {
483 EXPECT_NE(OK, error);
484 EXPECT_EQ(CERT_STATUS_WEAK_KEY,
485 verify_result.cert_status & CERT_STATUS_WEAK_KEY);
486 EXPECT_EQ(WeakKeysAreInvalid() ? CERT_STATUS_INVALID : 0,
487 verify_result.cert_status & CERT_STATUS_INVALID);
488 } else {
489 EXPECT_THAT(error, IsOk());
490 EXPECT_EQ(0U, verify_result.cert_status & CERT_STATUS_WEAK_KEY);
491 }
492 }
493 }
494 }
495
496 // Regression test for http://crbug.com/108514.
497 TEST_P(CertVerifyProcInternalTest, ExtraneousMD5RootCert) {
498 if (!SupportsReturningVerifiedChain()) {
499 LOG(INFO) << "Skipping this test in this platform.";
500 return;
501 }
502
503 if (verify_proc_type() == CERT_VERIFY_PROC_MAC) {
504 // Disabled on OS X - Security.framework doesn't ignore superflous
505 // certificates provided by servers.
506 // TODO(eroman): Is this still needed?
507 LOG(INFO) << "Skipping this test as Security.framework doesn't ignore "
508 "superflous certificates provided by servers.";
509 return;
510 }
511
512 base::FilePath certs_dir = GetTestCertsDirectory();
513
514 scoped_refptr<X509Certificate> server_cert =
515 ImportCertFromFile(certs_dir, "cross-signed-leaf.pem");
516 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
517
518 scoped_refptr<X509Certificate> extra_cert =
519 ImportCertFromFile(certs_dir, "cross-signed-root-md5.pem");
520 ASSERT_NE(static_cast<X509Certificate*>(NULL), extra_cert.get());
521
522 scoped_refptr<X509Certificate> root_cert =
523 ImportCertFromFile(certs_dir, "cross-signed-root-sha256.pem");
524 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert.get());
525
526 ScopedTestRoot scoped_root(root_cert.get());
527
528 X509Certificate::OSCertHandles intermediates;
529 intermediates.push_back(extra_cert->os_cert_handle());
530 scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromHandle(
531 server_cert->os_cert_handle(), intermediates);
532
533 CertVerifyResult verify_result;
534 int flags = 0;
535 int error = Verify(cert_chain.get(), "127.0.0.1", flags, NULL,
536 CertificateList(), &verify_result);
537 EXPECT_THAT(error, IsOk());
538
539 // The extra MD5 root should be discarded
540 ASSERT_TRUE(verify_result.verified_cert.get());
541 ASSERT_EQ(1u,
542 verify_result.verified_cert->GetIntermediateCertificates().size());
543 EXPECT_TRUE(X509Certificate::IsSameOSCert(
544 verify_result.verified_cert->GetIntermediateCertificates().front(),
545 root_cert->os_cert_handle()));
546
547 EXPECT_FALSE(verify_result.has_md5);
548 }
549
550 // Test for bug 94673.
551 TEST_P(CertVerifyProcInternalTest, GoogleDigiNotarTest) {
552 base::FilePath certs_dir = GetTestCertsDirectory();
553
554 scoped_refptr<X509Certificate> server_cert =
555 ImportCertFromFile(certs_dir, "google_diginotar.pem");
556 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
557
558 scoped_refptr<X509Certificate> intermediate_cert =
559 ImportCertFromFile(certs_dir, "diginotar_public_ca_2025.pem");
560 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert.get());
561
562 X509Certificate::OSCertHandles intermediates;
563 intermediates.push_back(intermediate_cert->os_cert_handle());
564 scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromHandle(
565 server_cert->os_cert_handle(), intermediates);
566
567 CertVerifyResult verify_result;
568 int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED;
569 int error = Verify(cert_chain.get(), "mail.google.com", flags, NULL,
570 CertificateList(), &verify_result);
571 EXPECT_NE(OK, error);
572
573 // Now turn off revocation checking. Certificate verification should still
574 // fail.
575 flags = 0;
576 error = Verify(cert_chain.get(), "mail.google.com", flags, NULL,
577 CertificateList(), &verify_result);
578 EXPECT_NE(OK, error);
579 }
580
581 // Ensures the CertVerifyProc blacklist remains in sorted order, so that it
582 // can be binary-searched.
583 TEST(CertVerifyProcTest, BlacklistIsSorted) {
584 // Defines kBlacklistedSPKIs.
585 #include "net/cert/cert_verify_proc_blacklist.inc"
586 for (size_t i = 0; i < arraysize(kBlacklistedSPKIs) - 1; ++i) {
587 EXPECT_GT(0, memcmp(kBlacklistedSPKIs[i], kBlacklistedSPKIs[i + 1],
588 crypto::kSHA256Length))
589 << " at index " << i;
590 }
591 }
592
593 TEST(CertVerifyProcTest, DigiNotarCerts) {
594 static const char* const kDigiNotarFilenames[] = {
595 "diginotar_root_ca.pem", "diginotar_cyber_ca.pem",
596 "diginotar_services_1024_ca.pem", "diginotar_pkioverheid.pem",
597 "diginotar_pkioverheid_g2.pem", NULL,
598 };
599
600 base::FilePath certs_dir = GetTestCertsDirectory();
601
602 for (size_t i = 0; kDigiNotarFilenames[i]; i++) {
603 scoped_refptr<X509Certificate> diginotar_cert =
604 ImportCertFromFile(certs_dir, kDigiNotarFilenames[i]);
605 std::string der_bytes;
606 ASSERT_TRUE(X509Certificate::GetDEREncoded(diginotar_cert->os_cert_handle(),
607 &der_bytes));
608
609 base::StringPiece spki;
610 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_bytes, &spki));
611
612 std::string spki_sha256 = crypto::SHA256HashString(spki.as_string());
613
614 HashValueVector public_keys;
615 HashValue hash(HASH_VALUE_SHA256);
616 ASSERT_EQ(hash.size(), spki_sha256.size());
617 memcpy(hash.data(), spki_sha256.data(), spki_sha256.size());
618 public_keys.push_back(hash);
619
620 EXPECT_TRUE(CertVerifyProc::IsPublicKeyBlacklisted(public_keys))
621 << "Public key not blocked for " << kDigiNotarFilenames[i];
622 }
623 }
624
625 TEST_P(CertVerifyProcInternalTest, NameConstraintsOk) {
626 CertificateList ca_cert_list =
627 CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem",
628 X509Certificate::FORMAT_AUTO);
629 ASSERT_EQ(1U, ca_cert_list.size());
630 ScopedTestRoot test_root(ca_cert_list[0].get());
631
632 CertificateList cert_list = CreateCertificateListFromFile(
633 GetTestCertsDirectory(), "name_constraint_good.pem",
634 X509Certificate::FORMAT_AUTO);
635 ASSERT_EQ(1U, cert_list.size());
636
637 X509Certificate::OSCertHandles intermediates;
638 scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromHandle(
639 cert_list[0]->os_cert_handle(), intermediates);
640
641 int flags = 0;
642 CertVerifyResult verify_result;
643 int error = Verify(leaf.get(), "test.example.com", flags, NULL,
644 CertificateList(), &verify_result);
645 EXPECT_THAT(error, IsOk());
646 EXPECT_EQ(0U, verify_result.cert_status);
647
648 error = Verify(leaf.get(), "foo.test2.example.com", flags, NULL,
649 CertificateList(), &verify_result);
650 EXPECT_THAT(error, IsOk());
651 EXPECT_EQ(0U, verify_result.cert_status);
652 }
653
654 TEST_P(CertVerifyProcInternalTest, NameConstraintsFailure) {
655 if (!SupportsReturningVerifiedChain()) {
656 LOG(INFO) << "Skipping this test in this platform.";
657 return;
658 }
659
660 CertificateList ca_cert_list =
661 CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem",
662 X509Certificate::FORMAT_AUTO);
663 ASSERT_EQ(1U, ca_cert_list.size());
664 ScopedTestRoot test_root(ca_cert_list[0].get());
665
666 CertificateList cert_list = CreateCertificateListFromFile(
667 GetTestCertsDirectory(), "name_constraint_bad.pem",
668 X509Certificate::FORMAT_AUTO);
669 ASSERT_EQ(1U, cert_list.size());
670
671 X509Certificate::OSCertHandles intermediates;
672 scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromHandle(
673 cert_list[0]->os_cert_handle(), intermediates);
674
675 int flags = 0;
676 CertVerifyResult verify_result;
677 int error = Verify(leaf.get(), "test.example.com", flags, NULL,
678 CertificateList(), &verify_result);
679 EXPECT_THAT(error, IsError(ERR_CERT_NAME_CONSTRAINT_VIOLATION));
680 EXPECT_EQ(CERT_STATUS_NAME_CONSTRAINT_VIOLATION,
681 verify_result.cert_status & CERT_STATUS_NAME_CONSTRAINT_VIOLATION);
682 }
683
684 TEST(CertVerifyProcTest, TestHasTooLongValidity) {
685 struct {
686 const char* const file;
687 bool is_valid_too_long;
688 } tests[] = {
689 {"twitter-chain.pem", false},
690 {"start_after_expiry.pem", true},
691 {"pre_br_validity_ok.pem", false},
692 {"pre_br_validity_bad_121.pem", true},
693 {"pre_br_validity_bad_2020.pem", true},
694 {"10_year_validity.pem", false},
695 {"11_year_validity.pem", true},
696 {"39_months_after_2015_04.pem", false},
697 {"40_months_after_2015_04.pem", true},
698 {"60_months_after_2012_07.pem", false},
699 {"61_months_after_2012_07.pem", true},
700 };
701
702 base::FilePath certs_dir = GetTestCertsDirectory();
703
704 for (size_t i = 0; i < arraysize(tests); ++i) {
705 scoped_refptr<X509Certificate> certificate =
706 ImportCertFromFile(certs_dir, tests[i].file);
707 SCOPED_TRACE(tests[i].file);
708 ASSERT_TRUE(certificate);
709 EXPECT_EQ(tests[i].is_valid_too_long,
710 CertVerifyProc::HasTooLongValidity(*certificate));
711 }
712 }
713
714 // TODO(crbug.com/610546): Fix and re-enable this test.
715 TEST_P(CertVerifyProcInternalTest, DISABLED_TestKnownRoot) {
716 if (!SupportsDetectingKnownRoots()) {
717 LOG(INFO) << "Skipping this test on this platform.";
718 return;
719 }
720
721 base::FilePath certs_dir = GetTestCertsDirectory();
722 CertificateList certs = CreateCertificateListFromFile(
723 certs_dir, "twitter-chain.pem", X509Certificate::FORMAT_AUTO);
724 ASSERT_EQ(3U, certs.size());
725
726 X509Certificate::OSCertHandles intermediates;
727 intermediates.push_back(certs[1]->os_cert_handle());
728
729 scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromHandle(
730 certs[0]->os_cert_handle(), intermediates);
731
732 int flags = 0;
733 CertVerifyResult verify_result;
734 // This will blow up, May 9th, 2016. Sorry! Please disable and file a bug
735 // against agl. See also PublicKeyHashes.
736 int error = Verify(cert_chain.get(), "twitter.com", flags, NULL,
737 CertificateList(), &verify_result);
738 EXPECT_THAT(error, IsOk());
739 EXPECT_TRUE(verify_result.is_issued_by_known_root);
740 }
741
742 // TODO(crbug.com/610546): Fix and re-enable this test.
743 TEST_P(CertVerifyProcInternalTest, DISABLED_PublicKeyHashes) {
744 if (!SupportsReturningVerifiedChain()) {
745 LOG(INFO) << "Skipping this test in this platform.";
746 return;
747 }
748
749 base::FilePath certs_dir = GetTestCertsDirectory();
750 CertificateList certs = CreateCertificateListFromFile(
751 certs_dir, "twitter-chain.pem", X509Certificate::FORMAT_AUTO);
752 ASSERT_EQ(3U, certs.size());
753
754 X509Certificate::OSCertHandles intermediates;
755 intermediates.push_back(certs[1]->os_cert_handle());
756
757 scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromHandle(
758 certs[0]->os_cert_handle(), intermediates);
759 int flags = 0;
760 CertVerifyResult verify_result;
761
762 // This will blow up, May 9th, 2016. Sorry! Please disable and file a bug
763 // against agl. See also TestKnownRoot.
764 int error = Verify(cert_chain.get(), "twitter.com", flags, NULL,
765 CertificateList(), &verify_result);
766 EXPECT_THAT(error, IsOk());
767 ASSERT_LE(3U, verify_result.public_key_hashes.size());
768
769 HashValueVector sha1_hashes;
770 for (size_t i = 0; i < verify_result.public_key_hashes.size(); ++i) {
771 if (verify_result.public_key_hashes[i].tag != HASH_VALUE_SHA1)
772 continue;
773 sha1_hashes.push_back(verify_result.public_key_hashes[i]);
774 }
775 ASSERT_LE(3u, sha1_hashes.size());
776
777 for (size_t i = 0; i < 3; ++i) {
778 EXPECT_EQ(HexEncode(kTwitterSPKIs[i], base::kSHA1Length),
779 HexEncode(sha1_hashes[i].data(), base::kSHA1Length));
780 }
781
782 HashValueVector sha256_hashes;
783 for (size_t i = 0; i < verify_result.public_key_hashes.size(); ++i) {
784 if (verify_result.public_key_hashes[i].tag != HASH_VALUE_SHA256)
785 continue;
786 sha256_hashes.push_back(verify_result.public_key_hashes[i]);
787 }
788 ASSERT_LE(3u, sha256_hashes.size());
789
790 for (size_t i = 0; i < 3; ++i) {
791 EXPECT_EQ(HexEncode(kTwitterSPKIsSHA256[i], crypto::kSHA256Length),
792 HexEncode(sha256_hashes[i].data(), crypto::kSHA256Length));
793 }
794 }
795
796 // A regression test for http://crbug.com/70293.
797 // The Key Usage extension in this RSA SSL server certificate does not have
798 // the keyEncipherment bit.
799 TEST_P(CertVerifyProcInternalTest, InvalidKeyUsage) {
800 base::FilePath certs_dir = GetTestCertsDirectory();
801
802 scoped_refptr<X509Certificate> server_cert =
803 ImportCertFromFile(certs_dir, "invalid_key_usage_cert.der");
804 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
805
806 int flags = 0;
807 CertVerifyResult verify_result;
808 int error = Verify(server_cert.get(), "jira.aquameta.com", flags, NULL,
809 CertificateList(), &verify_result);
810
811 // TODO(eroman): Change the test data so results are consistent across
812 // verifiers.
813 if (verify_proc_type() == CERT_VERIFY_PROC_OPENSSL) {
814 // This certificate has two errors: "invalid key usage" and "untrusted CA".
815 // However, OpenSSL returns only one (the latter), and we can't detect
816 // the other errors.
817 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
818 } else {
819 EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
820 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
821 }
822 // TODO(wtc): fix http://crbug.com/75520 to get all the certificate errors
823 // from NSS.
824 if (verify_proc_type() != CERT_VERIFY_PROC_NSS &&
825 verify_proc_type() != CERT_VERIFY_PROC_IOS &&
826 verify_proc_type() != CERT_VERIFY_PROC_ANDROID) {
827 // The certificate is issued by an unknown CA.
828 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
829 }
830 }
831
832 // Basic test for returning the chain in CertVerifyResult. Note that the
833 // returned chain may just be a reflection of the originally supplied chain;
834 // that is, if any errors occur, the default chain returned is an exact copy
835 // of the certificate to be verified. The remaining VerifyReturn* tests are
836 // used to ensure that the actual, verified chain is being returned by
837 // Verify().
838 TEST_P(CertVerifyProcInternalTest, VerifyReturnChainBasic) {
839 if (!SupportsReturningVerifiedChain()) {
840 LOG(INFO) << "Skipping this test in this platform.";
841 return;
842 }
843
844 base::FilePath certs_dir = GetTestCertsDirectory();
845 CertificateList certs = CreateCertificateListFromFile(
846 certs_dir, "x509_verify_results.chain.pem", X509Certificate::FORMAT_AUTO);
847 ASSERT_EQ(3U, certs.size());
848
849 X509Certificate::OSCertHandles intermediates;
850 intermediates.push_back(certs[1]->os_cert_handle());
851 intermediates.push_back(certs[2]->os_cert_handle());
852
853 ScopedTestRoot scoped_root(certs[2].get());
854
855 scoped_refptr<X509Certificate> google_full_chain =
856 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
857 intermediates);
858 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain.get());
859 ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size());
860
861 CertVerifyResult verify_result;
862 EXPECT_EQ(static_cast<X509Certificate*>(NULL),
863 verify_result.verified_cert.get());
864 int error = Verify(google_full_chain.get(), "127.0.0.1", 0, NULL,
865 CertificateList(), &verify_result);
866 EXPECT_THAT(error, IsOk());
867 ASSERT_NE(static_cast<X509Certificate*>(NULL),
868 verify_result.verified_cert.get());
869
870 EXPECT_NE(google_full_chain, verify_result.verified_cert);
871 EXPECT_TRUE(X509Certificate::IsSameOSCert(
872 google_full_chain->os_cert_handle(),
873 verify_result.verified_cert->os_cert_handle()));
874 const X509Certificate::OSCertHandles& return_intermediates =
875 verify_result.verified_cert->GetIntermediateCertificates();
876 ASSERT_EQ(2U, return_intermediates.size());
877 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
878 certs[1]->os_cert_handle()));
879 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
880 certs[2]->os_cert_handle()));
881 }
882
883 // Test that certificates issued for 'intranet' names (that is, containing no
884 // known public registry controlled domain information) issued by well-known
885 // CAs are flagged appropriately, while certificates that are issued by
886 // internal CAs are not flagged.
887 TEST(CertVerifyProcTest, IntranetHostsRejected) {
888 CertificateList cert_list = CreateCertificateListFromFile(
889 GetTestCertsDirectory(), "reject_intranet_hosts.pem",
890 X509Certificate::FORMAT_AUTO);
891 ASSERT_EQ(1U, cert_list.size());
892 scoped_refptr<X509Certificate> cert(cert_list[0]);
893
894 CertVerifyResult verify_result;
895 int error = 0;
896
897 // Intranet names for public CAs should be flagged:
898 CertVerifyResult dummy_result;
899 dummy_result.is_issued_by_known_root = true;
900 scoped_refptr<CertVerifyProc> verify_proc =
901 new MockCertVerifyProc(dummy_result);
902 error = verify_proc->Verify(cert.get(), "intranet", std::string(), 0, NULL,
903 CertificateList(), &verify_result);
904 EXPECT_THAT(error, IsOk());
905 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
906
907 // However, if the CA is not well known, these should not be flagged:
908 dummy_result.Reset();
909 dummy_result.is_issued_by_known_root = false;
910 verify_proc = make_scoped_refptr(new MockCertVerifyProc(dummy_result));
911 error = verify_proc->Verify(cert.get(), "intranet", std::string(), 0, NULL,
912 CertificateList(), &verify_result);
913 EXPECT_THAT(error, IsOk());
914 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
915 }
916
917 // While all SHA-1 certificates should be rejected, in the event that there
918 // emerges some unexpected bug, test that the 'legacy' behaviour works
919 // correctly - rejecting all SHA-1 certificates from publicly trusted CAs
920 // that were issued after 1 January 2016, while still allowing those from
921 // before that date, with SHA-1 in the intermediate, or from an enterprise
922 // CA.
923 TEST(CertVerifyProcTest, VerifyRejectsSHA1AfterDeprecationLegacyMode) {
924 base::test::ScopedFeatureList scoped_feature_list;
925 scoped_feature_list.InitAndEnableFeature(CertVerifyProc::kSHA1LegacyMode);
926
927 CertVerifyResult dummy_result;
928 CertVerifyResult verify_result;
929 int error = 0;
930 scoped_refptr<X509Certificate> cert;
931
932 // Publicly trusted SHA-1 leaf certificates issued before 1 January 2016
933 // are accepted.
934 verify_result.Reset();
935 dummy_result.Reset();
936 dummy_result.is_issued_by_known_root = true;
937 dummy_result.has_sha1 = true;
938 dummy_result.has_sha1_leaf = true;
939 scoped_refptr<CertVerifyProc> verify_proc =
940 new MockCertVerifyProc(dummy_result);
941 cert = CreateCertificateChainFromFile(GetTestCertsDirectory(),
942 "sha1_dec_2015.pem",
943 X509Certificate::FORMAT_AUTO);
944 ASSERT_TRUE(cert);
945 error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), 0, NULL,
946 CertificateList(), &verify_result);
947 EXPECT_THAT(error, IsOk());
948 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
949
950 // Publicly trusted SHA-1 leaf certificates issued on/after 1 January 2016
951 // are rejected.
952 verify_result.Reset();
953 dummy_result.Reset();
954 dummy_result.is_issued_by_known_root = true;
955 dummy_result.has_sha1 = true;
956 dummy_result.has_sha1_leaf = true;
957 verify_proc = make_scoped_refptr(new MockCertVerifyProc(dummy_result));
958 cert = CreateCertificateChainFromFile(GetTestCertsDirectory(),
959 "sha1_jan_2016.pem",
960 X509Certificate::FORMAT_AUTO);
961 ASSERT_TRUE(cert);
962 error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), 0, NULL,
963 CertificateList(), &verify_result);
964 EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM));
965 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
966
967 // Enterprise issued SHA-1 leaf certificates issued on/after 1 January 2016
968 // remain accepted.
969 verify_result.Reset();
970 dummy_result.Reset();
971 dummy_result.is_issued_by_known_root = false;
972 dummy_result.has_sha1 = true;
973 dummy_result.has_sha1_leaf = true;
974 verify_proc = make_scoped_refptr(new MockCertVerifyProc(dummy_result));
975 cert = CreateCertificateChainFromFile(GetTestCertsDirectory(),
976 "sha1_jan_2016.pem",
977 X509Certificate::FORMAT_AUTO);
978 ASSERT_TRUE(cert);
979 error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), 0, NULL,
980 CertificateList(), &verify_result);
981 EXPECT_THAT(error, IsOk());
982 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
983
984 // Publicly trusted SHA-1 intermediates issued on/after 1 January 2016 are,
985 // unfortunately, accepted. This can arise due to OS path building quirks.
986 verify_result.Reset();
987 dummy_result.Reset();
988 dummy_result.is_issued_by_known_root = true;
989 dummy_result.has_sha1 = true;
990 dummy_result.has_sha1_leaf = false;
991 verify_proc = make_scoped_refptr(new MockCertVerifyProc(dummy_result));
992 cert = CreateCertificateChainFromFile(GetTestCertsDirectory(),
993 "sha1_jan_2016.pem",
994 X509Certificate::FORMAT_AUTO);
995 ASSERT_TRUE(cert);
996 error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), 0, NULL,
997 CertificateList(), &verify_result);
998 EXPECT_THAT(error, IsOk());
999 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
1000 }
1001
1002 // Test that the certificate returned in CertVerifyResult is able to reorder
1003 // certificates that are not ordered from end-entity to root. While this is
1004 // a protocol violation if sent during a TLS handshake, if multiple sources
1005 // of intermediate certificates are combined, it's possible that order may
1006 // not be maintained.
1007 TEST_P(CertVerifyProcInternalTest, VerifyReturnChainProperlyOrdered) {
1008 if (!SupportsReturningVerifiedChain()) {
1009 LOG(INFO) << "Skipping this test in this platform.";
1010 return;
1011 }
1012
1013 base::FilePath certs_dir = GetTestCertsDirectory();
1014 CertificateList certs = CreateCertificateListFromFile(
1015 certs_dir, "x509_verify_results.chain.pem", X509Certificate::FORMAT_AUTO);
1016 ASSERT_EQ(3U, certs.size());
1017
1018 // Construct the chain out of order.
1019 X509Certificate::OSCertHandles intermediates;
1020 intermediates.push_back(certs[2]->os_cert_handle());
1021 intermediates.push_back(certs[1]->os_cert_handle());
1022
1023 ScopedTestRoot scoped_root(certs[2].get());
1024
1025 scoped_refptr<X509Certificate> google_full_chain =
1026 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
1027 intermediates);
1028 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain.get());
1029 ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size());
1030
1031 CertVerifyResult verify_result;
1032 EXPECT_EQ(static_cast<X509Certificate*>(NULL),
1033 verify_result.verified_cert.get());
1034 int error = Verify(google_full_chain.get(), "127.0.0.1", 0, NULL,
1035 CertificateList(), &verify_result);
1036 EXPECT_THAT(error, IsOk());
1037 ASSERT_NE(static_cast<X509Certificate*>(NULL),
1038 verify_result.verified_cert.get());
1039
1040 EXPECT_NE(google_full_chain, verify_result.verified_cert);
1041 EXPECT_TRUE(X509Certificate::IsSameOSCert(
1042 google_full_chain->os_cert_handle(),
1043 verify_result.verified_cert->os_cert_handle()));
1044 const X509Certificate::OSCertHandles& return_intermediates =
1045 verify_result.verified_cert->GetIntermediateCertificates();
1046 ASSERT_EQ(2U, return_intermediates.size());
1047 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
1048 certs[1]->os_cert_handle()));
1049 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
1050 certs[2]->os_cert_handle()));
1051 }
1052
1053 // Test that Verify() filters out certificates which are not related to
1054 // or part of the certificate chain being verified.
1055 TEST_P(CertVerifyProcInternalTest, VerifyReturnChainFiltersUnrelatedCerts) {
1056 if (!SupportsReturningVerifiedChain()) {
1057 LOG(INFO) << "Skipping this test in this platform.";
1058 return;
1059 }
1060
1061 base::FilePath certs_dir = GetTestCertsDirectory();
1062 CertificateList certs = CreateCertificateListFromFile(
1063 certs_dir, "x509_verify_results.chain.pem", X509Certificate::FORMAT_AUTO);
1064 ASSERT_EQ(3U, certs.size());
1065 ScopedTestRoot scoped_root(certs[2].get());
1066
1067 scoped_refptr<X509Certificate> unrelated_certificate =
1068 ImportCertFromFile(certs_dir, "duplicate_cn_1.pem");
1069 scoped_refptr<X509Certificate> unrelated_certificate2 =
1070 ImportCertFromFile(certs_dir, "aia-cert.pem");
1071 ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_certificate.get());
1072 ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_certificate2.get());
1073
1074 // Interject unrelated certificates into the list of intermediates.
1075 X509Certificate::OSCertHandles intermediates;
1076 intermediates.push_back(unrelated_certificate->os_cert_handle());
1077 intermediates.push_back(certs[1]->os_cert_handle());
1078 intermediates.push_back(unrelated_certificate2->os_cert_handle());
1079 intermediates.push_back(certs[2]->os_cert_handle());
1080
1081 scoped_refptr<X509Certificate> google_full_chain =
1082 X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
1083 intermediates);
1084 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain.get());
1085 ASSERT_EQ(4U, google_full_chain->GetIntermediateCertificates().size());
1086
1087 CertVerifyResult verify_result;
1088 EXPECT_EQ(static_cast<X509Certificate*>(NULL),
1089 verify_result.verified_cert.get());
1090 int error = Verify(google_full_chain.get(), "127.0.0.1", 0, NULL,
1091 CertificateList(), &verify_result);
1092 EXPECT_THAT(error, IsOk());
1093 ASSERT_NE(static_cast<X509Certificate*>(NULL),
1094 verify_result.verified_cert.get());
1095
1096 EXPECT_NE(google_full_chain, verify_result.verified_cert);
1097 EXPECT_TRUE(X509Certificate::IsSameOSCert(
1098 google_full_chain->os_cert_handle(),
1099 verify_result.verified_cert->os_cert_handle()));
1100 const X509Certificate::OSCertHandles& return_intermediates =
1101 verify_result.verified_cert->GetIntermediateCertificates();
1102 ASSERT_EQ(2U, return_intermediates.size());
1103 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
1104 certs[1]->os_cert_handle()));
1105 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
1106 certs[2]->os_cert_handle()));
1107 }
1108
1109 TEST_P(CertVerifyProcInternalTest, AdditionalTrustAnchors) {
1110 if (!SupportsAdditionalTrustAnchors()) {
1111 LOG(INFO) << "Skipping this test in this platform.";
1112 return;
1113 }
1114
1115 // |ca_cert| is the issuer of |cert|.
1116 CertificateList ca_cert_list =
1117 CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem",
1118 X509Certificate::FORMAT_AUTO);
1119 ASSERT_EQ(1U, ca_cert_list.size());
1120 scoped_refptr<X509Certificate> ca_cert(ca_cert_list[0]);
1121
1122 CertificateList cert_list = CreateCertificateListFromFile(
1123 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO);
1124 ASSERT_EQ(1U, cert_list.size());
1125 scoped_refptr<X509Certificate> cert(cert_list[0]);
1126
1127 // Verification of |cert| fails when |ca_cert| is not in the trust anchors
1128 // list.
1129 int flags = 0;
1130 CertVerifyResult verify_result;
1131 int error = Verify(cert.get(), "127.0.0.1", flags, NULL, CertificateList(),
1132 &verify_result);
1133 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1134 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
1135 EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
1136
1137 // Now add the |ca_cert| to the |trust_anchors|, and verification should pass.
1138 CertificateList trust_anchors;
1139 trust_anchors.push_back(ca_cert);
1140 error = Verify(cert.get(), "127.0.0.1", flags, NULL, trust_anchors,
1141 &verify_result);
1142 EXPECT_THAT(error, IsOk());
1143 EXPECT_EQ(0U, verify_result.cert_status);
1144 EXPECT_TRUE(verify_result.is_issued_by_additional_trust_anchor);
1145
1146 // Clearing the |trust_anchors| makes verification fail again (the cache
1147 // should be skipped).
1148 error = Verify(cert.get(), "127.0.0.1", flags, NULL, CertificateList(),
1149 &verify_result);
1150 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1151 EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
1152 EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
1153 }
1154
1155 // Tests that certificates issued by user-supplied roots are not flagged as
1156 // issued by a known root. This should pass whether or not the platform supports
1157 // detecting known roots.
1158 TEST_P(CertVerifyProcInternalTest, IsIssuedByKnownRootIgnoresTestRoots) {
1159 // Load root_ca_cert.pem into the test root store.
1160 ScopedTestRoot test_root(
1161 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem").get());
1162
1163 scoped_refptr<X509Certificate> cert(
1164 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
1165
1166 // Verification should pass.
1167 int flags = 0;
1168 CertVerifyResult verify_result;
1169 int error = Verify(cert.get(), "127.0.0.1", flags, NULL, CertificateList(),
1170 &verify_result);
1171 EXPECT_THAT(error, IsOk());
1172 EXPECT_EQ(0U, verify_result.cert_status);
1173 // But should not be marked as a known root.
1174 EXPECT_FALSE(verify_result.is_issued_by_known_root);
1175 }
1176
1177 // Test that CRLSets are effective in making a certificate appear to be
1178 // revoked.
1179 TEST_P(CertVerifyProcInternalTest, CRLSet) {
1180 if (!SupportsCRLSet()) {
1181 LOG(INFO) << "Skipping test as verifier doesn't support CRLSet";
1182 return;
1183 }
1184
1185 CertificateList ca_cert_list =
1186 CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem",
1187 X509Certificate::FORMAT_AUTO);
1188 ASSERT_EQ(1U, ca_cert_list.size());
1189 ScopedTestRoot test_root(ca_cert_list[0].get());
1190
1191 CertificateList cert_list = CreateCertificateListFromFile(
1192 GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO);
1193 ASSERT_EQ(1U, cert_list.size());
1194 scoped_refptr<X509Certificate> cert(cert_list[0]);
1195
1196 int flags = 0;
1197 CertVerifyResult verify_result;
1198 int error = Verify(cert.get(), "127.0.0.1", flags, NULL, CertificateList(),
1199 &verify_result);
1200 EXPECT_THAT(error, IsOk());
1201 EXPECT_EQ(0U, verify_result.cert_status);
1202
1203 scoped_refptr<CRLSet> crl_set;
1204 std::string crl_set_bytes;
1205
1206 // First test blocking by SPKI.
1207 EXPECT_TRUE(base::ReadFileToString(
1208 GetTestCertsDirectory().AppendASCII("crlset_by_leaf_spki.raw"),
1209 &crl_set_bytes));
1210 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
1211
1212 error = Verify(cert.get(), "127.0.0.1", flags, crl_set.get(),
1213 CertificateList(), &verify_result);
1214 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
1215
1216 // Second, test revocation by serial number of a cert directly under the
1217 // root.
1218 crl_set_bytes.clear();
1219 EXPECT_TRUE(base::ReadFileToString(
1220 GetTestCertsDirectory().AppendASCII("crlset_by_root_serial.raw"),
1221 &crl_set_bytes));
1222 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
1223
1224 error = Verify(cert.get(), "127.0.0.1", flags, crl_set.get(),
1225 CertificateList(), &verify_result);
1226 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
1227 }
1228
1229 TEST_P(CertVerifyProcInternalTest, CRLSetLeafSerial) {
1230 if (!SupportsCRLSet()) {
1231 LOG(INFO) << "Skipping test as verifier doesn't support CRLSet";
1232 return;
1233 }
1234
1235 CertificateList ca_cert_list =
1236 CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem",
1237 X509Certificate::FORMAT_AUTO);
1238 ASSERT_EQ(1U, ca_cert_list.size());
1239 ScopedTestRoot test_root(ca_cert_list[0].get());
1240
1241 CertificateList intermediate_cert_list = CreateCertificateListFromFile(
1242 GetTestCertsDirectory(), "intermediate_ca_cert.pem",
1243 X509Certificate::FORMAT_AUTO);
1244 ASSERT_EQ(1U, intermediate_cert_list.size());
1245 X509Certificate::OSCertHandles intermediates;
1246 intermediates.push_back(intermediate_cert_list[0]->os_cert_handle());
1247
1248 CertificateList cert_list = CreateCertificateListFromFile(
1249 GetTestCertsDirectory(), "ok_cert_by_intermediate.pem",
1250 X509Certificate::FORMAT_AUTO);
1251 ASSERT_EQ(1U, cert_list.size());
1252
1253 scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromHandle(
1254 cert_list[0]->os_cert_handle(), intermediates);
1255 ASSERT_TRUE(leaf);
1256
1257 int flags = 0;
1258 CertVerifyResult verify_result;
1259 int error = Verify(leaf.get(), "127.0.0.1", flags, NULL, CertificateList(),
1260 &verify_result);
1261 EXPECT_THAT(error, IsOk());
1262
1263 // Test revocation by serial number of a certificate not under the root.
1264 scoped_refptr<CRLSet> crl_set;
1265 std::string crl_set_bytes;
1266 ASSERT_TRUE(base::ReadFileToString(
1267 GetTestCertsDirectory().AppendASCII("crlset_by_intermediate_serial.raw"),
1268 &crl_set_bytes));
1269 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
1270
1271 error = Verify(leaf.get(), "127.0.0.1", flags, crl_set.get(),
1272 CertificateList(), &verify_result);
1273 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
1274 }
1275
1276 // Tests that CRLSets participate in path building functions, and that as
1277 // long as a valid path exists within the verification graph, verification
1278 // succeeds.
1279 //
1280 // In this test, there are two roots (D and E), and three possible paths
1281 // to validate a leaf (A):
1282 // 1. A(B) -> B(C) -> C(D) -> D(D)
1283 // 2. A(B) -> B(C) -> C(E) -> E(E)
1284 // 3. A(B) -> B(F) -> F(E) -> E(E)
1285 //
1286 // Each permutation of revocation is tried:
1287 // 1. Revoking E by SPKI, so that only Path 1 is valid (as E is in Paths 2 & 3)
1288 // 2. Revoking C(D) and F(E) by serial, so that only Path 2 is valid.
1289 // 3. Revoking C by SPKI, so that only Path 3 is valid (as C is in Paths 1 & 2)
1290 TEST_P(CertVerifyProcInternalTest, CRLSetDuringPathBuilding) {
1291 if (!SupportsCRLSetsInPathBuilding()) {
1292 LOG(INFO) << "Skipping this test on this platform.";
1293 return;
1294 }
1295
1296 const char* const kPath1Files[] = {
1297 "multi-root-A-by-B.pem", "multi-root-B-by-C.pem", "multi-root-C-by-D.pem",
1298 "multi-root-D-by-D.pem"};
1299 const char* const kPath2Files[] = {
1300 "multi-root-A-by-B.pem", "multi-root-B-by-C.pem", "multi-root-C-by-E.pem",
1301 "multi-root-E-by-E.pem"};
1302 const char* const kPath3Files[] = {
1303 "multi-root-A-by-B.pem", "multi-root-B-by-F.pem", "multi-root-F-by-E.pem",
1304 "multi-root-E-by-E.pem"};
1305
1306 CertificateList path_1_certs;
1307 ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath1Files, &path_1_certs));
1308
1309 CertificateList path_2_certs;
1310 ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath2Files, &path_2_certs));
1311
1312 CertificateList path_3_certs;
1313 ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath3Files, &path_3_certs));
1314
1315 // Add D and E as trust anchors.
1316 ScopedTestRoot test_root_D(path_1_certs[3].get()); // D-by-D
1317 ScopedTestRoot test_root_E(path_2_certs[3].get()); // E-by-E
1318
1319 // Create a chain that contains all the certificate paths possible.
1320 // CertVerifyProcInternalTest.VerifyReturnChainFiltersUnrelatedCerts already
1321 // ensures that it's safe to send additional certificates as inputs, and
1322 // that they're ignored if not necessary.
1323 // This is to avoid relying on AIA or internal object caches when
1324 // interacting with the underlying library.
1325 X509Certificate::OSCertHandles intermediates;
1326 intermediates.push_back(path_1_certs[1]->os_cert_handle()); // B-by-C
1327 intermediates.push_back(path_1_certs[2]->os_cert_handle()); // C-by-D
1328 intermediates.push_back(path_2_certs[2]->os_cert_handle()); // C-by-E
1329 intermediates.push_back(path_3_certs[1]->os_cert_handle()); // B-by-F
1330 intermediates.push_back(path_3_certs[2]->os_cert_handle()); // F-by-E
1331 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
1332 path_1_certs[0]->os_cert_handle(), intermediates);
1333 ASSERT_TRUE(cert);
1334
1335 struct TestPermutations {
1336 const char* crlset;
1337 bool expect_valid;
1338 scoped_refptr<X509Certificate> expected_intermediate;
1339 } kTests[] = {
1340 {"multi-root-crlset-D-and-E.raw", false, nullptr},
1341 {"multi-root-crlset-E.raw", true, path_1_certs[2].get()},
1342 {"multi-root-crlset-CD-and-FE.raw", true, path_2_certs[2].get()},
1343 {"multi-root-crlset-C.raw", true, path_3_certs[2].get()},
1344 {"multi-root-crlset-unrelated.raw", true, nullptr}};
1345
1346 for (const auto& testcase : kTests) {
1347 SCOPED_TRACE(testcase.crlset);
1348 scoped_refptr<CRLSet> crl_set;
1349 std::string crl_set_bytes;
1350 EXPECT_TRUE(base::ReadFileToString(
1351 GetTestCertsDirectory().AppendASCII(testcase.crlset), &crl_set_bytes));
1352 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
1353
1354 int flags = 0;
1355 CertVerifyResult verify_result;
1356 int error = Verify(cert.get(), "127.0.0.1", flags, crl_set.get(),
1357 CertificateList(), &verify_result);
1358
1359 if (!testcase.expect_valid) {
1360 EXPECT_NE(OK, error);
1361 EXPECT_NE(0U, verify_result.cert_status);
1362 continue;
1363 }
1364
1365 ASSERT_THAT(error, IsOk());
1366 ASSERT_EQ(0U, verify_result.cert_status);
1367 ASSERT_TRUE(verify_result.verified_cert.get());
1368
1369 if (!testcase.expected_intermediate)
1370 continue;
1371
1372 const X509Certificate::OSCertHandles& verified_intermediates =
1373 verify_result.verified_cert->GetIntermediateCertificates();
1374 ASSERT_EQ(3U, verified_intermediates.size());
1375
1376 scoped_refptr<X509Certificate> intermediate =
1377 X509Certificate::CreateFromHandle(verified_intermediates[1],
1378 X509Certificate::OSCertHandles());
1379 ASSERT_TRUE(intermediate);
1380
1381 EXPECT_TRUE(testcase.expected_intermediate->Equals(intermediate.get()))
1382 << "Expected: " << testcase.expected_intermediate->subject().common_name
1383 << " issued by " << testcase.expected_intermediate->issuer().common_name
1384 << "; Got: " << intermediate->subject().common_name << " issued by "
1385 << intermediate->issuer().common_name;
1386 }
1387 }
1388
1389 #if defined(OS_MACOSX) && !defined(OS_IOS)
1390 // Test that a CRLSet blocking one of the intermediates supplied by the server 34 // Test that a CRLSet blocking one of the intermediates supplied by the server
1391 // can be worked around by the chopping workaround for path building. (Once the 35 // can be worked around by the chopping workaround for path building. (Once the
1392 // supplied chain is chopped back to just the target, a better path can be 36 // supplied chain is chopped back to just the target, a better path can be
1393 // found out-of-band. Normally that would be by AIA fetching, for the purposes 37 // found out-of-band. Normally that would be by AIA fetching, for the purposes
1394 // of this test the better path is supplied by a test keychain.) 38 // of this test the better path is supplied by a test keychain.)
1395 // 39 //
1396 // In this test, there are two possible paths to validate a leaf (A): 40 // In this test, there are two possible paths to validate a leaf (A):
1397 // 1. A(B) -> B(C) -> C(E) -> E(E) 41 // 1. A(B) -> B(C) -> C(E) -> E(E)
1398 // 2. A(B) -> B(F) -> F(E) -> E(E) 42 // 2. A(B) -> B(F) -> F(E) -> E(E)
1399 // 43 //
1400 // A(B) -> B(C) -> C(E) is supplied to the verifier. 44 // A(B) -> B(C) -> C(E) is supplied to the verifier.
1401 // B(F) and F(E) are supplied in a test keychain. 45 // B(F) and F(E) are supplied in a test keychain.
1402 // C is blocked by a CRLset. 46 // C is blocked by a CRLset.
1403 // 47 //
1404 // The verifier should rollback until it just tries A(B) alone, at which point 48 // The verifier should rollback until it just tries A(B) alone, at which point
1405 // it will pull B(F) & F(E) from the keychain and succeed. 49 // it will pull B(F) & F(E) from the keychain and succeed.
1406 TEST(CertVerifyProcMacTest, MacCRLIntermediate) { 50 TEST(CertVerifyProcMacTest, MacCRLIntermediate) {
1407 if (base::mac::IsAtLeastOS10_12()) { 51 if (base::mac::IsAtLeastOS10_12()) {
1408 // TODO(crbug.com/671889): Investigate SecTrustSetKeychains issue on Sierra. 52 // TODO(crbug.com/671889): Investigate SecTrustSetKeychains issue on Sierra.
1409 LOG(INFO) << "Skipping test, SecTrustSetKeychains does not work on 10.12"; 53 LOG(INFO) << "Skipping test, SecTrustSetKeychains does not work on 10.12";
1410 return; 54 return;
1411 } 55 }
1412 const char* const kPath2Files[] = {
1413 "multi-root-A-by-B.pem", "multi-root-B-by-C.pem", "multi-root-C-by-E.pem",
1414 "multi-root-E-by-E.pem"};
1415 CertificateList path_2_certs; 56 CertificateList path_2_certs;
1416 ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath2Files, &path_2_certs)); 57 ASSERT_TRUE(
1417 58 LoadCertificateFiles({"multi-root-A-by-B.pem", "multi-root-B-by-C.pem",
1418 const char* const kPath3Files[] = { 59 "multi-root-C-by-E.pem", "multi-root-E-by-E.pem"},
1419 "multi-root-A-by-B.pem", "multi-root-B-by-F.pem", "multi-root-F-by-E.pem", 60 &path_2_certs));
1420 "multi-root-E-by-E.pem"};
1421 61
1422 CertificateList path_3_certs; 62 CertificateList path_3_certs;
1423 ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath3Files, &path_3_certs)); 63 ASSERT_TRUE(
64 LoadCertificateFiles({"multi-root-A-by-B.pem", "multi-root-B-by-F.pem",
65 "multi-root-F-by-E.pem", "multi-root-E-by-E.pem"},
66 &path_3_certs));
1424 67
1425 // Add E as trust anchor. 68 // Add E as trust anchor.
1426 ScopedTestRoot test_root_E(path_3_certs[3].get()); // E-by-E 69 ScopedTestRoot test_root_E(path_3_certs[3].get()); // E-by-E
1427 70
1428 X509Certificate::OSCertHandles intermediates; 71 X509Certificate::OSCertHandles intermediates;
1429 intermediates.push_back(path_2_certs[1]->os_cert_handle()); // B-by-C 72 intermediates.push_back(path_2_certs[1]->os_cert_handle()); // B-by-C
1430 intermediates.push_back(path_2_certs[2]->os_cert_handle()); // C-by-E 73 intermediates.push_back(path_2_certs[2]->os_cert_handle()); // C-by-E
1431 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( 74 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
1432 path_3_certs[0]->os_cert_handle(), intermediates); 75 path_3_certs[0]->os_cert_handle(), intermediates);
1433 ASSERT_TRUE(cert); 76 ASSERT_TRUE(cert);
(...skipping 19 matching lines...) Expand all
1453 std::string crl_set_bytes; 96 std::string crl_set_bytes;
1454 // CRL which blocks C by SPKI. 97 // CRL which blocks C by SPKI.
1455 EXPECT_TRUE(base::ReadFileToString( 98 EXPECT_TRUE(base::ReadFileToString(
1456 GetTestCertsDirectory().AppendASCII("multi-root-crlset-C.raw"), 99 GetTestCertsDirectory().AppendASCII("multi-root-crlset-C.raw"),
1457 &crl_set_bytes)); 100 &crl_set_bytes));
1458 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set)); 101 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
1459 102
1460 int flags = 0; 103 int flags = 0;
1461 CertVerifyResult verify_result; 104 CertVerifyResult verify_result;
1462 105
1463 scoped_refptr<CertVerifyProc> verify_proc = CertVerifyProc::CreateDefault(); 106 scoped_refptr<CertVerifyProc> verify_proc = new CertVerifyProcMac;
1464 int error = 107 int error =
1465 verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, 108 verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags,
1466 crl_set.get(), CertificateList(), &verify_result); 109 crl_set.get(), CertificateList(), &verify_result);
1467 110
1468 ASSERT_EQ(OK, error); 111 ASSERT_EQ(OK, error);
1469 ASSERT_EQ(0U, verify_result.cert_status); 112 ASSERT_EQ(0U, verify_result.cert_status);
1470 ASSERT_TRUE(verify_result.verified_cert.get()); 113 ASSERT_TRUE(verify_result.verified_cert.get());
1471 114
1472 const X509Certificate::OSCertHandles& verified_intermediates = 115 const X509Certificate::OSCertHandles& verified_intermediates =
1473 verify_result.verified_cert->GetIntermediateCertificates(); 116 verify_result.verified_cert->GetIntermediateCertificates();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 SecKeychainRef keychain; 153 SecKeychainRef keychain;
1511 OSStatus status = 154 OSStatus status =
1512 SecKeychainOpen(keychain_path.MaybeAsASCII().c_str(), &keychain); 155 SecKeychainOpen(keychain_path.MaybeAsASCII().c_str(), &keychain);
1513 ASSERT_EQ(errSecSuccess, status); 156 ASSERT_EQ(errSecSuccess, status);
1514 ASSERT_TRUE(keychain); 157 ASSERT_TRUE(keychain);
1515 base::ScopedCFTypeRef<SecKeychainRef> scoped_keychain(keychain); 158 base::ScopedCFTypeRef<SecKeychainRef> scoped_keychain(keychain);
1516 test_keychain_search_list->AddKeychain(keychain); 159 test_keychain_search_list->AddKeychain(keychain);
1517 160
1518 int flags = 0; 161 int flags = 0;
1519 CertVerifyResult verify_result; 162 CertVerifyResult verify_result;
1520 scoped_refptr<CertVerifyProc> verify_proc = CertVerifyProc::CreateDefault(); 163 scoped_refptr<CertVerifyProc> verify_proc = new CertVerifyProcMac;
1521 int error = verify_proc->Verify(cert.get(), "www.tripadvisor.com", 164 int error = verify_proc->Verify(cert.get(), "www.tripadvisor.com",
1522 std::string(), flags, nullptr /* crl_set */, 165 std::string(), flags, nullptr /* crl_set */,
1523 CertificateList(), &verify_result); 166 CertificateList(), &verify_result);
1524 167
1525 ASSERT_EQ(OK, error); 168 ASSERT_EQ(OK, error);
1526 EXPECT_EQ(0U, verify_result.cert_status); 169 EXPECT_EQ(0U, verify_result.cert_status);
1527 EXPECT_FALSE(verify_result.has_sha1); 170 EXPECT_FALSE(verify_result.has_sha1);
1528 ASSERT_TRUE(verify_result.verified_cert.get()); 171 ASSERT_TRUE(verify_result.verified_cert.get());
1529 172
1530 const X509Certificate::OSCertHandles& verified_intermediates = 173 const X509Certificate::OSCertHandles& verified_intermediates =
1531 verify_result.verified_cert->GetIntermediateCertificates(); 174 verify_result.verified_cert->GetIntermediateCertificates();
1532 ASSERT_EQ(2U, verified_intermediates.size()); 175 ASSERT_EQ(2U, verified_intermediates.size());
1533 } 176 }
1534 177
1535 // Test that the system root certificate keychain is in the expected location 178 // Test that the system root certificate keychain is in the expected location
1536 // and can be opened. Other tests would fail if this was not true, but this 179 // and can be opened. Other tests would fail if this was not true, but this
1537 // test makes the reason for the failure obvious. 180 // test makes the reason for the failure obvious.
1538 TEST(CertVerifyProcMacTest, MacSystemRootCertificateKeychainLocation) { 181 TEST(CertVerifyProcMacTest, MacSystemRootCertificateKeychainLocation) {
1539 const char* root_keychain_path = 182 const char* root_keychain_path =
1540 "/System/Library/Keychains/SystemRootCertificates.keychain"; 183 "/System/Library/Keychains/SystemRootCertificates.keychain";
1541 ASSERT_TRUE(base::PathExists(base::FilePath(root_keychain_path))); 184 ASSERT_TRUE(base::PathExists(base::FilePath(root_keychain_path)));
1542 185
1543 SecKeychainRef keychain; 186 SecKeychainRef keychain;
1544 OSStatus status = SecKeychainOpen(root_keychain_path, &keychain); 187 OSStatus status = SecKeychainOpen(root_keychain_path, &keychain);
1545 ASSERT_EQ(errSecSuccess, status); 188 ASSERT_EQ(errSecSuccess, status);
1546 CFRelease(keychain); 189 CFRelease(keychain);
1547 } 190 }
1548 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
1549 191
1550 // TODO(crbug.com/649017): This is not parameterized by the CertVerifyProc
1551 // because the CertVerifyProc::Verify() does this unconditionally based on the
1552 // platform.
1553 bool AreSHA1IntermediatesAllowed() {
1554 #if defined(OS_WIN)
1555 // TODO(rsleevi): Remove this once https://crbug.com/588789 is resolved
1556 // for Windows 7/2008 users.
1557 // Note: This must be kept in sync with cert_verify_proc.cc
1558 return base::win::GetVersion() < base::win::VERSION_WIN8;
1559 #else
1560 return false;
1561 #endif
1562 }
1563
1564 TEST(CertVerifyProcTest, RejectsMD2) {
1565 scoped_refptr<X509Certificate> cert(
1566 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
1567 ASSERT_TRUE(cert);
1568
1569 CertVerifyResult result;
1570 result.has_md2 = true;
1571 scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result);
1572
1573 int flags = 0;
1574 CertVerifyResult verify_result;
1575 int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags,
1576 nullptr /* crl_set */, CertificateList(),
1577 &verify_result);
1578 EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
1579 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
1580 }
1581
1582 TEST(CertVerifyProcTest, RejectsMD4) {
1583 scoped_refptr<X509Certificate> cert(
1584 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
1585 ASSERT_TRUE(cert);
1586
1587 CertVerifyResult result;
1588 result.has_md4 = true;
1589 scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result);
1590
1591 int flags = 0;
1592 CertVerifyResult verify_result;
1593 int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags,
1594 nullptr /* crl_set */, CertificateList(),
1595 &verify_result);
1596 EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
1597 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
1598 }
1599
1600 TEST(CertVerifyProcTest, RejectsMD5) {
1601 scoped_refptr<X509Certificate> cert(
1602 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
1603 ASSERT_TRUE(cert);
1604
1605 CertVerifyResult result;
1606 result.has_md5 = true;
1607 scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result);
1608
1609 int flags = 0;
1610 CertVerifyResult verify_result;
1611 int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags,
1612 nullptr /* crl_set */, CertificateList(),
1613 &verify_result);
1614 EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM));
1615 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
1616 }
1617
1618 TEST(CertVerifyProcTest, RejectsPublicSHA1Leaves) {
1619 scoped_refptr<X509Certificate> cert(
1620 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
1621 ASSERT_TRUE(cert);
1622
1623 CertVerifyResult result;
1624 result.has_sha1 = true;
1625 result.has_sha1_leaf = true;
1626 result.is_issued_by_known_root = true;
1627 scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result);
1628
1629 int flags = 0;
1630 CertVerifyResult verify_result;
1631 int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags,
1632 nullptr /* crl_set */, CertificateList(),
1633 &verify_result);
1634 EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM));
1635 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
1636 }
1637
1638 TEST(CertVerifyProcTest, RejectsPublicSHA1IntermediatesUnlessAllowed) {
1639 scoped_refptr<X509Certificate> cert(ImportCertFromFile(
1640 GetTestCertsDirectory(), "39_months_after_2015_04.pem"));
1641 ASSERT_TRUE(cert);
1642
1643 CertVerifyResult result;
1644 result.has_sha1 = true;
1645 result.has_sha1_leaf = false;
1646 result.is_issued_by_known_root = true;
1647 scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result);
1648
1649 int flags = 0;
1650 CertVerifyResult verify_result;
1651 int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags,
1652 nullptr /* crl_set */, CertificateList(),
1653 &verify_result);
1654 if (AreSHA1IntermediatesAllowed()) {
1655 EXPECT_THAT(error, IsOk());
1656 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
1657 } else {
1658 EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM));
1659 EXPECT_TRUE(verify_result.cert_status &
1660 CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
1661 }
1662 }
1663
1664 TEST(CertVerifyProcTest, RejectsPrivateSHA1UnlessFlag) {
1665 scoped_refptr<X509Certificate> cert(
1666 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
1667 ASSERT_TRUE(cert);
1668
1669 CertVerifyResult result;
1670 result.has_sha1 = true;
1671 result.has_sha1_leaf = true;
1672 result.is_issued_by_known_root = false;
1673 scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result);
1674
1675 // SHA-1 should be rejected by default for private roots...
1676 int flags = 0;
1677 CertVerifyResult verify_result;
1678 int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags,
1679 nullptr /* crl_set */, CertificateList(),
1680 &verify_result);
1681 EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM));
1682 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
1683
1684 // ... unless VERIFY_ENABLE_SHA1_LOCAL_ANCHORS was supplied.
1685 flags = CertVerifier::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS;
1686 verify_result.Reset();
1687 error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags,
1688 nullptr /* crl_set */, CertificateList(),
1689 &verify_result);
1690 EXPECT_THAT(error, IsOk());
1691 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT);
1692 }
1693
1694 enum ExpectedAlgorithms {
1695 EXPECT_MD2 = 1 << 0,
1696 EXPECT_MD4 = 1 << 1,
1697 EXPECT_MD5 = 1 << 2,
1698 EXPECT_SHA1 = 1 << 3,
1699 EXPECT_SHA1_LEAF = 1 << 4,
1700 };
1701
1702 struct WeakDigestTestData {
1703 const char* root_cert_filename;
1704 const char* intermediate_cert_filename;
1705 const char* ee_cert_filename;
1706 int expected_algorithms;
1707 };
1708
1709 const char* StringOrDefault(const char* str, const char* default_value) {
1710 if (!str)
1711 return default_value;
1712 return str;
1713 }
1714
1715 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
1716 // to output the parameter that was passed. Without this, it will simply
1717 // attempt to print out the first twenty bytes of the object, which depending
1718 // on platform and alignment, may result in an invalid read.
1719 void PrintTo(const WeakDigestTestData& data, std::ostream* os) {
1720 *os << "root: " << StringOrDefault(data.root_cert_filename, "none")
1721 << "; intermediate: "
1722 << StringOrDefault(data.intermediate_cert_filename, "none")
1723 << "; end-entity: " << data.ee_cert_filename;
1724 }
1725
1726 class CertVerifyProcWeakDigestTest
1727 : public testing::TestWithParam<WeakDigestTestData> {
1728 public:
1729 CertVerifyProcWeakDigestTest() {}
1730 virtual ~CertVerifyProcWeakDigestTest() {}
1731 };
1732
1733 // Tests that the CertVerifyProc::Verify() properly surfaces the (weak) hash
1734 // algorithms used in the chain.
1735 TEST_P(CertVerifyProcWeakDigestTest, VerifyDetectsAlgorithm) {
1736 WeakDigestTestData data = GetParam();
1737 base::FilePath certs_dir = GetTestCertsDirectory();
1738
1739 scoped_refptr<X509Certificate> intermediate_cert;
1740 scoped_refptr<X509Certificate> root_cert;
1741
1742 // Build |intermediates| as the full chain (including trust anchor).
1743 X509Certificate::OSCertHandles intermediates;
1744
1745 if (data.intermediate_cert_filename) {
1746 intermediate_cert =
1747 ImportCertFromFile(certs_dir, data.intermediate_cert_filename);
1748 ASSERT_TRUE(intermediate_cert);
1749 intermediates.push_back(intermediate_cert->os_cert_handle());
1750 }
1751
1752 if (data.root_cert_filename) {
1753 root_cert = ImportCertFromFile(certs_dir, data.root_cert_filename);
1754 ASSERT_TRUE(root_cert);
1755 intermediates.push_back(root_cert->os_cert_handle());
1756 }
1757
1758 scoped_refptr<X509Certificate> ee_cert =
1759 ImportCertFromFile(certs_dir, data.ee_cert_filename);
1760 ASSERT_TRUE(ee_cert);
1761
1762 scoped_refptr<X509Certificate> ee_chain = X509Certificate::CreateFromHandle(
1763 ee_cert->os_cert_handle(), intermediates);
1764 ASSERT_TRUE(ee_chain);
1765
1766 int flags = 0;
1767 CertVerifyResult verify_result;
1768
1769 // Use a mock CertVerifyProc that returns success with a verified_cert of
1770 // |ee_chain|.
1771 //
1772 // This is sufficient for the purposes of this test, as the checking for weak
1773 // hash algorithms is done by CertVerifyProc::Verify().
1774 scoped_refptr<CertVerifyProc> proc =
1775 new MockCertVerifyProc(CertVerifyResult());
1776 proc->Verify(ee_chain.get(), "127.0.0.1", std::string(), flags, nullptr,
1777 CertificateList(), &verify_result);
1778 EXPECT_EQ(!!(data.expected_algorithms & EXPECT_MD2), verify_result.has_md2);
1779 EXPECT_EQ(!!(data.expected_algorithms & EXPECT_MD4), verify_result.has_md4);
1780 EXPECT_EQ(!!(data.expected_algorithms & EXPECT_MD5), verify_result.has_md5);
1781 EXPECT_EQ(!!(data.expected_algorithms & EXPECT_SHA1), verify_result.has_sha1);
1782 EXPECT_EQ(!!(data.expected_algorithms & EXPECT_SHA1_LEAF),
1783 verify_result.has_sha1_leaf);
1784 }
1785
1786 // The signature algorithm of the root CA should not matter.
1787 const WeakDigestTestData kVerifyRootCATestData[] = {
1788 {"weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem",
1789 "weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF},
1790 {"weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem",
1791 "weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF},
1792 {"weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem",
1793 "weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF},
1794 };
1795 INSTANTIATE_TEST_CASE_P(VerifyRoot,
1796 CertVerifyProcWeakDigestTest,
1797 testing::ValuesIn(kVerifyRootCATestData));
1798
1799 // The signature algorithm of intermediates should be properly detected.
1800 const WeakDigestTestData kVerifyIntermediateCATestData[] = {
1801 {"weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
1802 "weak_digest_sha1_ee.pem", EXPECT_MD5 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
1803 {"weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
1804 "weak_digest_sha1_ee.pem", EXPECT_MD4 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
1805 {"weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
1806 "weak_digest_sha1_ee.pem", EXPECT_MD2 | EXPECT_SHA1 | EXPECT_SHA1_LEAF},
1807 };
1808
1809 INSTANTIATE_TEST_CASE_P(VerifyIntermediate,
1810 CertVerifyProcWeakDigestTest,
1811 testing::ValuesIn(kVerifyIntermediateCATestData));
1812
1813 // The signature algorithm of end-entity should be properly detected.
1814 const WeakDigestTestData kVerifyEndEntityTestData[] = {
1815 {"weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1816 "weak_digest_md5_ee.pem", EXPECT_MD5 | EXPECT_SHA1},
1817 {"weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1818 "weak_digest_md4_ee.pem", EXPECT_MD4 | EXPECT_SHA1},
1819 {"weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1820 "weak_digest_md2_ee.pem", EXPECT_MD2 | EXPECT_SHA1},
1821 };
1822
1823 INSTANTIATE_TEST_CASE_P(VerifyEndEntity,
1824 CertVerifyProcWeakDigestTest,
1825 testing::ValuesIn(kVerifyEndEntityTestData));
1826
1827 // Incomplete chains do not report the status of the intermediate.
1828 // Note: really each of these tests should also expect the digest algorithm of
1829 // the intermediate (included as a comment). However CertVerifyProc::Verify() is
1830 // unable to distinguish that this is an intermediate and not a trust anchor, so
1831 // this intermediate is treated like a trust anchor.
1832 const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] = {
1833 {NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem",
1834 /*EXPECT_MD5 |*/ EXPECT_SHA1 | EXPECT_SHA1_LEAF},
1835 {NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem",
1836 /*EXPECT_MD4 |*/ EXPECT_SHA1 | EXPECT_SHA1_LEAF},
1837 {NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem",
1838 /*EXPECT_MD2 |*/ EXPECT_SHA1 | EXPECT_SHA1_LEAF},
1839 };
1840
1841 INSTANTIATE_TEST_CASE_P(
1842 MAYBE_VerifyIncompleteIntermediate,
1843 CertVerifyProcWeakDigestTest,
1844 testing::ValuesIn(kVerifyIncompleteIntermediateTestData));
1845
1846 // Incomplete chains should report the status of the end-entity.
1847 // Note: really each of these tests should also expect EXPECT_SHA1 (included as
1848 // a comment). However CertVerifyProc::Verify() is unable to distinguish that
1849 // this is an intermediate and not a trust anchor, so this intermediate is
1850 // treated like a trust anchor.
1851 const WeakDigestTestData kVerifyIncompleteEETestData[] = {
1852 {NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem",
1853 /*EXPECT_SHA1 |*/ EXPECT_MD5},
1854 {NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem",
1855 /*EXPECT_SHA1 |*/ EXPECT_MD4},
1856 {NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem",
1857 /*EXPECT_SHA1 |*/ EXPECT_MD2},
1858 };
1859
1860 INSTANTIATE_TEST_CASE_P(VerifyIncompleteEndEntity,
1861 CertVerifyProcWeakDigestTest,
1862 testing::ValuesIn(kVerifyIncompleteEETestData));
1863
1864 // Differing algorithms between the intermediate and the EE should still be
1865 // reported.
1866 const WeakDigestTestData kVerifyMixedTestData[] = {
1867 {"weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
1868 "weak_digest_md2_ee.pem", EXPECT_MD2 | EXPECT_MD5},
1869 {"weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
1870 "weak_digest_md5_ee.pem", EXPECT_MD2 | EXPECT_MD5},
1871 {"weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
1872 "weak_digest_md2_ee.pem", EXPECT_MD2 | EXPECT_MD4},
1873 };
1874
1875 INSTANTIATE_TEST_CASE_P(VerifyMixed,
1876 CertVerifyProcWeakDigestTest,
1877 testing::ValuesIn(kVerifyMixedTestData));
1878
1879 // The EE is a trusted certificate. Even though it uses weak hashes, these
1880 // should not be reported.
1881 const WeakDigestTestData kVerifyTrustedEETestData[] = {
1882 {NULL, NULL, "weak_digest_md5_ee.pem", 0},
1883 {NULL, NULL, "weak_digest_md4_ee.pem", 0},
1884 {NULL, NULL, "weak_digest_md2_ee.pem", 0},
1885 {NULL, NULL, "weak_digest_sha1_ee.pem", 0},
1886 };
1887
1888 INSTANTIATE_TEST_CASE_P(VerifyTrustedEE,
1889 CertVerifyProcWeakDigestTest,
1890 testing::ValuesIn(kVerifyTrustedEETestData));
1891
1892 // For the list of valid hostnames, see
1893 // net/cert/data/ssl/certificates/subjectAltName_sanity_check.pem
1894 struct CertVerifyProcNameData {
1895 const char* hostname;
1896 bool valid; // Whether or not |hostname| matches a subjectAltName.
1897 };
1898
1899 // Test fixture for verifying certificate names. These tests are run for each
1900 // of the CertVerify implementations.
1901 class CertVerifyProcNameTest : public CertVerifyProcInternalTest {
1902 public:
1903 CertVerifyProcNameTest() {}
1904 virtual ~CertVerifyProcNameTest() {}
1905
1906 protected:
1907 void VerifyCertName(const char* hostname, bool valid) {
1908 CertificateList cert_list = CreateCertificateListFromFile(
1909 GetTestCertsDirectory(), "subjectAltName_sanity_check.pem",
1910 X509Certificate::FORMAT_AUTO);
1911 ASSERT_EQ(1U, cert_list.size());
1912 scoped_refptr<X509Certificate> cert(cert_list[0]);
1913
1914 ScopedTestRoot scoped_root(cert.get());
1915
1916 CertVerifyResult verify_result;
1917 int error = Verify(cert.get(), hostname, 0, NULL, CertificateList(),
1918 &verify_result);
1919 if (valid) {
1920 EXPECT_THAT(error, IsOk());
1921 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID);
1922 } else {
1923 EXPECT_THAT(error, IsError(ERR_CERT_COMMON_NAME_INVALID));
1924 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID);
1925 }
1926 }
1927 };
1928
1929 // Don't match the common name
1930 TEST_P(CertVerifyProcNameTest, DontMatchCommonName) {
1931 VerifyCertName("127.0.0.1", false);
1932 }
1933
1934 // Matches the iPAddress SAN (IPv4)
1935 TEST_P(CertVerifyProcNameTest, MatchesIpSanIpv4) {
1936 VerifyCertName("127.0.0.2", true);
1937 }
1938
1939 // Matches the iPAddress SAN (IPv6)
1940 TEST_P(CertVerifyProcNameTest, MatchesIpSanIpv6) {
1941 VerifyCertName("FE80:0:0:0:0:0:0:1", true);
1942 }
1943
1944 // Should not match the iPAddress SAN
1945 TEST_P(CertVerifyProcNameTest, DoesntMatchIpSanIpv6) {
1946 VerifyCertName("[FE80:0:0:0:0:0:0:1]", false);
1947 }
1948
1949 // Compressed form matches the iPAddress SAN (IPv6)
1950 TEST_P(CertVerifyProcNameTest, MatchesIpSanCompressedIpv6) {
1951 VerifyCertName("FE80::1", true);
1952 }
1953
1954 // IPv6 mapped form should NOT match iPAddress SAN
1955 TEST_P(CertVerifyProcNameTest, DoesntMatchIpSanIPv6Mapped) {
1956 VerifyCertName("::127.0.0.2", false);
1957 }
1958
1959 // Matches the dNSName SAN
1960 TEST_P(CertVerifyProcNameTest, MatchesDnsSan) {
1961 VerifyCertName("test.example", true);
1962 }
1963
1964 // Matches the dNSName SAN (trailing . ignored)
1965 TEST_P(CertVerifyProcNameTest, MatchesDnsSanTrailingDot) {
1966 VerifyCertName("test.example.", true);
1967 }
1968
1969 // Should not match the dNSName SAN
1970 TEST_P(CertVerifyProcNameTest, DoesntMatchDnsSan) {
1971 VerifyCertName("www.test.example", false);
1972 }
1973
1974 // Should not match the dNSName SAN
1975 TEST_P(CertVerifyProcNameTest, DoesntMatchDnsSanInvalid) {
1976 VerifyCertName("test..example", false);
1977 }
1978
1979 // Should not match the dNSName SAN
1980 TEST_P(CertVerifyProcNameTest, DoesntMatchDnsSanTwoTrailingDots) {
1981 VerifyCertName("test.example..", false);
1982 }
1983
1984 // Should not match the dNSName SAN
1985 TEST_P(CertVerifyProcNameTest, DoesntMatchDnsSanLeadingAndTrailingDot) {
1986 VerifyCertName(".test.example.", false);
1987 }
1988
1989 // Should not match the dNSName SAN
1990 TEST_P(CertVerifyProcNameTest, DoesntMatchDnsSanTrailingDot) {
1991 VerifyCertName(".test.example", false);
1992 }
1993
1994 INSTANTIATE_TEST_CASE_P(VerifyName,
1995 CertVerifyProcNameTest,
1996 testing::ValuesIn(kAllCertVerifiers),
1997 VerifyProcTypeToName);
1998
1999 #if defined(OS_MACOSX) && !defined(OS_IOS)
2000 // Test that CertVerifyProcMac reacts appropriately when Apple's certificate 192 // Test that CertVerifyProcMac reacts appropriately when Apple's certificate
2001 // verifier rejects a certificate with a fatal error. This is a regression 193 // verifier rejects a certificate with a fatal error. This is a regression
2002 // test for https://crbug.com/472291. 194 // test for https://crbug.com/472291.
2003 // (Since 10.12, this causes a recoverable error instead of a fatal one.) 195 // (Since 10.12, this causes a recoverable error instead of a fatal one.)
2004 // TODO(mattm): Try to find a different way to cause a fatal error that works 196 // TODO(mattm): Try to find a different way to cause a fatal error that works
2005 // on 10.12. 197 // on 10.12.
2006 TEST(CertVerifyProcMacTest, LargeKey) { 198 TEST(CertVerifyProcMacTest, LargeKey) {
2007 // Load root_ca_cert.pem into the test root store. 199 // Load root_ca_cert.pem into the test root store.
2008 ScopedTestRoot test_root( 200 ScopedTestRoot test_root(
2009 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem").get()); 201 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem").get());
2010 202
2011 scoped_refptr<X509Certificate> cert( 203 scoped_refptr<X509Certificate> cert(
2012 ImportCertFromFile(GetTestCertsDirectory(), "large_key.pem")); 204 ImportCertFromFile(GetTestCertsDirectory(), "large_key.pem"));
2013 205
2014 // Apple's verifier rejects this certificate as invalid because the 206 // Apple's verifier rejects this certificate as invalid because the
2015 // RSA key is too large. If a future version of OS X changes this, 207 // RSA key is too large. If a future version of OS X changes this,
2016 // large_key.pem may need to be regenerated with a larger key. 208 // large_key.pem may need to be regenerated with a larger key.
2017 int flags = 0; 209 int flags = 0;
2018 CertVerifyResult verify_result; 210 CertVerifyResult verify_result;
2019 scoped_refptr<CertVerifyProc> verify_proc = CertVerifyProc::CreateDefault(); 211 scoped_refptr<CertVerifyProc> verify_proc = new CertVerifyProcMac;
2020 int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, 212 int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags,
2021 NULL, CertificateList(), &verify_result); 213 NULL, CertificateList(), &verify_result);
2022 EXPECT_THAT(error, IsError(ERR_CERT_INVALID)); 214 EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
2023 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID); 215 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
2024 } 216 }
2025 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
2026 217
2027 // Tests that CertVerifyProc records a histogram correctly when a 218 } // namespace
2028 // certificate chaining to a private root contains the TLS feature
2029 // extension and does not have a stapled OCSP response.
2030 TEST(CertVerifyProcTest, HasTLSFeatureExtensionUMA) {
2031 base::HistogramTester histograms;
2032 scoped_refptr<X509Certificate> cert(
2033 ImportCertFromFile(GetTestCertsDirectory(), "tls_feature_extension.pem"));
2034 ASSERT_TRUE(cert);
2035 CertVerifyResult result;
2036 result.is_issued_by_known_root = false;
2037 scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result);
2038
2039 histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0);
2040 histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0);
2041
2042 int flags = 0;
2043 CertVerifyResult verify_result;
2044 int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags,
2045 NULL, CertificateList(), &verify_result);
2046 EXPECT_EQ(OK, error);
2047 histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 1);
2048 histograms.ExpectBucketCount(kTLSFeatureExtensionHistogram, true, 1);
2049 histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 1);
2050 histograms.ExpectBucketCount(kTLSFeatureExtensionOCSPHistogram, false, 1);
2051 }
2052
2053 // Tests that CertVerifyProc records a histogram correctly when a
2054 // certificate chaining to a private root contains the TLS feature
2055 // extension and does have a stapled OCSP response.
2056 TEST(CertVerifyProcTest, HasTLSFeatureExtensionWithStapleUMA) {
2057 base::HistogramTester histograms;
2058 scoped_refptr<X509Certificate> cert(
2059 ImportCertFromFile(GetTestCertsDirectory(), "tls_feature_extension.pem"));
2060 ASSERT_TRUE(cert);
2061 CertVerifyResult result;
2062 result.is_issued_by_known_root = false;
2063 scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result);
2064
2065 histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0);
2066 histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0);
2067
2068 int flags = 0;
2069 CertVerifyResult verify_result;
2070 int error =
2071 verify_proc->Verify(cert.get(), "127.0.0.1", "dummy response", flags,
2072 nullptr, CertificateList(), &verify_result);
2073 EXPECT_EQ(OK, error);
2074 histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 1);
2075 histograms.ExpectBucketCount(kTLSFeatureExtensionHistogram, true, 1);
2076 histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 1);
2077 histograms.ExpectBucketCount(kTLSFeatureExtensionOCSPHistogram, true, 1);
2078 }
2079
2080 // Tests that CertVerifyProc records a histogram correctly when a
2081 // certificate chaining to a private root does not contain the TLS feature
2082 // extension.
2083 TEST(CertVerifyProcTest, DoesNotHaveTLSFeatureExtensionUMA) {
2084 base::HistogramTester histograms;
2085 scoped_refptr<X509Certificate> cert(
2086 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"));
2087 ASSERT_TRUE(cert);
2088 CertVerifyResult result;
2089 result.is_issued_by_known_root = false;
2090 scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result);
2091
2092 histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0);
2093 histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0);
2094
2095 int flags = 0;
2096 CertVerifyResult verify_result;
2097 int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags,
2098 NULL, CertificateList(), &verify_result);
2099 EXPECT_EQ(OK, error);
2100 histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 1);
2101 histograms.ExpectBucketCount(kTLSFeatureExtensionHistogram, false, 1);
2102 histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0);
2103 }
2104
2105 // Tests that CertVerifyProc does not record a histogram when a
2106 // certificate contains the TLS feature extension but chains to a public
2107 // root.
2108 TEST(CertVerifyProcTest, HasTLSFeatureExtensionWithPublicRootUMA) {
2109 base::HistogramTester histograms;
2110 scoped_refptr<X509Certificate> cert(
2111 ImportCertFromFile(GetTestCertsDirectory(), "tls_feature_extension.pem"));
2112 ASSERT_TRUE(cert);
2113 CertVerifyResult result;
2114 result.is_issued_by_known_root = true;
2115 scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result);
2116
2117 histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0);
2118
2119 int flags = 0;
2120 CertVerifyResult verify_result;
2121 int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags,
2122 NULL, CertificateList(), &verify_result);
2123 EXPECT_EQ(OK, error);
2124 histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0);
2125 histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0);
2126 }
2127 219
2128 } // namespace net 220 } // namespace net
OLDNEW
« no previous file with comments | « net/cert/cert_verify_proc_mac.h ('k') | net/cert/cert_verify_proc_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698