| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/parsed_certificate.h" | 5 #include "net/cert/internal/parsed_certificate.h" |
| 6 | 6 |
| 7 #include "net/cert/internal/cert_errors.h" | 7 #include "net/cert/internal/cert_errors.h" |
| 8 #include "net/cert/internal/parse_certificate.h" | 8 #include "net/cert/internal/parse_certificate.h" |
| 9 #include "net/cert/internal/test_helpers.h" | 9 #include "net/cert/internal/test_helpers.h" |
| 10 #include "net/der/input.h" | 10 #include "net/der/input.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
| 12 #include "third_party/boringssl/src/include/openssl/pool.h" | 12 #include "third_party/boringssl/src/include/openssl/pool.h" |
| 13 | 13 |
| 14 namespace net { | 14 namespace net { |
| 15 | 15 |
| 16 namespace { | 16 namespace { |
| 17 | 17 |
| 18 std::string GetFilePath(const std::string& file_name) { | 18 std::string GetFilePath(const std::string& file_name) { |
| 19 return std::string("net/data/parse_certificate_unittest/") + file_name; | 19 return std::string("net/data/parse_certificate_unittest/") + file_name; |
| 20 } | 20 } |
| 21 | 21 |
| 22 // Reads and parses a certificate from the PEM file |file_name|. | 22 // Reads and parses a certificate from the PEM file |file_name|. |
| 23 // | 23 // |
| 24 // Returns nullptr if the certificate parsing failed, and verifies that any | 24 // Returns nullptr if the certificate parsing failed, and verifies that any |
| 25 // errors match the ERRORS block in the .pem file. | 25 // errors match the ERRORS block in the .pem file. |
| 26 scoped_refptr<ParsedCertificate> ParseCertificateFromFile( | 26 scoped_refptr<ParsedCertificate> ParseCertificateFromFile( |
| 27 const std::string& file_name) { | 27 const std::string& file_name, |
| 28 const ParseCertificateOptions& options) { |
| 28 std::string data; | 29 std::string data; |
| 29 std::string expected_errors; | 30 std::string expected_errors; |
| 30 | 31 |
| 31 // Read the certificate data and error expectations from a single PEM file. | 32 // Read the certificate data and error expectations from a single PEM file. |
| 32 const PemBlockMapping mappings[] = { | 33 const PemBlockMapping mappings[] = { |
| 33 {"CERTIFICATE", &data}, {"ERRORS", &expected_errors, true /*optional*/}, | 34 {"CERTIFICATE", &data}, {"ERRORS", &expected_errors, true /*optional*/}, |
| 34 }; | 35 }; |
| 35 std::string test_file_path = GetFilePath(file_name); | 36 std::string test_file_path = GetFilePath(file_name); |
| 36 EXPECT_TRUE(ReadTestDataFromPemFile(test_file_path, mappings)); | 37 EXPECT_TRUE(ReadTestDataFromPemFile(test_file_path, mappings)); |
| 37 | 38 |
| 38 CertErrors errors; | 39 CertErrors errors; |
| 39 scoped_refptr<ParsedCertificate> cert = ParsedCertificate::Create( | 40 scoped_refptr<ParsedCertificate> cert = ParsedCertificate::Create( |
| 40 bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new( | 41 bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new( |
| 41 reinterpret_cast<const uint8_t*>(data.data()), data.size(), nullptr)), | 42 reinterpret_cast<const uint8_t*>(data.data()), data.size(), nullptr)), |
| 42 {}, &errors); | 43 options, &errors); |
| 43 | 44 |
| 44 EXPECT_EQ(expected_errors, errors.ToDebugString()) << "Test file: " | 45 EXPECT_EQ(expected_errors, errors.ToDebugString()) << "Test file: " |
| 45 << test_file_path; | 46 << test_file_path; |
| 46 | 47 |
| 47 // TODO(crbug.com/634443): Every parse failure being tested should emit error | 48 // TODO(crbug.com/634443): Every parse failure being tested should emit error |
| 48 // information. | 49 // information. |
| 49 // if (!cert) | 50 // if (!cert) |
| 50 // EXPECT_FALSE(errors.empty()); | 51 // EXPECT_FALSE(errors.empty()); |
| 51 | 52 |
| 52 return cert; | 53 return cert; |
| 53 } | 54 } |
| 54 | 55 |
| 55 der::Input DavidBenOid() { | 56 der::Input DavidBenOid() { |
| 56 // This OID corresponds with | 57 // This OID corresponds with |
| 57 // 1.2.840.113554.4.1.72585.0 (https://davidben.net/oid) | 58 // 1.2.840.113554.4.1.72585.0 (https://davidben.net/oid) |
| 58 static const uint8_t kOid[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, | 59 static const uint8_t kOid[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, |
| 59 0x04, 0x01, 0x84, 0xb7, 0x09, 0x00}; | 60 0x04, 0x01, 0x84, 0xb7, 0x09, 0x00}; |
| 60 return der::Input(kOid); | 61 return der::Input(kOid); |
| 61 } | 62 } |
| 62 | 63 |
| 63 // Parses an Extension whose critical field is true (255). | 64 // Parses an Extension whose critical field is true (255). |
| 64 TEST(ParsedCertificateTest, ExtensionCritical) { | 65 TEST(ParsedCertificateTest, ExtensionCritical) { |
| 65 scoped_refptr<ParsedCertificate> cert = | 66 scoped_refptr<ParsedCertificate> cert = |
| 66 ParseCertificateFromFile("extension_critical.pem"); | 67 ParseCertificateFromFile("extension_critical.pem", {}); |
| 67 ASSERT_TRUE(cert); | 68 ASSERT_TRUE(cert); |
| 68 | 69 |
| 69 const uint8_t kExpectedValue[] = {0x30, 0x00}; | 70 const uint8_t kExpectedValue[] = {0x30, 0x00}; |
| 70 | 71 |
| 71 ParsedExtension extension; | 72 ParsedExtension extension; |
| 72 ASSERT_TRUE(cert->GetExtension(DavidBenOid(), &extension)); | 73 ASSERT_TRUE(cert->GetExtension(DavidBenOid(), &extension)); |
| 73 | 74 |
| 74 EXPECT_TRUE(extension.critical); | 75 EXPECT_TRUE(extension.critical); |
| 75 EXPECT_EQ(DavidBenOid(), extension.oid); | 76 EXPECT_EQ(DavidBenOid(), extension.oid); |
| 76 EXPECT_EQ(der::Input(kExpectedValue), extension.value); | 77 EXPECT_EQ(der::Input(kExpectedValue), extension.value); |
| 77 } | 78 } |
| 78 | 79 |
| 79 // Parses an Extension whose critical field is false (omitted). | 80 // Parses an Extension whose critical field is false (omitted). |
| 80 TEST(ParsedCertificateTest, ExtensionNotCritical) { | 81 TEST(ParsedCertificateTest, ExtensionNotCritical) { |
| 81 scoped_refptr<ParsedCertificate> cert = | 82 scoped_refptr<ParsedCertificate> cert = |
| 82 ParseCertificateFromFile("extension_not_critical.pem"); | 83 ParseCertificateFromFile("extension_not_critical.pem", {}); |
| 83 ASSERT_TRUE(cert); | 84 ASSERT_TRUE(cert); |
| 84 | 85 |
| 85 const uint8_t kExpectedValue[] = {0x30, 0x00}; | 86 const uint8_t kExpectedValue[] = {0x30, 0x00}; |
| 86 | 87 |
| 87 ParsedExtension extension; | 88 ParsedExtension extension; |
| 88 ASSERT_TRUE(cert->GetExtension(DavidBenOid(), &extension)); | 89 ASSERT_TRUE(cert->GetExtension(DavidBenOid(), &extension)); |
| 89 | 90 |
| 90 EXPECT_FALSE(extension.critical); | 91 EXPECT_FALSE(extension.critical); |
| 91 EXPECT_EQ(DavidBenOid(), extension.oid); | 92 EXPECT_EQ(DavidBenOid(), extension.oid); |
| 92 EXPECT_EQ(der::Input(kExpectedValue), extension.value); | 93 EXPECT_EQ(der::Input(kExpectedValue), extension.value); |
| 93 } | 94 } |
| 94 | 95 |
| 95 // Parses an Extension whose critical field is 0. This is in one sense FALSE, | 96 // Parses an Extension whose critical field is 0. This is in one sense FALSE, |
| 96 // however because critical has DEFAULT of false this is in fact invalid | 97 // however because critical has DEFAULT of false this is in fact invalid |
| 97 // DER-encoding. | 98 // DER-encoding. |
| 98 TEST(ParsedCertificateTest, ExtensionCritical0) { | 99 TEST(ParsedCertificateTest, ExtensionCritical0) { |
| 99 ASSERT_FALSE(ParseCertificateFromFile("extension_critical_0.pem")); | 100 ASSERT_FALSE(ParseCertificateFromFile("extension_critical_0.pem", {})); |
| 100 } | 101 } |
| 101 | 102 |
| 102 // Parses an Extension whose critical field is 3. Under DER-encoding BOOLEAN | 103 // Parses an Extension whose critical field is 3. Under DER-encoding BOOLEAN |
| 103 // values must an octet of either all zero bits, or all 1 bits, so this is not | 104 // values must an octet of either all zero bits, or all 1 bits, so this is not |
| 104 // valid. | 105 // valid. |
| 105 TEST(ParsedCertificateTest, ExtensionCritical3) { | 106 TEST(ParsedCertificateTest, ExtensionCritical3) { |
| 106 ASSERT_FALSE(ParseCertificateFromFile("extension_critical_3.pem")); | 107 ASSERT_FALSE(ParseCertificateFromFile("extension_critical_3.pem", {})); |
| 107 } | 108 } |
| 108 | 109 |
| 109 // Parses an Extensions that is an empty sequence. | 110 // Parses an Extensions that is an empty sequence. |
| 110 TEST(ParsedCertificateTest, ExtensionsEmptySequence) { | 111 TEST(ParsedCertificateTest, ExtensionsEmptySequence) { |
| 111 ASSERT_FALSE(ParseCertificateFromFile("extensions_empty_sequence.pem")); | 112 ASSERT_FALSE(ParseCertificateFromFile("extensions_empty_sequence.pem", {})); |
| 112 } | 113 } |
| 113 | 114 |
| 114 // Parses an Extensions that is not a sequence. | 115 // Parses an Extensions that is not a sequence. |
| 115 TEST(ParsedCertificateTest, ExtensionsNotSequence) { | 116 TEST(ParsedCertificateTest, ExtensionsNotSequence) { |
| 116 ASSERT_FALSE(ParseCertificateFromFile("extensions_not_sequence.pem")); | 117 ASSERT_FALSE(ParseCertificateFromFile("extensions_not_sequence.pem", {})); |
| 117 } | 118 } |
| 118 | 119 |
| 119 // Parses an Extensions that has data after the sequence. | 120 // Parses an Extensions that has data after the sequence. |
| 120 TEST(ParsedCertificateTest, ExtensionsDataAfterSequence) { | 121 TEST(ParsedCertificateTest, ExtensionsDataAfterSequence) { |
| 121 ASSERT_FALSE(ParseCertificateFromFile("extensions_data_after_sequence.pem")); | 122 ASSERT_FALSE( |
| 123 ParseCertificateFromFile("extensions_data_after_sequence.pem", {})); |
| 122 } | 124 } |
| 123 | 125 |
| 124 // Parses an Extensions that contains duplicated key usages. | 126 // Parses an Extensions that contains duplicated key usages. |
| 125 TEST(ParsedCertificateTest, ExtensionsDuplicateKeyUsage) { | 127 TEST(ParsedCertificateTest, ExtensionsDuplicateKeyUsage) { |
| 126 ASSERT_FALSE(ParseCertificateFromFile("extensions_duplicate_key_usage.pem")); | 128 ASSERT_FALSE( |
| 129 ParseCertificateFromFile("extensions_duplicate_key_usage.pem", {})); |
| 127 } | 130 } |
| 128 | 131 |
| 129 // Parses an Extensions that contains an extended key usages. | 132 // Parses an Extensions that contains an extended key usages. |
| 130 TEST(ParsedCertificateTest, ExtendedKeyUsage) { | 133 TEST(ParsedCertificateTest, ExtendedKeyUsage) { |
| 131 scoped_refptr<ParsedCertificate> cert = | 134 scoped_refptr<ParsedCertificate> cert = |
| 132 ParseCertificateFromFile("extended_key_usage.pem"); | 135 ParseCertificateFromFile("extended_key_usage.pem", {}); |
| 133 ASSERT_TRUE(cert); | 136 ASSERT_TRUE(cert); |
| 134 | 137 |
| 135 ASSERT_EQ(4u, cert->extensions().size()); | 138 ASSERT_EQ(4u, cert->extensions().size()); |
| 136 | 139 |
| 137 ParsedExtension extension; | 140 ParsedExtension extension; |
| 138 ASSERT_TRUE(cert->GetExtension(ExtKeyUsageOid(), &extension)); | 141 ASSERT_TRUE(cert->GetExtension(ExtKeyUsageOid(), &extension)); |
| 139 | 142 |
| 140 EXPECT_FALSE(extension.critical); | 143 EXPECT_FALSE(extension.critical); |
| 141 EXPECT_EQ(45u, extension.value.Length()); | 144 EXPECT_EQ(45u, extension.value.Length()); |
| 142 | 145 |
| 143 EXPECT_TRUE(cert->has_extended_key_usage()); | 146 EXPECT_TRUE(cert->has_extended_key_usage()); |
| 144 EXPECT_EQ(4u, cert->extended_key_usage().size()); | 147 EXPECT_EQ(4u, cert->extended_key_usage().size()); |
| 145 } | 148 } |
| 146 | 149 |
| 147 // Parses an Extensions that contains a key usage. | 150 // Parses an Extensions that contains a key usage. |
| 148 TEST(ParsedCertificateTest, KeyUsage) { | 151 TEST(ParsedCertificateTest, KeyUsage) { |
| 149 scoped_refptr<ParsedCertificate> cert = | 152 scoped_refptr<ParsedCertificate> cert = |
| 150 ParseCertificateFromFile("key_usage.pem"); | 153 ParseCertificateFromFile("key_usage.pem", {}); |
| 151 ASSERT_TRUE(cert); | 154 ASSERT_TRUE(cert); |
| 152 | 155 |
| 153 ASSERT_TRUE(cert->has_key_usage()); | 156 ASSERT_TRUE(cert->has_key_usage()); |
| 154 | 157 |
| 155 EXPECT_EQ(5u, cert->key_usage().unused_bits()); | 158 EXPECT_EQ(5u, cert->key_usage().unused_bits()); |
| 156 const uint8_t kExpectedBytes[] = {0xA0}; | 159 const uint8_t kExpectedBytes[] = {0xA0}; |
| 157 EXPECT_EQ(der::Input(kExpectedBytes), cert->key_usage().bytes()); | 160 EXPECT_EQ(der::Input(kExpectedBytes), cert->key_usage().bytes()); |
| 158 | 161 |
| 159 EXPECT_TRUE(cert->key_usage().AssertsBit(0)); | 162 EXPECT_TRUE(cert->key_usage().AssertsBit(0)); |
| 160 EXPECT_FALSE(cert->key_usage().AssertsBit(1)); | 163 EXPECT_FALSE(cert->key_usage().AssertsBit(1)); |
| 161 EXPECT_TRUE(cert->key_usage().AssertsBit(2)); | 164 EXPECT_TRUE(cert->key_usage().AssertsBit(2)); |
| 162 } | 165 } |
| 163 | 166 |
| 164 // Parses an Extensions that contains a policies extension. | 167 // Parses an Extensions that contains a policies extension. |
| 165 TEST(ParsedCertificateTest, Policies) { | 168 TEST(ParsedCertificateTest, Policies) { |
| 166 scoped_refptr<ParsedCertificate> cert = | 169 scoped_refptr<ParsedCertificate> cert = |
| 167 ParseCertificateFromFile("policies.pem"); | 170 ParseCertificateFromFile("policies.pem", {}); |
| 168 ASSERT_TRUE(cert); | 171 ASSERT_TRUE(cert); |
| 169 | 172 |
| 170 ASSERT_EQ(4u, cert->extensions().size()); | 173 ASSERT_EQ(4u, cert->extensions().size()); |
| 171 | 174 |
| 172 ParsedExtension extension; | 175 ParsedExtension extension; |
| 173 ASSERT_TRUE(cert->GetExtension(CertificatePoliciesOid(), &extension)); | 176 ASSERT_TRUE(cert->GetExtension(CertificatePoliciesOid(), &extension)); |
| 174 | 177 |
| 175 EXPECT_FALSE(extension.critical); | 178 EXPECT_FALSE(extension.critical); |
| 176 EXPECT_EQ(95u, extension.value.Length()); | 179 EXPECT_EQ(95u, extension.value.Length()); |
| 177 | 180 |
| 178 EXPECT_TRUE(cert->has_policy_oids()); | 181 EXPECT_TRUE(cert->has_policy_oids()); |
| 179 EXPECT_EQ(2u, cert->policy_oids().size()); | 182 EXPECT_EQ(2u, cert->policy_oids().size()); |
| 180 } | 183 } |
| 181 | 184 |
| 182 // Parses an Extensions that contains a subjectaltname extension. | 185 // Parses an Extensions that contains a subjectaltname extension. |
| 183 TEST(ParsedCertificateTest, SubjectAltName) { | 186 TEST(ParsedCertificateTest, SubjectAltName) { |
| 184 scoped_refptr<ParsedCertificate> cert = | 187 scoped_refptr<ParsedCertificate> cert = |
| 185 ParseCertificateFromFile("subject_alt_name.pem"); | 188 ParseCertificateFromFile("subject_alt_name.pem", {}); |
| 186 ASSERT_TRUE(cert); | 189 ASSERT_TRUE(cert); |
| 187 | 190 |
| 188 ASSERT_TRUE(cert->has_subject_alt_names()); | 191 ASSERT_TRUE(cert->has_subject_alt_names()); |
| 189 } | 192 } |
| 190 | 193 |
| 191 // Parses an Extensions that contains multiple extensions, sourced from a | 194 // Parses an Extensions that contains multiple extensions, sourced from a |
| 192 // real-world certificate. | 195 // real-world certificate. |
| 193 TEST(ParsedCertificateTest, ExtensionsReal) { | 196 TEST(ParsedCertificateTest, ExtensionsReal) { |
| 194 scoped_refptr<ParsedCertificate> cert = | 197 scoped_refptr<ParsedCertificate> cert = |
| 195 ParseCertificateFromFile("extensions_real.pem"); | 198 ParseCertificateFromFile("extensions_real.pem", {}); |
| 196 ASSERT_TRUE(cert); | 199 ASSERT_TRUE(cert); |
| 197 | 200 |
| 198 ASSERT_EQ(7u, cert->extensions().size()); | 201 ASSERT_EQ(7u, cert->extensions().size()); |
| 199 | 202 |
| 200 EXPECT_TRUE(cert->has_key_usage()); | 203 EXPECT_TRUE(cert->has_key_usage()); |
| 201 EXPECT_TRUE(cert->has_basic_constraints()); | 204 EXPECT_TRUE(cert->has_basic_constraints()); |
| 202 EXPECT_TRUE(cert->has_policy_oids()); | 205 EXPECT_TRUE(cert->has_policy_oids()); |
| 203 | 206 |
| 204 ParsedExtension extension; | 207 ParsedExtension extension; |
| 205 ASSERT_TRUE(cert->GetExtension(CertificatePoliciesOid(), &extension)); | 208 ASSERT_TRUE(cert->GetExtension(CertificatePoliciesOid(), &extension)); |
| 206 | 209 |
| 207 EXPECT_FALSE(extension.critical); | 210 EXPECT_FALSE(extension.critical); |
| 208 EXPECT_EQ(16u, extension.value.Length()); | 211 EXPECT_EQ(16u, extension.value.Length()); |
| 209 | 212 |
| 210 // TODO(eroman): Verify the other 4 extensions' values. | 213 // TODO(eroman): Verify the other 4 extensions' values. |
| 211 } | 214 } |
| 212 | 215 |
| 213 // Parses a BasicConstraints with no CA or pathlen. | 216 // Parses a BasicConstraints with no CA or pathlen. |
| 214 TEST(ParsedCertificateTest, BasicConstraintsNotCa) { | 217 TEST(ParsedCertificateTest, BasicConstraintsNotCa) { |
| 215 scoped_refptr<ParsedCertificate> cert = | 218 scoped_refptr<ParsedCertificate> cert = |
| 216 ParseCertificateFromFile("basic_constraints_not_ca.pem"); | 219 ParseCertificateFromFile("basic_constraints_not_ca.pem", {}); |
| 217 ASSERT_TRUE(cert); | 220 ASSERT_TRUE(cert); |
| 218 | 221 |
| 219 EXPECT_TRUE(cert->has_basic_constraints()); | 222 EXPECT_TRUE(cert->has_basic_constraints()); |
| 220 EXPECT_FALSE(cert->basic_constraints().is_ca); | 223 EXPECT_FALSE(cert->basic_constraints().is_ca); |
| 221 EXPECT_FALSE(cert->basic_constraints().has_path_len); | 224 EXPECT_FALSE(cert->basic_constraints().has_path_len); |
| 222 } | 225 } |
| 223 | 226 |
| 224 // Parses a BasicConstraints with CA but no pathlen. | 227 // Parses a BasicConstraints with CA but no pathlen. |
| 225 TEST(ParsedCertificateTest, BasicConstraintsCaNoPath) { | 228 TEST(ParsedCertificateTest, BasicConstraintsCaNoPath) { |
| 226 scoped_refptr<ParsedCertificate> cert = | 229 scoped_refptr<ParsedCertificate> cert = |
| 227 ParseCertificateFromFile("basic_constraints_ca_no_path.pem"); | 230 ParseCertificateFromFile("basic_constraints_ca_no_path.pem", {}); |
| 228 ASSERT_TRUE(cert); | 231 ASSERT_TRUE(cert); |
| 229 | 232 |
| 230 EXPECT_TRUE(cert->has_basic_constraints()); | 233 EXPECT_TRUE(cert->has_basic_constraints()); |
| 231 EXPECT_TRUE(cert->basic_constraints().is_ca); | 234 EXPECT_TRUE(cert->basic_constraints().is_ca); |
| 232 EXPECT_FALSE(cert->basic_constraints().has_path_len); | 235 EXPECT_FALSE(cert->basic_constraints().has_path_len); |
| 233 } | 236 } |
| 234 | 237 |
| 235 // Parses a BasicConstraints with CA and pathlen of 9. | 238 // Parses a BasicConstraints with CA and pathlen of 9. |
| 236 TEST(ParsedCertificateTest, BasicConstraintsCaPath9) { | 239 TEST(ParsedCertificateTest, BasicConstraintsCaPath9) { |
| 237 scoped_refptr<ParsedCertificate> cert = | 240 scoped_refptr<ParsedCertificate> cert = |
| 238 ParseCertificateFromFile("basic_constraints_ca_path_9.pem"); | 241 ParseCertificateFromFile("basic_constraints_ca_path_9.pem", {}); |
| 239 ASSERT_TRUE(cert); | 242 ASSERT_TRUE(cert); |
| 240 | 243 |
| 241 EXPECT_TRUE(cert->has_basic_constraints()); | 244 EXPECT_TRUE(cert->has_basic_constraints()); |
| 242 EXPECT_TRUE(cert->basic_constraints().is_ca); | 245 EXPECT_TRUE(cert->basic_constraints().is_ca); |
| 243 EXPECT_TRUE(cert->basic_constraints().has_path_len); | 246 EXPECT_TRUE(cert->basic_constraints().has_path_len); |
| 244 EXPECT_EQ(9u, cert->basic_constraints().path_len); | 247 EXPECT_EQ(9u, cert->basic_constraints().path_len); |
| 245 } | 248 } |
| 246 | 249 |
| 247 // Parses a BasicConstraints with CA and pathlen of 255 (largest allowed size). | 250 // Parses a BasicConstraints with CA and pathlen of 255 (largest allowed size). |
| 248 TEST(ParsedCertificateTest, BasicConstraintsPathlen255) { | 251 TEST(ParsedCertificateTest, BasicConstraintsPathlen255) { |
| 249 scoped_refptr<ParsedCertificate> cert = | 252 scoped_refptr<ParsedCertificate> cert = |
| 250 ParseCertificateFromFile("basic_constraints_pathlen_255.pem"); | 253 ParseCertificateFromFile("basic_constraints_pathlen_255.pem", {}); |
| 251 ASSERT_TRUE(cert); | 254 ASSERT_TRUE(cert); |
| 252 | 255 |
| 253 EXPECT_TRUE(cert->has_basic_constraints()); | 256 EXPECT_TRUE(cert->has_basic_constraints()); |
| 254 EXPECT_TRUE(cert->basic_constraints().is_ca); | 257 EXPECT_TRUE(cert->basic_constraints().is_ca); |
| 255 EXPECT_TRUE(cert->basic_constraints().has_path_len); | 258 EXPECT_TRUE(cert->basic_constraints().has_path_len); |
| 256 EXPECT_EQ(255, cert->basic_constraints().path_len); | 259 EXPECT_EQ(255, cert->basic_constraints().path_len); |
| 257 } | 260 } |
| 258 | 261 |
| 259 // Parses a BasicConstraints with CA and pathlen of 256 (too large). | 262 // Parses a BasicConstraints with CA and pathlen of 256 (too large). |
| 260 TEST(ParsedCertificateTest, BasicConstraintsPathlen256) { | 263 TEST(ParsedCertificateTest, BasicConstraintsPathlen256) { |
| 261 ASSERT_FALSE(ParseCertificateFromFile("basic_constraints_pathlen_256.pem")); | 264 ASSERT_FALSE( |
| 265 ParseCertificateFromFile("basic_constraints_pathlen_256.pem", {})); |
| 262 } | 266 } |
| 263 | 267 |
| 264 // Parses a BasicConstraints with CA and a negative pathlen. | 268 // Parses a BasicConstraints with CA and a negative pathlen. |
| 265 TEST(ParsedCertificateTest, BasicConstraintsNegativePath) { | 269 TEST(ParsedCertificateTest, BasicConstraintsNegativePath) { |
| 266 ASSERT_FALSE(ParseCertificateFromFile("basic_constraints_negative_path.pem")); | 270 ASSERT_FALSE( |
| 271 ParseCertificateFromFile("basic_constraints_negative_path.pem", {})); |
| 267 } | 272 } |
| 268 | 273 |
| 269 // Parses a BasicConstraints with CA and pathlen that is very large (and | 274 // Parses a BasicConstraints with CA and pathlen that is very large (and |
| 270 // couldn't fit in a 64-bit integer). | 275 // couldn't fit in a 64-bit integer). |
| 271 TEST(ParsedCertificateTest, BasicConstraintsPathTooLarge) { | 276 TEST(ParsedCertificateTest, BasicConstraintsPathTooLarge) { |
| 272 ASSERT_FALSE( | 277 ASSERT_FALSE( |
| 273 ParseCertificateFromFile("basic_constraints_path_too_large.pem")); | 278 ParseCertificateFromFile("basic_constraints_path_too_large.pem", {})); |
| 274 } | 279 } |
| 275 | 280 |
| 276 // Parses a BasicConstraints with CA explicitly set to false. This violates | 281 // Parses a BasicConstraints with CA explicitly set to false. This violates |
| 277 // DER-encoding rules, however is commonly used, so it is accepted. | 282 // DER-encoding rules, however is commonly used, so it is accepted. |
| 278 TEST(ParsedCertificateTest, BasicConstraintsCaFalse) { | 283 TEST(ParsedCertificateTest, BasicConstraintsCaFalse) { |
| 279 scoped_refptr<ParsedCertificate> cert = | 284 scoped_refptr<ParsedCertificate> cert = |
| 280 ParseCertificateFromFile("basic_constraints_ca_false.pem"); | 285 ParseCertificateFromFile("basic_constraints_ca_false.pem", {}); |
| 281 ASSERT_TRUE(cert); | 286 ASSERT_TRUE(cert); |
| 282 | 287 |
| 283 EXPECT_TRUE(cert->has_basic_constraints()); | 288 EXPECT_TRUE(cert->has_basic_constraints()); |
| 284 EXPECT_FALSE(cert->basic_constraints().is_ca); | 289 EXPECT_FALSE(cert->basic_constraints().is_ca); |
| 285 EXPECT_FALSE(cert->basic_constraints().has_path_len); | 290 EXPECT_FALSE(cert->basic_constraints().has_path_len); |
| 286 } | 291 } |
| 287 | 292 |
| 288 // Parses a BasicConstraints with CA set to true and an unexpected NULL at | 293 // Parses a BasicConstraints with CA set to true and an unexpected NULL at |
| 289 // the end. | 294 // the end. |
| 290 TEST(ParsedCertificateTest, BasicConstraintsUnconsumedData) { | 295 TEST(ParsedCertificateTest, BasicConstraintsUnconsumedData) { |
| 291 ASSERT_FALSE( | 296 ASSERT_FALSE( |
| 292 ParseCertificateFromFile("basic_constraints_unconsumed_data.pem")); | 297 ParseCertificateFromFile("basic_constraints_unconsumed_data.pem", {})); |
| 293 } | 298 } |
| 294 | 299 |
| 295 // Parses a BasicConstraints with CA omitted (false), but with a pathlen of 1. | 300 // Parses a BasicConstraints with CA omitted (false), but with a pathlen of 1. |
| 296 // This is valid DER for the ASN.1, however is not valid when interpreting the | 301 // This is valid DER for the ASN.1, however is not valid when interpreting the |
| 297 // BasicConstraints at a higher level. | 302 // BasicConstraints at a higher level. |
| 298 TEST(ParsedCertificateTest, BasicConstraintsPathLenButNotCa) { | 303 TEST(ParsedCertificateTest, BasicConstraintsPathLenButNotCa) { |
| 299 scoped_refptr<ParsedCertificate> cert = | 304 scoped_refptr<ParsedCertificate> cert = |
| 300 ParseCertificateFromFile("basic_constraints_pathlen_not_ca.pem"); | 305 ParseCertificateFromFile("basic_constraints_pathlen_not_ca.pem", {}); |
| 301 ASSERT_TRUE(cert); | 306 ASSERT_TRUE(cert); |
| 302 | 307 |
| 303 EXPECT_TRUE(cert->has_basic_constraints()); | 308 EXPECT_TRUE(cert->has_basic_constraints()); |
| 304 EXPECT_FALSE(cert->basic_constraints().is_ca); | 309 EXPECT_FALSE(cert->basic_constraints().is_ca); |
| 305 EXPECT_TRUE(cert->basic_constraints().has_path_len); | 310 EXPECT_TRUE(cert->basic_constraints().has_path_len); |
| 306 EXPECT_EQ(1u, cert->basic_constraints().path_len); | 311 EXPECT_EQ(1u, cert->basic_constraints().path_len); |
| 307 } | 312 } |
| 308 | 313 |
| 314 // Tests a certificate with a serial number with a leading 0 padding byte in |
| 315 // the encoding since it is not negative. |
| 316 TEST(ParsedCertificateTest, SerialNumberZeroPadded) { |
| 317 scoped_refptr<ParsedCertificate> cert = |
| 318 ParseCertificateFromFile("serial_zero_padded.pem", {}); |
| 319 ASSERT_TRUE(cert); |
| 320 |
| 321 static const uint8_t expected_serial[3] = {0x00, 0x80, 0x01}; |
| 322 EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number); |
| 323 } |
| 324 |
| 325 // Tests a serial number where the MSB is >= 0x80, causing the encoded |
| 326 // length to be 21 bytes long. This is an error, as RFC 5280 specifies a |
| 327 // maximum of 20 bytes. |
| 328 TEST(ParsedCertificateTest, SerialNumberZeroPadded21BytesLong) { |
| 329 scoped_refptr<ParsedCertificate> cert = |
| 330 ParseCertificateFromFile("serial_zero_padded_21_bytes.pem", {}); |
| 331 ASSERT_FALSE(cert); |
| 332 |
| 333 // Try again with allow_invalid_serial_numbers=true. Parsing should succeed. |
| 334 ParseCertificateOptions options; |
| 335 options.allow_invalid_serial_numbers = true; |
| 336 cert = ParseCertificateFromFile("serial_zero_padded_21_bytes.pem", options); |
| 337 ASSERT_TRUE(cert); |
| 338 |
| 339 static const uint8_t expected_serial[21] = { |
| 340 0x00, 0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, |
| 341 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13}; |
| 342 EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number); |
| 343 } |
| 344 |
| 345 // Tests a serial number which is negative. CAs are not supposed to include |
| 346 // negative serial numbers, however RFC 5280 expects consumers to deal with it |
| 347 // anyway. |
| 348 TEST(ParsedCertificateTest, SerialNumberNegative) { |
| 349 scoped_refptr<ParsedCertificate> cert = |
| 350 ParseCertificateFromFile("serial_negative.pem", {}); |
| 351 ASSERT_TRUE(cert); |
| 352 |
| 353 static const uint8_t expected_serial[2] = {0x80, 0x01}; |
| 354 EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number); |
| 355 } |
| 356 |
| 357 // Tests a serial number which is very long. RFC 5280 specifies a maximum of 20 |
| 358 // bytes. |
| 359 TEST(ParsedCertificateTest, SerialNumber37BytesLong) { |
| 360 scoped_refptr<ParsedCertificate> cert = |
| 361 ParseCertificateFromFile("serial_37_bytes.pem", {}); |
| 362 ASSERT_FALSE(cert); |
| 363 |
| 364 // Try again with allow_invalid_serial_numbers=true. Parsing should succeed. |
| 365 ParseCertificateOptions options; |
| 366 options.allow_invalid_serial_numbers = true; |
| 367 cert = ParseCertificateFromFile("serial_37_bytes.pem", options); |
| 368 ASSERT_TRUE(cert); |
| 369 |
| 370 static const uint8_t expected_serial[37] = { |
| 371 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, |
| 372 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, |
| 373 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, |
| 374 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25}; |
| 375 EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number); |
| 376 } |
| 377 |
| 309 } // namespace | 378 } // namespace |
| 310 | 379 |
| 311 } // namespace net | 380 } // namespace net |
| OLD | NEW |