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 #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" |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 | 115 |
116 // Tests what happens when the signature algorithm is present, but has the wrong | 116 // Tests what happens when the signature algorithm is present, but has the wrong |
117 // tag. | 117 // tag. |
118 TEST(ParseCertificateTest, AlgorithmNotSequence) { | 118 TEST(ParseCertificateTest, AlgorithmNotSequence) { |
119 RunCertificateTest("cert_algorithm_not_sequence.pem"); | 119 RunCertificateTest("cert_algorithm_not_sequence.pem"); |
120 } | 120 } |
121 | 121 |
122 // Loads tbsCertificate data and expectations from the PEM file |file_name|. | 122 // Loads tbsCertificate data and expectations from the PEM file |file_name|. |
123 // Verifies that parsing the TBSCertificate succeeds, and each parsed field | 123 // Verifies that parsing the TBSCertificate succeeds, and each parsed field |
124 // matches the expectations. | 124 // matches the expectations. |
125 void EnsureParsingTbsSucceeds(const std::string& file_name, | 125 // |
126 CertificateVersion expected_version) { | 126 // TODO(eroman): Get rid of the |expected_version| parameter -- this should be |
| 127 // encoded in the test expectations file. |
| 128 void RunTbsCertificateTestGivenVersion(const std::string& file_name, |
| 129 CertificateVersion expected_version) { |
127 std::string data; | 130 std::string data; |
128 std::string expected_serial_number; | 131 std::string expected_serial_number; |
129 std::string expected_signature_algorithm; | 132 std::string expected_signature_algorithm; |
130 std::string expected_issuer; | 133 std::string expected_issuer; |
131 std::string expected_validity_not_before; | 134 std::string expected_validity_not_before; |
132 std::string expected_validity_not_after; | 135 std::string expected_validity_not_after; |
133 std::string expected_subject; | 136 std::string expected_subject; |
134 std::string expected_spki; | 137 std::string expected_spki; |
135 std::string expected_issuer_unique_id; | 138 std::string expected_issuer_unique_id; |
136 std::string expected_subject_unique_id; | 139 std::string expected_subject_unique_id; |
137 std::string expected_extensions; | 140 std::string expected_extensions; |
| 141 std::string expected_errors; |
138 | 142 |
139 // Read the certificate data and test expectations from a single PEM file. | 143 // Read the certificate data and test expectations from a single PEM file. |
140 const PemBlockMapping mappings[] = { | 144 const PemBlockMapping mappings[] = { |
141 {"TBS CERTIFICATE", &data}, | 145 {"TBS CERTIFICATE", &data}, |
142 {"SIGNATURE ALGORITHM", &expected_signature_algorithm}, | 146 {"SIGNATURE ALGORITHM", &expected_signature_algorithm, true}, |
143 {"SERIAL NUMBER", &expected_serial_number}, | 147 {"SERIAL NUMBER", &expected_serial_number, true}, |
144 {"ISSUER", &expected_issuer}, | 148 {"ISSUER", &expected_issuer, true}, |
145 {"VALIDITY NOTBEFORE", &expected_validity_not_before}, | 149 {"VALIDITY NOTBEFORE", &expected_validity_not_before, true}, |
146 {"VALIDITY NOTAFTER", &expected_validity_not_after}, | 150 {"VALIDITY NOTAFTER", &expected_validity_not_after, true}, |
147 {"SUBJECT", &expected_subject}, | 151 {"SUBJECT", &expected_subject, true}, |
148 {"SPKI", &expected_spki}, | 152 {"SPKI", &expected_spki, true}, |
149 {"ISSUER UNIQUE ID", &expected_issuer_unique_id, true}, | 153 {"ISSUER UNIQUE ID", &expected_issuer_unique_id, true}, |
150 {"SUBJECT UNIQUE ID", &expected_subject_unique_id, true}, | 154 {"SUBJECT UNIQUE ID", &expected_subject_unique_id, true}, |
151 {"EXTENSIONS", &expected_extensions, true}, | 155 {"EXTENSIONS", &expected_extensions, true}, |
| 156 {"ERRORS", &expected_errors, true}, |
152 }; | 157 }; |
153 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); | 158 std::string test_file_path = GetFilePath(file_name); |
| 159 ASSERT_TRUE(ReadTestDataFromPemFile(test_file_path, mappings)); |
154 | 160 |
155 // Parsing the TBSCertificate should succeed. | 161 bool expected_result = !expected_spki.empty(); |
| 162 |
156 ParsedTbsCertificate parsed; | 163 ParsedTbsCertificate parsed; |
157 ASSERT_TRUE(ParseTbsCertificate(der::Input(&data), {}, &parsed)); | 164 CertErrors errors; |
| 165 bool actual_result = |
| 166 ParseTbsCertificate(der::Input(&data), {}, &parsed, &errors); |
| 167 |
| 168 EXPECT_EQ(expected_result, actual_result); |
| 169 EXPECT_EQ(expected_errors, errors.ToDebugString()) << "Test file: " |
| 170 << test_file_path; |
| 171 |
| 172 if (!expected_result || !actual_result) |
| 173 return; |
158 | 174 |
159 // Ensure that the ParsedTbsCertificate matches expectations. | 175 // Ensure that the ParsedTbsCertificate matches expectations. |
160 EXPECT_EQ(expected_version, parsed.version); | 176 EXPECT_EQ(expected_version, parsed.version); |
161 | 177 |
162 EXPECT_EQ(der::Input(&expected_serial_number), parsed.serial_number); | 178 EXPECT_EQ(der::Input(&expected_serial_number), parsed.serial_number); |
163 EXPECT_EQ(der::Input(&expected_signature_algorithm), | 179 EXPECT_EQ(der::Input(&expected_signature_algorithm), |
164 parsed.signature_algorithm_tlv); | 180 parsed.signature_algorithm_tlv); |
165 | 181 |
166 EXPECT_EQ(der::Input(&expected_issuer), parsed.issuer_tlv); | 182 EXPECT_EQ(der::Input(&expected_issuer), parsed.issuer_tlv); |
167 | 183 |
168 // In the test expectations PEM file, validity is described as a | 184 // In the test expectations PEM file, validity is described as a |
169 // textual string of the parsed value (rather than as DER). | 185 // textual string of the parsed value (rather than as DER). |
170 EXPECT_EQ(expected_validity_not_before, ToString(parsed.validity_not_before)); | 186 EXPECT_EQ(expected_validity_not_before, ToString(parsed.validity_not_before)); |
171 EXPECT_EQ(expected_validity_not_after, ToString(parsed.validity_not_after)); | 187 EXPECT_EQ(expected_validity_not_after, ToString(parsed.validity_not_after)); |
172 | 188 |
173 EXPECT_EQ(der::Input(&expected_subject), parsed.subject_tlv); | 189 EXPECT_EQ(der::Input(&expected_subject), parsed.subject_tlv); |
174 EXPECT_EQ(der::Input(&expected_spki), parsed.spki_tlv); | 190 EXPECT_EQ(der::Input(&expected_spki), parsed.spki_tlv); |
175 | 191 |
176 EXPECT_EQ(der::Input(&expected_issuer_unique_id), | 192 EXPECT_EQ(der::Input(&expected_issuer_unique_id), |
177 parsed.issuer_unique_id.bytes()); | 193 parsed.issuer_unique_id.bytes()); |
178 EXPECT_EQ(!expected_issuer_unique_id.empty(), parsed.has_issuer_unique_id); | 194 EXPECT_EQ(!expected_issuer_unique_id.empty(), parsed.has_issuer_unique_id); |
179 EXPECT_EQ(der::Input(&expected_subject_unique_id), | 195 EXPECT_EQ(der::Input(&expected_subject_unique_id), |
180 parsed.subject_unique_id.bytes()); | 196 parsed.subject_unique_id.bytes()); |
181 EXPECT_EQ(!expected_subject_unique_id.empty(), parsed.has_subject_unique_id); | 197 EXPECT_EQ(!expected_subject_unique_id.empty(), parsed.has_subject_unique_id); |
182 | 198 |
183 EXPECT_EQ(der::Input(&expected_extensions), parsed.extensions_tlv); | 199 EXPECT_EQ(der::Input(&expected_extensions), parsed.extensions_tlv); |
184 EXPECT_EQ(!expected_extensions.empty(), parsed.has_extensions); | 200 EXPECT_EQ(!expected_extensions.empty(), parsed.has_extensions); |
185 } | 201 } |
186 | 202 |
187 // Loads certificate data from the PEM file |file_name| and verifies that the | 203 void RunTbsCertificateTest(const std::string& file_name) { |
188 // Certificate parsing succeed, however the TBSCertificate parsing fails. | 204 RunTbsCertificateTestGivenVersion(file_name, CertificateVersion::V3); |
189 void EnsureParsingTbsFails(const std::string& file_name) { | |
190 std::string data; | |
191 | |
192 const PemBlockMapping mappings[] = { | |
193 {"TBS CERTIFICATE", &data}, | |
194 }; | |
195 | |
196 ASSERT_TRUE(ReadTestDataFromPemFile(GetFilePath(file_name), mappings)); | |
197 | |
198 // Parsing the TBSCertificate should fail. | |
199 ParsedTbsCertificate parsed; | |
200 ASSERT_FALSE(ParseTbsCertificate(der::Input(&data), {}, &parsed)); | |
201 } | 205 } |
202 | 206 |
203 // Tests parsing a TBSCertificate for v3 that contains no optional fields. | 207 // Tests parsing a TBSCertificate for v3 that contains no optional fields. |
204 TEST(ParseTbsCertificateTest, Version3NoOptionals) { | 208 TEST(ParseTbsCertificateTest, Version3NoOptionals) { |
205 EnsureParsingTbsSucceeds("tbs_v3_no_optionals.pem", CertificateVersion::V3); | 209 RunTbsCertificateTest("tbs_v3_no_optionals.pem"); |
206 } | 210 } |
207 | 211 |
208 // Tests parsing a TBSCertificate for v3 that contains extensions. | 212 // Tests parsing a TBSCertificate for v3 that contains extensions. |
209 TEST(ParseTbsCertificateTest, Version3WithExtensions) { | 213 TEST(ParseTbsCertificateTest, Version3WithExtensions) { |
210 EnsureParsingTbsSucceeds("tbs_v3_extensions.pem", CertificateVersion::V3); | 214 RunTbsCertificateTest("tbs_v3_extensions.pem"); |
211 } | 215 } |
212 | 216 |
213 // Tests parsing a TBSCertificate for v3 that contains no optional fields, and | 217 // Tests parsing a TBSCertificate for v3 that contains no optional fields, and |
214 // has a negative serial number. | 218 // has a negative serial number. |
215 // | 219 // |
216 // CAs are not supposed to include negative serial numbers, however RFC 5280 | 220 // CAs are not supposed to include negative serial numbers, however RFC 5280 |
217 // expects consumers to deal with it anyway). | 221 // expects consumers to deal with it anyway). |
218 TEST(ParseTbsCertificateTest, NegativeSerialNumber) { | 222 TEST(ParseTbsCertificateTest, NegativeSerialNumber) { |
219 EnsureParsingTbsSucceeds("tbs_negative_serial_number.pem", | 223 RunTbsCertificateTest("tbs_negative_serial_number.pem"); |
220 CertificateVersion::V3); | |
221 } | 224 } |
222 | 225 |
223 // Tests parsing a TBSCertificate with a serial number that is 21 octets long | 226 // Tests parsing a TBSCertificate with a serial number that is 21 octets long |
224 // (and the first byte is 0). | 227 // (and the first byte is 0). |
225 TEST(ParseTbCertificateTest, SerialNumber21OctetsLeading0) { | 228 TEST(ParseTbCertificateTest, SerialNumber21OctetsLeading0) { |
226 EnsureParsingTbsFails("tbs_serial_number_21_octets_leading_0.pem"); | 229 RunTbsCertificateTest("tbs_serial_number_21_octets_leading_0.pem"); |
227 } | 230 } |
228 | 231 |
229 // Tests parsing a TBSCertificate with a serial number that is 26 octets long | 232 // Tests parsing a TBSCertificate with a serial number that is 26 octets long |
230 // (and does not contain a leading 0). | 233 // (and does not contain a leading 0). |
231 TEST(ParseTbsCertificateTest, SerialNumber26Octets) { | 234 TEST(ParseTbsCertificateTest, SerialNumber26Octets) { |
232 EnsureParsingTbsFails("tbs_serial_number_26_octets.pem"); | 235 RunTbsCertificateTest("tbs_serial_number_26_octets.pem"); |
233 } | 236 } |
234 | 237 |
235 // Tests parsing a TBSCertificate which lacks a version number (causing it to | 238 // Tests parsing a TBSCertificate which lacks a version number (causing it to |
236 // default to v1). | 239 // default to v1). |
237 TEST(ParseTbsCertificateTest, Version1) { | 240 TEST(ParseTbsCertificateTest, Version1) { |
238 EnsureParsingTbsSucceeds("tbs_v1.pem", CertificateVersion::V1); | 241 RunTbsCertificateTestGivenVersion("tbs_v1.pem", CertificateVersion::V1); |
239 } | 242 } |
240 | 243 |
241 // The version was set to v1 explicitly rather than omitting the version field. | 244 // The version was set to v1 explicitly rather than omitting the version field. |
242 TEST(ParseTbsCertificateTest, ExplicitVersion1) { | 245 TEST(ParseTbsCertificateTest, ExplicitVersion1) { |
243 EnsureParsingTbsFails("tbs_explicit_v1.pem"); | 246 RunTbsCertificateTest("tbs_explicit_v1.pem"); |
244 } | 247 } |
245 | 248 |
246 // Extensions are not defined in version 1. | 249 // Extensions are not defined in version 1. |
247 TEST(ParseTbsCertificateTest, Version1WithExtensions) { | 250 TEST(ParseTbsCertificateTest, Version1WithExtensions) { |
248 EnsureParsingTbsFails("tbs_v1_extensions.pem"); | 251 RunTbsCertificateTest("tbs_v1_extensions.pem"); |
249 } | 252 } |
250 | 253 |
251 // Extensions are not defined in version 2. | 254 // Extensions are not defined in version 2. |
252 TEST(ParseTbsCertificateTest, Version2WithExtensions) { | 255 TEST(ParseTbsCertificateTest, Version2WithExtensions) { |
253 EnsureParsingTbsFails("tbs_v2_extensions.pem"); | 256 RunTbsCertificateTest("tbs_v2_extensions.pem"); |
254 } | 257 } |
255 | 258 |
256 // A boring version 2 certificate with none of the optional fields. | 259 // A boring version 2 certificate with none of the optional fields. |
257 TEST(ParseTbsCertificateTest, Version2NoOptionals) { | 260 TEST(ParseTbsCertificateTest, Version2NoOptionals) { |
258 EnsureParsingTbsSucceeds("tbs_v2_no_optionals.pem", CertificateVersion::V2); | 261 RunTbsCertificateTestGivenVersion("tbs_v2_no_optionals.pem", |
| 262 CertificateVersion::V2); |
259 } | 263 } |
260 | 264 |
261 // A version 2 certificate with an issuer unique ID field. | 265 // A version 2 certificate with an issuer unique ID field. |
262 TEST(ParseTbsCertificateTest, Version2IssuerUniqueId) { | 266 TEST(ParseTbsCertificateTest, Version2IssuerUniqueId) { |
263 EnsureParsingTbsSucceeds("tbs_v2_issuer_unique_id.pem", | 267 RunTbsCertificateTestGivenVersion("tbs_v2_issuer_unique_id.pem", |
264 CertificateVersion::V2); | 268 CertificateVersion::V2); |
265 } | 269 } |
266 | 270 |
267 // A version 2 certificate with both a issuer and subject unique ID field. | 271 // A version 2 certificate with both a issuer and subject unique ID field. |
268 TEST(ParseTbsCertificateTest, Version2IssuerAndSubjectUniqueId) { | 272 TEST(ParseTbsCertificateTest, Version2IssuerAndSubjectUniqueId) { |
269 EnsureParsingTbsSucceeds("tbs_v2_issuer_and_subject_unique_id.pem", | 273 RunTbsCertificateTestGivenVersion("tbs_v2_issuer_and_subject_unique_id.pem", |
270 CertificateVersion::V2); | 274 CertificateVersion::V2); |
271 } | 275 } |
272 | 276 |
273 // A version 3 certificate with all of the optional fields (issuer unique id, | 277 // A version 3 certificate with all of the optional fields (issuer unique id, |
274 // subject unique id, and extensions). | 278 // subject unique id, and extensions). |
275 TEST(ParseTbsCertificateTest, Version3AllOptionals) { | 279 TEST(ParseTbsCertificateTest, Version3AllOptionals) { |
276 EnsureParsingTbsSucceeds("tbs_v3_all_optionals.pem", CertificateVersion::V3); | 280 RunTbsCertificateTest("tbs_v3_all_optionals.pem"); |
277 } | 281 } |
278 | 282 |
279 // The version was set to v4, which is unrecognized. | 283 // The version was set to v4, which is unrecognized. |
280 TEST(ParseTbsCertificateTest, Version4) { | 284 TEST(ParseTbsCertificateTest, Version4) { |
281 EnsureParsingTbsFails("tbs_v4.pem"); | 285 RunTbsCertificateTest("tbs_v4.pem"); |
282 } | 286 } |
283 | 287 |
284 // Tests that extraneous data after extensions in a v3 is rejected. | 288 // Tests that extraneous data after extensions in a v3 is rejected. |
285 TEST(ParseTbsCertificateTest, Version3DataAfterExtensions) { | 289 TEST(ParseTbsCertificateTest, Version3DataAfterExtensions) { |
286 EnsureParsingTbsFails("tbs_v3_data_after_extensions.pem"); | 290 RunTbsCertificateTest("tbs_v3_data_after_extensions.pem"); |
287 } | 291 } |
288 | 292 |
289 // Tests using a real-world certificate (whereas the other tests are fabricated | 293 // Tests using a real-world certificate (whereas the other tests are fabricated |
290 // (and in fact invalid) data. | 294 // (and in fact invalid) data. |
291 TEST(ParseTbsCertificateTest, Version3Real) { | 295 TEST(ParseTbsCertificateTest, Version3Real) { |
292 EnsureParsingTbsSucceeds("tbs_v3_real.pem", CertificateVersion::V3); | 296 RunTbsCertificateTest("tbs_v3_real.pem"); |
293 } | 297 } |
294 | 298 |
295 // Parses a TBSCertificate whose "validity" field expresses both notBefore | 299 // Parses a TBSCertificate whose "validity" field expresses both notBefore |
296 // and notAfter using UTCTime. | 300 // and notAfter using UTCTime. |
297 TEST(ParseTbsCertificateTest, ValidityBothUtcTime) { | 301 TEST(ParseTbsCertificateTest, ValidityBothUtcTime) { |
298 EnsureParsingTbsSucceeds("tbs_validity_both_utc_time.pem", | 302 RunTbsCertificateTest("tbs_validity_both_utc_time.pem"); |
299 CertificateVersion::V3); | |
300 } | 303 } |
301 | 304 |
302 // Parses a TBSCertificate whose "validity" field expresses both notBefore | 305 // Parses a TBSCertificate whose "validity" field expresses both notBefore |
303 // and notAfter using GeneralizedTime. | 306 // and notAfter using GeneralizedTime. |
304 TEST(ParseTbsCertificateTest, ValidityBothGeneralizedTime) { | 307 TEST(ParseTbsCertificateTest, ValidityBothGeneralizedTime) { |
305 EnsureParsingTbsSucceeds("tbs_validity_both_generalized_time.pem", | 308 RunTbsCertificateTest("tbs_validity_both_generalized_time.pem"); |
306 CertificateVersion::V3); | |
307 } | 309 } |
308 | 310 |
309 // Parses a TBSCertificate whose "validity" field expresses notBefore using | 311 // Parses a TBSCertificate whose "validity" field expresses notBefore using |
310 // UTCTime and notAfter using GeneralizedTime. | 312 // UTCTime and notAfter using GeneralizedTime. |
311 TEST(ParseTbsCertificateTest, ValidityUTCTimeAndGeneralizedTime) { | 313 TEST(ParseTbsCertificateTest, ValidityUTCTimeAndGeneralizedTime) { |
312 EnsureParsingTbsSucceeds("tbs_validity_utc_time_and_generalized_time.pem", | 314 RunTbsCertificateTest("tbs_validity_utc_time_and_generalized_time.pem"); |
313 CertificateVersion::V3); | |
314 } | 315 } |
315 | 316 |
316 // Parses a TBSCertificate whose validity" field expresses notBefore using | 317 // Parses a TBSCertificate whose validity" field expresses notBefore using |
317 // GeneralizedTime and notAfter using UTCTime. Also of interest, notBefore > | 318 // GeneralizedTime and notAfter using UTCTime. Also of interest, notBefore > |
318 // notAfter. Parsing will succeed, however no time can satisfy this constraint. | 319 // notAfter. Parsing will succeed, however no time can satisfy this constraint. |
319 TEST(ParseTbsCertificateTest, ValidityGeneralizedTimeAndUTCTime) { | 320 TEST(ParseTbsCertificateTest, ValidityGeneralizedTimeAndUTCTime) { |
320 EnsureParsingTbsSucceeds("tbs_validity_generalized_time_and_utc_time.pem", | 321 RunTbsCertificateTest("tbs_validity_generalized_time_and_utc_time.pem"); |
321 CertificateVersion::V3); | |
322 } | 322 } |
323 | 323 |
324 // Parses a TBSCertificate whose "validity" field does not strictly follow | 324 // Parses a TBSCertificate whose "validity" field does not strictly follow |
325 // the DER rules (and fails to be parsed). | 325 // the DER rules (and fails to be parsed). |
326 TEST(ParseTbsCertificateTest, ValidityRelaxed) { | 326 TEST(ParseTbsCertificateTest, ValidityRelaxed) { |
327 EnsureParsingTbsFails("tbs_validity_relaxed.pem"); | 327 RunTbsCertificateTest("tbs_validity_relaxed.pem"); |
328 } | 328 } |
329 | 329 |
330 // Reads a PEM file containing a block "EXTENSION". This input will be | 330 // Reads a PEM file containing a block "EXTENSION". This input will be |
331 // passed to ParseExtension, and the results filled in |out|. | 331 // passed to ParseExtension, and the results filled in |out|. |
332 bool ParseExtensionFromFile(const std::string& file_name, | 332 bool ParseExtensionFromFile(const std::string& file_name, |
333 ParsedExtension* out, | 333 ParsedExtension* out, |
334 std::string* data) { | 334 std::string* data) { |
335 const PemBlockMapping mappings[] = { | 335 const PemBlockMapping mappings[] = { |
336 {"EXTENSION", data}, | 336 {"EXTENSION", data}, |
337 }; | 337 }; |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 0x00, // Number of unused bits | 784 0x00, // Number of unused bits |
785 }; | 785 }; |
786 | 786 |
787 der::BitString key_usage; | 787 der::BitString key_usage; |
788 ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage)); | 788 ASSERT_FALSE(ParseKeyUsage(der::Input(der), &key_usage)); |
789 } | 789 } |
790 | 790 |
791 } // namespace | 791 } // namespace |
792 | 792 |
793 } // namespace net | 793 } // namespace net |
OLD | NEW |