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 |