Chromium Code Reviews| 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 1229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1240 // Common name, may be used if |dns_names| or |ip_addrs| are empty. | 1240 // Common name, may be used if |dns_names| or |ip_addrs| are empty. |
| 1241 const char* common_name; | 1241 const char* common_name; |
| 1242 // Comma separated list of certificate names to match against. Any occurrence | 1242 // Comma separated list of certificate names to match against. Any occurrence |
| 1243 // of '#' will be replaced with a null character before processing. | 1243 // of '#' will be replaced with a null character before processing. |
| 1244 const char* dns_names; | 1244 const char* dns_names; |
| 1245 // Comma separated list of certificate IP Addresses to match against. Each | 1245 // Comma separated list of certificate IP Addresses to match against. Each |
| 1246 // address is x prefixed 16 byte hex code for v6 or dotted-decimals for v4. | 1246 // address is x prefixed 16 byte hex code for v6 or dotted-decimals for v4. |
| 1247 const char* ip_addrs; | 1247 const char* ip_addrs; |
| 1248 }; | 1248 }; |
| 1249 | 1249 |
| 1250 // Required by valgrind on mac, otherwise it complains when using its default | 1250 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how |
| 1251 // printer: | 1251 // to output the parameter that was passed. Without this, it will simply |
| 1252 // UninitCondition | 1252 // attempt to print out the first twenty bytes of the object, which depending |
| 1253 // Conditional jump or move depends on uninitialised value(s) | 1253 // on platform and alignment, may result in an invalid read. |
| 1254 // ... | |
| 1255 // snprintf | |
| 1256 // testing::(anonymous namespace)::PrintByteSegmentInObjectTo | |
| 1257 // testing::internal2::TypeWithoutFormatter | |
| 1258 // ... | |
| 1259 void PrintTo(const CertificateNameVerifyTestData& data, std::ostream* os) { | 1254 void PrintTo(const CertificateNameVerifyTestData& data, std::ostream* os) { |
| 1260 ASSERT_TRUE(data.hostname && data.common_name); | 1255 ASSERT_TRUE(data.hostname && data.common_name); |
| 1261 // Using StringPiece to allow for optional fields being NULL. | 1256 // Using StringPiece to allow for optional fields being NULL. |
| 1262 *os << " expected: " << data.expected | 1257 *os << " expected: " << data.expected |
| 1263 << "; hostname: " << data.hostname | 1258 << "; hostname: " << data.hostname |
| 1264 << "; common_name: " << data.common_name | 1259 << "; common_name: " << data.common_name |
| 1265 << "; dns_names: " << base::StringPiece(data.dns_names) | 1260 << "; dns_names: " << base::StringPiece(data.dns_names) |
| 1266 << "; ip_addrs: " << base::StringPiece(data.ip_addrs); | 1261 << "; ip_addrs: " << base::StringPiece(data.ip_addrs); |
| 1267 } | 1262 } |
| 1268 | 1263 |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1442 } | 1437 } |
| 1443 } | 1438 } |
| 1444 | 1439 |
| 1445 EXPECT_EQ(test_data.expected, X509Certificate::VerifyHostname( | 1440 EXPECT_EQ(test_data.expected, X509Certificate::VerifyHostname( |
| 1446 test_data.hostname, common_name, dns_names, ip_addressses)); | 1441 test_data.hostname, common_name, dns_names, ip_addressses)); |
| 1447 } | 1442 } |
| 1448 | 1443 |
| 1449 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest, | 1444 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest, |
| 1450 testing::ValuesIn(kNameVerifyTestData)); | 1445 testing::ValuesIn(kNameVerifyTestData)); |
| 1451 | 1446 |
| 1447 // Not implemented on Mac or OpenSSL - http://crbug.com/101123 | |
| 1448 #if defined(USE_NSS) || defined(OS_WIN) | |
| 1449 | |
| 1450 struct WeakDigestTestData { | |
| 1451 const char* root_cert_filename; | |
| 1452 const char* intermediate_cert_filename; | |
| 1453 const char* ee_cert_filename; | |
| 1454 bool expected_has_md5; | |
| 1455 bool expected_has_md4; | |
| 1456 bool expected_has_md2; | |
| 1457 bool expected_has_md5_ca; | |
| 1458 bool expected_has_md2_ca; | |
| 1459 }; | |
| 1460 | |
| 1461 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how | |
| 1462 // to output the parameter that was passed. Without this, it will simply | |
| 1463 // attempt to print out the first twenty bytes of the object, which depending | |
| 1464 // on platform and alignment, may result in an invalid read. | |
| 1465 void PrintTo(const WeakDigestTestData& data, std::ostream* os) { | |
| 1466 *os << "root: " | |
| 1467 << (data.root_cert_filename ? data.root_cert_filename : "none") | |
| 1468 << "; intermediate: " << data.intermediate_cert_filename | |
| 1469 << "; end-entity: " << data.ee_cert_filename; | |
| 1470 } | |
| 1471 | |
| 1472 class X509CertificateWeakDigestTest | |
| 1473 : public testing::TestWithParam<WeakDigestTestData> { | |
| 1474 public: | |
| 1475 X509CertificateWeakDigestTest() {} | |
| 1476 | |
| 1477 virtual void TearDown() { | |
| 1478 TestRootCerts::GetInstance()->Clear(); | |
| 1479 } | |
| 1480 }; | |
| 1481 | |
| 1482 TEST_P(X509CertificateWeakDigestTest, Verify) { | |
| 1483 WeakDigestTestData data = GetParam(); | |
| 1484 FilePath certs_dir = GetTestCertsDirectory(); | |
| 1485 | |
| 1486 if (data.root_cert_filename) { | |
| 1487 scoped_refptr<X509Certificate> root_cert = | |
| 1488 ImportCertFromFile(certs_dir, data.root_cert_filename); | |
| 1489 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert); | |
| 1490 TestRootCerts::GetInstance()->Add(root_cert.get()); | |
| 1491 } | |
| 1492 | |
| 1493 scoped_refptr<X509Certificate> intermediate_cert = | |
| 1494 ImportCertFromFile(certs_dir, data.intermediate_cert_filename); | |
| 1495 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert); | |
| 1496 scoped_refptr<X509Certificate> ee_cert = | |
| 1497 ImportCertFromFile(certs_dir, data.ee_cert_filename); | |
| 1498 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert); | |
| 1499 | |
| 1500 X509Certificate::OSCertHandles intermediates; | |
| 1501 intermediates.push_back(intermediate_cert->os_cert_handle()); | |
| 1502 | |
| 1503 scoped_refptr<X509Certificate> ee_chain = | |
| 1504 X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(), | |
| 1505 intermediates); | |
| 1506 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_chain); | |
| 1507 | |
| 1508 int flags = 0; | |
| 1509 CertVerifyResult verify_result; | |
| 1510 ee_chain->Verify("127.0.0.1", flags, NULL, &verify_result); | |
| 1511 EXPECT_EQ(data.expected_has_md5, verify_result.has_md5); | |
| 1512 EXPECT_EQ(data.expected_has_md4, verify_result.has_md4); | |
| 1513 EXPECT_EQ(data.expected_has_md2, verify_result.has_md2); | |
| 1514 EXPECT_EQ(data.expected_has_md5_ca, verify_result.has_md5_ca); | |
| 1515 EXPECT_EQ(data.expected_has_md2_ca, verify_result.has_md2_ca); | |
| 1516 } | |
| 1517 | |
| 1518 // Wrapper for the real GTest implementation so that macro expansion for tests | |
| 1519 // such as MAYBE_Foo can happen the same way it does for the other GTest | |
| 1520 // macros, like TEST or TEST_F. | |
|
wtc
2011/10/31 23:48:00
The need for this wrapper macro is not obvious to
Ryan Sleevi
2011/11/01 04:06:46
I expanded the comment to explain. TEST/TEST_F are
| |
| 1521 #define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ | |
|
palmer
2011/10/28 18:45:05
I admit I don't understand this, because I don't k
| |
| 1522 INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) | |
| 1523 | |
| 1524 // The signature algorithm of the root CA should not matter. | |
| 1525 const WeakDigestTestData kVerifyRootCATestData[] = { | |
| 1526 { "weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem", | |
| 1527 "weak_digest_sha1_ee.pem", false, false, false, false, false }, | |
| 1528 { "weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem", | |
| 1529 "weak_digest_sha1_ee.pem", false, false, false, false, false }, | |
| 1530 { "weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem", | |
| 1531 "weak_digest_sha1_ee.pem", false, false, false, false, false }, | |
| 1532 }; | |
| 1533 INSTANTIATE_TEST_CASE_P(VerifyRoot, X509CertificateWeakDigestTest, | |
| 1534 testing::ValuesIn(kVerifyRootCATestData)); | |
| 1535 | |
| 1536 // The signature algorithm of intermediates should be properly detected. | |
| 1537 const WeakDigestTestData kVerifyIntermediateCATestData[] = { | |
| 1538 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem", | |
| 1539 "weak_digest_sha1_ee.pem", true, false, false, true, false }, | |
| 1540 // NSS does not support MD4 and does not enable MD2 by policy. | |
| 1541 #if !defined(USE_NSS) | |
| 1542 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem", | |
| 1543 "weak_digest_sha1_ee.pem", false, true, false, false, false }, | |
| 1544 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem", | |
| 1545 "weak_digest_sha1_ee.pem", false, false, true, false, true }, | |
| 1546 #endif | |
| 1547 }; | |
| 1548 INSTANTIATE_TEST_CASE_P(VerifyIntermediate, X509CertificateWeakDigestTest, | |
| 1549 testing::ValuesIn(kVerifyIntermediateCATestData)); | |
| 1550 | |
| 1551 // The signature algorithm of end-entity should be properly detected. | |
| 1552 const WeakDigestTestData kVerifyEndEntityTestData[] = { | |
| 1553 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", | |
| 1554 "weak_digest_md5_ee.pem", true, false, false, false, false }, | |
| 1555 // NSS does not support MD4 and does not enable MD2 by policy. | |
| 1556 #if !defined(USE_NSS) | |
| 1557 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", | |
| 1558 "weak_digest_md4_ee.pem", false, true, false, false, false }, | |
| 1559 { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", | |
| 1560 "weak_digest_md2_ee.pem", false, false, true, false, false }, | |
| 1561 #endif | |
| 1562 }; | |
| 1563 // Disabled on NSS - NSS caches chains/signatures in such a way that cannot | |
| 1564 // be cleared until NSS is cleanly shutdown, which is not presently supported | |
| 1565 // in Chromium. | |
| 1566 #if defined(USE_NSS) | |
| 1567 #define MAYBE_VerifyEndEntity DISABLED_VerifyEndEntity | |
| 1568 #else | |
| 1569 #define MAYBE_VerifyEndEntity VerifyEndEntity | |
| 1570 #endif | |
| 1571 WRAPPED_INSTANTIATE_TEST_CASE_P(MAYBE_VerifyEndEntity, | |
| 1572 X509CertificateWeakDigestTest, | |
| 1573 testing::ValuesIn(kVerifyEndEntityTestData)); | |
| 1574 | |
| 1575 // Incomplete chains should still report the status of the intermediate. | |
| 1576 const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] = { | |
| 1577 { NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem", | |
| 1578 true, false, false, true, false }, | |
| 1579 { NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem", | |
| 1580 false, true, false, false, false }, | |
| 1581 { NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem", | |
| 1582 false, false, true, false, true }, | |
| 1583 }; | |
| 1584 // Disabled on Windows - http://crbug.com/101123. The Windows implementation | |
| 1585 // does not report the status of the last intermediate for incomplete chains. | |
| 1586 // Disabled on NSS - libpkix does not return constructed chains on error, | |
| 1587 // preventing us from detecting/inspecting the verified chain. | |
| 1588 #if defined(OS_WIN) || defined(USE_NSS) | |
| 1589 #define MAYBE_VerifyIncompleteIntermediate \ | |
| 1590 DISABLED_VerifyIncompleteIntermediate | |
| 1591 #else | |
| 1592 #define MAYBE_VerifyIncompleteIntermediate VerifyIncompleteIntermediate | |
| 1593 #endif | |
| 1594 WRAPPED_INSTANTIATE_TEST_CASE_P( | |
| 1595 MAYBE_VerifyIncompleteIntermediate, | |
| 1596 X509CertificateWeakDigestTest, | |
| 1597 testing::ValuesIn(kVerifyIncompleteIntermediateTestData)); | |
| 1598 | |
| 1599 // Incomplete chains should still report the status of the end-entity. | |
| 1600 const WeakDigestTestData kVerifyIncompleteEETestData[] = { | |
| 1601 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem", | |
| 1602 true, false, false, false, false }, | |
| 1603 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem", | |
| 1604 false, true, false, false, false }, | |
| 1605 { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem", | |
| 1606 false, false, true, false, false }, | |
| 1607 }; | |
| 1608 // Disabled on NSS - libpkix does not return constructed chains on error, | |
| 1609 // preventing us from detecting/inspecting the verified chain. | |
| 1610 #if defined(USE_NSS) | |
| 1611 #define MAYBE_VerifyIncompleteEndEntity DISABLED_VerifyIncompleteEndEntity | |
| 1612 #else | |
| 1613 #define MAYBE_VerifyIncompleteEndEntity VerifyIncompleteEndEntity | |
| 1614 #endif | |
| 1615 WRAPPED_INSTANTIATE_TEST_CASE_P( | |
| 1616 MAYBE_VerifyIncompleteEndEntity, | |
| 1617 X509CertificateWeakDigestTest, | |
| 1618 testing::ValuesIn(kVerifyIncompleteEETestData)); | |
| 1619 | |
| 1620 // Differing algorithms between the intermediate and the EE should still be | |
| 1621 // reported. | |
| 1622 const WeakDigestTestData kVerifyMixedTestData[] = { | |
| 1623 { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem", | |
| 1624 "weak_digest_md2_ee.pem", true, false, true, true, false }, | |
| 1625 { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem", | |
| 1626 "weak_digest_md5_ee.pem", true, false, true, false, true }, | |
| 1627 { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem", | |
| 1628 "weak_digest_md2_ee.pem", false, true, true, false, false }, | |
| 1629 }; | |
| 1630 // NSS does not support MD4 and does not enable MD2 by policy, making all | |
| 1631 // permutations invalid. | |
| 1632 #if defined(USE_NSS) | |
| 1633 #define MAYBE_VerifyMixed DISABLED_VerifyMixed | |
| 1634 #else | |
| 1635 #define MAYBE_VerifyMixed VerifyMixed | |
| 1636 #endif | |
| 1637 WRAPPED_INSTANTIATE_TEST_CASE_P( | |
| 1638 MAYBE_VerifyMixed, | |
| 1639 X509CertificateWeakDigestTest, | |
| 1640 testing::ValuesIn(kVerifyMixedTestData)); | |
| 1641 | |
| 1642 #endif // defined(USE_NSS) || defined(OS_WIN) | |
| 1643 | |
| 1452 } // namespace net | 1644 } // namespace net |
| OLD | NEW |