| 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/test_helpers.h" | 8 #include "net/cert/internal/test_helpers.h" |
| 9 #include "net/der/input.h" | 9 #include "net/der/input.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 const PemBlockMapping mappings[] = { | 39 const PemBlockMapping mappings[] = { |
| 40 {"CERTIFICATE", &data}, | 40 {"CERTIFICATE", &data}, |
| 41 {"SIGNATURE", &expected_signature}, | 41 {"SIGNATURE", &expected_signature}, |
| 42 {"SIGNATURE ALGORITHM", &expected_signature_algorithm}, | 42 {"SIGNATURE ALGORITHM", &expected_signature_algorithm}, |
| 43 {"TBS CERTIFICATE", &expected_tbs_certificate}, | 43 {"TBS CERTIFICATE", &expected_tbs_certificate}, |
| 44 }; | 44 }; |
| 45 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); | 45 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); |
| 46 | 46 |
| 47 // Parsing the certificate should succeed. | 47 // Parsing the certificate should succeed. |
| 48 ParsedCertificate parsed; | 48 ParsedCertificate parsed; |
| 49 ASSERT_TRUE(ParseCertificate(InputFromString(&data), &parsed)); | 49 ASSERT_TRUE(ParseCertificate(der::Input(&data), &parsed)); |
| 50 | 50 |
| 51 // Ensure that the ParsedCertificate matches expectations. | 51 // Ensure that the ParsedCertificate matches expectations. |
| 52 EXPECT_EQ(0, parsed.signature_value.unused_bits()); | 52 EXPECT_EQ(0, parsed.signature_value.unused_bits()); |
| 53 EXPECT_EQ(InputFromString(&expected_signature), | 53 EXPECT_EQ(der::Input(&expected_signature), parsed.signature_value.bytes()); |
| 54 parsed.signature_value.bytes()); | 54 EXPECT_EQ(der::Input(&expected_signature_algorithm), |
| 55 EXPECT_EQ(InputFromString(&expected_signature_algorithm), | |
| 56 parsed.signature_algorithm_tlv); | 55 parsed.signature_algorithm_tlv); |
| 57 EXPECT_EQ(InputFromString(&expected_tbs_certificate), | 56 EXPECT_EQ(der::Input(&expected_tbs_certificate), parsed.tbs_certificate_tlv); |
| 58 parsed.tbs_certificate_tlv); | |
| 59 } | 57 } |
| 60 | 58 |
| 61 // Loads certificate data from the PEM file |file_name| and verifies that the | 59 // Loads certificate data from the PEM file |file_name| and verifies that the |
| 62 // Certificate parsing fails. | 60 // Certificate parsing fails. |
| 63 void EnsureParsingCertificateFails(const std::string& file_name) { | 61 void EnsureParsingCertificateFails(const std::string& file_name) { |
| 64 std::string data; | 62 std::string data; |
| 65 | 63 |
| 66 const PemBlockMapping mappings[] = { | 64 const PemBlockMapping mappings[] = { |
| 67 {"CERTIFICATE", &data}, | 65 {"CERTIFICATE", &data}, |
| 68 }; | 66 }; |
| 69 | 67 |
| 70 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); | 68 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); |
| 71 | 69 |
| 72 // Parsing the Certificate should fail. | 70 // Parsing the Certificate should fail. |
| 73 ParsedCertificate parsed; | 71 ParsedCertificate parsed; |
| 74 ASSERT_FALSE(ParseCertificate(InputFromString(&data), &parsed)); | 72 ASSERT_FALSE(ParseCertificate(der::Input(&data), &parsed)); |
| 75 } | 73 } |
| 76 | 74 |
| 77 // Tests parsing a Certificate. | 75 // Tests parsing a Certificate. |
| 78 TEST(ParseCertificateTest, Version3) { | 76 TEST(ParseCertificateTest, Version3) { |
| 79 EnsureParsingCertificateSucceeds("cert_version3.pem"); | 77 EnsureParsingCertificateSucceeds("cert_version3.pem"); |
| 80 } | 78 } |
| 81 | 79 |
| 82 // Tests parsing a simplified Certificate-like structure (the sub-fields for | 80 // Tests parsing a simplified Certificate-like structure (the sub-fields for |
| 83 // algorithm and tbsCertificate are not actually valid, but ParseCertificate() | 81 // algorithm and tbsCertificate are not actually valid, but ParseCertificate() |
| 84 // doesn't check them) | 82 // doesn't check them) |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 {"SUBJECT", &expected_subject}, | 144 {"SUBJECT", &expected_subject}, |
| 147 {"SPKI", &expected_spki}, | 145 {"SPKI", &expected_spki}, |
| 148 {"ISSUER UNIQUE ID", &expected_issuer_unique_id, true}, | 146 {"ISSUER UNIQUE ID", &expected_issuer_unique_id, true}, |
| 149 {"SUBJECT UNIQUE ID", &expected_subject_unique_id, true}, | 147 {"SUBJECT UNIQUE ID", &expected_subject_unique_id, true}, |
| 150 {"EXTENSIONS", &expected_extensions, true}, | 148 {"EXTENSIONS", &expected_extensions, true}, |
| 151 }; | 149 }; |
| 152 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); | 150 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); |
| 153 | 151 |
| 154 // Parsing the TBSCertificate should succeed. | 152 // Parsing the TBSCertificate should succeed. |
| 155 ParsedTbsCertificate parsed; | 153 ParsedTbsCertificate parsed; |
| 156 ASSERT_TRUE(ParseTbsCertificate(InputFromString(&data), &parsed)); | 154 ASSERT_TRUE(ParseTbsCertificate(der::Input(&data), &parsed)); |
| 157 | 155 |
| 158 // Ensure that the ParsedTbsCertificate matches expectations. | 156 // Ensure that the ParsedTbsCertificate matches expectations. |
| 159 EXPECT_EQ(expected_version, parsed.version); | 157 EXPECT_EQ(expected_version, parsed.version); |
| 160 | 158 |
| 161 EXPECT_EQ(InputFromString(&expected_serial_number), parsed.serial_number); | 159 EXPECT_EQ(der::Input(&expected_serial_number), parsed.serial_number); |
| 162 EXPECT_EQ(InputFromString(&expected_signature_algorithm), | 160 EXPECT_EQ(der::Input(&expected_signature_algorithm), |
| 163 parsed.signature_algorithm_tlv); | 161 parsed.signature_algorithm_tlv); |
| 164 | 162 |
| 165 EXPECT_EQ(InputFromString(&expected_issuer), parsed.issuer_tlv); | 163 EXPECT_EQ(der::Input(&expected_issuer), parsed.issuer_tlv); |
| 166 | 164 |
| 167 // In the test expectations PEM file, validity is described as a | 165 // In the test expectations PEM file, validity is described as a |
| 168 // textual string of the parsed value (rather than as DER). | 166 // textual string of the parsed value (rather than as DER). |
| 169 EXPECT_EQ(expected_validity_not_before, ToString(parsed.validity_not_before)); | 167 EXPECT_EQ(expected_validity_not_before, ToString(parsed.validity_not_before)); |
| 170 EXPECT_EQ(expected_validity_not_after, ToString(parsed.validity_not_after)); | 168 EXPECT_EQ(expected_validity_not_after, ToString(parsed.validity_not_after)); |
| 171 | 169 |
| 172 EXPECT_EQ(InputFromString(&expected_subject), parsed.subject_tlv); | 170 EXPECT_EQ(der::Input(&expected_subject), parsed.subject_tlv); |
| 173 EXPECT_EQ(InputFromString(&expected_spki), parsed.spki_tlv); | 171 EXPECT_EQ(der::Input(&expected_spki), parsed.spki_tlv); |
| 174 | 172 |
| 175 EXPECT_EQ(InputFromString(&expected_issuer_unique_id), | 173 EXPECT_EQ(der::Input(&expected_issuer_unique_id), |
| 176 parsed.issuer_unique_id.bytes()); | 174 parsed.issuer_unique_id.bytes()); |
| 177 EXPECT_EQ(!expected_issuer_unique_id.empty(), parsed.has_issuer_unique_id); | 175 EXPECT_EQ(!expected_issuer_unique_id.empty(), parsed.has_issuer_unique_id); |
| 178 EXPECT_EQ(InputFromString(&expected_subject_unique_id), | 176 EXPECT_EQ(der::Input(&expected_subject_unique_id), |
| 179 parsed.subject_unique_id.bytes()); | 177 parsed.subject_unique_id.bytes()); |
| 180 EXPECT_EQ(!expected_subject_unique_id.empty(), parsed.has_subject_unique_id); | 178 EXPECT_EQ(!expected_subject_unique_id.empty(), parsed.has_subject_unique_id); |
| 181 | 179 |
| 182 EXPECT_EQ(InputFromString(&expected_extensions), parsed.extensions_tlv); | 180 EXPECT_EQ(der::Input(&expected_extensions), parsed.extensions_tlv); |
| 183 EXPECT_EQ(!expected_extensions.empty(), parsed.has_extensions); | 181 EXPECT_EQ(!expected_extensions.empty(), parsed.has_extensions); |
| 184 } | 182 } |
| 185 | 183 |
| 186 // Loads certificate data from the PEM file |file_name| and verifies that the | 184 // Loads certificate data from the PEM file |file_name| and verifies that the |
| 187 // Certificate parsing succeed, however the TBSCertificate parsing fails. | 185 // Certificate parsing succeed, however the TBSCertificate parsing fails. |
| 188 void EnsureParsingTbsFails(const std::string& file_name) { | 186 void EnsureParsingTbsFails(const std::string& file_name) { |
| 189 std::string data; | 187 std::string data; |
| 190 | 188 |
| 191 const PemBlockMapping mappings[] = { | 189 const PemBlockMapping mappings[] = { |
| 192 {"TBS CERTIFICATE", &data}, | 190 {"TBS CERTIFICATE", &data}, |
| 193 }; | 191 }; |
| 194 | 192 |
| 195 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); | 193 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); |
| 196 | 194 |
| 197 // Parsing the TBSCertificate should fail. | 195 // Parsing the TBSCertificate should fail. |
| 198 ParsedTbsCertificate parsed; | 196 ParsedTbsCertificate parsed; |
| 199 ASSERT_FALSE(ParseTbsCertificate(InputFromString(&data), &parsed)); | 197 ASSERT_FALSE(ParseTbsCertificate(der::Input(&data), &parsed)); |
| 200 } | 198 } |
| 201 | 199 |
| 202 // Tests parsing a TBSCertificate for v3 that contains no optional fields. | 200 // Tests parsing a TBSCertificate for v3 that contains no optional fields. |
| 203 TEST(ParseTbsCertificateTest, Version3NoOptionals) { | 201 TEST(ParseTbsCertificateTest, Version3NoOptionals) { |
| 204 EnsureParsingTbsSucceeds("tbs_v3_no_optionals.pem", CertificateVersion::V3); | 202 EnsureParsingTbsSucceeds("tbs_v3_no_optionals.pem", CertificateVersion::V3); |
| 205 } | 203 } |
| 206 | 204 |
| 207 // Tests parsing a TBSCertificate for v3 that contains extensions. | 205 // Tests parsing a TBSCertificate for v3 that contains extensions. |
| 208 TEST(ParseTbsCertificateTest, Version3WithExtensions) { | 206 TEST(ParseTbsCertificateTest, Version3WithExtensions) { |
| 209 EnsureParsingTbsSucceeds("tbs_v3_extensions.pem", CertificateVersion::V3); | 207 EnsureParsingTbsSucceeds("tbs_v3_extensions.pem", CertificateVersion::V3); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 // Reads a PEM file containing a block "EXTENSION". This input will be | 327 // Reads a PEM file containing a block "EXTENSION". This input will be |
| 330 // passed to ParseExtension, and the results filled in |out|. | 328 // passed to ParseExtension, and the results filled in |out|. |
| 331 bool ParseExtensionFromFile(const std::string& file_name, | 329 bool ParseExtensionFromFile(const std::string& file_name, |
| 332 ParsedExtension* out, | 330 ParsedExtension* out, |
| 333 std::string* data) { | 331 std::string* data) { |
| 334 const PemBlockMapping mappings[] = { | 332 const PemBlockMapping mappings[] = { |
| 335 {"EXTENSION", data}, | 333 {"EXTENSION", data}, |
| 336 }; | 334 }; |
| 337 | 335 |
| 338 EXPECT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); | 336 EXPECT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); |
| 339 return ParseExtension(InputFromString(data), out); | 337 return ParseExtension(der::Input(data), out); |
| 340 } | 338 } |
| 341 | 339 |
| 342 // Parses an Extension whose critical field is true (255). | 340 // Parses an Extension whose critical field is true (255). |
| 343 TEST(ParseExtensionTest, Critical) { | 341 TEST(ParseExtensionTest, Critical) { |
| 344 std::string data; | 342 std::string data; |
| 345 ParsedExtension extension; | 343 ParsedExtension extension; |
| 346 ASSERT_TRUE( | 344 ASSERT_TRUE( |
| 347 ParseExtensionFromFile("extension_critical.pem", &extension, &data)); | 345 ParseExtensionFromFile("extension_critical.pem", &extension, &data)); |
| 348 | 346 |
| 349 EXPECT_TRUE(extension.critical); | 347 EXPECT_TRUE(extension.critical); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 void EnsureParsingExtensionsSucceeds( | 395 void EnsureParsingExtensionsSucceeds( |
| 398 const std::string& file_name, | 396 const std::string& file_name, |
| 399 std::map<der::Input, ParsedExtension>* extensions, | 397 std::map<der::Input, ParsedExtension>* extensions, |
| 400 std::string* data) { | 398 std::string* data) { |
| 401 const PemBlockMapping mappings[] = { | 399 const PemBlockMapping mappings[] = { |
| 402 // Test Input. | 400 // Test Input. |
| 403 {"EXTENSIONS", data}, | 401 {"EXTENSIONS", data}, |
| 404 }; | 402 }; |
| 405 | 403 |
| 406 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); | 404 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); |
| 407 ASSERT_TRUE(ParseExtensions(InputFromString(data), extensions)); | 405 ASSERT_TRUE(ParseExtensions(der::Input(data), extensions)); |
| 408 } | 406 } |
| 409 | 407 |
| 410 // Runs a test that verifies extensions parsing fails. The input file is a PEM | 408 // Runs a test that verifies extensions parsing fails. The input file is a PEM |
| 411 // file which contains a DER-encoded Extensions sequence. | 409 // file which contains a DER-encoded Extensions sequence. |
| 412 void EnsureParsingExtensionsFails(const std::string& file_name) { | 410 void EnsureParsingExtensionsFails(const std::string& file_name) { |
| 413 std::string data; | 411 std::string data; |
| 414 | 412 |
| 415 const PemBlockMapping mappings[] = { | 413 const PemBlockMapping mappings[] = { |
| 416 {"EXTENSIONS", &data}, | 414 {"EXTENSIONS", &data}, |
| 417 }; | 415 }; |
| 418 | 416 |
| 419 std::map<der::Input, ParsedExtension> extensions; | 417 std::map<der::Input, ParsedExtension> extensions; |
| 420 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); | 418 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); |
| 421 ASSERT_FALSE(ParseExtensions(InputFromString(&data), &extensions)); | 419 ASSERT_FALSE(ParseExtensions(der::Input(&data), &extensions)); |
| 422 } | 420 } |
| 423 | 421 |
| 424 // Parses an Extensions that is an empty sequence. | 422 // Parses an Extensions that is an empty sequence. |
| 425 TEST(ParseExtensionsTest, EmptySequence) { | 423 TEST(ParseExtensionsTest, EmptySequence) { |
| 426 EnsureParsingExtensionsFails("extensions_empty_sequence.pem"); | 424 EnsureParsingExtensionsFails("extensions_empty_sequence.pem"); |
| 427 } | 425 } |
| 428 | 426 |
| 429 // Parses an Extensions that is not a sequence. | 427 // Parses an Extensions that is not a sequence. |
| 430 TEST(ParseExtensionsTest, NotSequence) { | 428 TEST(ParseExtensionsTest, NotSequence) { |
| 431 EnsureParsingExtensionsFails("extensions_not_sequence.pem"); | 429 EnsureParsingExtensionsFails("extensions_not_sequence.pem"); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 // Reads a PEM file containing a block "BASIC CONSTRAINTS". This input will | 582 // Reads a PEM file containing a block "BASIC CONSTRAINTS". This input will |
| 585 // be passed to ParseExtension, and the results filled in |out|. | 583 // be passed to ParseExtension, and the results filled in |out|. |
| 586 bool ParseBasicConstraintsFromFile(const std::string& file_name, | 584 bool ParseBasicConstraintsFromFile(const std::string& file_name, |
| 587 ParsedBasicConstraints* out) { | 585 ParsedBasicConstraints* out) { |
| 588 std::string data; | 586 std::string data; |
| 589 const PemBlockMapping mappings[] = { | 587 const PemBlockMapping mappings[] = { |
| 590 {"BASIC CONSTRAINTS", &data}, | 588 {"BASIC CONSTRAINTS", &data}, |
| 591 }; | 589 }; |
| 592 | 590 |
| 593 EXPECT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); | 591 EXPECT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); |
| 594 return ParseBasicConstraints(InputFromString(&data), out); | 592 return ParseBasicConstraints(der::Input(&data), out); |
| 595 } | 593 } |
| 596 | 594 |
| 597 // Parses a BasicConstraints with no CA or pathlen. | 595 // Parses a BasicConstraints with no CA or pathlen. |
| 598 TEST(ParseBasicConstraintsTest, NotCa) { | 596 TEST(ParseBasicConstraintsTest, NotCa) { |
| 599 ParsedBasicConstraints constraints; | 597 ParsedBasicConstraints constraints; |
| 600 ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_not_ca.pem", | 598 ASSERT_TRUE(ParseBasicConstraintsFromFile("basic_constraints_not_ca.pem", |
| 601 &constraints)); | 599 &constraints)); |
| 602 EXPECT_FALSE(constraints.is_ca); | 600 EXPECT_FALSE(constraints.is_ca); |
| 603 EXPECT_FALSE(constraints.has_path_len); | 601 EXPECT_FALSE(constraints.has_path_len); |
| 604 } | 602 } |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 0x00, // Number of unused bits | 781 0x00, // Number of unused bits |
| 784 }; | 782 }; |
| 785 | 783 |
| 786 der::BitString key_usage; | 784 der::BitString key_usage; |
| 787 ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage)); | 785 ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage)); |
| 788 } | 786 } |
| 789 | 787 |
| 790 } // namespace | 788 } // namespace |
| 791 | 789 |
| 792 } // namespace net | 790 } // namespace net |
| OLD | NEW |