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 |
309 // Tests parsing a certificate that contains a policyConstraints | 314 // Tests parsing a certificate that contains a policyConstraints |
310 // extension having requireExplicitPolicy:3. | 315 // extension having requireExplicitPolicy:3. |
311 TEST(ParsedCertificateTest, PolicyConstraintsRequire) { | 316 TEST(ParsedCertificateTest, PolicyConstraintsRequire) { |
312 scoped_refptr<ParsedCertificate> cert = | 317 scoped_refptr<ParsedCertificate> cert = |
313 ParseCertificateFromFile("policy_constraints_require.pem"); | 318 ParseCertificateFromFile("policy_constraints_require.pem", {}); |
314 ASSERT_TRUE(cert); | 319 ASSERT_TRUE(cert); |
315 | 320 |
316 EXPECT_TRUE(cert->has_policy_constraints()); | 321 EXPECT_TRUE(cert->has_policy_constraints()); |
317 EXPECT_TRUE(cert->policy_constraints().has_require_explicit_policy); | 322 EXPECT_TRUE(cert->policy_constraints().has_require_explicit_policy); |
318 EXPECT_EQ(3, cert->policy_constraints().require_explicit_policy); | 323 EXPECT_EQ(3, cert->policy_constraints().require_explicit_policy); |
319 EXPECT_FALSE(cert->policy_constraints().has_inhibit_policy_mapping); | 324 EXPECT_FALSE(cert->policy_constraints().has_inhibit_policy_mapping); |
320 EXPECT_EQ(0, cert->policy_constraints().inhibit_policy_mapping); | 325 EXPECT_EQ(0, cert->policy_constraints().inhibit_policy_mapping); |
321 } | 326 } |
322 | 327 |
323 // Tests parsing a certificate that contains a policyConstraints | 328 // Tests parsing a certificate that contains a policyConstraints |
324 // extension having inhibitPolicyMapping:1. | 329 // extension having inhibitPolicyMapping:1. |
325 TEST(ParsedCertificateTest, PolicyConstraintsInhibit) { | 330 TEST(ParsedCertificateTest, PolicyConstraintsInhibit) { |
326 scoped_refptr<ParsedCertificate> cert = | 331 scoped_refptr<ParsedCertificate> cert = |
327 ParseCertificateFromFile("policy_constraints_inhibit.pem"); | 332 ParseCertificateFromFile("policy_constraints_inhibit.pem", {}); |
328 ASSERT_TRUE(cert); | 333 ASSERT_TRUE(cert); |
329 | 334 |
330 EXPECT_TRUE(cert->has_policy_constraints()); | 335 EXPECT_TRUE(cert->has_policy_constraints()); |
331 EXPECT_FALSE(cert->policy_constraints().has_require_explicit_policy); | 336 EXPECT_FALSE(cert->policy_constraints().has_require_explicit_policy); |
332 EXPECT_EQ(0, cert->policy_constraints().require_explicit_policy); | 337 EXPECT_EQ(0, cert->policy_constraints().require_explicit_policy); |
333 EXPECT_TRUE(cert->policy_constraints().has_inhibit_policy_mapping); | 338 EXPECT_TRUE(cert->policy_constraints().has_inhibit_policy_mapping); |
334 EXPECT_EQ(1, cert->policy_constraints().inhibit_policy_mapping); | 339 EXPECT_EQ(1, cert->policy_constraints().inhibit_policy_mapping); |
335 } | 340 } |
336 | 341 |
337 // Tests parsing a certificate that contains a policyConstraints | 342 // Tests parsing a certificate that contains a policyConstraints |
338 // extension having requireExplicitPolicy:5,inhibitPolicyMapping:2. | 343 // extension having requireExplicitPolicy:5,inhibitPolicyMapping:2. |
339 TEST(ParsedCertificateTest, PolicyConstraintsInhibitRequire) { | 344 TEST(ParsedCertificateTest, PolicyConstraintsInhibitRequire) { |
340 scoped_refptr<ParsedCertificate> cert = | 345 scoped_refptr<ParsedCertificate> cert = |
341 ParseCertificateFromFile("policy_constraints_inhibit_require.pem"); | 346 ParseCertificateFromFile("policy_constraints_inhibit_require.pem", {}); |
342 ASSERT_TRUE(cert); | 347 ASSERT_TRUE(cert); |
343 | 348 |
344 EXPECT_TRUE(cert->has_policy_constraints()); | 349 EXPECT_TRUE(cert->has_policy_constraints()); |
345 EXPECT_TRUE(cert->policy_constraints().has_require_explicit_policy); | 350 EXPECT_TRUE(cert->policy_constraints().has_require_explicit_policy); |
346 EXPECT_EQ(5, cert->policy_constraints().require_explicit_policy); | 351 EXPECT_EQ(5, cert->policy_constraints().require_explicit_policy); |
347 EXPECT_TRUE(cert->policy_constraints().has_inhibit_policy_mapping); | 352 EXPECT_TRUE(cert->policy_constraints().has_inhibit_policy_mapping); |
348 EXPECT_EQ(2, cert->policy_constraints().inhibit_policy_mapping); | 353 EXPECT_EQ(2, cert->policy_constraints().inhibit_policy_mapping); |
349 } | 354 } |
350 | 355 |
351 // Tests parsing a certificate that has a policyConstraints | 356 // Tests parsing a certificate that has a policyConstraints |
352 // extension with an empty sequence. | 357 // extension with an empty sequence. |
353 TEST(ParsedCertificateTest, PolicyConstraintsEmpty) { | 358 TEST(ParsedCertificateTest, PolicyConstraintsEmpty) { |
354 scoped_refptr<ParsedCertificate> cert = | 359 scoped_refptr<ParsedCertificate> cert = |
355 ParseCertificateFromFile("policy_constraints_empty.pem"); | 360 ParseCertificateFromFile("policy_constraints_empty.pem", {}); |
356 ASSERT_FALSE(cert); | 361 ASSERT_FALSE(cert); |
357 } | 362 } |
358 | 363 |
| 364 // Tests a certificate with a serial number with a leading 0 padding byte in |
| 365 // the encoding since it is not negative. |
| 366 TEST(ParsedCertificateTest, SerialNumberZeroPadded) { |
| 367 scoped_refptr<ParsedCertificate> cert = |
| 368 ParseCertificateFromFile("serial_zero_padded.pem", {}); |
| 369 ASSERT_TRUE(cert); |
| 370 |
| 371 static const uint8_t expected_serial[3] = {0x00, 0x80, 0x01}; |
| 372 EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number); |
| 373 } |
| 374 |
| 375 // Tests a serial number where the MSB is >= 0x80, causing the encoded |
| 376 // length to be 21 bytes long. This is an error, as RFC 5280 specifies a |
| 377 // maximum of 20 bytes. |
| 378 TEST(ParsedCertificateTest, SerialNumberZeroPadded21BytesLong) { |
| 379 scoped_refptr<ParsedCertificate> cert = |
| 380 ParseCertificateFromFile("serial_zero_padded_21_bytes.pem", {}); |
| 381 ASSERT_FALSE(cert); |
| 382 |
| 383 // Try again with allow_invalid_serial_numbers=true. Parsing should succeed. |
| 384 ParseCertificateOptions options; |
| 385 options.allow_invalid_serial_numbers = true; |
| 386 cert = ParseCertificateFromFile("serial_zero_padded_21_bytes.pem", options); |
| 387 ASSERT_TRUE(cert); |
| 388 |
| 389 static const uint8_t expected_serial[21] = { |
| 390 0x00, 0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, |
| 391 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13}; |
| 392 EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number); |
| 393 } |
| 394 |
| 395 // Tests a serial number which is negative. CAs are not supposed to include |
| 396 // negative serial numbers, however RFC 5280 expects consumers to deal with it |
| 397 // anyway. |
| 398 TEST(ParsedCertificateTest, SerialNumberNegative) { |
| 399 scoped_refptr<ParsedCertificate> cert = |
| 400 ParseCertificateFromFile("serial_negative.pem", {}); |
| 401 ASSERT_TRUE(cert); |
| 402 |
| 403 static const uint8_t expected_serial[2] = {0x80, 0x01}; |
| 404 EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number); |
| 405 } |
| 406 |
| 407 // Tests a serial number which is very long. RFC 5280 specifies a maximum of 20 |
| 408 // bytes. |
| 409 TEST(ParsedCertificateTest, SerialNumber37BytesLong) { |
| 410 scoped_refptr<ParsedCertificate> cert = |
| 411 ParseCertificateFromFile("serial_37_bytes.pem", {}); |
| 412 ASSERT_FALSE(cert); |
| 413 |
| 414 // Try again with allow_invalid_serial_numbers=true. Parsing should succeed. |
| 415 ParseCertificateOptions options; |
| 416 options.allow_invalid_serial_numbers = true; |
| 417 cert = ParseCertificateFromFile("serial_37_bytes.pem", options); |
| 418 ASSERT_TRUE(cert); |
| 419 |
| 420 static const uint8_t expected_serial[37] = { |
| 421 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, |
| 422 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, |
| 423 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, |
| 424 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25}; |
| 425 EXPECT_EQ(der::Input(expected_serial), cert->tbs().serial_number); |
| 426 } |
| 427 |
359 } // namespace | 428 } // namespace |
360 | 429 |
361 } // namespace net | 430 } // namespace net |
OLD | NEW |