OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/file_path.h" | 5 #include "base/file_path.h" |
6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
7 #include "base/path_service.h" | 7 #include "base/path_service.h" |
8 #include "base/pickle.h" | 8 #include "base/pickle.h" |
9 #include "base/sha1.h" | 9 #include "base/sha1.h" |
10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
(...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1285 // Common name, may be used if |dns_names| or |ip_addrs| are empty. | 1285 // Common name, may be used if |dns_names| or |ip_addrs| are empty. |
1286 const char* common_name; | 1286 const char* common_name; |
1287 // Comma separated list of certificate names to match against. Any occurrence | 1287 // Comma separated list of certificate names to match against. Any occurrence |
1288 // of '#' will be replaced with a null character before processing. | 1288 // of '#' will be replaced with a null character before processing. |
1289 const char* dns_names; | 1289 const char* dns_names; |
1290 // Comma separated list of certificate IP Addresses to match against. Each | 1290 // Comma separated list of certificate IP Addresses to match against. Each |
1291 // address is x prefixed 16 byte hex code for v6 or dotted-decimals for v4. | 1291 // address is x prefixed 16 byte hex code for v6 or dotted-decimals for v4. |
1292 const char* ip_addrs; | 1292 const char* ip_addrs; |
1293 }; | 1293 }; |
1294 | 1294 |
1295 // Required by valgrind on mac, otherwise it complains when using its default | 1295 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how |
1296 // printer: | 1296 // to output the parameter that was passed. Without this, it will simply |
1297 // UninitCondition | 1297 // attempt to print out the first twenty bytes of the object, which depending |
1298 // Conditional jump or move depends on uninitialised value(s) | 1298 // on platform and alignment, may result in an invalid read. |
1299 // ... | |
1300 // snprintf | |
1301 // testing::(anonymous namespace)::PrintByteSegmentInObjectTo | |
1302 // testing::internal2::TypeWithoutFormatter | |
1303 // ... | |
1304 void PrintTo(const CertificateNameVerifyTestData& data, std::ostream* os) { | 1299 void PrintTo(const CertificateNameVerifyTestData& data, std::ostream* os) { |
1305 ASSERT_TRUE(data.hostname && data.common_name); | 1300 ASSERT_TRUE(data.hostname && data.common_name); |
1306 // Using StringPiece to allow for optional fields being NULL. | 1301 // Using StringPiece to allow for optional fields being NULL. |
1307 *os << " expected: " << data.expected | 1302 *os << " expected: " << data.expected |
1308 << "; hostname: " << data.hostname | 1303 << "; hostname: " << data.hostname |
1309 << "; common_name: " << data.common_name | 1304 << "; common_name: " << data.common_name |
1310 << "; dns_names: " << base::StringPiece(data.dns_names) | 1305 << "; dns_names: " << base::StringPiece(data.dns_names) |
1311 << "; ip_addrs: " << base::StringPiece(data.ip_addrs); | 1306 << "; ip_addrs: " << base::StringPiece(data.ip_addrs); |
1312 } | 1307 } |
1313 | 1308 |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1498 } | 1493 } |
1499 } | 1494 } |
1500 | 1495 |
1501 EXPECT_EQ(test_data.expected, X509Certificate::VerifyHostname( | 1496 EXPECT_EQ(test_data.expected, X509Certificate::VerifyHostname( |
1502 test_data.hostname, common_name, dns_names, ip_addressses)); | 1497 test_data.hostname, common_name, dns_names, ip_addressses)); |
1503 } | 1498 } |
1504 | 1499 |
1505 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest, | 1500 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest, |
1506 testing::ValuesIn(kNameVerifyTestData)); | 1501 testing::ValuesIn(kNameVerifyTestData)); |
1507 | 1502 |
| 1503 // Not implemented on Mac or OpenSSL - http://crbug.com/101123 |
| 1504 #if defined(USE_NSS) || defined(OS_WIN) |
| 1505 |
| 1506 struct WeakDigestTestData { |
| 1507 const char* root_cert_filename; |
| 1508 const char* intermediate_cert_filename; |
| 1509 const char* ee_cert_filename; |
| 1510 bool expected_has_md5; |
| 1511 bool expected_has_md4; |
| 1512 bool expected_has_md2; |
| 1513 bool expected_has_md5_ca; |
| 1514 bool expected_has_md2_ca; |
| 1515 }; |
| 1516 |
| 1517 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how |
| 1518 // to output the parameter that was passed. Without this, it will simply |
| 1519 // attempt to print out the first twenty bytes of the object, which depending |
| 1520 // on platform and alignment, may result in an invalid read. |
| 1521 void PrintTo(const WeakDigestTestData& data, std::ostream* os) { |
| 1522 *os << "root: " |
| 1523 << (data.root_cert_filename ? data.root_cert_filename : "none") |
| 1524 << "; intermediate: " << data.intermediate_cert_filename |
| 1525 << "; end-entity: " << data.ee_cert_filename; |
| 1526 } |
| 1527 |
| 1528 class X509CertificateWeakDigestTest |
| 1529 : public testing::TestWithParam<WeakDigestTestData> { |
| 1530 public: |
| 1531 X509CertificateWeakDigestTest() {} |
| 1532 |
| 1533 virtual void TearDown() { |
| 1534 TestRootCerts::GetInstance()->Clear(); |
| 1535 } |
| 1536 }; |
| 1537 |
| 1538 TEST_P(X509CertificateWeakDigestTest, Verify) { |
| 1539 WeakDigestTestData data = GetParam(); |
| 1540 FilePath certs_dir = GetTestCertsDirectory(); |
| 1541 |
| 1542 if (data.root_cert_filename) { |
| 1543 scoped_refptr<X509Certificate> root_cert = |
| 1544 ImportCertFromFile(certs_dir, data.root_cert_filename); |
| 1545 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert); |
| 1546 TestRootCerts::GetInstance()->Add(root_cert.get()); |
| 1547 } |
| 1548 |
| 1549 scoped_refptr<X509Certificate> intermediate_cert = |
| 1550 ImportCertFromFile(certs_dir, data.intermediate_cert_filename); |
| 1551 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert); |
| 1552 scoped_refptr<X509Certificate> ee_cert = |
| 1553 ImportCertFromFile(certs_dir, data.ee_cert_filename); |
| 1554 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert); |
| 1555 |
| 1556 X509Certificate::OSCertHandles intermediates; |
| 1557 intermediates.push_back(intermediate_cert->os_cert_handle()); |
| 1558 |
| 1559 scoped_refptr<X509Certificate> ee_chain = |
| 1560 X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(), |
| 1561 intermediates); |
| 1562 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_chain); |
| 1563 |
| 1564 int flags = 0; |
| 1565 CertVerifyResult verify_result; |
| 1566 ee_chain->Verify("127.0.0.1", flags, NULL, &verify_result); |
| 1567 EXPECT_EQ(data.expected_has_md5, verify_result.has_md5); |
| 1568 EXPECT_EQ(data.expected_has_md4, verify_result.has_md4); |
| 1569 EXPECT_EQ(data.expected_has_md2, verify_result.has_md2); |
| 1570 EXPECT_EQ(data.expected_has_md5_ca, verify_result.has_md5_ca); |
| 1571 EXPECT_EQ(data.expected_has_md2_ca, verify_result.has_md2_ca); |
| 1572 } |
| 1573 |
| 1574 // Unlike TEST/TEST_F, which are macros that expand to further macros, |
| 1575 // INSTANTIATE_TEST_CASE_P is a macro that expands directly to code that |
| 1576 // stringizes the arguments. As a result, macros passed as parameters (such as |
| 1577 // prefix or test_case_name) will not be expanded by the preprocessor. To work |
| 1578 // around this, indirect the macro for INSTANTIATE_TEST_CASE_P, so that the |
| 1579 // pre-processor will expand macros such as MAYBE_test_name before |
| 1580 // instantiating the test. |
| 1581 #define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ |
| 1582 INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) |
| 1583 |
| 1584 // The signature algorithm of the root CA should not matter. |
| 1585 const WeakDigestTestData kVerifyRootCATestData[] = { |
| 1586 { "weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem", |
| 1587 "weak_digest_sha1_ee.pem", false, false, false, false, false }, |
| 1588 { "weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem", |
| 1589 "weak_digest_sha1_ee.pem", false, false, false, false, false }, |
| 1590 { "weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem", |
| 1591 "weak_digest_sha1_ee.pem", false, false, false, false, false }, |
| 1592 }; |
| 1593 INSTANTIATE_TEST_CASE_P(VerifyRoot, X509CertificateWeakDigestTest, |
| 1594 testing::ValuesIn(kVerifyRootCATestData)); |
| 1595 |
| 1596 // The signature algorithm of intermediates should be properly detected. |
| 1597 const WeakDigestTestData kVerifyIntermediateCATestData[] = { |
| 1598 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem", |
| 1599 "weak_digest_sha1_ee.pem", true, false, false, true, false }, |
| 1600 // NSS does not support MD4 and does not enable MD2 by policy. |
| 1601 #if !defined(USE_NSS) |
| 1602 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem", |
| 1603 "weak_digest_sha1_ee.pem", false, true, false, false, false }, |
| 1604 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem", |
| 1605 "weak_digest_sha1_ee.pem", false, false, true, false, true }, |
| 1606 #endif |
| 1607 }; |
| 1608 INSTANTIATE_TEST_CASE_P(VerifyIntermediate, X509CertificateWeakDigestTest, |
| 1609 testing::ValuesIn(kVerifyIntermediateCATestData)); |
| 1610 |
| 1611 // The signature algorithm of end-entity should be properly detected. |
| 1612 const WeakDigestTestData kVerifyEndEntityTestData[] = { |
| 1613 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", |
| 1614 "weak_digest_md5_ee.pem", true, false, false, false, false }, |
| 1615 // NSS does not support MD4 and does not enable MD2 by policy. |
| 1616 #if !defined(USE_NSS) |
| 1617 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", |
| 1618 "weak_digest_md4_ee.pem", false, true, false, false, false }, |
| 1619 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", |
| 1620 "weak_digest_md2_ee.pem", false, false, true, false, false }, |
| 1621 #endif |
| 1622 }; |
| 1623 // Disabled on NSS - NSS caches chains/signatures in such a way that cannot |
| 1624 // be cleared until NSS is cleanly shutdown, which is not presently supported |
| 1625 // in Chromium. |
| 1626 #if defined(USE_NSS) |
| 1627 #define MAYBE_VerifyEndEntity DISABLED_VerifyEndEntity |
| 1628 #else |
| 1629 #define MAYBE_VerifyEndEntity VerifyEndEntity |
| 1630 #endif |
| 1631 WRAPPED_INSTANTIATE_TEST_CASE_P(MAYBE_VerifyEndEntity, |
| 1632 X509CertificateWeakDigestTest, |
| 1633 testing::ValuesIn(kVerifyEndEntityTestData)); |
| 1634 |
| 1635 // Incomplete chains should still report the status of the intermediate. |
| 1636 const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] = { |
| 1637 { NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem", |
| 1638 true, false, false, true, false }, |
| 1639 { NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem", |
| 1640 false, true, false, false, false }, |
| 1641 { NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem", |
| 1642 false, false, true, false, true }, |
| 1643 }; |
| 1644 // Disabled on Windows - http://crbug.com/101123. The Windows implementation |
| 1645 // does not report the status of the last intermediate for incomplete chains. |
| 1646 // Disabled on NSS - libpkix does not return constructed chains on error, |
| 1647 // preventing us from detecting/inspecting the verified chain. |
| 1648 #if defined(OS_WIN) || defined(USE_NSS) |
| 1649 #define MAYBE_VerifyIncompleteIntermediate \ |
| 1650 DISABLED_VerifyIncompleteIntermediate |
| 1651 #else |
| 1652 #define MAYBE_VerifyIncompleteIntermediate VerifyIncompleteIntermediate |
| 1653 #endif |
| 1654 WRAPPED_INSTANTIATE_TEST_CASE_P( |
| 1655 MAYBE_VerifyIncompleteIntermediate, |
| 1656 X509CertificateWeakDigestTest, |
| 1657 testing::ValuesIn(kVerifyIncompleteIntermediateTestData)); |
| 1658 |
| 1659 // Incomplete chains should still report the status of the end-entity. |
| 1660 const WeakDigestTestData kVerifyIncompleteEETestData[] = { |
| 1661 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem", |
| 1662 true, false, false, false, false }, |
| 1663 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem", |
| 1664 false, true, false, false, false }, |
| 1665 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem", |
| 1666 false, false, true, false, false }, |
| 1667 }; |
| 1668 // Disabled on NSS - libpkix does not return constructed chains on error, |
| 1669 // preventing us from detecting/inspecting the verified chain. |
| 1670 #if defined(USE_NSS) |
| 1671 #define MAYBE_VerifyIncompleteEndEntity DISABLED_VerifyIncompleteEndEntity |
| 1672 #else |
| 1673 #define MAYBE_VerifyIncompleteEndEntity VerifyIncompleteEndEntity |
| 1674 #endif |
| 1675 WRAPPED_INSTANTIATE_TEST_CASE_P( |
| 1676 MAYBE_VerifyIncompleteEndEntity, |
| 1677 X509CertificateWeakDigestTest, |
| 1678 testing::ValuesIn(kVerifyIncompleteEETestData)); |
| 1679 |
| 1680 // Differing algorithms between the intermediate and the EE should still be |
| 1681 // reported. |
| 1682 const WeakDigestTestData kVerifyMixedTestData[] = { |
| 1683 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem", |
| 1684 "weak_digest_md2_ee.pem", true, false, true, true, false }, |
| 1685 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem", |
| 1686 "weak_digest_md5_ee.pem", true, false, true, false, true }, |
| 1687 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem", |
| 1688 "weak_digest_md2_ee.pem", false, true, true, false, false }, |
| 1689 }; |
| 1690 // NSS does not support MD4 and does not enable MD2 by policy, making all |
| 1691 // permutations invalid. |
| 1692 #if defined(USE_NSS) |
| 1693 #define MAYBE_VerifyMixed DISABLED_VerifyMixed |
| 1694 #else |
| 1695 #define MAYBE_VerifyMixed VerifyMixed |
| 1696 #endif |
| 1697 WRAPPED_INSTANTIATE_TEST_CASE_P( |
| 1698 MAYBE_VerifyMixed, |
| 1699 X509CertificateWeakDigestTest, |
| 1700 testing::ValuesIn(kVerifyMixedTestData)); |
| 1701 |
| 1702 #endif // defined(USE_NSS) || defined(OS_WIN) |
| 1703 |
1508 } // namespace net | 1704 } // namespace net |
OLD | NEW |