Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(429)

Side by Side Diff: net/cert/internal/verify_certificate_chain.cc

Issue 2903283002: Add policies support to VerifyCertificateChain(). (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <algorithm>
7 #include <memory> 8 #include <memory>
8 9
9 #include "base/logging.h" 10 #include "base/logging.h"
10 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
11 #include "net/cert/internal/cert_error_params.h" 12 #include "net/cert/internal/cert_error_params.h"
12 #include "net/cert/internal/cert_errors.h" 13 #include "net/cert/internal/cert_errors.h"
13 #include "net/cert/internal/extended_key_usage.h" 14 #include "net/cert/internal/extended_key_usage.h"
14 #include "net/cert/internal/name_constraints.h" 15 #include "net/cert/internal/name_constraints.h"
15 #include "net/cert/internal/parse_certificate.h" 16 #include "net/cert/internal/parse_certificate.h"
16 #include "net/cert/internal/signature_algorithm.h" 17 #include "net/cert/internal/signature_algorithm.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 DEFINE_CERT_ERROR_ID(kVerifySignedDataFailed, "VerifySignedData failed"); 57 DEFINE_CERT_ERROR_ID(kVerifySignedDataFailed, "VerifySignedData failed");
57 DEFINE_CERT_ERROR_ID(kSignatureAlgorithmsDifferentEncoding, 58 DEFINE_CERT_ERROR_ID(kSignatureAlgorithmsDifferentEncoding,
58 "Certificate.signatureAlgorithm is encoded differently " 59 "Certificate.signatureAlgorithm is encoded differently "
59 "than TBSCertificate.signature"); 60 "than TBSCertificate.signature");
60 DEFINE_CERT_ERROR_ID(kEkuLacksServerAuth, 61 DEFINE_CERT_ERROR_ID(kEkuLacksServerAuth,
61 "The extended key usage does not include server auth"); 62 "The extended key usage does not include server auth");
62 DEFINE_CERT_ERROR_ID(kEkuLacksClientAuth, 63 DEFINE_CERT_ERROR_ID(kEkuLacksClientAuth,
63 "The extended key usage does not include client auth"); 64 "The extended key usage does not include client auth");
64 DEFINE_CERT_ERROR_ID(kCertIsNotTrustAnchor, 65 DEFINE_CERT_ERROR_ID(kCertIsNotTrustAnchor,
65 "Certificate is not a trust anchor"); 66 "Certificate is not a trust anchor");
67 DEFINE_CERT_ERROR_ID(kNoValidPolicy, "No valid policy");
68 DEFINE_CERT_ERROR_ID(kPolicyMappingAnyPolicy,
69 "PolicyMappings must not map anyPolicy");
66 70
67 bool IsHandledCriticalExtensionOid(const der::Input& oid) { 71 bool IsHandledCriticalExtensionOid(const der::Input& oid) {
68 if (oid == BasicConstraintsOid()) 72 if (oid == BasicConstraintsOid())
69 return true; 73 return true;
70 // Key Usage is NOT processed for end-entity certificates (this is the 74 // Key Usage is NOT processed for end-entity certificates (this is the
71 // responsibility of callers), however it is considered "handled" here in 75 // responsibility of callers), however it is considered "handled" here in
72 // order to allow being marked as critical. 76 // order to allow being marked as critical.
73 if (oid == KeyUsageOid()) 77 if (oid == KeyUsageOid())
74 return true; 78 return true;
75 if (oid == ExtKeyUsageOid()) 79 if (oid == ExtKeyUsageOid())
76 return true; 80 return true;
77 if (oid == NameConstraintsOid()) 81 if (oid == NameConstraintsOid())
78 return true; 82 return true;
79 if (oid == SubjectAltNameOid()) 83 if (oid == SubjectAltNameOid())
80 return true; 84 return true;
85 if (oid == CertificatePoliciesOid())
86 return true;
87 if (oid == PolicyMappingsOid())
88 return true;
89 if (oid == PolicyConstraintsOid())
90 return true;
91 if (oid == InhibitAnyPolicyOid())
92 return true;
81 93
82 // TODO(eroman): Make this more complete.
83 return false; 94 return false;
84 } 95 }
85 96
86 // Adds errors to |errors| if the certificate contains unconsumed _critical_ 97 // Adds errors to |errors| if the certificate contains unconsumed _critical_
87 // extensions. 98 // extensions.
88 void VerifyNoUnconsumedCriticalExtensions(const ParsedCertificate& cert, 99 void VerifyNoUnconsumedCriticalExtensions(const ParsedCertificate& cert,
89 CertErrors* errors) { 100 CertErrors* errors) {
90 for (const auto& it : cert.extensions()) { 101 for (const auto& it : cert.extensions()) {
91 const ParsedExtension& extension = it.second; 102 const ParsedExtension& extension = it.second;
92 if (extension.critical && !IsHandledCriticalExtensionOid(extension.oid)) { 103 if (extension.critical && !IsHandledCriticalExtensionOid(extension.oid)) {
(...skipping 20 matching lines...) Expand all
113 } 124 }
114 125
115 // Adds errors to |errors| if |cert| is not valid at time |time|. 126 // Adds errors to |errors| if |cert| is not valid at time |time|.
116 // 127 //
117 // The certificate's validity requirements are described by RFC 5280 section 128 // The certificate's validity requirements are described by RFC 5280 section
118 // 4.1.2.5: 129 // 4.1.2.5:
119 // 130 //
120 // The validity period for a certificate is the period of time from 131 // The validity period for a certificate is the period of time from
121 // notBefore through notAfter, inclusive. 132 // notBefore through notAfter, inclusive.
122 void VerifyTimeValidity(const ParsedCertificate& cert, 133 void VerifyTimeValidity(const ParsedCertificate& cert,
123 const der::GeneralizedTime time, 134 const der::GeneralizedTime& time,
124 CertErrors* errors) { 135 CertErrors* errors) {
125 if (time < cert.tbs().validity_not_before) 136 if (time < cert.tbs().validity_not_before)
126 errors->AddError(kValidityFailedNotBefore); 137 errors->AddError(kValidityFailedNotBefore);
127 138
128 if (cert.tbs().validity_not_after < time) 139 if (cert.tbs().validity_not_after < time)
129 errors->AddError(kValidityFailedNotAfter); 140 errors->AddError(kValidityFailedNotAfter);
130 } 141 }
131 142
132 // Adds errors to |errors| if |cert| has internally inconsistent signature 143 // Adds errors to |errors| if |cert| has internally inconsistent signature
133 // algorithms. 144 // algorithms.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 if (key_purpose_oid == ClientAuth()) 220 if (key_purpose_oid == ClientAuth())
210 return; 221 return;
211 } 222 }
212 223
213 errors->AddError(kEkuLacksClientAuth); 224 errors->AddError(kEkuLacksClientAuth);
214 break; 225 break;
215 } 226 }
216 } 227 }
217 } 228 }
218 229
219 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate 230 // Returns |true| if |policies| contains the OID |search_oid|.
220 // Processing" procedure. 231 bool ContainsPolicy(const std::set<der::Input>& policies,
221 void BasicCertificateProcessing( 232 const der::Input& search_oid) {
233 return policies.count(search_oid) > 0;
234 }
235
236 // Class that encapsulates the state variables used by certificate path
237 // validation.
238 class PathVerifier {
239 public:
240 // Same parameters and meaning as VerifyCertificateChain().
241 void Run(const ParsedCertificateList& certs,
242 const CertificateTrust& last_cert_trust,
243 const SignaturePolicy* signature_policy,
244 const der::GeneralizedTime& time,
245 KeyPurpose required_key_purpose,
246 bool initial_explicit_policy,
247 const std::set<der::Input>& user_initial_policy_set,
248 bool initial_policy_mapping_inhibit,
249 bool initial_any_policy_inhibit,
250 CertPathErrors* errors);
251
252 private:
253 // Verifies and updates the valid policies. This corresponds with RFC 5280
254 // section 6.1.3 steps d-f.
255 void VerifyPolicies(const ParsedCertificate& cert,
256 bool is_target_cert,
257 CertErrors* errors);
258
259 // Applies the policy mappings. This corresponds with RFC 5280 section 6.1.4
260 // steps a-b.
261 void VerifyPolicyMappings(const ParsedCertificate& cert, CertErrors* errors);
262
263 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate
264 // Processing" procedure.
265 void BasicCertificateProcessing(const ParsedCertificate& cert,
266 bool is_target_cert,
267 const SignaturePolicy* signature_policy,
268 const der::GeneralizedTime& time,
269 KeyPurpose required_key_purpose,
270 CertErrors* errors);
271
272 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for
273 // Certificate i+1" procedure. |cert| is expected to be an intermediate.
274 void PrepareForNextCertificate(const ParsedCertificate& cert,
275 CertErrors* errors);
276
277 // This function corresponds with RFC 5280 section 6.1.5's "Wrap-Up
278 // Procedure". It does processing for the final certificate (the target cert).
279 void WrapUp(const ParsedCertificate& cert, CertErrors* errors);
280
281 // Enforces trust anchor constraints compatibile with RFC 5937.
282 //
283 // Note that the anchor constraints are encoded via the attached certificate
284 // itself.
285 void ApplyTrustAnchorConstraints(const ParsedCertificate& cert,
286 KeyPurpose required_key_purpose,
287 CertErrors* errors);
288
289 // Initializes the path validation algorithm given anchor constraints. This
290 // follows the description in RFC 5937
291 void ProcessRootCertificate(const ParsedCertificate& cert,
292 const CertificateTrust& trust,
293 KeyPurpose required_key_purpose,
294 CertErrors* errors);
295
296 // The set of certificate policy OIDs that are valid at the current depth in
297 // the path. These OIDs are in the domain of the current issuer (relevant in
298 // case policy mapping were used). This variable is a simplification of RFC
299 // 5280's "valid_policy_tree" variable.
300 std::set<der::Input> valid_policies_;
301
302 // Will contain a NameConstraints for each previous cert in the chain which
303 // had nameConstraints. This corresponds to the permitted_subtrees and
304 // excluded_subtrees state variables from RFC 5280.
305 std::vector<const NameConstraints*> name_constraints_list_;
306
307 // |explicit_policy_| corresponds with the same named variable from RFC 5280
308 // section 6.1.2:
309 //
310 // explicit_policy: an integer that indicates if a non-NULL
311 // valid_policy_tree is required. The integer indicates the
312 // number of non-self-issued certificates to be processed before
313 // this requirement is imposed. Once set, this variable may be
314 // decreased, but may not be increased. That is, if a certificate in the
315 // path requires a non-NULL valid_policy_tree, a later certificate cannot
316 // remove this requirement. If initial-explicit-policy is set, then the
317 // initial value is 0, otherwise the initial value is n+1.
318 size_t explicit_policy_;
319
320 // |inhibit_any_policy_| corresponds with the same named variable from RFC
321 // 5280 section 6.1.2:
322 //
323 // inhibit_anyPolicy: an integer that indicates whether the
324 // anyPolicy policy identifier is considered a match. The
325 // integer indicates the number of non-self-issued certificates
326 // to be processed before the anyPolicy OID, if asserted in a
327 // certificate other than an intermediate self-issued
328 // certificate, is ignored. Once set, this variable may be
329 // decreased, but may not be increased. That is, if a
330 // certificate in the path inhibits processing of anyPolicy, a
331 // later certificate cannot permit it. If initial-any-policy-
332 // inhibit is set, then the initial value is 0, otherwise the
333 // initial value is n+1.
334 size_t inhibit_any_policy_;
335
336 // |policy_mapping_| corresponds with the same named variable from RFC 5280
337 // section 6.1.2:
338 //
339 // policy_mapping: an integer that indicates if policy mapping
340 // is permitted. The integer indicates the number of non-self-
341 // issued certificates to be processed before policy mapping is
342 // inhibited. Once set, this variable may be decreased, but may
343 // not be increased. That is, if a certificate in the path
344 // specifies that policy mapping is not permitted, it cannot be
345 // overridden by a later certificate. If initial-policy-
346 // mapping-inhibit is set, then the initial value is 0,
347 // otherwise the initial value is n+1.
348 size_t policy_mapping_;
349
350 // |working_spki_| is an amalgamation of 3 separate variables from RFC 5280:
351 // * working_public_key
352 // * working_public_key_algorithm
353 // * working_public_key_parameters
354 //
355 // They are combined for simplicity since the signature verification takes an
356 // SPKI, and the parameter inheritence is not applicable for the supported
357 // key types.
358 //
359 // An approximate explanation of |working_spki| is this description from RFC
360 // 5280 section 6.1.2:
361 //
362 // working_public_key: the public key used to verify the
363 // signature of a certificate.
364 der::Input working_spki_;
365
366 // |working_normalized_issuer_name_| is the normalized value of the
367 // working_issuer_name variable in RFC 5280 section 6.1.2:
368 //
369 // working_issuer_name: the issuer distinguished name expected
370 // in the next certificate in the chain.
371 der::Input working_normalized_issuer_name_;
372
373 // |max_path_length_| corresponds with the same named variable in RFC 5280
374 // section 6.1.2.
375 //
376 // max_path_length: this integer is initialized to n, is
377 // decremented for each non-self-issued certificate in the path,
378 // and may be reduced to the value in the path length constraint
379 // field within the basic constraints extension of a CA
380 // certificate.
381 size_t max_path_length_;
382 };
383
384 void PathVerifier::VerifyPolicies(const ParsedCertificate& cert,
385 bool is_target_cert,
386 CertErrors* errors) {
387 // RFC 5280 section 6.1.3:
388 //
389 // (d) If the certificate policies extension is present in the
390 // certificate and the valid_policy_tree is not NULL, process
391 // the policy information by performing the following steps in
392 // order:
393 if (cert.has_policy_oids() && !valid_policies_.empty()) {
394 std::set<der::Input> new_valid_policies;
395
396 bool valid_policies_contains_any_policy =
397 ContainsPolicy(valid_policies_, AnyPolicy());
398
399 bool cert_policies_contains_any_policy = false;
400
401 // (1) For each policy P not equal to anyPolicy in the
402 // certificate policies extension, let P-OID denote the OID
403 // for policy P and P-Q denote the qualifier set for policy
404 // P. Perform the following steps in order:
405 for (const der::Input& p_oid : cert.policy_oids()) {
406 if (p_oid == AnyPolicy()) {
407 cert_policies_contains_any_policy = true;
408 continue;
409 }
410
411 // (i) For each node of depth i-1 in the valid_policy_tree
412 // where P-OID is in the expected_policy_set,
413 if (ContainsPolicy(valid_policies_, p_oid)) {
414 new_valid_policies.insert(p_oid);
415 } else {
416 // (ii) If there was no match in step (i) and the
417 // valid_policy_tree includes a node of depth i-1 with
418 // the valid_policy anyPolicy, generate a child node with
419 // the following values: set the valid_policy to P-OID,
420 // set the qualifier_set to P-Q, and set the
421 // expected_policy_set to {P-OID}.
422 if (valid_policies_contains_any_policy) {
423 new_valid_policies.insert(p_oid);
424 }
425 }
426 }
427
428 // (2) If the certificate policies extension includes the policy
429 // anyPolicy with the qualifier set AP-Q and either (a)
430 // inhibit_anyPolicy is greater than 0 or (b) i<n and the
431 // certificate is self-issued, then:
mattm 2017/05/25 23:21:48 paste more RFC instead of leaving the cliffhanger
432 if (cert_policies_contains_any_policy &&
433 ((inhibit_any_policy_ > 0) ||
434 (!is_target_cert && IsSelfIssued(cert)))) {
435 for (const der::Input& valid_oid : valid_policies_) {
436 new_valid_policies.insert(valid_oid);
437 }
438 }
439
440 valid_policies_ = std::move(new_valid_policies);
mattm 2017/05/25 23:21:49 so is step (3) unnecessary because we replace vali
441 }
442
443 // (e) If the certificate policies extension is not present, set the
444 // valid_policy_tree to NULL.
445 if (!cert.has_policy_oids()) {
446 valid_policies_.clear();
447 }
448
449 // (f) Verify that either explicit_policy is greater than 0 or the
450 // valid_policy_tree is not equal to NULL;
451 if (explicit_policy_ == 0 && valid_policies_.empty()) {
452 errors->AddError(kNoValidPolicy);
453 }
454 }
455
456 void PathVerifier::VerifyPolicyMappings(const ParsedCertificate& cert,
457 CertErrors* errors) {
458 if (!cert.has_policy_mappings())
459 return;
460
461 // (a) If a policy mappings extension is present, verify that the
mattm 2017/05/25 23:21:48 Preceed this with what RFC section you're referenc
462 // special value anyPolicy does not appear as an
463 // issuerDomainPolicy or a subjectDomainPolicy.
464 for (const ParsedPolicyMapping& mapping : cert.policy_mappings()) {
465 if (mapping.issuer_domain_policy == AnyPolicy() ||
466 mapping.subject_domain_policy == AnyPolicy()) {
467 errors->AddError(kPolicyMappingAnyPolicy);
mattm 2017/05/25 23:21:48 Is it intentionally not returning here for the "tr
468 }
469 }
470
471 // (b) If a policy mappings extension is present, then for each
472 // issuerDomainPolicy ID-P in the policy mappings extension:
473 //
474 // (1) If the policy_mapping variable is greater than 0, for each
475 // node in the valid_policy_tree of depth i where ID-P is the
476 // valid_policy, set expected_policy_set to the set of
477 // subjectDomainPolicy values that are specified as
478 // equivalent to ID-P by the policy mappings extension.
479 //
480 // If no node of depth i in the valid_policy_tree has a
481 // valid_policy of ID-P but there is a node of depth i with a
482 // valid_policy of anyPolicy, then generate a child node of
483 // the node of depth i-1 that has a valid_policy of anyPolicy
484 // as follows:
485 //
486 // (i) set the valid_policy to ID-P;
487 //
488 // (ii) set the qualifier_set to the qualifier set of the
489 // policy anyPolicy in the certificate policies
490 // extension of certificate i; and
491 //
492 // (iii) set the expected_policy_set to the set of
493 // subjectDomainPolicy values that are specified as
494 // equivalent to ID-P by the policy mappings extension.
mattm 2017/05/25 23:21:48 Man the policy mapping stuff is impossible to comp
495 //
496 // (ii) If there is a node in the valid_policy_tree of depth
mattm 2017/05/25 23:21:48 comment out of place? (this is b.2.ii?)
497 // i-1 or less without any child nodes, delete that
498 // node. Repeat this step until there are no nodes of
499 // depth i-1 or less without children.
500 if (policy_mapping_ > 0) {
501 std::set<der::Input> new_valid_policies;
502
503 for (const der::Input& orig_policy : valid_policies_) {
504 bool is_remapped = false;
505
506 // Find everything it is got remapped to.
507 for (const ParsedPolicyMapping& mapping : cert.policy_mappings()) {
508 if (mapping.issuer_domain_policy == orig_policy ||
509 mapping.issuer_domain_policy == AnyPolicy()) {
mattm 2017/05/25 23:21:48 so this is an extrapolation for what to do when co
510 new_valid_policies.insert(mapping.subject_domain_policy);
511 is_remapped = true;
512 }
513 }
514
515 // If it wasn't remapped, carry it over as usual.
516 if (!is_remapped)
517 new_valid_policies.insert(orig_policy);
518 }
519
520 valid_policies_ = std::move(new_valid_policies);
521 } else {
522 // (2) If the policy_mapping variable is equal to 0:
523 //
524 // (i) delete each node of depth i in the valid_policy_tree
525 // where ID-P is the valid_policy.
526 for (const ParsedPolicyMapping& mapping : cert.policy_mappings()) {
527 valid_policies_.erase(mapping.issuer_domain_policy);
528 }
529 }
530 }
531
532 void PathVerifier::BasicCertificateProcessing(
222 const ParsedCertificate& cert, 533 const ParsedCertificate& cert,
223 bool is_target_cert, 534 bool is_target_cert,
224 const SignaturePolicy* signature_policy, 535 const SignaturePolicy* signature_policy,
225 const der::GeneralizedTime& time, 536 const der::GeneralizedTime& time,
226 const der::Input& working_spki, 537 KeyPurpose required_key_purpose,
227 const der::Input& working_normalized_issuer_name,
228 const std::vector<const NameConstraints*>& name_constraints_list,
229 CertErrors* errors) { 538 CertErrors* errors) {
230 // Check that the signature algorithms in Certificate vs TBSCertificate 539 // Check that the signature algorithms in Certificate vs TBSCertificate
231 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by 540 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by
232 // sections 4.1.1.2 and 4.1.2.3. 541 // sections 4.1.1.2 and 4.1.2.3.
233 VerifySignatureAlgorithmsMatch(cert, errors); 542 VerifySignatureAlgorithmsMatch(cert, errors);
234 543
235 // Verify the digital signature using the previous certificate's key (RFC 544 // Verify the digital signature using the previous certificate's key (RFC
236 // 5280 section 6.1.3 step a.1). 545 // 5280 section 6.1.3 step a.1).
237 if (!VerifySignedData(cert.signature_algorithm(), cert.tbs_certificate_tlv(), 546 if (!VerifySignedData(cert.signature_algorithm(), cert.tbs_certificate_tlv(),
238 cert.signature_value(), working_spki, signature_policy, 547 cert.signature_value(), working_spki_, signature_policy,
239 errors)) { 548 errors)) {
240 errors->AddError(kVerifySignedDataFailed); 549 errors->AddError(kVerifySignedDataFailed);
241 } 550 }
242 551
243 // Check the time range for the certificate's validity, ensuring it is valid 552 // Check the time range for the certificate's validity, ensuring it is valid
244 // at |time|. 553 // at |time|.
245 // (RFC 5280 section 6.1.3 step a.2) 554 // (RFC 5280 section 6.1.3 step a.2)
246 VerifyTimeValidity(cert, time, errors); 555 VerifyTimeValidity(cert, time, errors);
247 556
248 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) 557 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3)
249 558
250 // Verify the certificate's issuer name matches the issuing certificate's 559 // Verify the certificate's issuer name matches the issuing certificate's
251 // subject name. (RFC 5280 section 6.1.3 step a.4) 560 // subject name. (RFC 5280 section 6.1.3 step a.4)
252 if (cert.normalized_issuer() != working_normalized_issuer_name) 561 if (cert.normalized_issuer() != working_normalized_issuer_name_)
253 errors->AddError(kSubjectDoesNotMatchIssuer); 562 errors->AddError(kSubjectDoesNotMatchIssuer);
254 563
255 // Name constraints (RFC 5280 section 6.1.3 step b & c) 564 // Name constraints (RFC 5280 section 6.1.3 step b & c)
256 // If certificate i is self-issued and it is not the final certificate in the 565 // If certificate i is self-issued and it is not the final certificate in the
257 // path, skip this step for certificate i. 566 // path, skip this step for certificate i.
258 if (!name_constraints_list.empty() && 567 if (!name_constraints_list_.empty() &&
259 (!IsSelfIssued(cert) || is_target_cert)) { 568 (!IsSelfIssued(cert) || is_target_cert)) {
260 for (const NameConstraints* nc : name_constraints_list) { 569 for (const NameConstraints* nc : name_constraints_list_) {
261 if (!nc->IsPermittedCert(cert.normalized_subject(), 570 if (!nc->IsPermittedCert(cert.normalized_subject(),
262 cert.subject_alt_names())) { 571 cert.subject_alt_names())) {
263 errors->AddError(kNotPermittedByNameConstraints); 572 errors->AddError(kNotPermittedByNameConstraints);
264 } 573 }
265 } 574 }
266 } 575 }
267 576
268 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet 577 // RFC 5280 section 6.1.3 step d - f.
269 // implemented. 578 VerifyPolicies(cert, is_target_cert, errors);
579
580 // The key purpose is checked not just for the end-entity certificate, but
581 // also interpreted as a constraint when it appears in intermediates. This
582 // goes beyond what RFC 5280 describes, but is the de-facto standard. See
583 // https://wiki.mozilla.org/CA:CertificatePolicyV2.1#Frequently_Asked_Question s
584 VerifyExtendedKeyUsage(cert, required_key_purpose, errors);
270 } 585 }
271 586
272 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for 587 void PathVerifier::PrepareForNextCertificate(const ParsedCertificate& cert,
273 // Certificate i+1" procedure. |cert| is expected to be an intermediate. 588 CertErrors* errors) {
274 void PrepareForNextCertificate( 589 // RFC 5280 section 6.1.4 step a-b
275 const ParsedCertificate& cert, 590 VerifyPolicyMappings(cert, errors);
276 size_t* max_path_length_ptr,
277 der::Input* working_spki,
278 der::Input* working_normalized_issuer_name,
279 std::vector<const NameConstraints*>* name_constraints_list,
280 CertErrors* errors) {
281 // TODO(crbug.com/634456): Steps a-b are omitted, as policy mappings are not
282 // yet implemented.
283 591
284 // From RFC 5280 section 6.1.4 step c: 592 // From RFC 5280 section 6.1.4 step c:
285 // 593 //
286 // Assign the certificate subject name to working_normalized_issuer_name. 594 // Assign the certificate subject name to working_normalized_issuer_name.
287 *working_normalized_issuer_name = cert.normalized_subject(); 595 working_normalized_issuer_name_ = cert.normalized_subject();
288 596
289 // From RFC 5280 section 6.1.4 step d: 597 // From RFC 5280 section 6.1.4 step d:
290 // 598 //
291 // Assign the certificate subjectPublicKey to working_public_key. 599 // Assign the certificate subjectPublicKey to working_public_key.
292 *working_spki = cert.tbs().spki_tlv; 600 working_spki_ = cert.tbs().spki_tlv;
293 601
294 // Note that steps e and f are omitted as they are handled by 602 // Note that steps e and f are omitted as they are handled by
295 // the assignment to |working_spki| above. See the definition 603 // the assignment to |working_spki| above. See the definition
296 // of |working_spki|. 604 // of |working_spki|.
297 605
298 // From RFC 5280 section 6.1.4 step g: 606 // From RFC 5280 section 6.1.4 step g:
299 if (cert.has_name_constraints()) 607 if (cert.has_name_constraints())
300 name_constraints_list->push_back(&cert.name_constraints()); 608 name_constraints_list_.push_back(&cert.name_constraints());
301 609
302 // TODO(eroman): Steps h-j are omitted as policy 610 // (h) If certificate i is not self-issued:
303 // constraints/mappings/inhibitAnyPolicy are not yet implemented. 611 if (!IsSelfIssued(cert)) {
612 // (1) If explicit_policy is not 0, decrement explicit_policy by
613 // 1.
614 if (explicit_policy_ > 0)
615 explicit_policy_ -= 1;
616
617 // (2) If policy_mapping is not 0, decrement policy_mapping by 1.
618 if (policy_mapping_ > 0)
619 policy_mapping_ -= 1;
620
621 // (3) If inhibit_anyPolicy is not 0, decrement inhibit_anyPolicy
622 // by 1.
623 if (inhibit_any_policy_ > 0)
624 inhibit_any_policy_ -= 1;
625 }
626
627 // (i) If a policy constraints extension is included in the
628 // certificate, modify the explicit_policy and policy_mapping
629 // state variables as follows:
630 if (cert.has_policy_constraints()) {
631 // (1) If requireExplicitPolicy is present and is less than
632 // explicit_policy, set explicit_policy to the value of
633 // requireExplicitPolicy.
634 if (cert.policy_constraints().has_require_explicit_policy &&
635 cert.policy_constraints().require_explicit_policy < explicit_policy_) {
636 explicit_policy_ = cert.policy_constraints().require_explicit_policy;
637 }
638
639 // (2) If inhibitPolicyMapping is present and is less than
640 // policy_mapping, set policy_mapping to the value of
641 // inhibitPolicyMapping.
642 if (cert.policy_constraints().has_inhibit_policy_mapping &&
643 cert.policy_constraints().inhibit_policy_mapping < policy_mapping_) {
644 policy_mapping_ = cert.policy_constraints().inhibit_policy_mapping;
645 }
646 }
647
648 // (j) If the inhibitAnyPolicy extension is included in the
649 // certificate and is less than inhibit_anyPolicy, set
650 // inhibit_anyPolicy to the value of inhibitAnyPolicy.
651 if (cert.has_inhibit_any_policy() &&
652 cert.inhibit_any_policy() < inhibit_any_policy_) {
653 inhibit_any_policy_ = cert.inhibit_any_policy();
654 }
304 655
305 // From RFC 5280 section 6.1.4 step k: 656 // From RFC 5280 section 6.1.4 step k:
306 // 657 //
307 // If certificate i is a version 3 certificate, verify that the 658 // If certificate i is a version 3 certificate, verify that the
308 // basicConstraints extension is present and that cA is set to 659 // basicConstraints extension is present and that cA is set to
309 // TRUE. (If certificate i is a version 1 or version 2 660 // TRUE. (If certificate i is a version 1 or version 2
310 // certificate, then the application MUST either verify that 661 // certificate, then the application MUST either verify that
311 // certificate i is a CA certificate through out-of-band means 662 // certificate i is a CA certificate through out-of-band means
312 // or reject the certificate. Conforming implementations may 663 // or reject the certificate. Conforming implementations may
313 // choose to reject all version 1 and version 2 intermediate 664 // choose to reject all version 1 and version 2 intermediate
314 // certificates.) 665 // certificates.)
315 // 666 //
316 // This code implicitly rejects non version 3 intermediates, since they 667 // This code implicitly rejects non version 3 intermediates, since they
317 // can't contain a BasicConstraints extension. 668 // can't contain a BasicConstraints extension.
318 if (!cert.has_basic_constraints()) { 669 if (!cert.has_basic_constraints()) {
319 errors->AddError(kMissingBasicConstraints); 670 errors->AddError(kMissingBasicConstraints);
320 } else if (!cert.basic_constraints().is_ca) { 671 } else if (!cert.basic_constraints().is_ca) {
321 errors->AddError(kBasicConstraintsIndicatesNotCa); 672 errors->AddError(kBasicConstraintsIndicatesNotCa);
322 } 673 }
323 674
324 // From RFC 5280 section 6.1.4 step l: 675 // From RFC 5280 section 6.1.4 step l:
325 // 676 //
326 // If the certificate was not self-issued, verify that 677 // If the certificate was not self-issued, verify that
327 // max_path_length is greater than zero and decrement 678 // max_path_length is greater than zero and decrement
328 // max_path_length by 1. 679 // max_path_length by 1.
329 if (!IsSelfIssued(cert)) { 680 if (!IsSelfIssued(cert)) {
330 if (*max_path_length_ptr == 0) { 681 if (max_path_length_ == 0) {
331 errors->AddError(kMaxPathLengthViolated); 682 errors->AddError(kMaxPathLengthViolated);
332 } else { 683 } else {
333 --(*max_path_length_ptr); 684 --max_path_length_;
334 } 685 }
335 } 686 }
336 687
337 // From RFC 5280 section 6.1.4 step m: 688 // From RFC 5280 section 6.1.4 step m:
338 // 689 //
339 // If pathLenConstraint is present in the certificate and is 690 // If pathLenConstraint is present in the certificate and is
340 // less than max_path_length, set max_path_length to the value 691 // less than max_path_length, set max_path_length to the value
341 // of pathLenConstraint. 692 // of pathLenConstraint.
342 if (cert.has_basic_constraints() && cert.basic_constraints().has_path_len && 693 if (cert.has_basic_constraints() && cert.basic_constraints().has_path_len &&
343 cert.basic_constraints().path_len < *max_path_length_ptr) { 694 cert.basic_constraints().path_len < max_path_length_) {
344 *max_path_length_ptr = cert.basic_constraints().path_len; 695 max_path_length_ = cert.basic_constraints().path_len;
345 } 696 }
346 697
347 // From RFC 5280 section 6.1.4 step n: 698 // From RFC 5280 section 6.1.4 step n:
348 // 699 //
349 // If a key usage extension is present, verify that the 700 // If a key usage extension is present, verify that the
350 // keyCertSign bit is set. 701 // keyCertSign bit is set.
351 if (cert.has_key_usage() && 702 if (cert.has_key_usage() &&
352 !cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)) { 703 !cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)) {
353 errors->AddError(kKeyCertSignBitNotSet); 704 errors->AddError(kKeyCertSignBitNotSet);
354 } 705 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 cert.basic_constraints().is_ca && 752 cert.basic_constraints().is_ca &&
402 (!cert.has_key_usage() || 753 (!cert.has_key_usage() ||
403 cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)); 754 cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
404 if (!success) { 755 if (!success) {
405 // TODO(eroman): Add DER for basic constraints and key usage. 756 // TODO(eroman): Add DER for basic constraints and key usage.
406 errors->AddError(kTargetCertInconsistentCaBits); 757 errors->AddError(kTargetCertInconsistentCaBits);
407 } 758 }
408 } 759 }
409 } 760 }
410 761
411 // This function corresponds with RFC 5280 section 6.1.5's "Wrap-Up Procedure". 762 void PathVerifier::WrapUp(const ParsedCertificate& cert, CertErrors* errors) {
412 // It does processing for the final certificate (the target cert). 763 // From RFC 5280 section 6.1.5:
413 void WrapUp(const ParsedCertificate& cert, CertErrors* errors) { 764 // (a) If explicit_policy is not 0, decrement explicit_policy by 1.
414 // TODO(crbug.com/634452): Steps a-b are omitted as policy constraints are not 765 if (explicit_policy_ > 0)
415 // yet implemented. 766 explicit_policy_ -= 1;
416 767
417 // Note step c-e are omitted the verification function does 768 // (b) If a policy constraints extension is included in the
769 // certificate and requireExplicitPolicy is present and has a
770 // value of 0, set the explicit_policy state variable to 0.
771 if (cert.has_policy_constraints() &&
772 cert.policy_constraints().has_require_explicit_policy &&
773 cert.policy_constraints().require_explicit_policy == 0) {
774 explicit_policy_ = 0;
775 }
776
777 // Note step c-e are omitted as the verification function does
418 // not output the working public key. 778 // not output the working public key.
419 779
420 // From RFC 5280 section 6.1.5 step f: 780 // From RFC 5280 section 6.1.5 step f:
421 // 781 //
422 // Recognize and process any other critical extension present in 782 // Recognize and process any other critical extension present in
423 // the certificate n. Process any other recognized non-critical 783 // the certificate n. Process any other recognized non-critical
424 // extension present in certificate n that is relevant to path 784 // extension present in certificate n that is relevant to path
425 // processing. 785 // processing.
426 // 786 //
427 // Note that this is duplicated by PrepareForNextCertificate() so as to 787 // Note that this is duplicated by PrepareForNextCertificate() so as to
428 // directly match the procedures in RFC 5280's section 6.1. 788 // directly match the procedures in RFC 5280's section 6.1.
429 VerifyNoUnconsumedCriticalExtensions(cert, errors); 789 VerifyNoUnconsumedCriticalExtensions(cert, errors);
430 790
431 // TODO(eroman): Step g is omitted, as policy constraints are not yet 791 // RFC 5280 section 6.1.5 step g is skipped, as the intersection of valid
432 // implemented. 792 // policies was computed during previous steps.
793 //
794 // If either (1) the value of explicit_policy variable is greater than
795 // zero or (2) the valid_policy_tree is not NULL, then path processing
796 // has succeeded.
797 if (explicit_policy_ == 0 && valid_policies_.empty()) {
798 errors->AddError(kNoValidPolicy);
799 }
433 800
434 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure", 801 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure",
435 // however is implied by RFC 5280 section 4.2.1.9. 802 // however is implied by RFC 5280 section 4.2.1.9.
436 VerifyTargetCertHasConsistentCaBits(cert, errors); 803 VerifyTargetCertHasConsistentCaBits(cert, errors);
437 } 804 }
438 805
439 // Enforces trust anchor constraints compatibile with RFC 5937. 806 void PathVerifier::ApplyTrustAnchorConstraints(const ParsedCertificate& cert,
440 // 807 KeyPurpose required_key_purpose,
441 // Note that the anchor constraints are encoded via the attached certificate 808 CertErrors* errors) {
442 // itself.
443 void ApplyTrustAnchorConstraints(
444 const ParsedCertificate& cert,
445 KeyPurpose required_key_purpose,
446 size_t* max_path_length_ptr,
447 std::vector<const NameConstraints*>* name_constraints_list,
448 CertErrors* errors) {
449 // This is not part of RFC 5937 nor RFC 5280, but matches the EKU handling 809 // This is not part of RFC 5937 nor RFC 5280, but matches the EKU handling
450 // done for intermediates (described in Web PKI's Baseline Requirements). 810 // done for intermediates (described in Web PKI's Baseline Requirements).
451 VerifyExtendedKeyUsage(cert, required_key_purpose, errors); 811 VerifyExtendedKeyUsage(cert, required_key_purpose, errors);
452 812
453 // The following enforcements follow from RFC 5937 (primarily section 3.2): 813 // The following enforcements follow from RFC 5937 (primarily section 3.2):
454 814
455 // Initialize name constraints initial-permitted/excluded-subtrees. 815 // Initialize name constraints initial-permitted/excluded-subtrees.
456 if (cert.has_name_constraints()) 816 if (cert.has_name_constraints())
457 name_constraints_list->push_back(&cert.name_constraints()); 817 name_constraints_list_.push_back(&cert.name_constraints());
458 818
459 // TODO(eroman): Initialize user-initial-policy-set based on anchor 819 // TODO(eroman): Initialize user-initial-policy-set based on anchor
460 // constraints. 820 // constraints.
461 821
462 // TODO(eroman): Initialize inhibit any policy based on anchor constraints. 822 // TODO(eroman): Initialize inhibit any policy based on anchor constraints.
463 823
464 // TODO(eroman): Initialize require explicit policy based on anchor 824 // TODO(eroman): Initialize require explicit policy based on anchor
465 // constraints. 825 // constraints.
466 826
467 // TODO(eroman): Initialize inhibit policy mapping based on anchor 827 // TODO(eroman): Initialize inhibit policy mapping based on anchor
468 // constraints. 828 // constraints.
mattm 2017/05/25 23:21:48 should these todos be done?
469 829
470 // From RFC 5937 section 3.2: 830 // From RFC 5937 section 3.2:
471 // 831 //
472 // If a basic constraints extension is associated with the trust 832 // If a basic constraints extension is associated with the trust
473 // anchor and contains a pathLenConstraint value, set the 833 // anchor and contains a pathLenConstraint value, set the
474 // max_path_length state variable equal to the pathLenConstraint 834 // max_path_length state variable equal to the pathLenConstraint
475 // value from the basic constraints extension. 835 // value from the basic constraints extension.
476 // 836 //
477 // NOTE: RFC 5937 does not say to enforce the CA=true part of basic 837 // NOTE: RFC 5937 does not say to enforce the CA=true part of basic
478 // constraints. 838 // constraints.
479 if (cert.has_basic_constraints() && cert.basic_constraints().has_path_len) 839 if (cert.has_basic_constraints() && cert.basic_constraints().has_path_len)
480 *max_path_length_ptr = cert.basic_constraints().path_len; 840 max_path_length_ = cert.basic_constraints().path_len;
481 841
482 // From RFC 5937 section 2: 842 // From RFC 5937 section 2:
483 // 843 //
484 // Extensions may be marked critical or not critical. When trust anchor 844 // Extensions may be marked critical or not critical. When trust anchor
485 // constraints are enforced, clients MUST reject certification paths 845 // constraints are enforced, clients MUST reject certification paths
486 // containing a trust anchor with unrecognized critical extensions. 846 // containing a trust anchor with unrecognized critical extensions.
487 VerifyNoUnconsumedCriticalExtensions(cert, errors); 847 VerifyNoUnconsumedCriticalExtensions(cert, errors);
488 } 848 }
489 849
490 // Initializes the path validation algorithm given anchor constraints. This 850 void PathVerifier::ProcessRootCertificate(const ParsedCertificate& cert,
491 // follows the description in RFC 5937 851 const CertificateTrust& trust,
492 void ProcessRootCertificate( 852 KeyPurpose required_key_purpose,
493 const ParsedCertificate& cert, 853 CertErrors* errors) {
494 const CertificateTrust& trust,
495 KeyPurpose required_key_purpose,
496 size_t* max_path_length_ptr,
497 std::vector<const NameConstraints*>* name_constraints_list,
498 der::Input* working_spki,
499 der::Input* working_normalized_issuer_name,
500 CertErrors* errors) {
501 // Use the certificate's SPKI and subject when verifying the next certificate. 854 // Use the certificate's SPKI and subject when verifying the next certificate.
502 // Note this is initialized even in the case of untrusted roots (they already 855 // Note this is initialized even in the case of untrusted roots (they already
503 // emit an error for the distrust). 856 // emit an error for the distrust).
504 *working_spki = cert.tbs().spki_tlv; 857 working_spki_ = cert.tbs().spki_tlv;
505 *working_normalized_issuer_name = cert.normalized_subject(); 858 working_normalized_issuer_name_ = cert.normalized_subject();
506 859
507 switch (trust.type) { 860 switch (trust.type) {
508 case CertificateTrustType::UNSPECIFIED: 861 case CertificateTrustType::UNSPECIFIED:
509 // Doesn't chain to a trust anchor - implicitly distrusted 862 // Doesn't chain to a trust anchor - implicitly distrusted
510 errors->AddError(kCertIsNotTrustAnchor); 863 errors->AddError(kCertIsNotTrustAnchor);
511 break; 864 break;
512 case CertificateTrustType::DISTRUSTED: 865 case CertificateTrustType::DISTRUSTED:
513 // Chains to an actively distrusted certificate. 866 // Chains to an actively distrusted certificate.
514 errors->AddError(kCertIsDistrusted); 867 errors->AddError(kCertIsDistrusted);
515 break; 868 break;
516 case CertificateTrustType::TRUSTED_ANCHOR: 869 case CertificateTrustType::TRUSTED_ANCHOR:
517 case CertificateTrustType::TRUSTED_ANCHOR_WITH_CONSTRAINTS: 870 case CertificateTrustType::TRUSTED_ANCHOR_WITH_CONSTRAINTS:
518 // If the trust anchor has constraints, enforce them. 871 // If the trust anchor has constraints, enforce them.
519 if (trust.type == CertificateTrustType::TRUSTED_ANCHOR_WITH_CONSTRAINTS) { 872 if (trust.type == CertificateTrustType::TRUSTED_ANCHOR_WITH_CONSTRAINTS) {
520 ApplyTrustAnchorConstraints(cert, required_key_purpose, 873 ApplyTrustAnchorConstraints(cert, required_key_purpose, errors);
521 max_path_length_ptr, name_constraints_list,
522 errors);
523 } 874 }
524 break; 875 break;
525 } 876 }
526 } 877 }
527 878
528 } // namespace 879 void PathVerifier::Run(const ParsedCertificateList& certs,
529 880 const CertificateTrust& last_cert_trust,
530 // This implementation is structured to mimic the description of certificate 881 const SignaturePolicy* signature_policy,
531 // path verification given by RFC 5280 section 6.1. 882 const der::GeneralizedTime& time,
532 void VerifyCertificateChain(const ParsedCertificateList& certs, 883 KeyPurpose required_key_purpose,
533 const CertificateTrust& last_cert_trust, 884 bool initial_explicit_policy,
534 const SignaturePolicy* signature_policy, 885 const std::set<der::Input>& user_initial_policy_set,
535 const der::GeneralizedTime& time, 886 bool initial_policy_mapping_inhibit,
536 KeyPurpose required_key_purpose, 887 bool initial_any_policy_inhibit,
537 CertPathErrors* errors) { 888 CertPathErrors* errors) {
889 // This implementation is structured to mimic the description of certificate
890 // path verification given by RFC 5280 section 6.1.
538 DCHECK(signature_policy); 891 DCHECK(signature_policy);
539 DCHECK(errors); 892 DCHECK(errors);
540 893
541 // An empty chain is necessarily invalid. 894 // An empty chain is necessarily invalid.
542 if (certs.empty()) { 895 if (certs.empty()) {
543 errors->GetOtherErrors()->AddError(kChainIsEmpty); 896 errors->GetOtherErrors()->AddError(kChainIsEmpty);
544 return; 897 return;
545 } 898 }
546 899
547 // TODO(eroman): Verifying a trusted leaf certificate is not currently 900 // TODO(eroman): Verifying a trusted leaf certificate is not currently
548 // permitted. 901 // permitted.
549 if (certs.size() == 1) { 902 if (certs.size() == 1) {
550 errors->GetOtherErrors()->AddError(kChainIsLength1); 903 errors->GetOtherErrors()->AddError(kChainIsLength1);
551 return; 904 return;
552 } 905 }
553 906
554 // Will contain a NameConstraints for each previous cert in the chain which 907 // RFC 5280's "n" variable is the length of the path, which does not count
555 // had nameConstraints. This corresponds to the permitted_subtrees and 908 // the trust anchor. (Although in practice it doesn't really change behaviors
556 // excluded_subtrees state variables from RFC 5280. 909 // if n is used in place of n+1).
557 std::vector<const NameConstraints*> name_constraints_list; 910 const size_t n = certs.size() - 1;
558 911
559 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: 912 valid_policies_ = user_initial_policy_set;
560 // * working_public_key 913 explicit_policy_ = initial_explicit_policy ? 0 : n + 1;
561 // * working_public_key_algorithm 914 inhibit_any_policy_ = initial_any_policy_inhibit ? 0 : n + 1;
562 // * working_public_key_parameters 915 policy_mapping_ = initial_policy_mapping_inhibit ? 0 : n + 1;
563 // 916 max_path_length_ = n;
564 // They are combined for simplicity since the signature verification takes an
565 // SPKI, and the parameter inheritence is not applicable for the supported
566 // key types.
567 //
568 // An approximate explanation of |working_spki| is this description from RFC
569 // 5280 section 6.1.2:
570 //
571 // working_public_key: the public key used to verify the
572 // signature of a certificate.
573 der::Input working_spki;
574
575 // |working_normalized_issuer_name| is the normalized value of the
576 // working_issuer_name variable in RFC 5280 section 6.1.2:
577 //
578 // working_issuer_name: the issuer distinguished name expected
579 // in the next certificate in the chain.
580 der::Input working_normalized_issuer_name;
581
582 // |max_path_length| corresponds with the same named variable in RFC 5280
583 // section 6.1.2:
584 //
585 // max_path_length: this integer is initialized to n, is
586 // decremented for each non-self-issued certificate in the path,
587 // and may be reduced to the value in the path length constraint
588 // field within the basic constraints extension of a CA
589 // certificate.
590 size_t max_path_length = certs.size();
591 917
592 // Iterate over all the certificates in the reverse direction: starting from 918 // Iterate over all the certificates in the reverse direction: starting from
593 // the root certificate and progressing towards the target certificate. 919 // the root certificate and progressing towards the target certificate.
594 // 920 //
595 // * i=0 : Root certificate (i.e. trust anchor) 921 // * i=0 : Root certificate (i.e. trust anchor)
596 // * i=1 : Certificated signed by the root certificate 922 // * i=1 : Certificate issued by root
597 // * i=certs.size()-1 : Target certificate. 923 // * i=x : Certificate i=x is issued by certificate i=x-1
924 // * i=n : Target certificate.
598 for (size_t i = 0; i < certs.size(); ++i) { 925 for (size_t i = 0; i < certs.size(); ++i) {
599 const size_t index_into_certs = certs.size() - i - 1; 926 const size_t index_into_certs = certs.size() - i - 1;
600 927
601 // |is_target_cert| is true if the current certificate is the target 928 // |is_target_cert| is true if the current certificate is the target
602 // certificate being verified. The target certificate isn't necessarily an 929 // certificate being verified. The target certificate isn't necessarily an
603 // end-entity certificate. 930 // end-entity certificate.
604 const bool is_target_cert = index_into_certs == 0; 931 const bool is_target_cert = index_into_certs == 0;
605 const bool is_root_cert = i == 0; 932 const bool is_root_cert = i == 0;
606 933
607 const ParsedCertificate& cert = *certs[index_into_certs]; 934 const ParsedCertificate& cert = *certs[index_into_certs];
608 935
609 // Output errors for the current certificate into an error bucket that is 936 // Output errors for the current certificate into an error bucket that is
610 // associated with that certificate. 937 // associated with that certificate.
611 CertErrors* cert_errors = errors->GetErrorsForCert(index_into_certs); 938 CertErrors* cert_errors = errors->GetErrorsForCert(index_into_certs);
612 939
613 if (is_root_cert) { 940 if (is_root_cert) {
614 ProcessRootCertificate(cert, last_cert_trust, required_key_purpose, 941 ProcessRootCertificate(cert, last_cert_trust, required_key_purpose,
615 &max_path_length, &name_constraints_list,
616 &working_spki, &working_normalized_issuer_name,
617 cert_errors); 942 cert_errors);
618 943
619 // Don't do any other checks for root certificates. 944 // Don't do any other checks for root certificates.
620 continue; 945 continue;
621 } 946 }
622 947
623 // Per RFC 5280 section 6.1: 948 // Per RFC 5280 section 6.1:
624 // * Do basic processing for each certificate 949 // * Do basic processing for each certificate
625 // * If it is the last certificate in the path (target certificate) 950 // * If it is the last certificate in the path (target certificate)
626 // - Then run "Wrap up" 951 // - Then run "Wrap up"
627 // - Otherwise run "Prepare for Next cert" 952 // - Otherwise run "Prepare for Next cert"
628 BasicCertificateProcessing(cert, is_target_cert, signature_policy, time, 953 BasicCertificateProcessing(cert, is_target_cert, signature_policy, time,
629 working_spki, working_normalized_issuer_name, 954 required_key_purpose, cert_errors);
630 name_constraints_list, cert_errors);
631
632 // The key purpose is checked not just for the end-entity certificate, but
633 // also interpreted as a constraint when it appears in intermediates. This
634 // goes beyond what RFC 5280 describes, but is the de-facto standard. See
635 // https://wiki.mozilla.org/CA:CertificatePolicyV2.1#Frequently_Asked_Questi ons
636 VerifyExtendedKeyUsage(cert, required_key_purpose, cert_errors);
637
638 if (!is_target_cert) { 955 if (!is_target_cert) {
639 PrepareForNextCertificate(cert, &max_path_length, &working_spki, 956 PrepareForNextCertificate(cert, cert_errors);
640 &working_normalized_issuer_name,
641 &name_constraints_list, cert_errors);
642 } else { 957 } else {
643 WrapUp(cert, cert_errors); 958 WrapUp(cert, cert_errors);
644 } 959 }
645 } 960 }
646 961
647 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: 962 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1:
648 // 963 //
649 // A certificate MUST NOT appear more than once in a prospective 964 // A certificate MUST NOT appear more than once in a prospective
650 // certification path. 965 // certification path.
651 } 966 }
652 967
968 } // namespace
969
970 void VerifyCertificateChain(const ParsedCertificateList& certs,
971 const CertificateTrust& last_cert_trust,
972 const SignaturePolicy* signature_policy,
973 const der::GeneralizedTime& time,
974 KeyPurpose required_key_purpose,
975 bool initial_explicit_policy,
976 const std::set<der::Input>& user_initial_policy_set,
977 bool initial_policy_mapping_inhibit,
978 bool initial_any_policy_inhibit,
979 CertPathErrors* errors) {
980 PathVerifier verifier;
981 verifier.Run(certs, last_cert_trust, signature_policy, time,
982 required_key_purpose, initial_explicit_policy,
983 user_initial_policy_set, initial_policy_mapping_inhibit,
984 initial_any_policy_inhibit, errors);
985 }
986
653 } // namespace net 987 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698