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

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

Issue 2903283002: Add policies support to VerifyCertificateChain(). (Closed)
Patch Set: improve comments, and null policy tree when anyPolicy is incorrectly mapped 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 // TODO(eroman): The policy qualifiers are not processed (or in some cases
86 // even parsed). This is fine when the policies extension is non-critical,
87 // however if it is critical the code should also ensure that the policy
88 // qualifiers are only recognized ones (CPS and User Notice).
89 if (oid == CertificatePoliciesOid())
90 return true;
91 if (oid == PolicyMappingsOid())
92 return true;
93 if (oid == PolicyConstraintsOid())
94 return true;
95 if (oid == InhibitAnyPolicyOid())
96 return true;
81 97
82 // TODO(eroman): Make this more complete.
83 return false; 98 return false;
84 } 99 }
85 100
86 // Adds errors to |errors| if the certificate contains unconsumed _critical_ 101 // Adds errors to |errors| if the certificate contains unconsumed _critical_
87 // extensions. 102 // extensions.
88 void VerifyNoUnconsumedCriticalExtensions(const ParsedCertificate& cert, 103 void VerifyNoUnconsumedCriticalExtensions(const ParsedCertificate& cert,
89 CertErrors* errors) { 104 CertErrors* errors) {
90 for (const auto& it : cert.extensions()) { 105 for (const auto& it : cert.extensions()) {
91 const ParsedExtension& extension = it.second; 106 const ParsedExtension& extension = it.second;
92 if (extension.critical && !IsHandledCriticalExtensionOid(extension.oid)) { 107 if (extension.critical && !IsHandledCriticalExtensionOid(extension.oid)) {
(...skipping 20 matching lines...) Expand all
113 } 128 }
114 129
115 // Adds errors to |errors| if |cert| is not valid at time |time|. 130 // Adds errors to |errors| if |cert| is not valid at time |time|.
116 // 131 //
117 // The certificate's validity requirements are described by RFC 5280 section 132 // The certificate's validity requirements are described by RFC 5280 section
118 // 4.1.2.5: 133 // 4.1.2.5:
119 // 134 //
120 // The validity period for a certificate is the period of time from 135 // The validity period for a certificate is the period of time from
121 // notBefore through notAfter, inclusive. 136 // notBefore through notAfter, inclusive.
122 void VerifyTimeValidity(const ParsedCertificate& cert, 137 void VerifyTimeValidity(const ParsedCertificate& cert,
123 const der::GeneralizedTime time, 138 const der::GeneralizedTime& time,
124 CertErrors* errors) { 139 CertErrors* errors) {
125 if (time < cert.tbs().validity_not_before) 140 if (time < cert.tbs().validity_not_before)
126 errors->AddError(kValidityFailedNotBefore); 141 errors->AddError(kValidityFailedNotBefore);
127 142
128 if (cert.tbs().validity_not_after < time) 143 if (cert.tbs().validity_not_after < time)
129 errors->AddError(kValidityFailedNotAfter); 144 errors->AddError(kValidityFailedNotAfter);
130 } 145 }
131 146
132 // Adds errors to |errors| if |cert| has internally inconsistent signature 147 // Adds errors to |errors| if |cert| has internally inconsistent signature
133 // algorithms. 148 // algorithms.
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 if (key_purpose_oid == ClientAuth()) 224 if (key_purpose_oid == ClientAuth())
210 return; 225 return;
211 } 226 }
212 227
213 errors->AddError(kEkuLacksClientAuth); 228 errors->AddError(kEkuLacksClientAuth);
214 break; 229 break;
215 } 230 }
216 } 231 }
217 } 232 }
218 233
219 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate 234 // Returns |true| if |policies| contains the OID |search_oid|.
220 // Processing" procedure. 235 bool SetContains(const std::set<der::Input>& policies,
221 void BasicCertificateProcessing( 236 const der::Input& search_oid) {
237 return policies.count(search_oid) > 0;
238 }
239
240 // Representation of RFC 5280's "valid_policy_tree", used to keep track of the
241 // valid policies and policy re-mappings.
242 //
243 // ValidPolicyTree differs slightly from RFC 5280's description in that:
244 //
245 // (1) It does not track "qualifier_set". This is not needed as it is not
246 // output by this implementation.
247 //
248 // (2) It only stores the most recent level of the policy tree rather than
249 // the full tree of nodes.
250 class ValidPolicyTree {
251 public:
252 ValidPolicyTree() {}
253
254 struct Node {
255 // |root_policy| is equivalent to |valid_policy|, but in the domain of the
256 // caller.
257 //
258 // The reason for this distinction is the Policy Mappings extension.
259 //
260 // So whereas |valid_policy| is in the remapped domain defined by the
261 // issuing certificate, |root_policy| is in the fixed domain of the caller.
262 //
263 // OIDs in "user_initial_policy_set" and "user_constrained_policy_set" are
264 // directly comparable to |root_policy| values, but not necessarily to
265 // |valid_policy|.
266 //
267 // In terms of the valid policy tree, |root_policy| can be found by
268 // starting at the node's root ancestor, and finding the first node with a
269 // valid_policy other than anyPolicy. This is effectively the same process
270 // as used during policy tree intersection in RFC 5280 6.1.5.g.iii.1
271 der::Input root_policy;
272
273 // The same as RFC 5280's "valid_policy" variable.
274 der::Input valid_policy;
275
276 // The same as RFC 5280s "expected_policy_set" variable.
277 std::set<der::Input> expected_policy_set;
278
279 // Note that RFC 5280's "qualifier_set" is omitted.
280 };
281
282 // Level represents all the nodes at depth "i" in the valid_policy_tree.
283 using Level = std::vector<Node>;
284
285 // Initializes the ValidPolicyTree for the given "user_initial_policy_set".
286 //
287 // In RFC 5280, the valid_policy_tree is initialized to a root node at depth
288 // 0 of "anyPolicy"; the intersection with the "user_initial_policy_set" is
289 // done at the end (Wrap Up) as described in section 6.1.5 step g.
290 //
291 // Whereas in this implementation, the restriction on policies is added here,
292 // and intersecting the valid policy tree during Wrap Up is no longer needed.
293 //
294 // The final "user_constrained_policy_set" obtained will be the same. The
295 // advantages of this approach is simpler code.
296 void Init(const std::set<der::Input>& user_initial_policy_set) {
297 Clear();
298 for (const der::Input& policy_oid : user_initial_policy_set)
299 AddRootNode(policy_oid);
300 }
301
302 // Returns the current level (i.e. all nodes at depth i in the valid
303 // policy tree).
304 const Level& current_level() const { return current_level_; }
305 Level& current_level() { return current_level_; }
306
307 // In RFC 5280 valid_policy_tree may be set to null. That is represented here
308 // by emptiness.
309 bool IsNull() const { return current_level_.empty(); }
310 void SetNull() { Clear(); }
311
312 // This implementation keeps only the last level of the valid policy
313 // tree. Calling StartLevel() returns the nodes for the previous
314 // level, and starts a new level.
315 Level StartLevel() {
316 Level prev_level;
317 std::swap(prev_level, current_level_);
318 return prev_level;
319 }
320
321 // Gets the set of policies (in terms of root authority's policy domain) that
322 // are valid at the curent level of the policy tree.
323 //
324 // For example:
325 //
326 // * If the valid policy tree was initialized with anyPolicy, then this
327 // function returns what X.509 calls "authorities-constrained-policy-set".
328 //
329 // * If the valid policy tree was instead initialized with the
330 // "user-initial-policy_set", then this function returns what X.509
331 // calls "user-constrained-policy-set"
332 // ("authorities-constrained-policy-set" intersected with the
333 // "user-initial-policy-set").
334 void GetValidRootPolicySet(std::set<der::Input>* policy_set) {
335 policy_set->clear();
336 for (const Node& node : current_level_)
337 policy_set->insert(node.root_policy);
338
339 // If the result includes anyPolicy, simplify it to a set of size 1.
340 if (policy_set->size() > 1 && SetContains(*policy_set, AnyPolicy()))
341 *policy_set = {AnyPolicy()};
342 }
343
344 // Adds a node |n| to the current level which is a child of |parent|
345 // such that:
346 // * n.valid_policy = policy_oid
347 // * n.expected_policy_set = {policy_oid}
348 void AddNode(const Node& parent, const der::Input& policy_oid) {
349 AddNodeWithExpectedPolicySet(parent, policy_oid, {policy_oid});
350 }
351
352 // Adds a node |n| to the current level which is a child of |parent|
353 // such that:
354 // * n.valid_policy = policy_oid
355 // * n.expected_policy_set = expected_policy_set
356 void AddNodeWithExpectedPolicySet(
357 const Node& parent,
358 const der::Input& policy_oid,
359 const std::set<der::Input>& expected_policy_set) {
360 Node new_node;
361 new_node.valid_policy = policy_oid;
362 new_node.expected_policy_set = expected_policy_set;
363
364 // Consider the root policy as the first policy other than anyPolicy (or
365 // anyPolicy if it hasn't been restricted yet).
366 new_node.root_policy =
367 (parent.root_policy == AnyPolicy()) ? policy_oid : parent.root_policy;
368
369 current_level_.push_back(std::move(new_node));
370 }
371
372 // Returns the first node having valid_policy == anyPolicy in |level|, or
373 // nullptr if there is none.
374 static const Node* FindAnyPolicyNode(const Level& level) {
375 for (const Node& node : level) {
376 if (node.valid_policy == AnyPolicy())
377 return &node;
378 }
379 return nullptr;
380 }
381
382 // Deletes all nodes |n| in |level| where |n.valid_policy| matches the given
383 // |valid_policy|. This may re-order the nodes in |level|.
384 static void DeleteNodesMatchingValidPolicy(const der::Input& valid_policy,
385 Level* level) {
386 // This works by swapping nodes to the end of the vector, and then doing a
387 // single resize to delete them all.
388 auto cur = level->begin();
389 auto end = level->end();
390 while (cur != end) {
391 bool should_delete_node = cur->valid_policy == valid_policy;
392 if (should_delete_node) {
393 end = std::prev(end);
394 std::iter_swap(cur, end);
395 } else {
396 ++cur;
397 }
398 }
399 level->erase(end, level->end());
400 }
401
402 private:
403 // Deletes all nodes in the valid policy tree.
404 void Clear() { current_level_.clear(); }
405
406 // Adds a node to the current level for OID |policy_oid|. The current level
407 // is assumed to be the root level.
408 void AddRootNode(const der::Input& policy_oid) {
409 Node new_node;
410 new_node.root_policy = policy_oid;
411 new_node.valid_policy = policy_oid;
412 new_node.expected_policy_set = {policy_oid};
413 current_level_.push_back(std::move(new_node));
414 }
415
416 Level current_level_;
417
418 DISALLOW_COPY_AND_ASSIGN(ValidPolicyTree);
419 };
420
421 // Class that encapsulates the state variables used by certificate path
422 // validation.
423 class PathVerifier {
424 public:
425 // Same parameters and meaning as VerifyCertificateChain().
426 void Run(const ParsedCertificateList& certs,
427 const CertificateTrust& last_cert_trust,
428 const SignaturePolicy* signature_policy,
429 const der::GeneralizedTime& time,
430 KeyPurpose required_key_purpose,
431 InitialExplicitPolicy initial_explicit_policy,
432 const std::set<der::Input>& user_initial_policy_set,
433 InitialPolicyMappingInhibit initial_policy_mapping_inhibit,
434 InitialAnyPolicyInhibit initial_any_policy_inhibit,
435 std::set<der::Input>* user_constrained_policy_set,
436 CertPathErrors* errors);
437
438 private:
439 // Verifies and updates the valid policies. This corresponds with RFC 5280
440 // section 6.1.3 steps d-f.
441 void VerifyPolicies(const ParsedCertificate& cert,
442 bool is_target_cert,
443 CertErrors* errors);
444
445 // Applies the policy mappings. This corresponds with RFC 5280 section 6.1.4
446 // steps a-b.
447 void VerifyPolicyMappings(const ParsedCertificate& cert, CertErrors* errors);
448
449 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate
450 // Processing" procedure.
451 void BasicCertificateProcessing(const ParsedCertificate& cert,
452 bool is_target_cert,
453 const SignaturePolicy* signature_policy,
454 const der::GeneralizedTime& time,
455 KeyPurpose required_key_purpose,
456 CertErrors* errors);
457
458 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for
459 // Certificate i+1" procedure. |cert| is expected to be an intermediate.
460 void PrepareForNextCertificate(const ParsedCertificate& cert,
461 CertErrors* errors);
462
463 // This function corresponds with RFC 5280 section 6.1.5's "Wrap-Up
464 // Procedure". It does processing for the final certificate (the target cert).
465 void WrapUp(const ParsedCertificate& cert, CertErrors* errors);
466
467 // Enforces trust anchor constraints compatibile with RFC 5937.
468 //
469 // Note that the anchor constraints are encoded via the attached certificate
470 // itself.
471 void ApplyTrustAnchorConstraints(const ParsedCertificate& cert,
472 KeyPurpose required_key_purpose,
473 CertErrors* errors);
474
475 // Initializes the path validation algorithm given anchor constraints. This
476 // follows the description in RFC 5937
477 void ProcessRootCertificate(const ParsedCertificate& cert,
478 const CertificateTrust& trust,
479 KeyPurpose required_key_purpose,
480 CertErrors* errors);
481
482 ValidPolicyTree valid_policy_tree_;
483
484 // Will contain a NameConstraints for each previous cert in the chain which
485 // had nameConstraints. This corresponds to the permitted_subtrees and
486 // excluded_subtrees state variables from RFC 5280.
487 std::vector<const NameConstraints*> name_constraints_list_;
488
489 // |explicit_policy_| corresponds with the same named variable from RFC 5280
490 // section 6.1.2:
491 //
492 // explicit_policy: an integer that indicates if a non-NULL
493 // valid_policy_tree is required. The integer indicates the
494 // number of non-self-issued certificates to be processed before
495 // this requirement is imposed. Once set, this variable may be
496 // decreased, but may not be increased. That is, if a certificate in the
497 // path requires a non-NULL valid_policy_tree, a later certificate cannot
498 // remove this requirement. If initial-explicit-policy is set, then the
499 // initial value is 0, otherwise the initial value is n+1.
500 size_t explicit_policy_;
501
502 // |inhibit_any_policy_| corresponds with the same named variable from RFC
503 // 5280 section 6.1.2:
504 //
505 // inhibit_anyPolicy: an integer that indicates whether the
506 // anyPolicy policy identifier is considered a match. The
507 // integer indicates the number of non-self-issued certificates
508 // to be processed before the anyPolicy OID, if asserted in a
509 // certificate other than an intermediate self-issued
510 // certificate, is ignored. Once set, this variable may be
511 // decreased, but may not be increased. That is, if a
512 // certificate in the path inhibits processing of anyPolicy, a
513 // later certificate cannot permit it. If initial-any-policy-
514 // inhibit is set, then the initial value is 0, otherwise the
515 // initial value is n+1.
516 size_t inhibit_any_policy_;
517
518 // |policy_mapping_| corresponds with the same named variable from RFC 5280
519 // section 6.1.2:
520 //
521 // policy_mapping: an integer that indicates if policy mapping
522 // is permitted. The integer indicates the number of non-self-
523 // issued certificates to be processed before policy mapping is
524 // inhibited. Once set, this variable may be decreased, but may
525 // not be increased. That is, if a certificate in the path
526 // specifies that policy mapping is not permitted, it cannot be
527 // overridden by a later certificate. If initial-policy-
528 // mapping-inhibit is set, then the initial value is 0,
529 // otherwise the initial value is n+1.
530 size_t policy_mapping_;
531
532 // |working_spki_| is an amalgamation of 3 separate variables from RFC 5280:
533 // * working_public_key
534 // * working_public_key_algorithm
535 // * working_public_key_parameters
536 //
537 // They are combined for simplicity since the signature verification takes an
538 // SPKI, and the parameter inheritence is not applicable for the supported
539 // key types.
540 //
541 // An approximate explanation of |working_spki| is this description from RFC
542 // 5280 section 6.1.2:
543 //
544 // working_public_key: the public key used to verify the
545 // signature of a certificate.
546 der::Input working_spki_;
547
548 // |working_normalized_issuer_name_| is the normalized value of the
549 // working_issuer_name variable in RFC 5280 section 6.1.2:
550 //
551 // working_issuer_name: the issuer distinguished name expected
552 // in the next certificate in the chain.
553 der::Input working_normalized_issuer_name_;
554
555 // |max_path_length_| corresponds with the same named variable in RFC 5280
556 // section 6.1.2.
557 //
558 // max_path_length: this integer is initialized to n, is
559 // decremented for each non-self-issued certificate in the path,
560 // and may be reduced to the value in the path length constraint
561 // field within the basic constraints extension of a CA
562 // certificate.
563 size_t max_path_length_;
564 };
565
566 void PathVerifier::VerifyPolicies(const ParsedCertificate& cert,
567 bool is_target_cert,
568 CertErrors* errors) {
569 // From RFC 5280 section 6.1.3:
570 //
571 // (d) If the certificate policies extension is present in the
572 // certificate and the valid_policy_tree is not NULL, process
573 // the policy information by performing the following steps in
574 // order:
575 if (cert.has_policy_oids() && !valid_policy_tree_.IsNull()) {
576 ValidPolicyTree::Level previous_level = valid_policy_tree_.StartLevel();
577
578 // Identify if there was a node with valid_policy == anyPolicy at depth i-1.
579 const ValidPolicyTree::Node* any_policy_node_prev_level =
580 ValidPolicyTree::FindAnyPolicyNode(previous_level);
581
582 // (1) For each policy P not equal to anyPolicy in the
583 // certificate policies extension, let P-OID denote the OID
584 // for policy P and P-Q denote the qualifier set for policy
585 // P. Perform the following steps in order:
586 bool cert_has_any_policy = false;
587 for (const der::Input& p_oid : cert.policy_oids()) {
588 if (p_oid == AnyPolicy()) {
589 cert_has_any_policy = true;
590 continue;
591 }
592
593 // (i) For each node of depth i-1 in the valid_policy_tree
594 // where P-OID is in the expected_policy_set, create a
595 // child node as follows: set the valid_policy to P-OID,
596 // set the qualifier_set to P-Q, and set the
597 // expected_policy_set to {P-OID}.
598 bool found_match = false;
599 for (const ValidPolicyTree::Node& prev_node : previous_level) {
600 if (SetContains(prev_node.expected_policy_set, p_oid)) {
601 valid_policy_tree_.AddNode(prev_node, p_oid);
602 found_match = true;
603 }
604 }
605
606 // (ii) If there was no match in step (i) and the
607 // valid_policy_tree includes a node of depth i-1 with
608 // the valid_policy anyPolicy, generate a child node with
609 // the following values: set the valid_policy to P-OID,
610 // set the qualifier_set to P-Q, and set the
611 // expected_policy_set to {P-OID}.
612 if (!found_match && any_policy_node_prev_level)
613 valid_policy_tree_.AddNode(*any_policy_node_prev_level, p_oid);
614 }
615
616 // (2) If the certificate policies extension includes the policy
617 // anyPolicy with the qualifier set AP-Q and either (a)
618 // inhibit_anyPolicy is greater than 0 or (b) i<n and the
619 // certificate is self-issued, then:
620 //
621 // For each node in the valid_policy_tree of depth i-1, for
622 // each value in the expected_policy_set (including
623 // anyPolicy) that does not appear in a child node, create a
624 // child node with the following values: set the valid_policy
625 // to the value from the expected_policy_set in the parent
626 // node, set the qualifier_set to AP-Q, and set the
627 // expected_policy_set to the value in the valid_policy from
628 // this node.
629 if (cert_has_any_policy && ((inhibit_any_policy_ > 0) ||
630 (!is_target_cert && IsSelfIssued(cert)))) {
631 // Keep track of the existing policies at depth i.
632 std::set<der::Input> child_node_policies;
633 for (const ValidPolicyTree::Node& node :
634 valid_policy_tree_.current_level())
635 child_node_policies.insert(node.valid_policy);
636
637 for (const ValidPolicyTree::Node& prev_node : previous_level) {
638 for (const der::Input& expected_policy :
639 prev_node.expected_policy_set) {
640 if (!SetContains(child_node_policies, expected_policy)) {
641 child_node_policies.insert(expected_policy);
642 valid_policy_tree_.AddNode(prev_node, expected_policy);
643 }
644 }
645 }
646 }
647
648 // (3) If there is a node in the valid_policy_tree of depth i-1
649 // or less without any child nodes, delete that node. Repeat
650 // this step until there are no nodes of depth i-1 or less
651 // without children.
652 //
653 // Nothing needs to be done for this step, since this implementation only
654 // stores the nodes at depth i, and the entire level has already been
655 // calculated.
656 }
657
658 // (e) If the certificate policies extension is not present, set the
659 // valid_policy_tree to NULL.
660 if (!cert.has_policy_oids())
661 valid_policy_tree_.SetNull();
662
663 // (f) Verify that either explicit_policy is greater than 0 or the
664 // valid_policy_tree is not equal to NULL;
665 if (!((explicit_policy_ > 0) || !valid_policy_tree_.IsNull()))
666 errors->AddError(kNoValidPolicy);
667 }
668
669 void PathVerifier::VerifyPolicyMappings(const ParsedCertificate& cert,
670 CertErrors* errors) {
671 if (!cert.has_policy_mappings())
672 return;
673
674 // From RFC 5280 section 6.1.4:
675 //
676 // (a) If a policy mappings extension is present, verify that the
677 // special value anyPolicy does not appear as an
678 // issuerDomainPolicy or a subjectDomainPolicy.
679 for (const ParsedPolicyMapping& mapping : cert.policy_mappings()) {
680 if (mapping.issuer_domain_policy == AnyPolicy() ||
681 mapping.subject_domain_policy == AnyPolicy()) {
682 // Because this implementation continues processing certificates after
683 // this error, clear the valid policy tree to ensure the
684 // "user_constrained_policy_set" output upon failure is empty.
685 valid_policy_tree_.SetNull();
686 errors->AddError(kPolicyMappingAnyPolicy);
687 }
688 }
689
690 // (b) If a policy mappings extension is present, then for each
691 // issuerDomainPolicy ID-P in the policy mappings extension:
692 //
693 // (1) If the policy_mapping variable is greater than 0, for each
694 // node in the valid_policy_tree of depth i where ID-P is the
695 // valid_policy, set expected_policy_set to the set of
696 // subjectDomainPolicy values that are specified as
697 // equivalent to ID-P by the policy mappings extension.
698 //
699 // If no node of depth i in the valid_policy_tree has a
700 // valid_policy of ID-P but there is a node of depth i with a
701 // valid_policy of anyPolicy, then generate a child node of
702 // the node of depth i-1 that has a valid_policy of anyPolicy
703 // as follows:
704 //
705 // (i) set the valid_policy to ID-P;
706 //
707 // (ii) set the qualifier_set to the qualifier set of the
708 // policy anyPolicy in the certificate policies
709 // extension of certificate i; and
710 //
711 // (iii) set the expected_policy_set to the set of
712 // subjectDomainPolicy values that are specified as
713 // equivalent to ID-P by the policy mappings extension.
714 //
715 if (policy_mapping_ > 0) {
716 const ValidPolicyTree::Node* any_policy_node =
717 ValidPolicyTree::FindAnyPolicyNode(valid_policy_tree_.current_level());
718
719 // Group mappings by issuer domain policy.
720 std::map<der::Input, std::set<der::Input>> mappings;
721 for (const ParsedPolicyMapping& mapping : cert.policy_mappings()) {
722 mappings[mapping.issuer_domain_policy].insert(
723 mapping.subject_domain_policy);
724 }
725
726 for (const auto& it : mappings) {
727 const der::Input& issuer_domain_policy = it.first;
728 const std::set<der::Input>& subject_domain_policies = it.second;
729 bool found_node = false;
730
731 for (ValidPolicyTree::Node& node : valid_policy_tree_.current_level()) {
732 if (node.valid_policy == issuer_domain_policy) {
733 node.expected_policy_set = subject_domain_policies;
734 found_node = true;
735 }
736 }
737
738 if (!found_node && any_policy_node) {
739 valid_policy_tree_.AddNodeWithExpectedPolicySet(
740 *any_policy_node, issuer_domain_policy, subject_domain_policies);
741 }
742 }
743 }
744
745 // (b) If a policy mappings extension is present, then for each
746 // issuerDomainPolicy ID-P in the policy mappings extension:
747 //
748 // ...
749 //
750 // (2) If the policy_mapping variable is equal to 0:
751 //
752 // (i) delete each node of depth i in the valid_policy_tree
753 // where ID-P is the valid_policy.
754 //
755 // (ii) If there is a node in the valid_policy_tree of depth
756 // i-1 or less without any child nodes, delete that
757 // node. Repeat this step until there are no nodes of
758 // depth i-1 or less without children.
759 if (policy_mapping_ == 0) {
760 for (const ParsedPolicyMapping& mapping : cert.policy_mappings()) {
761 ValidPolicyTree::DeleteNodesMatchingValidPolicy(
762 mapping.issuer_domain_policy, &valid_policy_tree_.current_level());
763 }
764 }
765 }
766
767 void PathVerifier::BasicCertificateProcessing(
222 const ParsedCertificate& cert, 768 const ParsedCertificate& cert,
223 bool is_target_cert, 769 bool is_target_cert,
224 const SignaturePolicy* signature_policy, 770 const SignaturePolicy* signature_policy,
225 const der::GeneralizedTime& time, 771 const der::GeneralizedTime& time,
226 const der::Input& working_spki, 772 KeyPurpose required_key_purpose,
227 const der::Input& working_normalized_issuer_name,
228 const std::vector<const NameConstraints*>& name_constraints_list,
229 CertErrors* errors) { 773 CertErrors* errors) {
230 // Check that the signature algorithms in Certificate vs TBSCertificate 774 // 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 775 // 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. 776 // sections 4.1.1.2 and 4.1.2.3.
233 VerifySignatureAlgorithmsMatch(cert, errors); 777 VerifySignatureAlgorithmsMatch(cert, errors);
234 778
235 // Verify the digital signature using the previous certificate's key (RFC 779 // Verify the digital signature using the previous certificate's key (RFC
236 // 5280 section 6.1.3 step a.1). 780 // 5280 section 6.1.3 step a.1).
237 if (!VerifySignedData(cert.signature_algorithm(), cert.tbs_certificate_tlv(), 781 if (!VerifySignedData(cert.signature_algorithm(), cert.tbs_certificate_tlv(),
238 cert.signature_value(), working_spki, signature_policy, 782 cert.signature_value(), working_spki_, signature_policy,
239 errors)) { 783 errors)) {
240 errors->AddError(kVerifySignedDataFailed); 784 errors->AddError(kVerifySignedDataFailed);
241 } 785 }
242 786
243 // Check the time range for the certificate's validity, ensuring it is valid 787 // Check the time range for the certificate's validity, ensuring it is valid
244 // at |time|. 788 // at |time|.
245 // (RFC 5280 section 6.1.3 step a.2) 789 // (RFC 5280 section 6.1.3 step a.2)
246 VerifyTimeValidity(cert, time, errors); 790 VerifyTimeValidity(cert, time, errors);
247 791
248 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) 792 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3)
249 793
250 // Verify the certificate's issuer name matches the issuing certificate's 794 // Verify the certificate's issuer name matches the issuing certificate's
251 // subject name. (RFC 5280 section 6.1.3 step a.4) 795 // subject name. (RFC 5280 section 6.1.3 step a.4)
252 if (cert.normalized_issuer() != working_normalized_issuer_name) 796 if (cert.normalized_issuer() != working_normalized_issuer_name_)
253 errors->AddError(kSubjectDoesNotMatchIssuer); 797 errors->AddError(kSubjectDoesNotMatchIssuer);
254 798
255 // Name constraints (RFC 5280 section 6.1.3 step b & c) 799 // 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 800 // If certificate i is self-issued and it is not the final certificate in the
257 // path, skip this step for certificate i. 801 // path, skip this step for certificate i.
258 if (!name_constraints_list.empty() && 802 if (!name_constraints_list_.empty() &&
259 (!IsSelfIssued(cert) || is_target_cert)) { 803 (!IsSelfIssued(cert) || is_target_cert)) {
260 for (const NameConstraints* nc : name_constraints_list) { 804 for (const NameConstraints* nc : name_constraints_list_) {
261 if (!nc->IsPermittedCert(cert.normalized_subject(), 805 if (!nc->IsPermittedCert(cert.normalized_subject(),
262 cert.subject_alt_names())) { 806 cert.subject_alt_names())) {
263 errors->AddError(kNotPermittedByNameConstraints); 807 errors->AddError(kNotPermittedByNameConstraints);
264 } 808 }
265 } 809 }
266 } 810 }
267 811
268 // TODO(eroman): Steps d-f are omitted, as policy constraints are not yet 812 // RFC 5280 section 6.1.3 step d - f.
269 // implemented. 813 VerifyPolicies(cert, is_target_cert, errors);
814
815 // The key purpose is checked not just for the end-entity certificate, but
816 // also interpreted as a constraint when it appears in intermediates. This
817 // goes beyond what RFC 5280 describes, but is the de-facto standard. See
818 // https://wiki.mozilla.org/CA:CertificatePolicyV2.1#Frequently_Asked_Question s
819 VerifyExtendedKeyUsage(cert, required_key_purpose, errors);
270 } 820 }
271 821
272 // This function corresponds to RFC 5280 section 6.1.4's "Preparation for 822 void PathVerifier::PrepareForNextCertificate(const ParsedCertificate& cert,
273 // Certificate i+1" procedure. |cert| is expected to be an intermediate. 823 CertErrors* errors) {
274 void PrepareForNextCertificate( 824 // RFC 5280 section 6.1.4 step a-b
275 const ParsedCertificate& cert, 825 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 826
284 // From RFC 5280 section 6.1.4 step c: 827 // From RFC 5280 section 6.1.4 step c:
285 // 828 //
286 // Assign the certificate subject name to working_normalized_issuer_name. 829 // Assign the certificate subject name to working_normalized_issuer_name.
287 *working_normalized_issuer_name = cert.normalized_subject(); 830 working_normalized_issuer_name_ = cert.normalized_subject();
288 831
289 // From RFC 5280 section 6.1.4 step d: 832 // From RFC 5280 section 6.1.4 step d:
290 // 833 //
291 // Assign the certificate subjectPublicKey to working_public_key. 834 // Assign the certificate subjectPublicKey to working_public_key.
292 *working_spki = cert.tbs().spki_tlv; 835 working_spki_ = cert.tbs().spki_tlv;
293 836
294 // Note that steps e and f are omitted as they are handled by 837 // Note that steps e and f are omitted as they are handled by
295 // the assignment to |working_spki| above. See the definition 838 // the assignment to |working_spki| above. See the definition
296 // of |working_spki|. 839 // of |working_spki|.
297 840
298 // From RFC 5280 section 6.1.4 step g: 841 // From RFC 5280 section 6.1.4 step g:
299 if (cert.has_name_constraints()) 842 if (cert.has_name_constraints())
300 name_constraints_list->push_back(&cert.name_constraints()); 843 name_constraints_list_.push_back(&cert.name_constraints());
301 844
302 // TODO(eroman): Steps h-j are omitted as policy 845 // (h) If certificate i is not self-issued:
303 // constraints/mappings/inhibitAnyPolicy are not yet implemented. 846 if (!IsSelfIssued(cert)) {
847 // (1) If explicit_policy is not 0, decrement explicit_policy by
848 // 1.
849 if (explicit_policy_ > 0)
850 explicit_policy_ -= 1;
851
852 // (2) If policy_mapping is not 0, decrement policy_mapping by 1.
853 if (policy_mapping_ > 0)
854 policy_mapping_ -= 1;
855
856 // (3) If inhibit_anyPolicy is not 0, decrement inhibit_anyPolicy
857 // by 1.
858 if (inhibit_any_policy_ > 0)
859 inhibit_any_policy_ -= 1;
860 }
861
862 // (i) If a policy constraints extension is included in the
863 // certificate, modify the explicit_policy and policy_mapping
864 // state variables as follows:
865 if (cert.has_policy_constraints()) {
866 // (1) If requireExplicitPolicy is present and is less than
867 // explicit_policy, set explicit_policy to the value of
868 // requireExplicitPolicy.
869 if (cert.policy_constraints().has_require_explicit_policy &&
870 cert.policy_constraints().require_explicit_policy < explicit_policy_) {
871 explicit_policy_ = cert.policy_constraints().require_explicit_policy;
872 }
873
874 // (2) If inhibitPolicyMapping is present and is less than
875 // policy_mapping, set policy_mapping to the value of
876 // inhibitPolicyMapping.
877 if (cert.policy_constraints().has_inhibit_policy_mapping &&
878 cert.policy_constraints().inhibit_policy_mapping < policy_mapping_) {
879 policy_mapping_ = cert.policy_constraints().inhibit_policy_mapping;
880 }
881 }
882
883 // (j) If the inhibitAnyPolicy extension is included in the
884 // certificate and is less than inhibit_anyPolicy, set
885 // inhibit_anyPolicy to the value of inhibitAnyPolicy.
886 if (cert.has_inhibit_any_policy() &&
887 cert.inhibit_any_policy() < inhibit_any_policy_) {
888 inhibit_any_policy_ = cert.inhibit_any_policy();
889 }
304 890
305 // From RFC 5280 section 6.1.4 step k: 891 // From RFC 5280 section 6.1.4 step k:
306 // 892 //
307 // If certificate i is a version 3 certificate, verify that the 893 // If certificate i is a version 3 certificate, verify that the
308 // basicConstraints extension is present and that cA is set to 894 // basicConstraints extension is present and that cA is set to
309 // TRUE. (If certificate i is a version 1 or version 2 895 // TRUE. (If certificate i is a version 1 or version 2
310 // certificate, then the application MUST either verify that 896 // certificate, then the application MUST either verify that
311 // certificate i is a CA certificate through out-of-band means 897 // certificate i is a CA certificate through out-of-band means
312 // or reject the certificate. Conforming implementations may 898 // or reject the certificate. Conforming implementations may
313 // choose to reject all version 1 and version 2 intermediate 899 // choose to reject all version 1 and version 2 intermediate
314 // certificates.) 900 // certificates.)
315 // 901 //
316 // This code implicitly rejects non version 3 intermediates, since they 902 // This code implicitly rejects non version 3 intermediates, since they
317 // can't contain a BasicConstraints extension. 903 // can't contain a BasicConstraints extension.
318 if (!cert.has_basic_constraints()) { 904 if (!cert.has_basic_constraints()) {
319 errors->AddError(kMissingBasicConstraints); 905 errors->AddError(kMissingBasicConstraints);
320 } else if (!cert.basic_constraints().is_ca) { 906 } else if (!cert.basic_constraints().is_ca) {
321 errors->AddError(kBasicConstraintsIndicatesNotCa); 907 errors->AddError(kBasicConstraintsIndicatesNotCa);
322 } 908 }
323 909
324 // From RFC 5280 section 6.1.4 step l: 910 // From RFC 5280 section 6.1.4 step l:
325 // 911 //
326 // If the certificate was not self-issued, verify that 912 // If the certificate was not self-issued, verify that
327 // max_path_length is greater than zero and decrement 913 // max_path_length is greater than zero and decrement
328 // max_path_length by 1. 914 // max_path_length by 1.
329 if (!IsSelfIssued(cert)) { 915 if (!IsSelfIssued(cert)) {
330 if (*max_path_length_ptr == 0) { 916 if (max_path_length_ == 0) {
331 errors->AddError(kMaxPathLengthViolated); 917 errors->AddError(kMaxPathLengthViolated);
332 } else { 918 } else {
333 --(*max_path_length_ptr); 919 --max_path_length_;
334 } 920 }
335 } 921 }
336 922
337 // From RFC 5280 section 6.1.4 step m: 923 // From RFC 5280 section 6.1.4 step m:
338 // 924 //
339 // If pathLenConstraint is present in the certificate and is 925 // If pathLenConstraint is present in the certificate and is
340 // less than max_path_length, set max_path_length to the value 926 // less than max_path_length, set max_path_length to the value
341 // of pathLenConstraint. 927 // of pathLenConstraint.
342 if (cert.has_basic_constraints() && cert.basic_constraints().has_path_len && 928 if (cert.has_basic_constraints() && cert.basic_constraints().has_path_len &&
343 cert.basic_constraints().path_len < *max_path_length_ptr) { 929 cert.basic_constraints().path_len < max_path_length_) {
344 *max_path_length_ptr = cert.basic_constraints().path_len; 930 max_path_length_ = cert.basic_constraints().path_len;
345 } 931 }
346 932
347 // From RFC 5280 section 6.1.4 step n: 933 // From RFC 5280 section 6.1.4 step n:
348 // 934 //
349 // If a key usage extension is present, verify that the 935 // If a key usage extension is present, verify that the
350 // keyCertSign bit is set. 936 // keyCertSign bit is set.
351 if (cert.has_key_usage() && 937 if (cert.has_key_usage() &&
352 !cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)) { 938 !cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)) {
353 errors->AddError(kKeyCertSignBitNotSet); 939 errors->AddError(kKeyCertSignBitNotSet);
354 } 940 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 cert.basic_constraints().is_ca && 987 cert.basic_constraints().is_ca &&
402 (!cert.has_key_usage() || 988 (!cert.has_key_usage() ||
403 cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN)); 989 cert.key_usage().AssertsBit(KEY_USAGE_BIT_KEY_CERT_SIGN));
404 if (!success) { 990 if (!success) {
405 // TODO(eroman): Add DER for basic constraints and key usage. 991 // TODO(eroman): Add DER for basic constraints and key usage.
406 errors->AddError(kTargetCertInconsistentCaBits); 992 errors->AddError(kTargetCertInconsistentCaBits);
407 } 993 }
408 } 994 }
409 } 995 }
410 996
411 // This function corresponds with RFC 5280 section 6.1.5's "Wrap-Up Procedure". 997 void PathVerifier::WrapUp(const ParsedCertificate& cert, CertErrors* errors) {
412 // It does processing for the final certificate (the target cert). 998 // From RFC 5280 section 6.1.5:
413 void WrapUp(const ParsedCertificate& cert, CertErrors* errors) { 999 // (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 1000 if (explicit_policy_ > 0)
415 // yet implemented. 1001 explicit_policy_ -= 1;
416 1002
417 // Note step c-e are omitted the verification function does 1003 // (b) If a policy constraints extension is included in the
1004 // certificate and requireExplicitPolicy is present and has a
1005 // value of 0, set the explicit_policy state variable to 0.
1006 if (cert.has_policy_constraints() &&
1007 cert.policy_constraints().has_require_explicit_policy &&
1008 cert.policy_constraints().require_explicit_policy == 0) {
1009 explicit_policy_ = 0;
1010 }
1011
1012 // Note step c-e are omitted as the verification function does
418 // not output the working public key. 1013 // not output the working public key.
419 1014
420 // From RFC 5280 section 6.1.5 step f: 1015 // From RFC 5280 section 6.1.5 step f:
421 // 1016 //
422 // Recognize and process any other critical extension present in 1017 // Recognize and process any other critical extension present in
423 // the certificate n. Process any other recognized non-critical 1018 // the certificate n. Process any other recognized non-critical
424 // extension present in certificate n that is relevant to path 1019 // extension present in certificate n that is relevant to path
425 // processing. 1020 // processing.
426 // 1021 //
427 // Note that this is duplicated by PrepareForNextCertificate() so as to 1022 // Note that this is duplicated by PrepareForNextCertificate() so as to
428 // directly match the procedures in RFC 5280's section 6.1. 1023 // directly match the procedures in RFC 5280's section 6.1.
429 VerifyNoUnconsumedCriticalExtensions(cert, errors); 1024 VerifyNoUnconsumedCriticalExtensions(cert, errors);
430 1025
431 // TODO(eroman): Step g is omitted, as policy constraints are not yet 1026 // RFC 5280 section 6.1.5 step g is skipped, as the intersection of valid
432 // implemented. 1027 // policies was computed during previous steps.
1028 //
1029 // If either (1) the value of explicit_policy variable is greater than
1030 // zero or (2) the valid_policy_tree is not NULL, then path processing
1031 // has succeeded.
1032 if (!(explicit_policy_ > 0 || !valid_policy_tree_.IsNull())) {
1033 errors->AddError(kNoValidPolicy);
1034 }
433 1035
434 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure", 1036 // 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. 1037 // however is implied by RFC 5280 section 4.2.1.9.
436 VerifyTargetCertHasConsistentCaBits(cert, errors); 1038 VerifyTargetCertHasConsistentCaBits(cert, errors);
437 } 1039 }
438 1040
439 // Enforces trust anchor constraints compatibile with RFC 5937. 1041 void PathVerifier::ApplyTrustAnchorConstraints(const ParsedCertificate& cert,
440 // 1042 KeyPurpose required_key_purpose,
441 // Note that the anchor constraints are encoded via the attached certificate 1043 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 1044 // 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). 1045 // done for intermediates (described in Web PKI's Baseline Requirements).
451 VerifyExtendedKeyUsage(cert, required_key_purpose, errors); 1046 VerifyExtendedKeyUsage(cert, required_key_purpose, errors);
452 1047
453 // The following enforcements follow from RFC 5937 (primarily section 3.2): 1048 // The following enforcements follow from RFC 5937 (primarily section 3.2):
454 1049
455 // Initialize name constraints initial-permitted/excluded-subtrees. 1050 // Initialize name constraints initial-permitted/excluded-subtrees.
456 if (cert.has_name_constraints()) 1051 if (cert.has_name_constraints())
457 name_constraints_list->push_back(&cert.name_constraints()); 1052 name_constraints_list_.push_back(&cert.name_constraints());
458 1053
459 // TODO(eroman): Initialize user-initial-policy-set based on anchor 1054 // TODO(eroman): Initialize user-initial-policy-set based on anchor
460 // constraints. 1055 // constraints.
461 1056
462 // TODO(eroman): Initialize inhibit any policy based on anchor constraints. 1057 // TODO(eroman): Initialize inhibit any policy based on anchor constraints.
463 1058
464 // TODO(eroman): Initialize require explicit policy based on anchor 1059 // TODO(eroman): Initialize require explicit policy based on anchor
465 // constraints. 1060 // constraints.
466 1061
467 // TODO(eroman): Initialize inhibit policy mapping based on anchor 1062 // TODO(eroman): Initialize inhibit policy mapping based on anchor
468 // constraints. 1063 // constraints.
469 1064
470 // From RFC 5937 section 3.2: 1065 // From RFC 5937 section 3.2:
471 // 1066 //
472 // If a basic constraints extension is associated with the trust 1067 // If a basic constraints extension is associated with the trust
473 // anchor and contains a pathLenConstraint value, set the 1068 // anchor and contains a pathLenConstraint value, set the
474 // max_path_length state variable equal to the pathLenConstraint 1069 // max_path_length state variable equal to the pathLenConstraint
475 // value from the basic constraints extension. 1070 // value from the basic constraints extension.
476 // 1071 //
477 // NOTE: RFC 5937 does not say to enforce the CA=true part of basic 1072 // NOTE: RFC 5937 does not say to enforce the CA=true part of basic
478 // constraints. 1073 // constraints.
479 if (cert.has_basic_constraints() && cert.basic_constraints().has_path_len) 1074 if (cert.has_basic_constraints() && cert.basic_constraints().has_path_len)
480 *max_path_length_ptr = cert.basic_constraints().path_len; 1075 max_path_length_ = cert.basic_constraints().path_len;
481 1076
482 // From RFC 5937 section 2: 1077 // From RFC 5937 section 2:
483 // 1078 //
484 // Extensions may be marked critical or not critical. When trust anchor 1079 // Extensions may be marked critical or not critical. When trust anchor
485 // constraints are enforced, clients MUST reject certification paths 1080 // constraints are enforced, clients MUST reject certification paths
486 // containing a trust anchor with unrecognized critical extensions. 1081 // containing a trust anchor with unrecognized critical extensions.
487 VerifyNoUnconsumedCriticalExtensions(cert, errors); 1082 VerifyNoUnconsumedCriticalExtensions(cert, errors);
488 } 1083 }
489 1084
490 // Initializes the path validation algorithm given anchor constraints. This 1085 void PathVerifier::ProcessRootCertificate(const ParsedCertificate& cert,
491 // follows the description in RFC 5937 1086 const CertificateTrust& trust,
492 void ProcessRootCertificate( 1087 KeyPurpose required_key_purpose,
493 const ParsedCertificate& cert, 1088 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. 1089 // 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 1090 // Note this is initialized even in the case of untrusted roots (they already
503 // emit an error for the distrust). 1091 // emit an error for the distrust).
504 *working_spki = cert.tbs().spki_tlv; 1092 working_spki_ = cert.tbs().spki_tlv;
505 *working_normalized_issuer_name = cert.normalized_subject(); 1093 working_normalized_issuer_name_ = cert.normalized_subject();
506 1094
507 switch (trust.type) { 1095 switch (trust.type) {
508 case CertificateTrustType::UNSPECIFIED: 1096 case CertificateTrustType::UNSPECIFIED:
509 // Doesn't chain to a trust anchor - implicitly distrusted 1097 // Doesn't chain to a trust anchor - implicitly distrusted
510 errors->AddError(kCertIsNotTrustAnchor); 1098 errors->AddError(kCertIsNotTrustAnchor);
511 break; 1099 break;
512 case CertificateTrustType::DISTRUSTED: 1100 case CertificateTrustType::DISTRUSTED:
513 // Chains to an actively distrusted certificate. 1101 // Chains to an actively distrusted certificate.
514 errors->AddError(kCertIsDistrusted); 1102 errors->AddError(kCertIsDistrusted);
515 break; 1103 break;
516 case CertificateTrustType::TRUSTED_ANCHOR: 1104 case CertificateTrustType::TRUSTED_ANCHOR:
517 case CertificateTrustType::TRUSTED_ANCHOR_WITH_CONSTRAINTS: 1105 case CertificateTrustType::TRUSTED_ANCHOR_WITH_CONSTRAINTS:
518 // If the trust anchor has constraints, enforce them. 1106 // If the trust anchor has constraints, enforce them.
519 if (trust.type == CertificateTrustType::TRUSTED_ANCHOR_WITH_CONSTRAINTS) { 1107 if (trust.type == CertificateTrustType::TRUSTED_ANCHOR_WITH_CONSTRAINTS) {
520 ApplyTrustAnchorConstraints(cert, required_key_purpose, 1108 ApplyTrustAnchorConstraints(cert, required_key_purpose, errors);
521 max_path_length_ptr, name_constraints_list,
522 errors);
523 } 1109 }
524 break; 1110 break;
525 } 1111 }
526 } 1112 }
527 1113
528 } // namespace 1114 void PathVerifier::Run(
529 1115 const ParsedCertificateList& certs,
530 // This implementation is structured to mimic the description of certificate 1116 const CertificateTrust& last_cert_trust,
531 // path verification given by RFC 5280 section 6.1. 1117 const SignaturePolicy* signature_policy,
532 void VerifyCertificateChain(const ParsedCertificateList& certs, 1118 const der::GeneralizedTime& time,
533 const CertificateTrust& last_cert_trust, 1119 KeyPurpose required_key_purpose,
534 const SignaturePolicy* signature_policy, 1120 InitialExplicitPolicy initial_explicit_policy,
535 const der::GeneralizedTime& time, 1121 const std::set<der::Input>& user_initial_policy_set,
536 KeyPurpose required_key_purpose, 1122 InitialPolicyMappingInhibit initial_policy_mapping_inhibit,
537 CertPathErrors* errors) { 1123 InitialAnyPolicyInhibit initial_any_policy_inhibit,
1124 std::set<der::Input>* user_constrained_policy_set,
1125 CertPathErrors* errors) {
1126 // This implementation is structured to mimic the description of certificate
1127 // path verification given by RFC 5280 section 6.1.
538 DCHECK(signature_policy); 1128 DCHECK(signature_policy);
539 DCHECK(errors); 1129 DCHECK(errors);
540 1130
541 // An empty chain is necessarily invalid. 1131 // An empty chain is necessarily invalid.
542 if (certs.empty()) { 1132 if (certs.empty()) {
543 errors->GetOtherErrors()->AddError(kChainIsEmpty); 1133 errors->GetOtherErrors()->AddError(kChainIsEmpty);
544 return; 1134 return;
545 } 1135 }
546 1136
547 // TODO(eroman): Verifying a trusted leaf certificate is not currently 1137 // TODO(eroman): Verifying a trusted leaf certificate is not currently
548 // permitted. 1138 // permitted.
549 if (certs.size() == 1) { 1139 if (certs.size() == 1) {
550 errors->GetOtherErrors()->AddError(kChainIsLength1); 1140 errors->GetOtherErrors()->AddError(kChainIsLength1);
551 return; 1141 return;
552 } 1142 }
553 1143
554 // Will contain a NameConstraints for each previous cert in the chain which 1144 // 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 1145 // the trust anchor. (Although in practice it doesn't really change behaviors
556 // excluded_subtrees state variables from RFC 5280. 1146 // if n is used in place of n+1).
557 std::vector<const NameConstraints*> name_constraints_list; 1147 const size_t n = certs.size() - 1;
558 1148
559 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: 1149 valid_policy_tree_.Init(user_initial_policy_set);
560 // * working_public_key 1150
561 // * working_public_key_algorithm 1151 // RFC 5280 section section 6.1.2:
562 // * working_public_key_parameters
563 // 1152 //
564 // They are combined for simplicity since the signature verification takes an 1153 // If initial-explicit-policy is set, then the initial value
565 // SPKI, and the parameter inheritence is not applicable for the supported 1154 // [of explicit_policy] is 0, otherwise the initial value is n+1.
566 // key types. 1155 explicit_policy_ =
1156 initial_explicit_policy == InitialExplicitPolicy::kTrue ? 0 : n + 1;
1157
1158 // RFC 5280 section section 6.1.2:
567 // 1159 //
568 // An approximate explanation of |working_spki| is this description from RFC 1160 // If initial-any-policy-inhibit is set, then the initial value
569 // 5280 section 6.1.2: 1161 // [of inhibit_anyPolicy] is 0, otherwise the initial value is n+1.
1162 inhibit_any_policy_ =
1163 initial_any_policy_inhibit == InitialAnyPolicyInhibit::kTrue ? 0 : n + 1;
1164
1165 // RFC 5280 section section 6.1.2:
570 // 1166 //
571 // working_public_key: the public key used to verify the 1167 // If initial-policy-mapping-inhibit is set, then the initial value
572 // signature of a certificate. 1168 // [of policy_mapping] is 0, otherwise the initial value is n+1.
573 der::Input working_spki; 1169 policy_mapping_ =
1170 initial_policy_mapping_inhibit == InitialPolicyMappingInhibit::kTrue
1171 ? 0
1172 : n + 1;
574 1173
575 // |working_normalized_issuer_name| is the normalized value of the 1174 // RFC 5280 section section 6.1.2:
576 // working_issuer_name variable in RFC 5280 section 6.1.2:
577 // 1175 //
578 // working_issuer_name: the issuer distinguished name expected 1176 // max_path_length: this integer is initialized to n, ...
579 // in the next certificate in the chain. 1177 max_path_length_ = n;
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 1178
592 // Iterate over all the certificates in the reverse direction: starting from 1179 // Iterate over all the certificates in the reverse direction: starting from
593 // the root certificate and progressing towards the target certificate. 1180 // the root certificate and progressing towards the target certificate.
594 // 1181 //
595 // * i=0 : Root certificate (i.e. trust anchor) 1182 // * i=0 : Root certificate (i.e. trust anchor)
596 // * i=1 : Certificated signed by the root certificate 1183 // * i=1 : Certificate issued by root
597 // * i=certs.size()-1 : Target certificate. 1184 // * i=x : Certificate i=x is issued by certificate i=x-1
1185 // * i=n : Target certificate.
598 for (size_t i = 0; i < certs.size(); ++i) { 1186 for (size_t i = 0; i < certs.size(); ++i) {
599 const size_t index_into_certs = certs.size() - i - 1; 1187 const size_t index_into_certs = certs.size() - i - 1;
600 1188
601 // |is_target_cert| is true if the current certificate is the target 1189 // |is_target_cert| is true if the current certificate is the target
602 // certificate being verified. The target certificate isn't necessarily an 1190 // certificate being verified. The target certificate isn't necessarily an
603 // end-entity certificate. 1191 // end-entity certificate.
604 const bool is_target_cert = index_into_certs == 0; 1192 const bool is_target_cert = index_into_certs == 0;
605 const bool is_root_cert = i == 0; 1193 const bool is_root_cert = i == 0;
606 1194
607 const ParsedCertificate& cert = *certs[index_into_certs]; 1195 const ParsedCertificate& cert = *certs[index_into_certs];
608 1196
609 // Output errors for the current certificate into an error bucket that is 1197 // Output errors for the current certificate into an error bucket that is
610 // associated with that certificate. 1198 // associated with that certificate.
611 CertErrors* cert_errors = errors->GetErrorsForCert(index_into_certs); 1199 CertErrors* cert_errors = errors->GetErrorsForCert(index_into_certs);
612 1200
613 if (is_root_cert) { 1201 if (is_root_cert) {
614 ProcessRootCertificate(cert, last_cert_trust, required_key_purpose, 1202 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); 1203 cert_errors);
618 1204
619 // Don't do any other checks for root certificates. 1205 // Don't do any other checks for root certificates.
620 continue; 1206 continue;
621 } 1207 }
622 1208
623 // Per RFC 5280 section 6.1: 1209 // Per RFC 5280 section 6.1:
624 // * Do basic processing for each certificate 1210 // * Do basic processing for each certificate
625 // * If it is the last certificate in the path (target certificate) 1211 // * If it is the last certificate in the path (target certificate)
626 // - Then run "Wrap up" 1212 // - Then run "Wrap up"
627 // - Otherwise run "Prepare for Next cert" 1213 // - Otherwise run "Prepare for Next cert"
628 BasicCertificateProcessing(cert, is_target_cert, signature_policy, time, 1214 BasicCertificateProcessing(cert, is_target_cert, signature_policy, time,
629 working_spki, working_normalized_issuer_name, 1215 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) { 1216 if (!is_target_cert) {
639 PrepareForNextCertificate(cert, &max_path_length, &working_spki, 1217 PrepareForNextCertificate(cert, cert_errors);
640 &working_normalized_issuer_name,
641 &name_constraints_list, cert_errors);
642 } else { 1218 } else {
643 WrapUp(cert, cert_errors); 1219 WrapUp(cert, cert_errors);
644 } 1220 }
645 } 1221 }
646 1222
1223 if (user_constrained_policy_set) {
1224 // valid_policy_tree_ already contains the intersection of valid policies
1225 // with user_initial_policy_set.
1226 valid_policy_tree_.GetValidRootPolicySet(user_constrained_policy_set);
1227 }
1228
647 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: 1229 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1:
648 // 1230 //
649 // A certificate MUST NOT appear more than once in a prospective 1231 // A certificate MUST NOT appear more than once in a prospective
650 // certification path. 1232 // certification path.
651 } 1233 }
652 1234
1235 } // namespace
1236
1237 void VerifyCertificateChain(
1238 const ParsedCertificateList& certs,
1239 const CertificateTrust& last_cert_trust,
1240 const SignaturePolicy* signature_policy,
1241 const der::GeneralizedTime& time,
1242 KeyPurpose required_key_purpose,
1243 InitialExplicitPolicy initial_explicit_policy,
1244 const std::set<der::Input>& user_initial_policy_set,
1245 InitialPolicyMappingInhibit initial_policy_mapping_inhibit,
1246 InitialAnyPolicyInhibit initial_any_policy_inhibit,
1247 std::set<der::Input>* user_constrained_policy_set,
1248 CertPathErrors* errors) {
1249 PathVerifier verifier;
1250 verifier.Run(certs, last_cert_trust, signature_policy, time,
1251 required_key_purpose, initial_explicit_policy,
1252 user_initial_policy_set, initial_policy_mapping_inhibit,
1253 initial_any_policy_inhibit, user_constrained_policy_set, errors);
1254 }
1255
653 } // namespace net 1256 } // namespace net
OLDNEW
« no previous file with comments | « net/cert/internal/verify_certificate_chain.h ('k') | net/cert/internal/verify_certificate_chain_pkits_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698