Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/internal/parse_certificate.h" | 5 #include "net/cert/internal/parse_certificate.h" |
| 6 | 6 |
| 7 #include "base/strings/stringprintf.h" | 7 #include "base/strings/stringprintf.h" |
| 8 #include "net/cert/internal/cert_errors.h" | 8 #include "net/cert/internal/cert_errors.h" |
| 9 // TODO(eroman): These tests should be moved into | |
| 10 // parsed_certificate_unittest.cc; this include dependency should | |
| 11 // go. | |
| 12 #include "net/cert/internal/parsed_certificate.h" | |
| 9 #include "net/cert/internal/test_helpers.h" | 13 #include "net/cert/internal/test_helpers.h" |
| 10 #include "net/der/input.h" | 14 #include "net/der/input.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 12 | 16 |
| 13 namespace net { | 17 namespace net { |
| 14 | 18 |
| 15 namespace { | 19 namespace { |
| 16 | 20 |
| 17 // Pretty-prints a GeneralizedTime as a human-readable string for use in test | 21 // Pretty-prints a GeneralizedTime as a human-readable string for use in test |
| 18 // expectations (it is more readable to specify the expected results as a | 22 // expectations (it is more readable to specify the expected results as a |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 // Ensure that the parsed certificate matches expectations. | 72 // Ensure that the parsed certificate matches expectations. |
| 69 if (expected_result && actual_result) { | 73 if (expected_result && actual_result) { |
| 70 EXPECT_EQ(0, signature_value.unused_bits()); | 74 EXPECT_EQ(0, signature_value.unused_bits()); |
| 71 EXPECT_EQ(der::Input(&expected_signature), signature_value.bytes()); | 75 EXPECT_EQ(der::Input(&expected_signature), signature_value.bytes()); |
| 72 EXPECT_EQ(der::Input(&expected_signature_algorithm), | 76 EXPECT_EQ(der::Input(&expected_signature_algorithm), |
| 73 signature_algorithm_tlv); | 77 signature_algorithm_tlv); |
| 74 EXPECT_EQ(der::Input(&expected_tbs_certificate), tbs_certificate_tlv); | 78 EXPECT_EQ(der::Input(&expected_tbs_certificate), tbs_certificate_tlv); |
| 75 } | 79 } |
| 76 } | 80 } |
| 77 | 81 |
| 82 // Reads and parses a certificate from the PEM file |file_name|. | |
| 83 // | |
| 84 // Returns nullptr if the certificate parsing failed, and verifies that any | |
| 85 // errors match the ERRORS block in the .pem file. | |
| 86 scoped_refptr<ParsedCertificate> ParseCertificateFromFile( | |
| 87 const std::string& file_name) { | |
| 88 std::string data; | |
| 89 std::string expected_errors; | |
| 90 | |
| 91 // Read the certificate data and error expectations from a single PEM file. | |
| 92 const PemBlockMapping mappings[] = { | |
| 93 {"CERTIFICATE", &data}, {"ERRORS", &expected_errors, true /*optional*/}, | |
| 94 }; | |
| 95 std::string test_file_path = GetFilePath(file_name); | |
| 96 EXPECT_TRUE(ReadTestDataFromPemFile(test_file_path, mappings)); | |
| 97 | |
| 98 CertErrors errors; | |
| 99 scoped_refptr<ParsedCertificate> cert = | |
| 100 ParsedCertificate::Create(data, {}, &errors); | |
| 101 | |
| 102 EXPECT_EQ(expected_errors, errors.ToDebugString()) << "Test file: " | |
| 103 << test_file_path; | |
| 104 return cert; | |
| 105 } | |
| 106 | |
| 78 // Tests parsing a Certificate. | 107 // Tests parsing a Certificate. |
| 79 TEST(ParseCertificateTest, Version3) { | 108 TEST(ParseCertificateTest, Version3) { |
| 80 RunCertificateTest("cert_version3.pem"); | 109 RunCertificateTest("cert_version3.pem"); |
| 81 } | 110 } |
| 82 | 111 |
| 83 // Tests parsing a simplified Certificate-like structure (the sub-fields for | 112 // Tests parsing a simplified Certificate-like structure (the sub-fields for |
| 84 // algorithm and tbsCertificate are not actually valid, but ParseCertificate() | 113 // algorithm and tbsCertificate are not actually valid, but ParseCertificate() |
| 85 // doesn't check them) | 114 // doesn't check them) |
| 86 TEST(ParseCertificateTest, Skeleton) { | 115 TEST(ParseCertificateTest, Skeleton) { |
| 87 RunCertificateTest("cert_skeleton.pem"); | 116 RunCertificateTest("cert_skeleton.pem"); |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 575 EXPECT_EQ(8u, iter->second.value.Length()); | 604 EXPECT_EQ(8u, iter->second.value.Length()); |
| 576 | 605 |
| 577 iter = extensions.find(CertificatePoliciesOid()); | 606 iter = extensions.find(CertificatePoliciesOid()); |
| 578 ASSERT_TRUE(iter != extensions.end()); | 607 ASSERT_TRUE(iter != extensions.end()); |
| 579 EXPECT_FALSE(iter->second.critical); | 608 EXPECT_FALSE(iter->second.critical); |
| 580 EXPECT_EQ(16u, iter->second.value.Length()); | 609 EXPECT_EQ(16u, iter->second.value.Length()); |
| 581 | 610 |
| 582 // TODO(eroman): Verify the other 4 extensions' values. | 611 // TODO(eroman): Verify the other 4 extensions' values. |
| 583 } | 612 } |
| 584 | 613 |
| 585 // Reads a PEM file containing a block "BASIC CONSTRAINTS". This input will | 614 // Parses a BasicConstraints with no CA or pathlen. |
| 586 // be passed to ParseExtension, and the results filled in |out|. | 615 TEST(ParseCertificateTest, BasicConstraintsNotCa) { |
| 587 bool ParseBasicConstraintsFromFile(const std::string& file_name, | 616 scoped_refptr<ParsedCertificate> cert = |
| 588 ParsedBasicConstraints* out) { | 617 ParseCertificateFromFile("basic_constraints_not_ca.pem"); |
| 589 std::string data; | 618 ASSERT_TRUE(cert); |
| 590 const PemBlockMapping mappings[] = { | |
| 591 {"BASIC CONSTRAINTS", &data}, | |
| 592 }; | |
| 593 | 619 |
| 594 EXPECT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); | 620 EXPECT_TRUE(cert->has_basic_constraints()); |
| 595 return ParseBasicConstraints(der::Input(&data), out); | 621 EXPECT_FALSE(cert->basic_constraints().is_ca); |
| 596 } | 622 EXPECT_FALSE(cert->basic_constraints().has_path_len); |
| 597 | |
| 598 // Parses a BasicConstraints with no CA or pathlen. | |
| 599 TEST(ParseBasicConstraintsTest, NotCa) { | |
| 600 ParsedBasicConstraints constraints; | |
| 601 ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_not_ca.pem", | |
| 602 &constraints)); | |
| 603 EXPECT_FALSE(constraints.is_ca); | |
| 604 EXPECT_FALSE(constraints.has_path_len); | |
| 605 } | 623 } |
| 606 | 624 |
| 607 // Parses a BasicConstraints with CA but no pathlen. | 625 // Parses a BasicConstraints with CA but no pathlen. |
| 608 TEST(ParseBasicConstraintsTest, CaNoPath) { | 626 TEST(ParseCertificateTest, BasicConstraintsCaNoPath) { |
| 609 ParsedBasicConstraints constraints; | 627 scoped_refptr<ParsedCertificate> cert = |
| 610 ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_ca_no_path.pem", | 628 ParseCertificateFromFile("basic_constraints_ca_no_path.pem"); |
| 611 &constraints)); | 629 ASSERT_TRUE(cert); |
| 612 EXPECT_TRUE(constraints.is_ca); | 630 |
| 613 EXPECT_FALSE(constraints.has_path_len); | 631 EXPECT_TRUE(cert->has_basic_constraints()); |
| 632 EXPECT_TRUE(cert->basic_constraints().is_ca); | |
| 633 EXPECT_FALSE(cert->basic_constraints().has_path_len); | |
| 614 } | 634 } |
| 615 | 635 |
| 616 // Parses a BasicConstraints with CA and pathlen of 9. | 636 // Parses a BasicConstraints with CA and pathlen of 9. |
| 617 TEST(ParseBasicConstraintsTest, CaPath9) { | 637 TEST(ParseCertificateTest, BasicConstraintsCaPath9) { |
| 618 ParsedBasicConstraints constraints; | 638 scoped_refptr<ParsedCertificate> cert = |
| 619 ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_ca_path_9.pem", | 639 ParseCertificateFromFile("basic_constraints_ca_path_9.pem"); |
| 620 &constraints)); | 640 ASSERT_TRUE(cert); |
| 621 EXPECT_TRUE(constraints.is_ca); | 641 |
| 622 EXPECT_TRUE(constraints.has_path_len); | 642 EXPECT_TRUE(cert->has_basic_constraints()); |
| 623 EXPECT_EQ(9u, constraints.path_len); | 643 EXPECT_TRUE(cert->basic_constraints().is_ca); |
| 644 EXPECT_TRUE(cert->basic_constraints().has_path_len); | |
| 645 EXPECT_EQ(9u, cert->basic_constraints().path_len); | |
| 624 } | 646 } |
| 625 | 647 |
| 626 // Parses a BasicConstraints with CA and pathlen of 255 (largest allowed size). | 648 // Parses a BasicConstraints with CA and pathlen of 255 (largest allowed size). |
| 627 TEST(ParseBasicConstraintsTest, Pathlen255) { | 649 TEST(ParseCertificateTest, BasicConstraintsPathlen255) { |
| 628 ParsedBasicConstraints constraints; | 650 scoped_refptr<ParsedCertificate> cert = |
| 629 ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_pathlen_255.pem", | 651 ParseCertificateFromFile("basic_constraints_pathlen_255.pem"); |
| 630 &constraints)); | 652 ASSERT_TRUE(cert); |
| 631 EXPECT_TRUE(constraints.is_ca); | 653 |
| 632 EXPECT_TRUE(constraints.has_path_len); | 654 EXPECT_TRUE(cert->has_basic_constraints()); |
| 633 EXPECT_EQ(255, constraints.path_len); | 655 EXPECT_TRUE(cert->basic_constraints().is_ca); |
| 656 EXPECT_TRUE(cert->basic_constraints().has_path_len); | |
| 657 EXPECT_EQ(255, cert->basic_constraints().path_len); | |
| 634 } | 658 } |
| 635 | 659 |
| 636 // Parses a BasicConstraints with CA and pathlen of 256 (too large). | 660 // Parses a BasicConstraints with CA and pathlen of 256 (too large). |
| 637 TEST(ParseBasicConstraintsTest, Pathlen256) { | 661 TEST(ParseCertificateTest, BasicConstraintsPathlen256) { |
| 638 ParsedBasicConstraints constraints; | 662 ASSERT_FALSE(ParseCertificateFromFile("basic_constraints_pathlen_256.pem")); |
|
mattm
2016/09/22 02:48:19
Is there a TODO for adding error logging to ParseB
eroman
2016/09/22 06:13:14
I have added a TODO to ParseCertificateFromFile().
| |
| 639 ASSERT_FALSE(ParseBasicConstraintsFromFile( | |
| 640 "basic_constraints_pathlen_256.pem", &constraints)); | |
| 641 } | 663 } |
| 642 | 664 |
| 643 // Parses a BasicConstraints with CA and a negative pathlen. | 665 // Parses a BasicConstraints with CA and a negative pathlen. |
| 644 TEST(ParseBasicConstraintsTest, NegativePath) { | 666 TEST(ParseCertificateTest, BasicConstraintsNegativePath) { |
| 645 ParsedBasicConstraints constraints; | 667 ASSERT_FALSE(ParseCertificateFromFile("basic_constraints_negative_path.pem")); |
| 646 ASSERT_FALSE(ParseBasicConstraintsFromFile( | |
| 647 "basic_constraints_negative_path.pem", &constraints)); | |
| 648 } | 668 } |
| 649 | 669 |
| 650 // Parses a BasicConstraints with CA and pathlen that is very large (and | 670 // Parses a BasicConstraints with CA and pathlen that is very large (and |
| 651 // couldn't fit in a 64-bit integer). | 671 // couldn't fit in a 64-bit integer). |
| 652 TEST(ParseBasicConstraintsTest, PathTooLarge) { | 672 TEST(ParseCertificateTest, BasicConstraintsPathTooLarge) { |
| 653 ParsedBasicConstraints constraints; | 673 ASSERT_FALSE( |
| 654 ASSERT_FALSE(ParseBasicConstraintsFromFile( | 674 ParseCertificateFromFile("basic_constraints_path_too_large.pem")); |
| 655 "basic_constraints_path_too_large.pem", &constraints)); | |
| 656 } | 675 } |
| 657 | 676 |
| 658 // Parses a BasicConstraints with CA explicitly set to false. This violates | 677 // Parses a BasicConstraints with CA explicitly set to false. This violates |
| 659 // DER-encoding rules, however is commonly used, so it is accepted. | 678 // DER-encoding rules, however is commonly used, so it is accepted. |
| 660 TEST(ParseBasicConstraintsTest, CaFalse) { | 679 TEST(ParseCertificateTest, BasicConstraintsCaFalse) { |
| 661 ParsedBasicConstraints constraints; | 680 scoped_refptr<ParsedCertificate> cert = |
| 662 ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_ca_false.pem", | 681 ParseCertificateFromFile("basic_constraints_ca_false.pem"); |
| 663 &constraints)); | 682 ASSERT_TRUE(cert); |
| 664 EXPECT_FALSE(constraints.is_ca); | 683 |
| 665 EXPECT_FALSE(constraints.has_path_len); | 684 EXPECT_TRUE(cert->has_basic_constraints()); |
| 685 EXPECT_FALSE(cert->basic_constraints().is_ca); | |
| 686 EXPECT_FALSE(cert->basic_constraints().has_path_len); | |
| 666 } | 687 } |
| 667 | 688 |
| 668 // Parses a BasicConstraints with CA set to true and an unexpected NULL at | 689 // Parses a BasicConstraints with CA set to true and an unexpected NULL at |
| 669 // the end. | 690 // the end. |
| 670 TEST(ParseBasicConstraintsTest, UnconsumedData) { | 691 TEST(ParseCertificateTest, BasicConstraintsUnconsumedData) { |
| 671 ParsedBasicConstraints constraints; | 692 ASSERT_FALSE( |
| 672 ASSERT_FALSE(ParseBasicConstraintsFromFile( | 693 ParseCertificateFromFile("basic_constraints_unconsumed_data.pem")); |
| 673 "basic_constraints_unconsumed_data.pem", &constraints)); | |
| 674 } | 694 } |
| 675 | 695 |
| 676 // Parses a BasicConstraints with CA omitted (false), but with a pathlen of 1. | 696 // Parses a BasicConstraints with CA omitted (false), but with a pathlen of 1. |
| 677 // This is valid DER for the ASN.1, however is not valid when interpreting the | 697 // This is valid DER for the ASN.1, however is not valid when interpreting the |
| 678 // BasicConstraints at a higher level. | 698 // BasicConstraints at a higher level. |
| 679 TEST(ParseBasicConstraintsTest, PathLenButNotCa) { | 699 TEST(ParseCertificateTest, BasicConstraintsPathLenButNotCa) { |
| 680 ParsedBasicConstraints constraints; | 700 scoped_refptr<ParsedCertificate> cert = |
| 681 ASSERT_TRUE(ParseBasicConstraintsFromFile( | 701 ParseCertificateFromFile("basic_constraints_pathlen_not_ca.pem"); |
| 682 "basic_constraints_pathlen_not_ca.pem", &constraints)); | 702 ASSERT_TRUE(cert); |
| 683 EXPECT_FALSE(constraints.is_ca); | 703 |
| 684 EXPECT_TRUE(constraints.has_path_len); | 704 EXPECT_TRUE(cert->has_basic_constraints()); |
| 685 EXPECT_EQ(1u, constraints.path_len); | 705 EXPECT_FALSE(cert->basic_constraints().is_ca); |
| 706 EXPECT_TRUE(cert->basic_constraints().has_path_len); | |
| 707 EXPECT_EQ(1u, cert->basic_constraints().path_len); | |
| 686 } | 708 } |
| 687 | 709 |
| 688 // Parses a KeyUsage with a single 0 bit. | 710 // Parses a KeyUsage with a single 0 bit. |
| 689 TEST(ParseKeyUsageTest, OneBitAllZeros) { | 711 TEST(ParseKeyUsageTest, OneBitAllZeros) { |
| 690 const uint8_t der[] = { | 712 const uint8_t der[] = { |
| 691 0x03, 0x02, // BIT STRING | 713 0x03, 0x02, // BIT STRING |
| 692 0x07, // Number of unused bits | 714 0x07, // Number of unused bits |
| 693 0x00, // bits | 715 0x00, // bits |
| 694 }; | 716 }; |
| 695 | 717 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 784 0x00, // Number of unused bits | 806 0x00, // Number of unused bits |
| 785 }; | 807 }; |
| 786 | 808 |
| 787 der::BitString key_usage; | 809 der::BitString key_usage; |
| 788 ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage)); | 810 ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage)); |
| 789 } | 811 } |
| 790 | 812 |
| 791 } // namespace | 813 } // namespace |
| 792 | 814 |
| 793 } // namespace net | 815 } // namespace net |
| OLD | NEW |