OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |