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" |
11 #include "base/string_split.h" | 11 #include "base/string_split.h" |
12 #include "crypto/rsa_private_key.h" | 12 #include "crypto/rsa_private_key.h" |
13 #include "net/base/asn1_util.h" | 13 #include "net/base/asn1_util.h" |
14 #include "net/base/cert_status_flags.h" | 14 #include "net/base/cert_status_flags.h" |
15 #include "net/base/cert_test_util.h" | 15 #include "net/base/cert_test_util.h" |
16 #include "net/base/cert_verify_result.h" | 16 #include "net/base/cert_verify_result.h" |
17 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
18 #include "net/base/test_certificate_data.h" | 18 #include "net/base/test_certificate_data.h" |
19 #include "net/base/test_root_certs.h" | 19 #include "net/base/test_root_certs.h" |
20 #include "net/base/x509_certificate.h" | 20 #include "net/base/x509_certificate.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
22 | 22 |
23 #if defined(USE_NSS) | 23 #if defined(USE_NSS) |
24 #include <cert.h> | 24 #include <cert.h> |
25 #endif | 25 #endif |
26 | 26 |
| 27 #if defined(OS_WIN) |
| 28 #include "base/win/windows_version.h" |
| 29 #elif defined(OS_MACOSX) |
| 30 #include "base/mac/mac_util.h" |
| 31 #endif |
| 32 |
27 // Unit tests aren't allowed to access external resources. Unfortunately, to | 33 // Unit tests aren't allowed to access external resources. Unfortunately, to |
28 // properly verify the EV-ness of a cert, we need to check for its revocation | 34 // properly verify the EV-ness of a cert, we need to check for its revocation |
29 // through online servers. If you're manually running unit tests, feel free to | 35 // through online servers. If you're manually running unit tests, feel free to |
30 // turn this on to test EV certs. But leave it turned off for the automated | 36 // turn this on to test EV certs. But leave it turned off for the automated |
31 // testing. | 37 // testing. |
32 #define ALLOW_EXTERNAL_ACCESS 0 | 38 #define ALLOW_EXTERNAL_ACCESS 0 |
33 | 39 |
34 #if ALLOW_EXTERNAL_ACCESS && defined(OS_WIN) | 40 #if ALLOW_EXTERNAL_ACCESS && defined(OS_WIN) |
35 #define TEST_EV 1 // Test CERT_STATUS_IS_EV | 41 #define TEST_EV 1 // Test CERT_STATUS_IS_EV |
36 #endif | 42 #endif |
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 int flags = X509Certificate::VERIFY_REV_CHECKING_ENABLED | | 610 int flags = X509Certificate::VERIFY_REV_CHECKING_ENABLED | |
605 X509Certificate::VERIFY_EV_CERT; | 611 X509Certificate::VERIFY_EV_CERT; |
606 int error = cert_chain->Verify("2029.globalsign.com", flags, NULL, | 612 int error = cert_chain->Verify("2029.globalsign.com", flags, NULL, |
607 &verify_result); | 613 &verify_result); |
608 if (error == OK) | 614 if (error == OK) |
609 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV); | 615 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV); |
610 else | 616 else |
611 EXPECT_EQ(ERR_CERT_DATE_INVALID, error); | 617 EXPECT_EQ(ERR_CERT_DATE_INVALID, error); |
612 } | 618 } |
613 | 619 |
| 620 // Currently, only RSA and DSA keys are checked for weakness, and our example |
| 621 // weak size is 768. These could change in the future. |
| 622 // |
| 623 // Note that this means there may be false negatives: keys for other |
| 624 // algorithms and which are weak will pass this test. |
| 625 static bool IsWeakKeyType(const std::string& key_type) { |
| 626 size_t pos = key_type.find("-"); |
| 627 std::string size = key_type.substr(0, pos); |
| 628 std::string type = key_type.substr(pos + 1); |
| 629 |
| 630 if (type == "rsa" || type == "dsa") |
| 631 return size == "768"; |
| 632 |
| 633 return false; |
| 634 } |
| 635 |
| 636 TEST(X509CertificateTest, RejectWeakKeys) { |
| 637 FilePath certs_dir = GetTestCertsDirectory(); |
| 638 typedef std::vector<std::string> Strings; |
| 639 Strings key_types; |
| 640 |
| 641 // generate-weak-test-chains.sh currently has: |
| 642 // key_types="768-rsa 1024-rsa 2048-rsa prime256v1-ecdsa" |
| 643 // We must use the same key types here. The filenames generated look like: |
| 644 // 2048-rsa-ee-by-768-rsa-intermediate.pem |
| 645 key_types.push_back("768-rsa"); |
| 646 key_types.push_back("1024-rsa"); |
| 647 key_types.push_back("2048-rsa"); |
| 648 |
| 649 bool use_ecdsa = true; |
| 650 #if defined(OS_WIN) |
| 651 use_ecdsa = base::win::GetVersion() > base::win::VERSION_XP; |
| 652 #elif defined(OS_MACOSX) |
| 653 use_ecdsa = base::mac::IsOSSnowLeopardOrLater(); |
| 654 #endif |
| 655 |
| 656 if (use_ecdsa) |
| 657 key_types.push_back("prime256v1-ecdsa"); |
| 658 |
| 659 // Add the root that signed the intermediates for this test. |
| 660 scoped_refptr<X509Certificate> root_cert = |
| 661 ImportCertFromFile(certs_dir, "2048-rsa-root.pem"); |
| 662 ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert); |
| 663 TestRootCerts::GetInstance()->Add(root_cert.get()); |
| 664 |
| 665 // Now test each chain. |
| 666 for (Strings::const_iterator ee_type = key_types.begin(); |
| 667 ee_type != key_types.end(); ++ee_type) { |
| 668 for (Strings::const_iterator signer_type = key_types.begin(); |
| 669 signer_type != key_types.end(); ++signer_type) { |
| 670 std::string basename = *ee_type + "-ee-by-" + *signer_type + |
| 671 "-intermediate.pem"; |
| 672 scoped_refptr<X509Certificate> ee_cert = |
| 673 ImportCertFromFile(certs_dir, basename); |
| 674 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert); |
| 675 |
| 676 basename = *signer_type + "-intermediate.pem"; |
| 677 scoped_refptr<X509Certificate> intermediate = |
| 678 ImportCertFromFile(certs_dir, basename); |
| 679 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate); |
| 680 |
| 681 X509Certificate::OSCertHandles intermediates; |
| 682 intermediates.push_back(intermediate->os_cert_handle()); |
| 683 scoped_refptr<X509Certificate> cert_chain = |
| 684 X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(), |
| 685 intermediates); |
| 686 |
| 687 CertVerifyResult verify_result; |
| 688 int error = cert_chain->Verify("127.0.0.1", 0, NULL, &verify_result); |
| 689 |
| 690 if (IsWeakKeyType(*ee_type) || IsWeakKeyType(*signer_type)) { |
| 691 EXPECT_NE(OK, error); |
| 692 EXPECT_EQ(CERT_STATUS_WEAK_KEY, |
| 693 verify_result.cert_status & CERT_STATUS_WEAK_KEY); |
| 694 } else { |
| 695 EXPECT_EQ(OK, error); |
| 696 EXPECT_EQ(0U, verify_result.cert_status & CERT_STATUS_WEAK_KEY); |
| 697 } |
| 698 } |
| 699 } |
| 700 |
| 701 TestRootCerts::GetInstance()->Clear(); |
| 702 } |
| 703 |
614 // Test for bug 94673. | 704 // Test for bug 94673. |
615 TEST(X509CertificateTest, GoogleDigiNotarTest) { | 705 TEST(X509CertificateTest, GoogleDigiNotarTest) { |
616 FilePath certs_dir = GetTestCertsDirectory(); | 706 FilePath certs_dir = GetTestCertsDirectory(); |
617 | 707 |
618 scoped_refptr<X509Certificate> server_cert = | 708 scoped_refptr<X509Certificate> server_cert = |
619 ImportCertFromFile(certs_dir, "google_diginotar.pem"); | 709 ImportCertFromFile(certs_dir, "google_diginotar.pem"); |
620 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); | 710 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert); |
621 | 711 |
622 scoped_refptr<X509Certificate> intermediate_cert = | 712 scoped_refptr<X509Certificate> intermediate_cert = |
623 ImportCertFromFile(certs_dir, "diginotar_public_ca_2025.pem"); | 713 ImportCertFromFile(certs_dir, "diginotar_public_ca_2025.pem"); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(), | 810 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(), |
721 &derBytes)); | 811 &derBytes)); |
722 | 812 |
723 base::StringPiece spkiBytes; | 813 base::StringPiece spkiBytes; |
724 EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(derBytes, &spkiBytes)); | 814 EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(derBytes, &spkiBytes)); |
725 | 815 |
726 uint8 hash[base::kSHA1Length]; | 816 uint8 hash[base::kSHA1Length]; |
727 base::SHA1HashBytes(reinterpret_cast<const uint8*>(spkiBytes.data()), | 817 base::SHA1HashBytes(reinterpret_cast<const uint8*>(spkiBytes.data()), |
728 spkiBytes.size(), hash); | 818 spkiBytes.size(), hash); |
729 | 819 |
730 EXPECT_TRUE(0 == memcmp(hash, nistSPKIHash, sizeof(hash))); | 820 EXPECT_EQ(0, memcmp(hash, nistSPKIHash, sizeof(hash))); |
731 } | 821 } |
732 | 822 |
733 TEST(X509CertificateTest, ExtractCRLURLsFromDERCert) { | 823 TEST(X509CertificateTest, ExtractCRLURLsFromDERCert) { |
734 FilePath certs_dir = GetTestCertsDirectory(); | 824 FilePath certs_dir = GetTestCertsDirectory(); |
735 scoped_refptr<X509Certificate> cert = | 825 scoped_refptr<X509Certificate> cert = |
736 ImportCertFromFile(certs_dir, "nist.der"); | 826 ImportCertFromFile(certs_dir, "nist.der"); |
737 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert); | 827 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert); |
738 | 828 |
739 std::string derBytes; | 829 std::string derBytes; |
740 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(), | 830 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(), |
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1375 { true, "f", "f" }, | 1465 { true, "f", "f" }, |
1376 { false, "h", "i" }, | 1466 { false, "h", "i" }, |
1377 { true, "bar.foo.com", "*.foo.com" }, | 1467 { true, "bar.foo.com", "*.foo.com" }, |
1378 { true, "www.test.fr", "common.name", | 1468 { true, "www.test.fr", "common.name", |
1379 "*.test.com,*.test.co.uk,*.test.de,*.test.fr" }, | 1469 "*.test.com,*.test.co.uk,*.test.de,*.test.fr" }, |
1380 { true, "wwW.tESt.fr", "common.name", | 1470 { true, "wwW.tESt.fr", "common.name", |
1381 ",*.*,*.test.de,*.test.FR,www" }, | 1471 ",*.*,*.test.de,*.test.FR,www" }, |
1382 { false, "f.uk", ".uk" }, | 1472 { false, "f.uk", ".uk" }, |
1383 { false, "w.bar.foo.com", "?.bar.foo.com" }, | 1473 { false, "w.bar.foo.com", "?.bar.foo.com" }, |
1384 { false, "www.foo.com", "(www|ftp).foo.com" }, | 1474 { false, "www.foo.com", "(www|ftp).foo.com" }, |
1385 { false, "www.foo.com", "www.foo.com#" }, // # = null char. | 1475 { false, "www.foo.com", "www.foo.com#" }, // # = null char. |
1386 { false, "www.foo.com", "", "www.foo.com#*.foo.com,#,#" }, | 1476 { false, "www.foo.com", "", "www.foo.com#*.foo.com,#,#" }, |
1387 { false, "www.house.example", "ww.house.example" }, | 1477 { false, "www.house.example", "ww.house.example" }, |
1388 { false, "test.org", "", "www.test.org,*.test.org,*.org" }, | 1478 { false, "test.org", "", "www.test.org,*.test.org,*.org" }, |
1389 { false, "w.bar.foo.com", "w*.bar.foo.com" }, | 1479 { false, "w.bar.foo.com", "w*.bar.foo.com" }, |
1390 { false, "www.bar.foo.com", "ww*ww.bar.foo.com" }, | 1480 { false, "www.bar.foo.com", "ww*ww.bar.foo.com" }, |
1391 { false, "wwww.bar.foo.com", "ww*ww.bar.foo.com" }, | 1481 { false, "wwww.bar.foo.com", "ww*ww.bar.foo.com" }, |
1392 { true, "wwww.bar.foo.com", "w*w.bar.foo.com" }, | 1482 { true, "wwww.bar.foo.com", "w*w.bar.foo.com" }, |
1393 { false, "wwww.bar.foo.com", "w*w.bar.foo.c0m" }, | 1483 { false, "wwww.bar.foo.com", "w*w.bar.foo.c0m" }, |
1394 { true, "WALLY.bar.foo.com", "wa*.bar.foo.com" }, | 1484 { true, "WALLY.bar.foo.com", "wa*.bar.foo.com" }, |
1395 { true, "wally.bar.foo.com", "*Ly.bar.foo.com" }, | 1485 { true, "wally.bar.foo.com", "*Ly.bar.foo.com" }, |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1513 } | 1603 } |
1514 | 1604 |
1515 if (test_data.ip_addrs) { | 1605 if (test_data.ip_addrs) { |
1516 // Build up the certificate IP address list. | 1606 // Build up the certificate IP address list. |
1517 std::string ip_addrs_line(test_data.ip_addrs); | 1607 std::string ip_addrs_line(test_data.ip_addrs); |
1518 std::vector<std::string> ip_addressses_ascii; | 1608 std::vector<std::string> ip_addressses_ascii; |
1519 base::SplitString(ip_addrs_line, ',', &ip_addressses_ascii); | 1609 base::SplitString(ip_addrs_line, ',', &ip_addressses_ascii); |
1520 for (size_t i = 0; i < ip_addressses_ascii.size(); ++i) { | 1610 for (size_t i = 0; i < ip_addressses_ascii.size(); ++i) { |
1521 std::string& addr_ascii = ip_addressses_ascii[i]; | 1611 std::string& addr_ascii = ip_addressses_ascii[i]; |
1522 ASSERT_NE(0U, addr_ascii.length()); | 1612 ASSERT_NE(0U, addr_ascii.length()); |
1523 if (addr_ascii[0] == 'x') { // Hex encoded address | 1613 if (addr_ascii[0] == 'x') { // Hex encoded address |
1524 addr_ascii.erase(0, 1); | 1614 addr_ascii.erase(0, 1); |
1525 std::vector<uint8> bytes; | 1615 std::vector<uint8> bytes; |
1526 EXPECT_TRUE(base::HexStringToBytes(addr_ascii, &bytes)) | 1616 EXPECT_TRUE(base::HexStringToBytes(addr_ascii, &bytes)) |
1527 << "Could not parse hex address " << addr_ascii << " i = " << i; | 1617 << "Could not parse hex address " << addr_ascii << " i = " << i; |
1528 ip_addressses.push_back(std::string(reinterpret_cast<char*>(&bytes[0]), | 1618 ip_addressses.push_back(std::string(reinterpret_cast<char*>(&bytes[0]), |
1529 bytes.size())); | 1619 bytes.size())); |
1530 ASSERT_EQ(16U, ip_addressses.back().size()) << i; | 1620 ASSERT_EQ(16U, ip_addressses.back().size()) << i; |
1531 } else { // Decimal groups | 1621 } else { // Decimal groups |
1532 std::vector<std::string> decimals_ascii; | 1622 std::vector<std::string> decimals_ascii; |
1533 base::SplitString(addr_ascii, '.', &decimals_ascii); | 1623 base::SplitString(addr_ascii, '.', &decimals_ascii); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1780 #define MAYBE_VerifyMixed DISABLED_VerifyMixed | 1870 #define MAYBE_VerifyMixed DISABLED_VerifyMixed |
1781 #else | 1871 #else |
1782 #define MAYBE_VerifyMixed VerifyMixed | 1872 #define MAYBE_VerifyMixed VerifyMixed |
1783 #endif | 1873 #endif |
1784 WRAPPED_INSTANTIATE_TEST_CASE_P( | 1874 WRAPPED_INSTANTIATE_TEST_CASE_P( |
1785 MAYBE_VerifyMixed, | 1875 MAYBE_VerifyMixed, |
1786 X509CertificateWeakDigestTest, | 1876 X509CertificateWeakDigestTest, |
1787 testing::ValuesIn(kVerifyMixedTestData)); | 1877 testing::ValuesIn(kVerifyMixedTestData)); |
1788 | 1878 |
1789 } // namespace net | 1879 } // namespace net |
OLD | NEW |