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/verify_certificate_chain.h" | 5 #include "net/cert/internal/verify_certificate_chain.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "net/cert/internal/name_constraints.h" | 10 #include "net/cert/internal/name_constraints.h" |
11 #include "net/cert/internal/parse_certificate.h" | 11 #include "net/cert/internal/parse_certificate.h" |
12 #include "net/cert/internal/signature_algorithm.h" | 12 #include "net/cert/internal/signature_algorithm.h" |
13 #include "net/cert/internal/signature_policy.h" | 13 #include "net/cert/internal/signature_policy.h" |
14 #include "net/cert/internal/verify_name_match.h" | 14 #include "net/cert/internal/verify_name_match.h" |
15 #include "net/cert/internal/verify_signed_data.h" | 15 #include "net/cert/internal/verify_signed_data.h" |
16 #include "net/der/input.h" | 16 #include "net/der/input.h" |
17 #include "net/der/parser.h" | 17 #include "net/der/parser.h" |
18 | 18 |
19 namespace net { | 19 namespace net { |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 // Map from OID to ParsedExtension. | 23 // Map from OID to ParsedExtension. |
24 using ExtensionsMap = std::map<der::Input, ParsedExtension>; | 24 using ExtensionsMap = std::map<der::Input, ParsedExtension>; |
25 | 25 |
26 // Describes all parsed properties of a certificate that are relevant for | 26 // Describes all parsed properties of a certificate that are relevant for |
27 // certificate verification. | 27 // certificate verification. |
28 struct FullyParsedCert { | 28 struct FullyParsedCert { |
29 ParsedCertificate cert; | 29 // XXX better naming.. this results in lots of non-obvious cert.cert->foo code |
30 ParsedTbsCertificate tbs; | 30 const CertThing* cert; |
| 31 |
| 32 // XXX should some of this be moved into CertThing? |
31 | 33 |
32 std::unique_ptr<SignatureAlgorithm> signature_algorithm; | 34 std::unique_ptr<SignatureAlgorithm> signature_algorithm; |
33 | 35 |
34 // Standard extensions that were parsed. | 36 // Standard extensions that were parsed. |
35 bool has_basic_constraints = false; | 37 bool has_basic_constraints = false; |
36 ParsedBasicConstraints basic_constraints; | 38 ParsedBasicConstraints basic_constraints; |
37 | 39 |
38 bool has_key_usage = false; | 40 bool has_key_usage = false; |
39 der::BitString key_usage; | 41 der::BitString key_usage; |
40 | 42 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 } | 74 } |
73 return true; | 75 return true; |
74 } | 76 } |
75 | 77 |
76 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv, | 78 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv, |
77 der::Input* value) { | 79 der::Input* value) { |
78 der::Parser parser(tlv); | 80 der::Parser parser(tlv); |
79 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); | 81 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); |
80 } | 82 } |
81 | 83 |
| 84 // XXX update doc |
82 // Parses an X.509 Certificate fully (including the TBSCertificate and | 85 // Parses an X.509 Certificate fully (including the TBSCertificate and |
83 // standard extensions), saving all the properties to |out_|. | 86 // standard extensions), saving all the properties to |out_|. |
84 WARN_UNUSED_RESULT bool FullyParseCertificate(const der::Input& cert_tlv, | 87 WARN_UNUSED_RESULT bool FullyParseCertificate(const CertThing& cert, |
85 FullyParsedCert* out) { | 88 FullyParsedCert* out) { |
86 // Parse the outer Certificate. | 89 // XXX move more of this into CertThing? |
87 if (!ParseCertificate(cert_tlv, &out->cert)) | 90 |
88 return false; | 91 out->cert = &cert; |
89 | 92 |
90 // Parse the signature algorithm contained in the Certificate (there is | 93 // Parse the signature algorithm contained in the Certificate (there is |
91 // another one in the TBSCertificate, which is checked later by | 94 // another one in the TBSCertificate, which is checked later by |
92 // VerifySignatureAlgorithmsMatch) | 95 // VerifySignatureAlgorithmsMatch) |
93 out->signature_algorithm = | 96 out->signature_algorithm = SignatureAlgorithm::CreateFromDer( |
94 SignatureAlgorithm::CreateFromDer(out->cert.signature_algorithm_tlv); | 97 cert.parsed_cert().signature_algorithm_tlv); |
95 if (!out->signature_algorithm) | 98 if (!out->signature_algorithm) |
96 return false; | 99 return false; |
97 | 100 |
98 // Parse the TBSCertificate. | |
99 if (!ParseTbsCertificate(out->cert.tbs_certificate_tlv, &out->tbs)) | |
100 return false; | |
101 | |
102 // Reset state relating to extensions (which may not get overwritten). This is | 101 // Reset state relating to extensions (which may not get overwritten). This is |
103 // just a precaution, since in practice |out| will already be default | 102 // just a precaution, since in practice |out| will already be default |
104 // initialize. | 103 // initialize. |
105 out->has_basic_constraints = false; | 104 out->has_basic_constraints = false; |
106 out->has_key_usage = false; | 105 out->has_key_usage = false; |
107 out->unconsumed_extensions.clear(); | 106 out->unconsumed_extensions.clear(); |
108 out->subject_alt_names.reset(); | 107 out->subject_alt_names.reset(); |
109 out->has_name_constraints = false; | 108 out->has_name_constraints = false; |
110 | 109 |
111 // Parse the standard X.509 extensions and remove them from | 110 // Parse the standard X.509 extensions and remove them from |
112 // |unconsumed_extensions|. | 111 // |unconsumed_extensions|. |
113 if (out->tbs.has_extensions) { | 112 if (cert.parsed_tbs().has_extensions) { |
114 // ParseExtensions() ensures there are no duplicates, and maps the (unique) | 113 // ParseExtensions() ensures there are no duplicates, and maps the (unique) |
115 // OID to the extension value. | 114 // OID to the extension value. |
116 if (!ParseExtensions(out->tbs.extensions_tlv, &out->unconsumed_extensions)) | 115 if (!ParseExtensions(cert.parsed_tbs().extensions_tlv, |
| 116 &out->unconsumed_extensions)) |
117 return false; | 117 return false; |
118 | 118 |
119 ParsedExtension extension; | 119 ParsedExtension extension; |
120 | 120 |
121 // Basic constraints. | 121 // Basic constraints. |
122 if (ConsumeExtension(BasicConstraintsOid(), &out->unconsumed_extensions, | 122 if (ConsumeExtension(BasicConstraintsOid(), &out->unconsumed_extensions, |
123 &extension)) { | 123 &extension)) { |
124 out->has_basic_constraints = true; | 124 out->has_basic_constraints = true; |
125 if (!ParseBasicConstraints(extension.value, &out->basic_constraints)) | 125 if (!ParseBasicConstraints(extension.value, &out->basic_constraints)) |
126 return false; | 126 return false; |
(...skipping 15 matching lines...) Expand all Loading... |
142 out->subject_alt_names = GeneralNames::CreateFromDer(extension.value); | 142 out->subject_alt_names = GeneralNames::CreateFromDer(extension.value); |
143 if (!out->subject_alt_names) | 143 if (!out->subject_alt_names) |
144 return false; | 144 return false; |
145 // RFC 5280 section 4.1.2.6: | 145 // RFC 5280 section 4.1.2.6: |
146 // If subject naming information is present only in the subjectAltName | 146 // If subject naming information is present only in the subjectAltName |
147 // extension (e.g., a key bound only to an email address or URI), then the | 147 // extension (e.g., a key bound only to an email address or URI), then the |
148 // subject name MUST be an empty sequence and the subjectAltName extension | 148 // subject name MUST be an empty sequence and the subjectAltName extension |
149 // MUST be critical. | 149 // MUST be critical. |
150 if (!extension.critical) { | 150 if (!extension.critical) { |
151 der::Input subject_value; | 151 der::Input subject_value; |
152 if (!GetSequenceValue(out->tbs.subject_tlv, &subject_value)) | 152 if (!GetSequenceValue(cert.parsed_tbs().subject_tlv, &subject_value)) |
153 return false; | 153 return false; |
154 if (subject_value.Length() == 0) | 154 if (subject_value.Length() == 0) |
155 return false; | 155 return false; |
156 } | 156 } |
157 } | 157 } |
158 | 158 |
159 // Name constraints. | 159 // Name constraints. |
160 if (ConsumeExtension(NameConstraintsOid(), &out->unconsumed_extensions, | 160 if (ConsumeExtension(NameConstraintsOid(), &out->unconsumed_extensions, |
161 &out->name_constraints_extension)) { | 161 &out->name_constraints_extension)) { |
162 out->has_name_constraints = true; | 162 out->has_name_constraints = true; |
(...skipping 25 matching lines...) Expand all Loading... |
188 // | 188 // |
189 // A certificate is self-issued if the same DN appears in the subject | 189 // A certificate is self-issued if the same DN appears in the subject |
190 // and issuer fields (the two DNs are the same if they match according | 190 // and issuer fields (the two DNs are the same if they match according |
191 // to the rules specified in Section 7.1). In general, the issuer and | 191 // to the rules specified in Section 7.1). In general, the issuer and |
192 // subject of the certificates that make up a path are different for | 192 // subject of the certificates that make up a path are different for |
193 // each certificate. However, a CA may issue a certificate to itself to | 193 // each certificate. However, a CA may issue a certificate to itself to |
194 // support key rollover or changes in certificate policies. These | 194 // support key rollover or changes in certificate policies. These |
195 // self-issued certificates are not counted when evaluating path length | 195 // self-issued certificates are not counted when evaluating path length |
196 // or name constraints. | 196 // or name constraints. |
197 WARN_UNUSED_RESULT bool IsSelfIssued(const FullyParsedCert& cert) { | 197 WARN_UNUSED_RESULT bool IsSelfIssued(const FullyParsedCert& cert) { |
198 return NameMatches(cert.tbs.subject_tlv, cert.tbs.issuer_tlv); | 198 return cert.cert->normalized_subject() == cert.cert->normalized_issuer(); |
199 } | 199 } |
200 | 200 |
201 // Returns true if |cert| is valid at time |time|. | 201 // Returns true if |cert| is valid at time |time|. |
202 // | 202 // |
203 // The certificate's validity requirements are described by RFC 5280 section | 203 // The certificate's validity requirements are described by RFC 5280 section |
204 // 4.1.2.5: | 204 // 4.1.2.5: |
205 // | 205 // |
206 // The validity period for a certificate is the period of time from | 206 // The validity period for a certificate is the period of time from |
207 // notBefore through notAfter, inclusive. | 207 // notBefore through notAfter, inclusive. |
208 WARN_UNUSED_RESULT bool VerifyTimeValidity(const FullyParsedCert& cert, | 208 WARN_UNUSED_RESULT bool VerifyTimeValidity(const FullyParsedCert& cert, |
209 const der::GeneralizedTime time) { | 209 const der::GeneralizedTime time) { |
210 return !(time < cert.tbs.validity_not_before) && | 210 return !(time < cert.cert->parsed_tbs().validity_not_before) && |
211 !(cert.tbs.validity_not_after < time); | 211 !(cert.cert->parsed_tbs().validity_not_after < time); |
212 } | 212 } |
213 | 213 |
214 // Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for | 214 // Returns true if |signature_algorithm_tlv| is a valid algorithm encoding for |
215 // RSA with SHA1. | 215 // RSA with SHA1. |
216 WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm( | 216 WARN_UNUSED_RESULT bool IsRsaWithSha1SignatureAlgorithm( |
217 const der::Input& signature_algorithm_tlv) { | 217 const der::Input& signature_algorithm_tlv) { |
218 std::unique_ptr<SignatureAlgorithm> algorithm = | 218 std::unique_ptr<SignatureAlgorithm> algorithm = |
219 SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv); | 219 SignatureAlgorithm::CreateFromDer(signature_algorithm_tlv); |
220 | 220 |
221 return algorithm && | 221 return algorithm && |
(...skipping 15 matching lines...) Expand all Loading... |
237 // | 237 // |
238 // The spec is not explicit about what "the same algorithm identifier" means. | 238 // The spec is not explicit about what "the same algorithm identifier" means. |
239 // Our interpretation is that the two DER-encoded fields must be byte-for-byte | 239 // Our interpretation is that the two DER-encoded fields must be byte-for-byte |
240 // identical. | 240 // identical. |
241 // | 241 // |
242 // In practice however there are certificates which use different encodings for | 242 // In practice however there are certificates which use different encodings for |
243 // specifying RSA with SHA1 (different OIDs). This is special-cased for | 243 // specifying RSA with SHA1 (different OIDs). This is special-cased for |
244 // compatibility sake. | 244 // compatibility sake. |
245 WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch( | 245 WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch( |
246 const FullyParsedCert& cert) { | 246 const FullyParsedCert& cert) { |
247 const der::Input& alg1_tlv = cert.cert.signature_algorithm_tlv; | 247 const der::Input& alg1_tlv = cert.cert->parsed_cert().signature_algorithm_tlv; |
248 const der::Input& alg2_tlv = cert.tbs.signature_algorithm_tlv; | 248 const der::Input& alg2_tlv = cert.cert->parsed_tbs().signature_algorithm_tlv; |
249 | 249 |
250 // Ensure that the two DER-encoded signature algorithms are byte-for-byte | 250 // Ensure that the two DER-encoded signature algorithms are byte-for-byte |
251 // equal, but make a compatibility concession for RSA with SHA1. | 251 // equal, but make a compatibility concession for RSA with SHA1. |
252 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && | 252 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && |
253 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)); | 253 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)); |
254 } | 254 } |
255 | 255 |
256 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate | 256 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate |
257 // Processing" procedure. | 257 // Processing" procedure. |
258 // | 258 // |
259 // |skip_issuer_checks| controls whether the function will skip: | 259 // |skip_issuer_checks| controls whether the function will skip: |
260 // - Checking that |cert|'s signature using |working_spki| | 260 // - Checking that |cert|'s signature using |working_spki| |
261 // - Checkinging that |cert|'s issuer matches |working_issuer_name| | 261 // - Checkinging that |cert|'s issuer matches |working_normalized_issuer_name| |
262 // This should be set to true only when verifying a trusted root certificate. | 262 // This should be set to true only when verifying a trusted root certificate. |
263 WARN_UNUSED_RESULT bool BasicCertificateProcessing( | 263 WARN_UNUSED_RESULT bool BasicCertificateProcessing( |
264 const FullyParsedCert& cert, | 264 const FullyParsedCert& cert, |
265 bool is_target_cert, | 265 bool is_target_cert, |
266 bool skip_issuer_checks, | 266 bool skip_issuer_checks, |
267 const SignaturePolicy* signature_policy, | 267 const SignaturePolicy* signature_policy, |
268 const der::GeneralizedTime& time, | 268 const der::GeneralizedTime& time, |
269 const der::Input& working_spki, | 269 const der::Input& working_spki, |
270 const der::Input& working_issuer_name, | 270 const der::Input& working_normalized_issuer_name, |
271 const std::vector<std::unique_ptr<NameConstraints>>& | 271 const std::vector<std::unique_ptr<NameConstraints>>& |
272 name_constraints_list) { | 272 name_constraints_list) { |
273 // Check that the signature algorithms in Certificate vs TBSCertificate | 273 // Check that the signature algorithms in Certificate vs TBSCertificate |
274 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by | 274 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by |
275 // sections 4.1.1.2 and 4.1.2.3. | 275 // sections 4.1.1.2 and 4.1.2.3. |
276 if (!VerifySignatureAlgorithmsMatch(cert)) | 276 if (!VerifySignatureAlgorithmsMatch(cert)) |
277 return false; | 277 return false; |
278 | 278 |
279 // Verify the digital signature using the previous certificate's key (RFC | 279 // Verify the digital signature using the previous certificate's key (RFC |
280 // 5280 section 6.1.3 step a.1). | 280 // 5280 section 6.1.3 step a.1). |
281 if (!skip_issuer_checks) { | 281 if (!skip_issuer_checks) { |
282 if (!VerifySignedData( | 282 if (!VerifySignedData(*cert.signature_algorithm, |
283 *cert.signature_algorithm, cert.cert.tbs_certificate_tlv, | 283 cert.cert->parsed_cert().tbs_certificate_tlv, |
284 cert.cert.signature_value, working_spki, signature_policy)) { | 284 cert.cert->parsed_cert().signature_value, |
| 285 working_spki, signature_policy)) { |
285 return false; | 286 return false; |
286 } | 287 } |
287 } | 288 } |
288 | 289 |
289 // Check the time range for the certificate's validity, ensuring it is valid | 290 // Check the time range for the certificate's validity, ensuring it is valid |
290 // at |time|. | 291 // at |time|. |
291 // (RFC 5280 section 6.1.3 step a.2) | 292 // (RFC 5280 section 6.1.3 step a.2) |
292 if (!VerifyTimeValidity(cert, time)) | 293 if (!VerifyTimeValidity(cert, time)) |
293 return false; | 294 return false; |
294 | 295 |
295 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) | 296 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) |
296 | 297 |
297 // Verify the certificate's issuer name matches the issuing certificate's | 298 // Verify the certificate's issuer name matches the issuing certificate's |
298 // subject name. (RFC 5280 section 6.1.3 step a.4) | 299 // subject name. (RFC 5280 section 6.1.3 step a.4) |
299 if (!skip_issuer_checks) { | 300 if (!skip_issuer_checks) { |
300 if (!NameMatches(cert.tbs.issuer_tlv, working_issuer_name)) | 301 if (der::Input(&cert.cert->normalized_issuer()) != |
| 302 working_normalized_issuer_name) |
301 return false; | 303 return false; |
302 } | 304 } |
303 | 305 |
304 // Name constraints (RFC 5280 section 6.1.3 step b & c) | 306 // Name constraints (RFC 5280 section 6.1.3 step b & c) |
305 // If certificate i is self-issued and it is not the final certificate in the | 307 // If certificate i is self-issued and it is not the final certificate in the |
306 // path, skip this step for certificate i. | 308 // path, skip this step for certificate i. |
307 if (!name_constraints_list.empty() && | 309 if (!name_constraints_list.empty() && |
308 (!IsSelfIssued(cert) || is_target_cert)) { | 310 (!IsSelfIssued(cert) || is_target_cert)) { |
| 311 // XXX used normalized_subject here |
309 der::Input subject_value; | 312 der::Input subject_value; |
310 if (!GetSequenceValue(cert.tbs.subject_tlv, &subject_value)) | 313 if (!GetSequenceValue(cert.cert->parsed_tbs().subject_tlv, &subject_value)) |
311 return false; | 314 return false; |
312 for (const auto& nc : name_constraints_list) { | 315 for (const auto& nc : name_constraints_list) { |
313 if (!nc->IsPermittedCert(subject_value, cert.subject_alt_names.get())) | 316 if (!nc->IsPermittedCert(subject_value, cert.subject_alt_names.get())) |
314 return false; | 317 return false; |
315 } | 318 } |
316 } | 319 } |
317 | 320 |
318 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet | 321 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet |
319 // implemented. | 322 // implemented. |
320 | 323 |
321 return true; | 324 return true; |
322 } | 325 } |
323 | 326 |
324 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for | 327 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for |
325 // Certificate i+1" procedure. |cert| is expected to be an intermediary. | 328 // Certificate i+1" procedure. |cert| is expected to be an intermediary. |
326 WARN_UNUSED_RESULT bool PrepareForNextCertificate( | 329 WARN_UNUSED_RESULT bool PrepareForNextCertificate( |
327 const FullyParsedCert& cert, | 330 const FullyParsedCert& cert, |
328 size_t* max_path_length_ptr, | 331 size_t* max_path_length_ptr, |
329 der::Input* working_spki, | 332 der::Input* working_spki, |
330 der::Input* working_issuer_name, | 333 der::Input* working_normalized_issuer_name, |
331 std::vector<std::unique_ptr<NameConstraints>>* name_constraints_list) { | 334 std::vector<std::unique_ptr<NameConstraints>>* name_constraints_list) { |
332 // TODO(eroman): Steps a-b are omitted, as policy constraints are not yet | 335 // TODO(eroman): Steps a-b are omitted, as policy constraints are not yet |
333 // implemented. | 336 // implemented. |
334 | 337 |
335 // From RFC 5280 section 6.1.4 step c: | 338 // From RFC 5280 section 6.1.4 step c: |
336 // | 339 // |
337 // Assign the certificate subject name to working_issuer_name. | 340 // Assign the certificate subject name to working_normalized_issuer_name. |
338 *working_issuer_name = cert.tbs.subject_tlv; | 341 *working_normalized_issuer_name = |
| 342 der::Input(&cert.cert->normalized_subject()); |
339 | 343 |
340 // From RFC 5280 section 6.1.4 step d: | 344 // From RFC 5280 section 6.1.4 step d: |
341 // | 345 // |
342 // Assign the certificate subjectPublicKey to working_public_key. | 346 // Assign the certificate subjectPublicKey to working_public_key. |
343 *working_spki = cert.tbs.spki_tlv; | 347 *working_spki = cert.cert->parsed_tbs().spki_tlv; |
344 | 348 |
345 // Note that steps e and f are omitted as they are handled by | 349 // Note that steps e and f are omitted as they are handled by |
346 // the assignment to |working_spki| above. See the definition | 350 // the assignment to |working_spki| above. See the definition |
347 // of |working_spki|. | 351 // of |working_spki|. |
348 | 352 |
349 // From RFC 5280 section 6.1.4 step g: | 353 // From RFC 5280 section 6.1.4 step g: |
350 if (cert.has_name_constraints) { | 354 if (cert.has_name_constraints) { |
351 std::unique_ptr<NameConstraints> name_constraints( | 355 std::unique_ptr<NameConstraints> name_constraints( |
352 NameConstraints::CreateFromDer( | 356 NameConstraints::CreateFromDer( |
353 cert.name_constraints_extension.value, | 357 cert.name_constraints_extension.value, |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
487 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure", | 491 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure", |
488 // however is implied by RFC 5280 section 4.2.1.9. | 492 // however is implied by RFC 5280 section 4.2.1.9. |
489 if (!VerifyTargetCertHasConsistentCaBits(cert)) | 493 if (!VerifyTargetCertHasConsistentCaBits(cert)) |
490 return false; | 494 return false; |
491 | 495 |
492 return true; | 496 return true; |
493 } | 497 } |
494 | 498 |
495 } // namespace | 499 } // namespace |
496 | 500 |
497 TrustAnchor::TrustAnchor() {} | 501 CertThing::CertThing() {} |
498 TrustAnchor::~TrustAnchor() {} | 502 CertThing::~CertThing() {} |
499 | 503 |
500 std::unique_ptr<TrustAnchor> TrustAnchor::CreateFromCertificateData( | 504 std::unique_ptr<CertThing> CertThing::CreateFromCertificateData( |
501 const uint8_t* data, | 505 const uint8_t* data, |
502 size_t length, | 506 size_t length, |
503 DataSource source) { | 507 DataSource source) { |
504 std::unique_ptr<TrustAnchor> result(new TrustAnchor); | 508 std::unique_ptr<CertThing> result(new CertThing); |
505 | 509 |
506 switch (source) { | 510 switch (source) { |
507 case DataSource::INTERNAL_COPY: | 511 case DataSource::INTERNAL_COPY: |
508 result->cert_data_.assign(data, data + length); | 512 result->cert_data_.assign(data, data + length); |
509 result->cert_ = | 513 result->cert_ = |
510 der::Input(result->cert_data_.data(), result->cert_data_.size()); | 514 der::Input(result->cert_data_.data(), result->cert_data_.size()); |
511 break; | 515 break; |
512 case DataSource::EXTERNAL_REFERENCE: | 516 case DataSource::EXTERNAL_REFERENCE: |
513 result->cert_ = der::Input(data, length); | 517 result->cert_ = der::Input(data, length); |
514 break; | 518 break; |
515 } | 519 } |
516 | 520 |
517 // Parse the certificate to get its name. | 521 // Parse the certificate to get its name. |
518 ParsedCertificate cert; | 522 if (!ParseCertificate(result->cert_, &result->parsed_cert_)) |
519 if (!ParseCertificate(result->cert(), &cert)) | |
520 return nullptr; | 523 return nullptr; |
521 | 524 |
522 ParsedTbsCertificate tbs; | 525 if (!ParseTbsCertificate(result->parsed_cert_.tbs_certificate_tlv, |
523 if (!ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) | 526 &result->parsed_tbs_)) |
524 return nullptr; | 527 return nullptr; |
525 | 528 |
526 result->name_ = tbs.subject_tlv; | 529 der::Input subject_value; |
527 | 530 if (!GetSequenceValue(result->parsed_tbs_.subject_tlv, &subject_value) || |
528 // TODO(eroman): If adding a self-signed certificate, check that its | 531 !NormalizeName(subject_value, &result->normalized_subject_)) |
529 // signature is correct? This check will not otherwise be done during | 532 return nullptr; |
530 // verification. | 533 der::Input issuer_value; |
| 534 if (!GetSequenceValue(result->parsed_tbs_.issuer_tlv, &issuer_value) || |
| 535 !NormalizeName(issuer_value, &result->normalized_issuer_)) |
| 536 return nullptr; |
531 | 537 |
532 return result; | 538 return result; |
533 } | 539 } |
534 | 540 |
535 bool TrustAnchor::MatchesName(const der::Input& name) const { | 541 std::unique_ptr<CertThing> CertThing::CreateFromCertificateCopy( |
536 return NameMatches(name, name_); | 542 const base::StringPiece& data) { |
| 543 return CertThing::CreateFromCertificateData( |
| 544 reinterpret_cast<const uint8_t*>(data.data()), data.size(), |
| 545 DataSource::INTERNAL_COPY); |
| 546 } |
| 547 |
| 548 std::unique_ptr<CertThing> CertThing::Clone() const { |
| 549 // XXX Should it always INTERNAL_COPY, or should it continue with what the |
| 550 // previous had?.. lifetimes could get weird with that. (Eg, someone created a |
| 551 // Cert, passed it to a function they could gaurantee it would outlive, but |
| 552 // that function internall makes a clone and returns it as part of the results |
| 553 // or error info..) |
| 554 /*std::unique_ptr<CertThing> |
| 555 result(CreateFromCertificateData(cert_.UnsafeData(), cert_.Length(), |
| 556 CertThing::DataSource::INTERNAL_COPY)); |
| 557 // If it parsed to make this object, it should never fail to parse again. |
| 558 CHECK(result); |
| 559 return result;*/ |
| 560 |
| 561 std::unique_ptr<CertThing> result(new CertThing); |
| 562 |
| 563 result->cert_data_.assign( |
| 564 reinterpret_cast<const char*>(cert_.UnsafeData()), |
| 565 reinterpret_cast<const char*>(cert_.UnsafeData()) + cert_.Length()); |
| 566 result->cert_ = |
| 567 der::Input(result->cert_data_.data(), result->cert_data_.size()); |
| 568 |
| 569 result->parsed_cert_ = ParsedCertificate(parsed_cert_, cert_, result->cert_); |
| 570 result->parsed_tbs_ = ParsedTbsCertificate(parsed_tbs_, cert_, result->cert_); |
| 571 |
| 572 result->normalized_subject_ = normalized_subject_; |
| 573 result->normalized_issuer_ = normalized_issuer_; |
| 574 |
| 575 // XXX clean up |
| 576 /*result->parsed_cert_.tbs_certificate_tlv = der::Input( |
| 577 result->cert_.UnsafeData() + |
| 578 (parsed_cert_.tbs_certificate_tlv.UnsafeData() - cert_.UnsafeData()), |
| 579 parsed_cert_.tbs_certificate_tlv.Length());*/ |
| 580 |
| 581 return result; |
| 582 } |
| 583 |
| 584 bool CertThing::MatchesName(const der::Input& name) const { |
| 585 return NameMatches(name, parsed_tbs_.subject_tlv); // XXX don't re-normalize |
537 } | 586 } |
538 | 587 |
539 TrustStore::TrustStore() {} | 588 TrustStore::TrustStore() {} |
540 TrustStore::~TrustStore() {} | 589 TrustStore::~TrustStore() {} |
541 | 590 |
542 void TrustStore::Clear() { | 591 void TrustStore::Clear() { |
543 anchors_.clear(); | 592 anchors_.clear(); |
544 } | 593 } |
545 | 594 |
546 bool TrustStore::AddTrustedCertificate(const uint8_t* data, size_t length) { | 595 bool TrustStore::AddTrustedCertificate(const uint8_t* data, size_t length) { |
| 596 // TODO(eroman): If adding a self-signed certificate, check that its |
| 597 // signature is correct? This check will not otherwise be done during |
| 598 // verification. |
547 return AddTrustedCertificate(data, length, | 599 return AddTrustedCertificate(data, length, |
548 TrustAnchor::DataSource::INTERNAL_COPY); | 600 CertThing::DataSource::INTERNAL_COPY); |
549 } | 601 } |
550 | 602 |
551 bool TrustStore::AddTrustedCertificate(const base::StringPiece& data) { | 603 bool TrustStore::AddTrustedCertificate(const base::StringPiece& data) { |
552 return AddTrustedCertificate(reinterpret_cast<const uint8_t*>(data.data()), | 604 return AddTrustedCertificate(reinterpret_cast<const uint8_t*>(data.data()), |
553 data.size()); | 605 data.size()); |
554 } | 606 } |
555 | 607 |
556 bool TrustStore::AddTrustedCertificateWithoutCopying(const uint8_t* data, | 608 bool TrustStore::AddTrustedCertificateWithoutCopying(const uint8_t* data, |
557 size_t length) { | 609 size_t length) { |
558 return AddTrustedCertificate(data, length, | 610 return AddTrustedCertificate(data, length, |
559 TrustAnchor::DataSource::EXTERNAL_REFERENCE); | 611 CertThing::DataSource::EXTERNAL_REFERENCE); |
560 } | 612 } |
561 | 613 |
562 const TrustAnchor* TrustStore::FindTrustAnchorByName( | 614 const CertThing* TrustStore::FindTrustAnchorByName( |
563 const der::Input& name) const { | 615 const der::Input& name) const { |
564 for (const auto& anchor : anchors_) { | 616 for (const auto& anchor : anchors_) { |
565 if (anchor->MatchesName(name)) { | 617 if (anchor->MatchesName(name)) { |
566 return anchor.get(); | 618 return anchor.get(); |
567 } | 619 } |
568 } | 620 } |
569 return nullptr; | 621 return nullptr; |
570 } | 622 } |
571 | 623 |
| 624 std::vector<const CertThing*> TrustStore::FindTrustAnchorsByNormalizedName( |
| 625 const std::string& normalized_name) const { |
| 626 std::vector<const CertThing*> result; |
| 627 for (const auto& anchor : anchors_) { |
| 628 if (anchor->normalized_subject() == normalized_name) { |
| 629 result.push_back(anchor.get()); |
| 630 } |
| 631 } |
| 632 return result; |
| 633 } |
| 634 |
572 bool TrustStore::IsTrustedCertificate(const der::Input& cert_der) const { | 635 bool TrustStore::IsTrustedCertificate(const der::Input& cert_der) const { |
573 for (const auto& anchor : anchors_) { | 636 for (const auto& anchor : anchors_) { |
574 if (anchor->cert() == cert_der) | 637 if (anchor->der_cert() == cert_der) |
575 return true; | 638 return true; |
576 } | 639 } |
577 return false; | 640 return false; |
578 } | 641 } |
579 | 642 |
580 bool TrustStore::AddTrustedCertificate(const uint8_t* data, | 643 bool TrustStore::AddTrustedCertificate(const uint8_t* data, |
581 size_t length, | 644 size_t length, |
582 TrustAnchor::DataSource source) { | 645 CertThing::DataSource source) { |
583 auto anchor = TrustAnchor::CreateFromCertificateData(data, length, source); | 646 auto anchor = CertThing::CreateFromCertificateData(data, length, source); |
584 if (!anchor) | 647 if (!anchor) |
585 return false; | 648 return false; |
586 anchors_.push_back(std::move(anchor)); | 649 anchors_.push_back(std::move(anchor)); |
587 return true; | 650 return true; |
588 } | 651 } |
589 | 652 |
590 // TODO(eroman): Move this into existing anonymous namespace. | |
591 namespace { | |
592 | |
593 // This implementation is structured to mimic the description of certificate | 653 // This implementation is structured to mimic the description of certificate |
594 // path verification given by RFC 5280 section 6.1. | 654 // path verification given by RFC 5280 section 6.1. |
595 // | 655 // |
596 // Unlike RFC 5280, the trust anchor is specified as the root certificate in | 656 // Unlike RFC 5280, the trust anchor is specified as the root certificate in |
597 // the chain. This root certificate is assumed to be trusted, and neither its | 657 // the chain. This root certificate is assumed to be trusted, and neither its |
598 // signature nor issuer name are verified. (It needn't be self-signed). | 658 // signature nor issuer name are verified. (It needn't be self-signed). |
599 bool VerifyCertificateChainAssumingTrustedRoot( | 659 bool VerifyCertificateChainAssumingTrustedRoot( |
600 const std::vector<der::Input>& certs_der, | 660 const std::vector<std::unique_ptr<CertThing>>& certs, |
601 // The trust store is only used for assertions. | 661 // The trust store is only used for assertions. |
602 const TrustStore& trust_store, | 662 const TrustStore& trust_store, |
603 const SignaturePolicy* signature_policy, | 663 const SignaturePolicy* signature_policy, |
604 const der::GeneralizedTime& time) { | 664 const der::GeneralizedTime& time) { |
605 // An empty chain is necessarily invalid. | 665 // An empty chain is necessarily invalid. |
606 if (certs_der.empty()) | 666 if (certs.empty()) |
607 return false; | 667 return false; |
608 | 668 |
609 // IMPORTANT: the assumption being made is that the root certificate in | 669 // IMPORTANT: the assumption being made is that the root certificate in |
610 // the given path is the trust anchor (and has already been verified as | 670 // the given path is the trust anchor (and has already been verified as |
611 // such). | 671 // such). |
612 DCHECK(trust_store.IsTrustedCertificate(certs_der.back())); | 672 DCHECK(trust_store.IsTrustedCertificate(certs.back()->der_cert())); // XXX |
613 | 673 |
614 // Will contain a NameConstraints for each previous cert in the chain which | 674 // Will contain a NameConstraints for each previous cert in the chain which |
615 // had nameConstraints. This corresponds to the permitted_subtrees and | 675 // had nameConstraints. This corresponds to the permitted_subtrees and |
616 // excluded_subtrees state variables from RFC 5280. | 676 // excluded_subtrees state variables from RFC 5280. |
617 std::vector<std::unique_ptr<NameConstraints>> name_constraints_list; | 677 std::vector<std::unique_ptr<NameConstraints>> name_constraints_list; |
618 | 678 |
619 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: | 679 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: |
620 // * working_public_key | 680 // * working_public_key |
621 // * working_public_key_algorithm | 681 // * working_public_key_algorithm |
622 // * working_public_key_parameters | 682 // * working_public_key_parameters |
623 // | 683 // |
624 // They are combined for simplicity since the signature verification takes an | 684 // They are combined for simplicity since the signature verification takes an |
625 // SPKI, and the parameter inheritence is not applicable for the supported | 685 // SPKI, and the parameter inheritence is not applicable for the supported |
626 // key types. | 686 // key types. |
627 // | 687 // |
628 // An approximate explanation of |working_spki| is this description from RFC | 688 // An approximate explanation of |working_spki| is this description from RFC |
629 // 5280 section 6.1.2: | 689 // 5280 section 6.1.2: |
630 // | 690 // |
631 // working_public_key: the public key used to verify the | 691 // working_public_key: the public key used to verify the |
632 // signature of a certificate. | 692 // signature of a certificate. |
633 der::Input working_spki; | 693 der::Input working_spki; |
634 | 694 |
635 // |working_issuer_name| corresponds with the same named variable in RFC 5280 | 695 // |working_normalized_issuer_name| is the normalized value of the |
636 // section 6.1.2: | 696 // working_issuer_name variable in RFC 5280 section 6.1.2: |
637 // | 697 // |
638 // working_issuer_name: the issuer distinguished name expected | 698 // working_issuer_name: the issuer distinguished name expected |
639 // in the next certificate in the chain. | 699 // in the next certificate in the chain. |
640 der::Input working_issuer_name; | 700 der::Input working_normalized_issuer_name; |
641 | 701 |
642 // |max_path_length| corresponds with the same named variable in RFC 5280 | 702 // |max_path_length| corresponds with the same named variable in RFC 5280 |
643 // section 6.1.2: | 703 // section 6.1.2: |
644 // | 704 // |
645 // max_path_length: this integer is initialized to n, is | 705 // max_path_length: this integer is initialized to n, is |
646 // decremented for each non-self-issued certificate in the path, | 706 // decremented for each non-self-issued certificate in the path, |
647 // and may be reduced to the value in the path length constraint | 707 // and may be reduced to the value in the path length constraint |
648 // field within the basic constraints extension of a CA | 708 // field within the basic constraints extension of a CA |
649 // certificate. | 709 // certificate. |
650 size_t max_path_length = certs_der.size(); | 710 size_t max_path_length = certs.size(); |
651 | 711 |
652 // Iterate over all the certificates in the reverse direction: starting from | 712 // Iterate over all the certificates in the reverse direction: starting from |
653 // the trust anchor and progressing towards the target certificate. | 713 // the trust anchor and progressing towards the target certificate. |
654 // | 714 // |
655 // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based. | 715 // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based. |
656 // | 716 // |
657 // * i=0 : Trust anchor. | 717 // * i=0 : Trust anchor. |
658 // * i=N-1 : Target certificate. | 718 // * i=N-1 : Target certificate. |
659 for (size_t i = 0; i < certs_der.size(); ++i) { | 719 for (size_t i = 0; i < certs.size(); ++i) { |
660 const size_t index_into_certs_der = certs_der.size() - i - 1; | 720 const size_t index_into_certs = certs.size() - i - 1; |
661 | 721 |
662 // |is_target_cert| is true if the current certificate is the target | 722 // |is_target_cert| is true if the current certificate is the target |
663 // certificate being verified. The target certificate isn't necessarily an | 723 // certificate being verified. The target certificate isn't necessarily an |
664 // end-entity certificate. | 724 // end-entity certificate. |
665 const bool is_target_cert = index_into_certs_der == 0; | 725 const bool is_target_cert = index_into_certs == 0; |
666 | 726 |
667 // |is_trust_anchor| is true if the current certificate is the trust | 727 // |is_trust_anchor| is true if the current certificate is the trust |
668 // anchor. This certificate is implicitly trusted. | 728 // anchor. This certificate is implicitly trusted. |
669 const bool is_trust_anchor = i == 0; | 729 const bool is_trust_anchor = i == 0; |
670 | 730 |
671 // Parse the current certificate into |cert|. | 731 // Parse the current certificate into |cert|. |
672 FullyParsedCert cert; | 732 FullyParsedCert cert; |
673 const der::Input& cert_der = certs_der[index_into_certs_der]; | 733 const CertThing& cert_thing = *certs[index_into_certs]; |
674 if (!FullyParseCertificate(cert_der, &cert)) | 734 if (!FullyParseCertificate(cert_thing, &cert)) |
675 return false; | 735 return false; |
676 | 736 |
677 // Per RFC 5280 section 6.1: | 737 // Per RFC 5280 section 6.1: |
678 // * Do basic processing for each certificate | 738 // * Do basic processing for each certificate |
679 // * If it is the last certificate in the path (target certificate) | 739 // * If it is the last certificate in the path (target certificate) |
680 // - Then run "Wrap up" | 740 // - Then run "Wrap up" |
681 // - Otherwise run "Prepare for Next cert" | 741 // - Otherwise run "Prepare for Next cert" |
682 if (!BasicCertificateProcessing( | 742 if (!BasicCertificateProcessing(cert, is_target_cert, is_trust_anchor, |
683 cert, is_target_cert, is_trust_anchor, signature_policy, time, | 743 signature_policy, time, working_spki, |
684 working_spki, working_issuer_name, name_constraints_list)) { | 744 working_normalized_issuer_name, |
| 745 name_constraints_list)) { |
685 return false; | 746 return false; |
686 } | 747 } |
687 if (!is_target_cert) { | 748 if (!is_target_cert) { |
688 if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki, | 749 if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki, |
689 &working_issuer_name, | 750 &working_normalized_issuer_name, |
690 &name_constraints_list)) { | 751 &name_constraints_list)) { |
691 return false; | 752 return false; |
692 } | 753 } |
693 } else { | 754 } else { |
694 if (!WrapUp(cert)) | 755 if (!WrapUp(cert)) |
695 return false; | 756 return false; |
696 } | 757 } |
697 } | 758 } |
698 | 759 |
699 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: | 760 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: |
700 // | 761 // |
701 // A certificate MUST NOT appear more than once in a prospective | 762 // A certificate MUST NOT appear more than once in a prospective |
702 // certification path. | 763 // certification path. |
703 | 764 |
704 return true; | 765 return true; |
705 } | 766 } |
706 | 767 |
| 768 // TODO(eroman): Move this into existing anonymous namespace. |
| 769 namespace { |
| 770 |
707 // TODO(eroman): This function is a temporary hack in the absence of full | 771 // TODO(eroman): This function is a temporary hack in the absence of full |
708 // path building. It may insert 1 certificate at the root of the | 772 // path building. It may insert 1 certificate at the root of the |
709 // chain to ensure that the path's root certificate is a trust anchor. | 773 // chain to ensure that the path's root certificate is a trust anchor. |
710 // | 774 // |
711 // Beyond this no other verification is done on the chain. The caller is | 775 // Beyond this no other verification is done on the chain. The caller is |
712 // responsible for verifying the subsequent chain's correctness. | 776 // responsible for verifying the subsequent chain's correctness. |
713 WARN_UNUSED_RESULT bool BuildSimplePathToTrustAnchor( | 777 WARN_UNUSED_RESULT bool BuildSimplePathToTrustAnchor( |
714 const std::vector<der::Input>& certs_der, | 778 const std::vector<der::Input>& certs_der, |
715 const TrustStore& trust_store, | 779 const TrustStore& trust_store, |
716 std::vector<der::Input>* certs_der_trusted_root) { | 780 std::vector<der::Input>* certs_der_trusted_root) { |
(...skipping 14 matching lines...) Expand all Loading... |
731 ParsedCertificate cert; | 795 ParsedCertificate cert; |
732 ParsedTbsCertificate tbs; | 796 ParsedTbsCertificate tbs; |
733 if (!ParseCertificate(certs_der.back(), &cert) || | 797 if (!ParseCertificate(certs_der.back(), &cert) || |
734 !ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) { | 798 !ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) { |
735 return false; | 799 return false; |
736 } | 800 } |
737 | 801 |
738 auto trust_anchor = trust_store.FindTrustAnchorByName(tbs.issuer_tlv); | 802 auto trust_anchor = trust_store.FindTrustAnchorByName(tbs.issuer_tlv); |
739 if (!trust_anchor) | 803 if (!trust_anchor) |
740 return false; | 804 return false; |
741 certs_der_trusted_root->push_back(trust_anchor->cert()); | 805 certs_der_trusted_root->push_back(trust_anchor->der_cert()); |
742 return true; | 806 return true; |
743 } | 807 } |
744 | 808 |
745 } // namespace | 809 } // namespace |
746 | 810 |
747 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der, | 811 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der, |
748 const TrustStore& trust_store, | 812 const TrustStore& trust_store, |
749 const SignaturePolicy* signature_policy, | 813 const SignaturePolicy* signature_policy, |
750 const der::GeneralizedTime& time) { | 814 const der::GeneralizedTime& time) { |
751 // Modify the certificate chain so that its root is a trusted certificate. | 815 // Modify the certificate chain so that its root is a trusted certificate. |
752 std::vector<der::Input> certs_der_trusted_root; | 816 std::vector<der::Input> certs_der_trusted_root; |
753 if (!BuildSimplePathToTrustAnchor(certs_der, trust_store, | 817 if (!BuildSimplePathToTrustAnchor(certs_der, trust_store, |
754 &certs_der_trusted_root)) { | 818 &certs_der_trusted_root)) { |
755 return false; | 819 return false; |
756 } | 820 } |
757 | 821 |
| 822 std::vector<std::unique_ptr<CertThing>> certs_trusted_root; |
| 823 for (const auto& cert_der : certs_der_trusted_root) { |
| 824 std::unique_ptr<CertThing> cert(CertThing::CreateFromCertificateData( |
| 825 cert_der.UnsafeData(), cert_der.Length(), |
| 826 CertThing::DataSource::EXTERNAL_REFERENCE)); |
| 827 if (!cert) |
| 828 return false; |
| 829 certs_trusted_root.push_back(std::move(cert)); |
| 830 } |
| 831 |
758 // Verify the chain. | 832 // Verify the chain. |
759 return VerifyCertificateChainAssumingTrustedRoot( | 833 return VerifyCertificateChainAssumingTrustedRoot( |
760 certs_der_trusted_root, trust_store, signature_policy, time); | 834 certs_trusted_root, trust_store, signature_policy, time); |
761 } | 835 } |
762 | 836 |
763 } // namespace net | 837 } // namespace net |
OLD | NEW |