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

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

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

Powered by Google App Engine
This is Rietveld 408576698