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

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

Issue 1557133002: Perform CRLSet evaluation during Path Building on Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More tests Created 4 years, 11 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 | « no previous file | net/cert/cert_verify_proc_win.cc » ('j') | net/cert/cert_verify_proc_win.cc » ('J')
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 (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 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after
1353 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set)); 1353 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
1354 1354
1355 error = Verify(leaf.get(), 1355 error = Verify(leaf.get(),
1356 "test.example.com", 1356 "test.example.com",
1357 flags, 1357 flags,
1358 crl_set.get(), 1358 crl_set.get(),
1359 empty_cert_list_, 1359 empty_cert_list_,
1360 &verify_result); 1360 &verify_result);
1361 EXPECT_EQ(ERR_CERT_REVOKED, error); 1361 EXPECT_EQ(ERR_CERT_REVOKED, error);
1362 } 1362 }
1363
1364 // Test that when multiple paths exist for a certificate to be verified, and
1365 // one of them is revoked by a CRLSet, that the alternate and still valid
1366 // paths are considered.
1367 // This tests when the leaf (A) is issued by B, which is issued by C. Two
1368 // different versions of C exist, but both versions are signed by a trust
1369 // anchor (D and F, respectively).
1370 TEST_F(CertVerifyProcTest, CRLSetRevokedIntermediateSameName) {
1371 // Load the supplemental certificates for path building (B, C) into memory.
1372 CertificateList ca_cert_list = CreateCertificateListFromFile(
1373 GetTestCertsDirectory(), "multi-root-chain1.pem",
davidben 2016/01/21 02:37:39 Seeing as the tests themselves disassemble the pre
1374 X509Certificate::FORMAT_AUTO);
1375 ASSERT_EQ(4U, ca_cert_list.size());
1376
1377 // Add the "D" test root.
1378 ScopedTestRoot test_root(ca_cert_list[3].get());
1379
1380 CertificateList cert_list = CreateCertificateListFromFile(
1381 GetTestCertsDirectory(), "multi-root-chain3.pem",
1382 X509Certificate::FORMAT_AUTO);
1383 ASSERT_EQ(4U, cert_list.size());
1384
1385 // Add the "F" test root.
1386 ScopedTestRoot second_test_root(cert_list[3].get());
1387
1388 // Create a certificate chain that sends
1389 // A -> B -> C3 -> C
1390 // This is way of ensuring that both versions of C are supplied as
1391 // supplemental certificates to be verified. The
1392 // CertVerifyProcTest.VerifyReturnChainFiltersUnrelatedCerts test ensures that
1393 // these should not negatively impact chain building, as they would otherwise
1394 // be treated as 'ignorable' certificates.
1395 X509Certificate::OSCertHandles intermediates;
1396 intermediates.push_back(cert_list[1]->os_cert_handle());
1397 intermediates.push_back(cert_list[2]->os_cert_handle());
1398 intermediates.push_back(ca_cert_list[2]->os_cert_handle());
1399 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
1400 cert_list[0]->os_cert_handle(), intermediates);
1401 ASSERT_TRUE(cert.get());
1402
1403 // Verify that, without any revocation, things verify successfully and
1404 // prefer the newer (to be revoked) certificate.
1405 int flags = 0;
1406 CertVerifyResult verify_result;
1407 int error = Verify(cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_,
1408 &verify_result);
1409 ASSERT_EQ(OK, error);
1410 ASSERT_EQ(0U, verify_result.cert_status);
1411 ASSERT_TRUE(verify_result.verified_cert.get());
1412
1413 // Ensure the first / newest chain provided is preferred - as this is the
1414 // chain that will subsequently be revoked.
1415 // The expected path is A -> B -> C3 -> F
1416 const X509Certificate::OSCertHandles& verified_intermediates =
1417 verify_result.verified_cert->GetIntermediateCertificates();
1418 ASSERT_EQ(3U, verified_intermediates.size());
1419 scoped_refptr<X509Certificate> verified_root =
1420 X509Certificate::CreateFromHandle(verified_intermediates[2],
1421 X509Certificate::OSCertHandles());
1422 ASSERT_TRUE(verified_root.get());
1423 EXPECT_EQ("F Root CA", verified_root->subject().common_name);
davidben 2016/01/21 02:37:39 It seems these tests could do with a few helper fu
Ryan Sleevi 2016/01/21 02:54:04 This is strongly discouraged by our internal testi
1424
1425 // Now test by blocking the C3-by-F intermediate, which should result
1426 // in a path of A -> B -> C -> D
1427 scoped_refptr<CRLSet> crl_set;
1428 std::string crl_set_bytes;
1429 EXPECT_TRUE(base::ReadFileToString(
1430 GetTestCertsDirectory().AppendASCII("multi-root-crlset-C3.raw"),
1431 &crl_set_bytes));
1432 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
1433
1434 error = Verify(cert.get(), "127.0.0.1", flags, crl_set.get(),
1435 empty_cert_list_, &verify_result);
1436 ASSERT_EQ(OK, error);
1437 ASSERT_EQ(0U, verify_result.cert_status);
1438 ASSERT_TRUE(verify_result.verified_cert.get());
1439
1440 const X509Certificate::OSCertHandles& new_verified_intermediates =
1441 verify_result.verified_cert->GetIntermediateCertificates();
1442 ASSERT_EQ(3U, new_verified_intermediates.size());
1443 verified_root = X509Certificate::CreateFromHandle(
1444 new_verified_intermediates[2], X509Certificate::OSCertHandles());
1445 ASSERT_TRUE(verified_root.get());
1446 EXPECT_EQ("D Root CA", verified_root->subject().common_name);
1447
1448 // Now reverify the cert without the CRLSet, to ensure that the CRLSet does
1449 // not persist in between independent calls.
1450 error = Verify(cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_,
1451 &verify_result);
1452 ASSERT_EQ(OK, error);
1453 ASSERT_EQ(0U, verify_result.cert_status);
1454 ASSERT_TRUE(verify_result.verified_cert.get());
1455
1456 // The expected path is A -> B -> C3 -> F
1457 const X509Certificate::OSCertHandles& final_verified_intermediates =
1458 verify_result.verified_cert->GetIntermediateCertificates();
1459 ASSERT_EQ(3U, final_verified_intermediates.size());
1460 verified_root = X509Certificate::CreateFromHandle(
1461 final_verified_intermediates[2], X509Certificate::OSCertHandles());
1462 ASSERT_TRUE(verified_root.get());
1463 EXPECT_EQ("F Root CA", verified_root->subject().common_name);
1464 }
1465
1466 // Test that when multiple paths exist for a certificate to be verified, and
1467 // one of them is revoked by a CRLSet, that the alternate and still valid
1468 // paths are considered.
1469 // This tests when the leaf (A) is issued by B. Two versions of B
1470 // exist - one that goes to G and one that goes to C. Both G and C
1471 // are signed by trust anchors (F and D/E/F, respectively). This tests
1472 // the ability of path building to explore an edge where the immediate
1473 // certificate is not revoked, but the issuer is (in this case, G) - and thus
1474 // needs to backtrack to find the alternative path (B -> C -> D)
1475 TEST_F(CertVerifyProcTest, CRLSetRevokedIntermediateCrossIntermediates) {
1476 // Load the supplemental certificates for path building (B, C) into memory.
1477 CertificateList ca_cert_list = CreateCertificateListFromFile(
1478 GetTestCertsDirectory(), "multi-root-chain1.pem",
1479 X509Certificate::FORMAT_AUTO);
1480 ASSERT_EQ(4U, ca_cert_list.size());
1481
1482 // Add the "D" test root.
1483 ScopedTestRoot test_root(ca_cert_list[3].get());
1484
1485 CertificateList cert_list = CreateCertificateListFromFile(
1486 GetTestCertsDirectory(), "multi-root-chain4.pem",
1487 X509Certificate::FORMAT_AUTO);
1488 ASSERT_EQ(4U, cert_list.size());
1489
1490 // Add the "F" test root.
1491 ScopedTestRoot second_test_root(cert_list[3].get());
1492
1493 // Create a certificate chain that sends
1494 // A -> B2 -> G -> B -> C
1495 // This is way of ensuring that both B and C are supplied as supplemental
1496 // certificates to be verified. The
1497 // CertVerifyProcTest.VerifyReturnChainFiltersUnrelatedCerts test ensures that
1498 // these should not negatively impact chain building, as they would otherwise
1499 // be treated as 'ignorable' certificates.
1500 X509Certificate::OSCertHandles intermediates;
1501 intermediates.push_back(cert_list[1]->os_cert_handle());
1502 intermediates.push_back(cert_list[2]->os_cert_handle());
1503 intermediates.push_back(ca_cert_list[1]->os_cert_handle());
1504 intermediates.push_back(ca_cert_list[2]->os_cert_handle());
1505 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
1506 cert_list[0]->os_cert_handle(), intermediates);
1507 ASSERT_TRUE(cert.get());
1508
1509 // Verify that, without any revocation, things verify successfully and
1510 // prefer the newer (to be revoked) certificate.
1511 int flags = 0;
1512 CertVerifyResult verify_result;
1513 int error = Verify(cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_,
1514 &verify_result);
1515 ASSERT_EQ(OK, error);
1516 ASSERT_EQ(0U, verify_result.cert_status);
1517 ASSERT_TRUE(verify_result.verified_cert.get());
1518
1519 // Ensure the first / newest chain provided is preferred - as this is the
1520 // chain that will subsequently be revoked.
1521 // The expected path is A -> B2 -> G -> F
1522 const X509Certificate::OSCertHandles& verified_intermediates =
1523 verify_result.verified_cert->GetIntermediateCertificates();
1524 ASSERT_EQ(3U, verified_intermediates.size());
1525 scoped_refptr<X509Certificate> verified_root =
1526 X509Certificate::CreateFromHandle(verified_intermediates[2],
1527 X509Certificate::OSCertHandles());
1528 ASSERT_TRUE(verified_root.get());
1529 EXPECT_EQ("F Root CA", verified_root->subject().common_name);
1530 scoped_refptr<X509Certificate> verified_intermediate =
1531 X509Certificate::CreateFromHandle(verified_intermediates[1],
1532 X509Certificate::OSCertHandles());
1533 ASSERT_TRUE(verified_intermediate.get());
1534 EXPECT_EQ("G CA", verified_intermediate->subject().common_name);
1535
1536 // Now test by blocking the G-by-F intermediate, which should result
1537 // in a path of A -> B -> C -> D
1538 scoped_refptr<CRLSet> crl_set;
1539 std::string crl_set_bytes;
1540 EXPECT_TRUE(base::ReadFileToString(
1541 GetTestCertsDirectory().AppendASCII("multi-root-crlset-G.raw"),
1542 &crl_set_bytes));
1543 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
1544
1545 error = Verify(cert.get(), "127.0.0.1", flags, crl_set.get(),
1546 empty_cert_list_, &verify_result);
1547 ASSERT_EQ(OK, error);
1548 ASSERT_EQ(0U, verify_result.cert_status);
1549 ASSERT_TRUE(verify_result.verified_cert.get());
1550
1551 const X509Certificate::OSCertHandles& new_verified_intermediates =
1552 verify_result.verified_cert->GetIntermediateCertificates();
1553 ASSERT_EQ(3U, new_verified_intermediates.size());
1554 verified_root = X509Certificate::CreateFromHandle(
1555 new_verified_intermediates[2], X509Certificate::OSCertHandles());
1556 ASSERT_TRUE(verified_root.get());
1557 EXPECT_EQ("D Root CA", verified_root->subject().common_name);
1558
1559 // Now reverify the cert without the CRLSet, to ensure that the CRLSet does
1560 // not persist in between independent calls.
1561 error = Verify(cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_,
1562 &verify_result);
1563 ASSERT_EQ(OK, error);
1564 ASSERT_EQ(0U, verify_result.cert_status);
1565 ASSERT_TRUE(verify_result.verified_cert.get());
1566
1567 const X509Certificate::OSCertHandles& final_verified_intermediates =
1568 verify_result.verified_cert->GetIntermediateCertificates();
1569 ASSERT_EQ(3U, final_verified_intermediates.size());
1570 verified_root = X509Certificate::CreateFromHandle(
1571 final_verified_intermediates[2], X509Certificate::OSCertHandles());
1572 ASSERT_TRUE(verified_root.get());
1573 EXPECT_EQ("F Root CA", verified_root->subject().common_name);
1574 }
1575
1576 // Test that when multiple paths exist for a certificate to be verified, and
1577 // one of them is revoked by a CRLSet, that the alternate and still valid
1578 // paths are considered.
1579 // This tests a variety of situations in which a CA has cyclicly certified
1580 // the certificates (e.g. Root J signed Root K, and Root K signed Root J).
1581 // When both of these roots are present in the trust store (J and K), but
1582 // one is revoked (K), paths should build and terminate in J.
1583 // This tests when the leaf (A) is issued by B. Two versions of B
1584 // exist - one that goes to G and one that goes to C. Both G and C
1585 // are signed by trust anchors (F and D/E/F, respectively). This tests
1586 // the ability of path building to explore an edge where the immediate
1587 // certificate is not revoked, but the issuer is (in this case, G) - and thus
1588 // needs to backtrack to find the alternative path (B -> C -> D)
1589 TEST_F(CertVerifyProcTest, CRLSetRevokedCyclicPathBuilding) {
1590 // Load the supplemental certificates for path building (B, C) into memory.
1591 CertificateList ca_cert_list = CreateCertificateListFromFile(
1592 GetTestCertsDirectory(), "multi-root-chain5.pem",
1593 X509Certificate::FORMAT_AUTO);
1594 ASSERT_EQ(3U, ca_cert_list.size());
1595
1596 struct TestData {
1597 // The name of the chain file to load.
1598 const char* const filename;
1599 // The expected length of the (parsed, validated) chain.
1600 const size_t chain_length;
1601 } kTestChains[] = {
1602 {"multi-root-chain6.pem", 4},
1603 {"multi-root-chain7.pem", 5},
1604 {"multi-root-chain8.pem", 6},
1605 };
1606 for (const auto& test_case : kTestChains) {
1607 SCOPED_TRACE(test_case.filename);
1608
1609 CertificateList cert_list = CreateCertificateListFromFile(
1610 GetTestCertsDirectory(), test_case.filename,
1611 X509Certificate::FORMAT_AUTO);
1612 ASSERT_EQ(test_case.chain_length, cert_list.size());
1613
1614 // Add the "J" test root.
1615 ScopedTestRoot test_root(ca_cert_list[2].get());
1616
1617 // Add the chain root as a test root
1618 ScopedTestRoot second_test_root(cert_list.back().get());
1619
1620 // Create a certificate chain that sends everything but the last
1621 // certificate.
1622 cert_list.pop_back();
1623 X509Certificate::OSCertHandles intermediates;
1624 for (size_t i = 1; i < cert_list.size(); ++i) {
1625 intermediates.push_back(cert_list[i]->os_cert_handle());
1626 }
1627 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
1628 cert_list[0]->os_cert_handle(), intermediates);
1629 ASSERT_TRUE(cert.get());
1630
1631 // Verify that, without any revocation, the certificate verifies
1632 // successfully.
1633 int flags = 0;
1634 CertVerifyResult verify_result;
1635 int error = Verify(cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_,
1636 &verify_result);
1637 ASSERT_EQ(OK, error);
1638 ASSERT_EQ(0U, verify_result.cert_status);
1639 ASSERT_TRUE(verify_result.verified_cert.get());
1640
1641 // Now test by blocking K, which should result in a path of H -> I -> J
1642 scoped_refptr<CRLSet> crl_set;
1643 std::string crl_set_bytes;
1644 EXPECT_TRUE(base::ReadFileToString(
1645 GetTestCertsDirectory().AppendASCII("multi-root-crlset-K.raw"),
1646 &crl_set_bytes));
1647 ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set));
1648
1649 error = Verify(cert.get(), "127.0.0.1", flags, crl_set.get(),
1650 empty_cert_list_, &verify_result);
1651 ASSERT_EQ(OK, error);
1652 ASSERT_EQ(0U, verify_result.cert_status);
1653 ASSERT_TRUE(verify_result.verified_cert.get());
1654
1655 const X509Certificate::OSCertHandles& new_verified_intermediates =
1656 verify_result.verified_cert->GetIntermediateCertificates();
1657 ASSERT_EQ(2U, new_verified_intermediates.size());
1658 scoped_refptr<X509Certificate> verified_root =
1659 X509Certificate::CreateFromHandle(new_verified_intermediates[1],
1660 X509Certificate::OSCertHandles());
1661 ASSERT_TRUE(verified_root.get());
1662 EXPECT_EQ("J Root CA", verified_root->subject().common_name);
1663 }
1664 }
1665
1363 #endif 1666 #endif
1364 1667
1365 enum ExpectedAlgorithms { 1668 enum ExpectedAlgorithms {
1366 EXPECT_MD2 = 1 << 0, 1669 EXPECT_MD2 = 1 << 0,
1367 EXPECT_MD4 = 1 << 1, 1670 EXPECT_MD4 = 1 << 1,
1368 EXPECT_MD5 = 1 << 2, 1671 EXPECT_MD5 = 1 << 2,
1369 EXPECT_SHA1 = 1 << 3, 1672 EXPECT_SHA1 = 1 << 3,
1370 EXPECT_SHA1_LEAF = 1 << 4, 1673 EXPECT_SHA1_LEAF = 1 << 4,
1371 }; 1674 };
1372 1675
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1705 int flags = 0; 2008 int flags = 0;
1706 CertVerifyResult verify_result; 2009 CertVerifyResult verify_result;
1707 int error = Verify(cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, 2010 int error = Verify(cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_,
1708 &verify_result); 2011 &verify_result);
1709 EXPECT_EQ(ERR_CERT_INVALID, error); 2012 EXPECT_EQ(ERR_CERT_INVALID, error);
1710 EXPECT_EQ(CERT_STATUS_INVALID, verify_result.cert_status); 2013 EXPECT_EQ(CERT_STATUS_INVALID, verify_result.cert_status);
1711 } 2014 }
1712 #endif // defined(OS_MACOSX) && !defined(OS_IOS) 2015 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
1713 2016
1714 } // namespace net 2017 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/cert/cert_verify_proc_win.cc » ('j') | net/cert/cert_verify_proc_win.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698