OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/cert/internal/verify_certificate_chain.h" | 5 #include "net/cert/internal/verify_certificate_chain.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "net/cert/internal/name_constraints.h" | 10 #include "net/cert/internal/name_constraints.h" |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 // to the rules specified in Section 7.1). In general, the issuer and | 191 // to the rules specified in Section 7.1). In general, the issuer and |
192 // subject of the certificates that make up a path are different for | 192 // subject of the certificates that make up a path are different for |
193 // each certificate. However, a CA may issue a certificate to itself to | 193 // each certificate. However, a CA may issue a certificate to itself to |
194 // support key rollover or changes in certificate policies. These | 194 // support key rollover or changes in certificate policies. These |
195 // self-issued certificates are not counted when evaluating path length | 195 // self-issued certificates are not counted when evaluating path length |
196 // or name constraints. | 196 // or name constraints. |
197 WARN_UNUSED_RESULT bool IsSelfIssued(const FullyParsedCert& cert) { | 197 WARN_UNUSED_RESULT bool IsSelfIssued(const FullyParsedCert& cert) { |
198 return NameMatches(cert.tbs.subject_tlv, cert.tbs.issuer_tlv); | 198 return NameMatches(cert.tbs.subject_tlv, cert.tbs.issuer_tlv); |
199 } | 199 } |
200 | 200 |
201 // Finds a trust anchor that matches |name| in |trust_store| or returns | |
202 // nullptr. The returned pointer references data in |trust_store|. | |
203 // | |
204 // TODO(eroman): This implementation is linear in the size of the trust store, | |
205 // and also presumes that all names are unique. In practice it is possible to | |
206 // have multiple SPKIs with the same name. Also this mechanism of | |
207 // searching is fairly primitive, and does not take advantage of other | |
208 // properties like the authority key id. | |
209 WARN_UNUSED_RESULT const TrustAnchor* FindTrustAnchorByName( | |
210 const TrustStore& trust_store, | |
211 const der::Input& name) { | |
212 for (const auto& anchor : trust_store.anchors) { | |
213 if (NameMatches(name, der::Input(&anchor.name))) | |
214 return &anchor; | |
215 } | |
216 return nullptr; | |
217 } | |
218 | |
219 // Returns true if |cert| is valid at time |time|. | 201 // Returns true if |cert| is valid at time |time|. |
220 // | 202 // |
221 // The certificate's validity requirements are described by RFC 5280 section | 203 // The certificate's validity requirements are described by RFC 5280 section |
222 // 4.1.2.5: | 204 // 4.1.2.5: |
223 // | 205 // |
224 // The validity period for a certificate is the period of time from | 206 // The validity period for a certificate is the period of time from |
225 // notBefore through notAfter, inclusive. | 207 // notBefore through notAfter, inclusive. |
226 WARN_UNUSED_RESULT bool VerifyTimeValidity(const FullyParsedCert& cert, | 208 WARN_UNUSED_RESULT bool VerifyTimeValidity(const FullyParsedCert& cert, |
227 const der::GeneralizedTime time) { | 209 const der::GeneralizedTime time) { |
228 return !(time < cert.tbs.validity_not_before) && | 210 return !(time < cert.tbs.validity_not_before) && |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 const der::Input& alg2_tlv = cert.tbs.signature_algorithm_tlv; | 248 const der::Input& alg2_tlv = cert.tbs.signature_algorithm_tlv; |
267 | 249 |
268 // Ensure that the two DER-encoded signature algorithms are byte-for-byte | 250 // Ensure that the two DER-encoded signature algorithms are byte-for-byte |
269 // equal, but make a compatibility concession for RSA with SHA1. | 251 // equal, but make a compatibility concession for RSA with SHA1. |
270 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && | 252 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && |
271 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)); | 253 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)); |
272 } | 254 } |
273 | 255 |
274 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate | 256 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate |
275 // Processing" procedure. | 257 // Processing" procedure. |
| 258 // |
| 259 // |skip_issuer_checks| controls whether the function will skip: |
| 260 // - Checking that |cert|'s signature using |working_spki| |
| 261 // - Checkinging that |cert|'s issuer matches |working_issuer_name| |
| 262 // This should be set to true only when verifying a trusted root certificate. |
276 WARN_UNUSED_RESULT bool BasicCertificateProcessing( | 263 WARN_UNUSED_RESULT bool BasicCertificateProcessing( |
277 const FullyParsedCert& cert, | 264 const FullyParsedCert& cert, |
278 bool is_target_cert, | 265 bool is_target_cert, |
| 266 bool skip_issuer_checks, |
279 const SignaturePolicy* signature_policy, | 267 const SignaturePolicy* signature_policy, |
280 const der::GeneralizedTime& time, | 268 const der::GeneralizedTime& time, |
281 const der::Input& working_spki, | 269 const der::Input& working_spki, |
282 const der::Input& working_issuer_name, | 270 const der::Input& working_issuer_name, |
283 const std::vector<std::unique_ptr<NameConstraints>>& | 271 const std::vector<std::unique_ptr<NameConstraints>>& |
284 name_constraints_list) { | 272 name_constraints_list) { |
285 // Check that the signature algorithms in Certificate vs TBSCertificate | 273 // Check that the signature algorithms in Certificate vs TBSCertificate |
286 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by | 274 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by |
287 // sections 4.1.1.2 and 4.1.2.3. | 275 // sections 4.1.1.2 and 4.1.2.3. |
288 if (!VerifySignatureAlgorithmsMatch(cert)) | 276 if (!VerifySignatureAlgorithmsMatch(cert)) |
289 return false; | 277 return false; |
290 | 278 |
291 // Verify the digital signature using the previous certificate's (or trust | 279 // Verify the digital signature using the previous certificate's key (RFC |
292 // anchor's) key (RFC 5280 section 6.1.3 step a.1). | 280 // 5280 section 6.1.3 step a.1). |
293 if (!VerifySignedData( | 281 if (!skip_issuer_checks) { |
294 *cert.signature_algorithm, cert.cert.tbs_certificate_tlv, | 282 if (!VerifySignedData( |
295 cert.cert.signature_value, working_spki, signature_policy)) { | 283 *cert.signature_algorithm, cert.cert.tbs_certificate_tlv, |
296 return false; | 284 cert.cert.signature_value, working_spki, signature_policy)) { |
| 285 return false; |
| 286 } |
297 } | 287 } |
298 | 288 |
299 // Check the time range for the certificate's validity, ensuring it is valid | 289 // Check the time range for the certificate's validity, ensuring it is valid |
300 // at |time|. | 290 // at |time|. |
301 // (RFC 5280 section 6.1.3 step a.2) | 291 // (RFC 5280 section 6.1.3 step a.2) |
302 if (!VerifyTimeValidity(cert, time)) | 292 if (!VerifyTimeValidity(cert, time)) |
303 return false; | 293 return false; |
304 | 294 |
305 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) | 295 // TODO(eroman): Check revocation (RFC 5280 section 6.1.3 step a.3) |
306 | 296 |
307 // Verify the certificate's issuer name matches the issuing certificate's (or | 297 // Verify the certificate's issuer name matches the issuing certificate's |
308 // trust anchor's) subject name. (RFC 5280 section 6.1.3 step a.4) | 298 // subject name. (RFC 5280 section 6.1.3 step a.4) |
309 if (!NameMatches(cert.tbs.issuer_tlv, working_issuer_name)) | 299 if (!skip_issuer_checks) { |
310 return false; | 300 if (!NameMatches(cert.tbs.issuer_tlv, working_issuer_name)) |
| 301 return false; |
| 302 } |
311 | 303 |
312 // Name constraints (RFC 5280 section 6.1.3 step b & c) | 304 // Name constraints (RFC 5280 section 6.1.3 step b & c) |
313 // If certificate i is self-issued and it is not the final certificate in the | 305 // If certificate i is self-issued and it is not the final certificate in the |
314 // path, skip this step for certificate i. | 306 // path, skip this step for certificate i. |
315 if (!name_constraints_list.empty() && | 307 if (!name_constraints_list.empty() && |
316 (!IsSelfIssued(cert) || is_target_cert)) { | 308 (!IsSelfIssued(cert) || is_target_cert)) { |
317 der::Input subject_value; | 309 der::Input subject_value; |
318 if (!GetSequenceValue(cert.tbs.subject_tlv, &subject_value)) | 310 if (!GetSequenceValue(cert.tbs.subject_tlv, &subject_value)) |
319 return false; | 311 return false; |
320 for (const auto& nc : name_constraints_list) { | 312 for (const auto& nc : name_constraints_list) { |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure", | 487 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure", |
496 // however is implied by RFC 5280 section 4.2.1.9. | 488 // however is implied by RFC 5280 section 4.2.1.9. |
497 if (!VerifyTargetCertHasConsistentCaBits(cert)) | 489 if (!VerifyTargetCertHasConsistentCaBits(cert)) |
498 return false; | 490 return false; |
499 | 491 |
500 return true; | 492 return true; |
501 } | 493 } |
502 | 494 |
503 } // namespace | 495 } // namespace |
504 | 496 |
| 497 TrustAnchor::TrustAnchor() {} |
505 TrustAnchor::~TrustAnchor() {} | 498 TrustAnchor::~TrustAnchor() {} |
506 | 499 |
| 500 std::unique_ptr<TrustAnchor> TrustAnchor::CreateFromCertificateData( |
| 501 const uint8_t* data, |
| 502 size_t length, |
| 503 DataSource source) { |
| 504 std::unique_ptr<TrustAnchor> result(new TrustAnchor); |
| 505 |
| 506 switch (source) { |
| 507 case DataSource::INTERNAL_COPY: |
| 508 result->cert_data_.assign(data, data + length); |
| 509 result->cert_ = |
| 510 der::Input(result->cert_data_.data(), result->cert_data_.size()); |
| 511 break; |
| 512 case DataSource::EXTERNAL_REFERENCE: |
| 513 result->cert_ = der::Input(data, length); |
| 514 break; |
| 515 } |
| 516 |
| 517 // Parse the certificate to get its name. |
| 518 ParsedCertificate cert; |
| 519 if (!ParseCertificate(result->cert(), &cert)) |
| 520 return nullptr; |
| 521 |
| 522 ParsedTbsCertificate tbs; |
| 523 if (!ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) |
| 524 return nullptr; |
| 525 |
| 526 result->name_ = tbs.subject_tlv; |
| 527 |
| 528 // TODO(eroman): If adding a self-signed certificate, check that its |
| 529 // signature is correct? This check will not otherwise be done during |
| 530 // verification. |
| 531 |
| 532 return result; |
| 533 } |
| 534 |
| 535 bool TrustAnchor::MatchesName(const der::Input& name) const { |
| 536 return NameMatches(name, name_); |
| 537 } |
| 538 |
507 TrustStore::TrustStore() {} | 539 TrustStore::TrustStore() {} |
508 TrustStore::TrustStore(const TrustStore& other) = default; | |
509 TrustStore::~TrustStore() {} | 540 TrustStore::~TrustStore() {} |
510 | 541 |
| 542 void TrustStore::Clear() { |
| 543 anchors_.clear(); |
| 544 } |
| 545 |
| 546 bool TrustStore::AddTrustedCertificate(const uint8_t* data, size_t length) { |
| 547 return AddTrustedCertificate(data, length, |
| 548 TrustAnchor::DataSource::INTERNAL_COPY); |
| 549 } |
| 550 |
| 551 bool TrustStore::AddTrustedCertificate(const base::StringPiece& data) { |
| 552 return AddTrustedCertificate(reinterpret_cast<const uint8_t*>(data.data()), |
| 553 data.size()); |
| 554 } |
| 555 |
| 556 bool TrustStore::AddTrustedCertificateWithoutCopying(const uint8_t* data, |
| 557 size_t length) { |
| 558 return AddTrustedCertificate(data, length, |
| 559 TrustAnchor::DataSource::EXTERNAL_REFERENCE); |
| 560 } |
| 561 |
| 562 const TrustAnchor* TrustStore::FindTrustAnchorByName( |
| 563 const der::Input& name) const { |
| 564 for (const auto& anchor : anchors_) { |
| 565 if (anchor->MatchesName(name)) { |
| 566 return anchor.get(); |
| 567 } |
| 568 } |
| 569 return nullptr; |
| 570 } |
| 571 |
| 572 bool TrustStore::IsTrustedCertificate(const der::Input& cert_der) const { |
| 573 for (const auto& anchor : anchors_) { |
| 574 if (anchor->cert() == cert_der) |
| 575 return true; |
| 576 } |
| 577 return false; |
| 578 } |
| 579 |
| 580 bool TrustStore::AddTrustedCertificate(const uint8_t* data, |
| 581 size_t length, |
| 582 TrustAnchor::DataSource source) { |
| 583 auto anchor = TrustAnchor::CreateFromCertificateData(data, length, source); |
| 584 if (!anchor) |
| 585 return false; |
| 586 anchors_.push_back(std::move(anchor)); |
| 587 return true; |
| 588 } |
| 589 |
| 590 // TODO(eroman): Move this into existing anonymous namespace. |
| 591 namespace { |
| 592 |
511 // This implementation is structured to mimic the description of certificate | 593 // This implementation is structured to mimic the description of certificate |
512 // path verification given by RFC 5280 section 6.1. | 594 // path verification given by RFC 5280 section 6.1. |
513 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der, | 595 // |
514 const TrustStore& trust_store, | 596 // Unlike RFC 5280, the trust anchor is specified as the root certificate in |
515 const SignaturePolicy* signature_policy, | 597 // the chain. This root certificate is assumed to be trusted, and neither its |
516 const der::GeneralizedTime& time) { | 598 // signature nor issuer name are verified. (It needn't be self-signed). |
| 599 bool VerifyCertificateChainAssumingTrustedRoot( |
| 600 const std::vector<der::Input>& certs_der, |
| 601 // The trust store is only used for assertions. |
| 602 const TrustStore& trust_store, |
| 603 const SignaturePolicy* signature_policy, |
| 604 const der::GeneralizedTime& time) { |
517 // An empty chain is necessarily invalid. | 605 // An empty chain is necessarily invalid. |
518 if (certs_der.empty()) | 606 if (certs_der.empty()) |
519 return false; | 607 return false; |
520 | 608 |
| 609 // IMPORTANT: the assumption being made is that the root certificate in |
| 610 // the given path is the trust anchor (and has already been verified as |
| 611 // such). |
| 612 DCHECK(trust_store.IsTrustedCertificate(certs_der.back())); |
| 613 |
521 // Will contain a NameConstraints for each previous cert in the chain which | 614 // Will contain a NameConstraints for each previous cert in the chain which |
522 // had nameConstraints. This corresponds to the permitted_subtrees and | 615 // had nameConstraints. This corresponds to the permitted_subtrees and |
523 // excluded_subtrees state variables from RFC 5280. | 616 // excluded_subtrees state variables from RFC 5280. |
524 std::vector<std::unique_ptr<NameConstraints>> name_constraints_list; | 617 std::vector<std::unique_ptr<NameConstraints>> name_constraints_list; |
525 | 618 |
526 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: | 619 // |working_spki| is an amalgamation of 3 separate variables from RFC 5280: |
527 // * working_public_key | 620 // * working_public_key |
528 // * working_public_key_algorithm | 621 // * working_public_key_algorithm |
529 // * working_public_key_parameters | 622 // * working_public_key_parameters |
530 // | 623 // |
531 // They are combined for simplicity since the signature verification takes an | 624 // They are combined for simplicity since the signature verification takes an |
532 // SPKI, and the parameter inheritence is not applicable for the supported | 625 // SPKI, and the parameter inheritence is not applicable for the supported |
533 // key types. | 626 // key types. |
534 // | 627 // |
535 // An approximate explanation of |working_spki| is this description from RFC | 628 // An approximate explanation of |working_spki| is this description from RFC |
536 // 5280 section 6.1.2: | 629 // 5280 section 6.1.2: |
537 // | 630 // |
538 // working_public_key: the public key used to verify the | 631 // working_public_key: the public key used to verify the |
539 // signature of a certificate. The working_public_key is | 632 // signature of a certificate. |
540 // initialized from the trusted public key provided in the trust | |
541 // anchor information. | |
542 der::Input working_spki; | 633 der::Input working_spki; |
543 | 634 |
544 // |working_issuer_name| corresponds with the same named variable in RFC 5280 | 635 // |working_issuer_name| corresponds with the same named variable in RFC 5280 |
545 // section 6.1.2: | 636 // section 6.1.2: |
546 // | 637 // |
547 // working_issuer_name: the issuer distinguished name expected | 638 // working_issuer_name: the issuer distinguished name expected |
548 // in the next certificate in the chain. The | 639 // in the next certificate in the chain. |
549 // working_issuer_name is initialized to the trusted issuer name | |
550 // provided in the trust anchor information. | |
551 der::Input working_issuer_name; | 640 der::Input working_issuer_name; |
552 | 641 |
553 // |max_path_length| corresponds with the same named variable in RFC 5280 | 642 // |max_path_length| corresponds with the same named variable in RFC 5280 |
554 // section 6.1.2: | 643 // section 6.1.2: |
555 // | 644 // |
556 // max_path_length: this integer is initialized to n, is | 645 // max_path_length: this integer is initialized to n, is |
557 // decremented for each non-self-issued certificate in the path, | 646 // decremented for each non-self-issued certificate in the path, |
558 // and may be reduced to the value in the path length constraint | 647 // and may be reduced to the value in the path length constraint |
559 // field within the basic constraints extension of a CA | 648 // field within the basic constraints extension of a CA |
560 // certificate. | 649 // certificate. |
561 size_t max_path_length = certs_der.size(); | 650 size_t max_path_length = certs_der.size(); |
562 | 651 |
563 // Iterate over all the certificates in the reverse direction: starting from | 652 // Iterate over all the certificates in the reverse direction: starting from |
564 // the trust anchor and progressing towards the target certificate. | 653 // the trust anchor and progressing towards the target certificate. |
565 // | 654 // |
566 // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based. | 655 // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based. |
567 // | 656 // |
568 // * i=0 : Certificate signed by a trust anchor. | 657 // * i=0 : Trust anchor. |
569 // * i=N-1 : Target certificate. | 658 // * i=N-1 : Target certificate. |
570 for (size_t i = 0; i < certs_der.size(); ++i) { | 659 for (size_t i = 0; i < certs_der.size(); ++i) { |
571 const size_t index_into_certs_der = certs_der.size() - i - 1; | 660 const size_t index_into_certs_der = certs_der.size() - i - 1; |
| 661 |
| 662 // |is_target_cert| is true if the current certificate is the target |
| 663 // certificate being verified. The target certificate isn't necessarily an |
| 664 // end-entity certificate. |
572 const bool is_target_cert = index_into_certs_der == 0; | 665 const bool is_target_cert = index_into_certs_der == 0; |
573 | 666 |
| 667 // |is_trust_anchor| is true if the current certificate is the trust |
| 668 // anchor. This certificate is implicitly trusted. |
| 669 const bool is_trust_anchor = i == 0; |
| 670 |
574 // Parse the current certificate into |cert|. | 671 // Parse the current certificate into |cert|. |
575 FullyParsedCert cert; | 672 FullyParsedCert cert; |
576 const der::Input& cert_der = certs_der[index_into_certs_der]; | 673 const der::Input& cert_der = certs_der[index_into_certs_der]; |
577 if (!FullyParseCertificate(cert_der, &cert)) | 674 if (!FullyParseCertificate(cert_der, &cert)) |
578 return false; | 675 return false; |
579 | 676 |
580 // When processing the first certificate, initialize |working_spki| | |
581 // and |working_issuer_name| to the trust anchor per RFC 5280 section 6.1.2. | |
582 // This is done inside the loop in order to have access to the parsed | |
583 // certificate. | |
584 if (i == 0) { | |
585 const TrustAnchor* trust_anchor = | |
586 FindTrustAnchorByName(trust_store, cert.tbs.issuer_tlv); | |
587 if (!trust_anchor) | |
588 return false; | |
589 working_spki = der::Input(&trust_anchor->spki); | |
590 working_issuer_name = der::Input(&trust_anchor->name); | |
591 } | |
592 | |
593 // Per RFC 5280 section 6.1: | 677 // Per RFC 5280 section 6.1: |
594 // * Do basic processing for each certificate | 678 // * Do basic processing for each certificate |
595 // * If it is the last certificate in the path (target certificate) | 679 // * If it is the last certificate in the path (target certificate) |
596 // - Then run "Wrap up" | 680 // - Then run "Wrap up" |
597 // - Otherwise run "Prepare for Next cert" | 681 // - Otherwise run "Prepare for Next cert" |
598 if (!BasicCertificateProcessing(cert, is_target_cert, signature_policy, | 682 if (!BasicCertificateProcessing( |
599 time, working_spki, working_issuer_name, | 683 cert, is_target_cert, is_trust_anchor, signature_policy, time, |
600 name_constraints_list)) { | 684 working_spki, working_issuer_name, name_constraints_list)) { |
601 return false; | 685 return false; |
602 } | 686 } |
603 if (!is_target_cert) { | 687 if (!is_target_cert) { |
604 if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki, | 688 if (!PrepareForNextCertificate(cert, &max_path_length, &working_spki, |
605 &working_issuer_name, | 689 &working_issuer_name, |
606 &name_constraints_list)) { | 690 &name_constraints_list)) { |
607 return false; | 691 return false; |
608 } | 692 } |
609 } else { | 693 } else { |
610 if (!WrapUp(cert)) | 694 if (!WrapUp(cert)) |
611 return false; | 695 return false; |
612 } | 696 } |
613 } | 697 } |
614 | 698 |
615 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: | 699 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: |
616 // | 700 // |
617 // A certificate MUST NOT appear more than once in a prospective | 701 // A certificate MUST NOT appear more than once in a prospective |
618 // certification path. | 702 // certification path. |
619 | 703 |
620 return true; | 704 return true; |
621 } | 705 } |
622 | 706 |
| 707 // TODO(eroman): This function is a temporary hack in the absence of full |
| 708 // path building. It may insert 1 certificate at the root of the |
| 709 // chain to ensure that the path's root certificate is a trust anchor. |
| 710 // |
| 711 // Beyond this no other verification is done on the chain. The caller is |
| 712 // responsible for verifying the subsequent chain's correctness. |
| 713 WARN_UNUSED_RESULT bool BuildSimplePathToTrustAnchor( |
| 714 const std::vector<der::Input>& certs_der, |
| 715 const TrustStore& trust_store, |
| 716 std::vector<der::Input>* certs_der_trusted_root) { |
| 717 // Copy the input chain. |
| 718 *certs_der_trusted_root = certs_der; |
| 719 |
| 720 if (certs_der.empty()) |
| 721 return false; |
| 722 |
| 723 // Check if the current root certificate is trusted. If it is then no |
| 724 // extra work is needed. |
| 725 if (trust_store.IsTrustedCertificate(certs_der_trusted_root->back())) |
| 726 return true; |
| 727 |
| 728 // Otherwise if it is not trusted, check whether its issuer is trusted. If |
| 729 // so, make *that* trusted certificate the root. If the issuer is not in |
| 730 // the trust store then give up and fail (this is not full path building). |
| 731 ParsedCertificate cert; |
| 732 ParsedTbsCertificate tbs; |
| 733 if (!ParseCertificate(certs_der.back(), &cert) || |
| 734 !ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) { |
| 735 return false; |
| 736 } |
| 737 |
| 738 auto trust_anchor = trust_store.FindTrustAnchorByName(tbs.issuer_tlv); |
| 739 if (!trust_anchor) |
| 740 return false; |
| 741 certs_der_trusted_root->push_back(trust_anchor->cert()); |
| 742 return true; |
| 743 } |
| 744 |
| 745 } // namespace |
| 746 |
| 747 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der, |
| 748 const TrustStore& trust_store, |
| 749 const SignaturePolicy* signature_policy, |
| 750 const der::GeneralizedTime& time) { |
| 751 // Modify the certificate chain so that its root is a trusted certificate. |
| 752 std::vector<der::Input> certs_der_trusted_root; |
| 753 if (!BuildSimplePathToTrustAnchor(certs_der, trust_store, |
| 754 &certs_der_trusted_root)) { |
| 755 return false; |
| 756 } |
| 757 |
| 758 // Verify the chain. |
| 759 return VerifyCertificateChainAssumingTrustedRoot( |
| 760 certs_der_trusted_root, trust_store, signature_policy, time); |
| 761 } |
| 762 |
623 } // namespace net | 763 } // namespace net |
OLD | NEW |