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

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

Issue 2101303005: CertVerifyProcMac: Add Keychain re-ordering hack, check CRLsets in path pruning loop. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: review changes and url_request_unittest fixes Created 4 years, 5 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 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.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
(...skipping 15 matching lines...) Expand all
26 #include "net/cert/test_root_certs.h" 26 #include "net/cert/test_root_certs.h"
27 #include "net/cert/x509_certificate.h" 27 #include "net/cert/x509_certificate.h"
28 #include "net/test/cert_test_util.h" 28 #include "net/test/cert_test_util.h"
29 #include "net/test/test_certificate_data.h" 29 #include "net/test/test_certificate_data.h"
30 #include "testing/gtest/include/gtest/gtest.h" 30 #include "testing/gtest/include/gtest/gtest.h"
31 31
32 #if defined(OS_ANDROID) 32 #if defined(OS_ANDROID)
33 #include "base/android/build_info.h" 33 #include "base/android/build_info.h"
34 #endif 34 #endif
35 35
36 #if defined(OS_MACOSX) && !defined(OS_IOS)
37 #include "net/cert/test_keychain_search_list_mac.h"
38 #endif
39
36 using base::HexEncode; 40 using base::HexEncode;
37 41
38 namespace net { 42 namespace net {
39 43
40 namespace { 44 namespace {
41 45
42 // A certificate for www.paypal.com with a NULL byte in the common name. 46 // A certificate for www.paypal.com with a NULL byte in the common name.
43 // From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363 47 // From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363
44 unsigned char paypal_null_fingerprint[] = { 48 unsigned char paypal_null_fingerprint[] = {
45 0x4c, 0x88, 0x9e, 0x28, 0xd7, 0x7a, 0x44, 0x1e, 0x13, 0xf2, 0x6a, 0xba, 49 0x4c, 0x88, 0x9e, 0x28, 0xd7, 0x7a, 0x44, 0x1e, 0x13, 0xf2, 0x6a, 0xba,
(...skipping 1287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1333 EXPECT_TRUE(testcase.expected_intermediate->Equals(intermediate.get())) 1337 EXPECT_TRUE(testcase.expected_intermediate->Equals(intermediate.get()))
1334 << "Expected: " << testcase.expected_intermediate->subject().common_name 1338 << "Expected: " << testcase.expected_intermediate->subject().common_name
1335 << " issued by " << testcase.expected_intermediate->issuer().common_name 1339 << " issued by " << testcase.expected_intermediate->issuer().common_name
1336 << "; Got: " << intermediate->subject().common_name << " issued by " 1340 << "; Got: " << intermediate->subject().common_name << " issued by "
1337 << intermediate->issuer().common_name; 1341 << intermediate->issuer().common_name;
1338 } 1342 }
1339 } 1343 }
1340 1344
1341 #endif 1345 #endif
1342 1346
1347 #if defined(OS_MACOSX) && !defined(OS_IOS)
1348 // Test that a CRLSet blocking one of the intermediates supplied by the server
1349 // can be worked around by the chopping workaround for path building. (Once the
1350 // supplied chain is chopped back to just the target, a better path can be
1351 // found out-of-band. Normally that would be by AIA fetching, for the purposes
1352 // of this test the better path is supplied by a test keychain.)
1353 //
1354 // In this test, there are two possible paths to validate a leaf (A):
1355 // 1. A(B) -> B(C) -> C(E) -> E(E)
1356 // 2. A(B) -> B(F) -> F(E) -> E(E)
1357 //
1358 // A(B) -> B(C) -> C(E) is supplied to the verifier.
1359 // B(F) and F(E) are supplied in a test keychain.
1360 // C is blocked by a CRLset.
1361 //
1362 // The verifier should rollback until it just tries A(B) alone, at which point
1363 // it will pull B(F) & F(E) from the keychain and succeed.
1364 TEST_F(CertVerifyProcTest, MacCRLIntermediate) {
1365 const char* const kPath2Files[] = {
1366 "multi-root-A-by-B.pem", "multi-root-B-by-C.pem", "multi-root-C-by-E.pem",
1367 "multi-root-E-by-E.pem"};
1368 CertificateList path_2_certs;
1369 ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath2Files, &path_2_certs));
1370
1371 const char* const kPath3Files[] = {
1372 "multi-root-A-by-B.pem", "multi-root-B-by-F.pem", "multi-root-F-by-E.pem",
1373 "multi-root-E-by-E.pem"};
1374
1375 CertificateList path_3_certs;
1376 ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath3Files, &path_3_certs));
1377
1378 // Add E as trust anchor.
1379 ScopedTestRoot test_root_E(path_3_certs[3].get()); // E-by-E
1380
1381 X509Certificate::OSCertHandles intermediates;
1382 intermediates.push_back(path_2_certs[1]->os_cert_handle()); // B-by-C
1383 intermediates.push_back(path_2_certs[2]->os_cert_handle()); // C-by-E
1384 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
1385 path_3_certs[0]->os_cert_handle(), intermediates);
1386 ASSERT_TRUE(cert);
1387
1388 std::unique_ptr<TestKeychainSearchList> test_keychain_search_list(
1389 TestKeychainSearchList::Create());
1390 ASSERT_TRUE(test_keychain_search_list);
1391
1392 base::FilePath keychain_path(
1393 GetTestCertsDirectory().AppendASCII("multi-root-BFE.keychain"));
1394 // SecKeychainOpen does not fail if the file doesn't exist, so assert it here
1395 // for easier debugging.
1396 ASSERT_TRUE(base::PathExists(keychain_path));
1397 SecKeychainRef keychain;
1398 OSStatus status =
1399 SecKeychainOpen(keychain_path.MaybeAsASCII().c_str(), &keychain);
1400 ASSERT_EQ(errSecSuccess, status);
1401 ASSERT_TRUE(keychain);
1402 base::ScopedCFTypeRef<SecKeychainRef> scoped_keychain(keychain);
1403 test_keychain_search_list->AddKeychain(keychain);
1404
1405 scoped_refptr<CRLSet> crl_set;
1406 std::string crl_set_bytes;
1407 // CRL which blocks C by SPKI.
1408 EXPECT_TRUE(base::ReadFileToString(
1409 GetTestCertsDirectory().AppendASCII("multi-root-crlset-C.raw"),
1410 &crl_set_bytes));
1411 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
1412
1413 int flags = 0;
1414 CertVerifyResult verify_result;
1415 int error = Verify(cert.get(), "127.0.0.1", flags, crl_set.get(),
1416 empty_cert_list_, &verify_result);
1417
1418 ASSERT_EQ(OK, error);
1419 ASSERT_EQ(0U, verify_result.cert_status);
1420 ASSERT_TRUE(verify_result.verified_cert.get());
1421
1422 const X509Certificate::OSCertHandles& verified_intermediates =
1423 verify_result.verified_cert->GetIntermediateCertificates();
1424 ASSERT_EQ(3U, verified_intermediates.size());
1425
1426 scoped_refptr<X509Certificate> intermediate =
1427 X509Certificate::CreateFromHandle(verified_intermediates[1],
1428 X509Certificate::OSCertHandles());
1429 ASSERT_TRUE(intermediate);
1430
1431 scoped_refptr<X509Certificate> expected_intermediate = path_3_certs[2];
1432 EXPECT_TRUE(expected_intermediate->Equals(intermediate.get()))
1433 << "Expected: " << expected_intermediate->subject().common_name
1434 << " issued by " << expected_intermediate->issuer().common_name
1435 << "; Got: " << intermediate->subject().common_name << " issued by "
1436 << intermediate->issuer().common_name;
1437 }
1438
1439 // Test that if a keychain is present which trusts a less-desirable root (ex,
1440 // one using SHA1), that the keychain reordering hack will cause the better
1441 // root in the System Roots to be used instead.
1442 TEST_F(CertVerifyProcTest, MacKeychainReordering) {
1443 // Note: target cert expires Apr 2 23:59:59 2018 GMT
1444 scoped_refptr<X509Certificate> cert = CreateCertificateChainFromFile(
1445 GetTestCertsDirectory(), "tripadvisor-verisign-chain.pem",
Ryan Sleevi 2016/08/12 19:50:17 Can we generate a test cert that demonstrates the
mattm 2016/08/16 01:41:34 I didn't like including this, but I think to do th
Ryan Sleevi 2016/08/17 02:28:12 Can we get away without hardcoding SytemRootCertif
mattm 2016/08/17 03:50:57 Unfortunately, SystemRootCertificates is not in th
1446 X509Certificate::FORMAT_AUTO);
1447 ASSERT_TRUE(cert);
1448
1449 // Create a test keychain search list that will Always Trust the SHA1
1450 // cross-signed VeriSign Class 3 Public Primary Certification Authority - G5
1451 std::unique_ptr<TestKeychainSearchList> test_keychain_search_list(
1452 TestKeychainSearchList::Create());
1453 ASSERT_TRUE(test_keychain_search_list);
1454
1455 base::FilePath keychain_path(GetTestCertsDirectory().AppendASCII(
1456 "verisign_class3_g5_crosssigned-trusted.keychain"));
1457 // SecKeychainOpen does not fail if the file doesn't exist, so assert it here
1458 // for easier debugging.
1459 ASSERT_TRUE(base::PathExists(keychain_path));
1460 SecKeychainRef keychain;
1461 OSStatus status =
1462 SecKeychainOpen(keychain_path.MaybeAsASCII().c_str(), &keychain);
1463 ASSERT_EQ(errSecSuccess, status);
1464 ASSERT_TRUE(keychain);
1465 base::ScopedCFTypeRef<SecKeychainRef> scoped_keychain(keychain);
1466 test_keychain_search_list->AddKeychain(keychain);
1467
1468 int flags = 0;
1469 CertVerifyResult verify_result;
1470 int error = Verify(cert.get(), "www.tripadvisor.com", flags,
1471 nullptr /* crl_set */, empty_cert_list_, &verify_result);
1472
1473 ASSERT_EQ(OK, error);
1474 EXPECT_EQ(0U, verify_result.cert_status);
1475 EXPECT_FALSE(verify_result.has_sha1);
1476 ASSERT_TRUE(verify_result.verified_cert.get());
1477
1478 const X509Certificate::OSCertHandles& verified_intermediates =
1479 verify_result.verified_cert->GetIntermediateCertificates();
1480 ASSERT_EQ(2U, verified_intermediates.size());
1481 }
1482 #endif
1483
1343 enum ExpectedAlgorithms { 1484 enum ExpectedAlgorithms {
1344 EXPECT_MD2 = 1 << 0, 1485 EXPECT_MD2 = 1 << 0,
1345 EXPECT_MD4 = 1 << 1, 1486 EXPECT_MD4 = 1 << 1,
1346 EXPECT_MD5 = 1 << 2, 1487 EXPECT_MD5 = 1 << 2,
1347 EXPECT_SHA1 = 1 << 3, 1488 EXPECT_SHA1 = 1 << 3,
1348 EXPECT_SHA1_LEAF = 1 << 4, 1489 EXPECT_SHA1_LEAF = 1 << 4,
1349 }; 1490 };
1350 1491
1351 struct WeakDigestTestData { 1492 struct WeakDigestTestData {
1352 const char* root_cert_filename; 1493 const char* root_cert_filename;
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
1683 int flags = 0; 1824 int flags = 0;
1684 CertVerifyResult verify_result; 1825 CertVerifyResult verify_result;
1685 int error = Verify(cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, 1826 int error = Verify(cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_,
1686 &verify_result); 1827 &verify_result);
1687 EXPECT_EQ(ERR_CERT_INVALID, error); 1828 EXPECT_EQ(ERR_CERT_INVALID, error);
1688 EXPECT_EQ(CERT_STATUS_INVALID, verify_result.cert_status); 1829 EXPECT_EQ(CERT_STATUS_INVALID, verify_result.cert_status);
1689 } 1830 }
1690 #endif // defined(OS_MACOSX) && !defined(OS_IOS) 1831 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
1691 1832
1692 } // namespace net 1833 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698