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

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

Issue 2093223002: Allow Cast certificates to have serial numbers greater than 20 bytes, as well as non-minimal INTEGE… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2743
Patch Set: Created 4 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 <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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 } 76 }
77 77
78 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv, 78 WARN_UNUSED_RESULT bool GetSequenceValue(const der::Input& tlv,
79 der::Input* value) { 79 der::Input* value) {
80 der::Parser parser(tlv); 80 der::Parser parser(tlv);
81 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); 81 return parser.ReadTag(der::kSequence, value) && !parser.HasMore();
82 } 82 }
83 83
84 // Parses an X.509 Certificate fully (including the TBSCertificate and 84 // Parses an X.509 Certificate fully (including the TBSCertificate and
85 // standard extensions), saving all the properties to |out_|. 85 // standard extensions), saving all the properties to |out_|.
86 WARN_UNUSED_RESULT bool FullyParseCertificate(const der::Input& cert_tlv, 86 WARN_UNUSED_RESULT bool FullyParseCertificate(
87 FullyParsedCert* out) { 87 const der::Input& cert_tlv,
88 const ParseCertificateOptions& options,
89 FullyParsedCert* out) {
88 // Parse the outer Certificate. 90 // Parse the outer Certificate.
89 if (!ParseCertificate(cert_tlv, &out->tbs_certificate_tlv, 91 if (!ParseCertificate(cert_tlv, &out->tbs_certificate_tlv,
90 &out->signature_algorithm_tlv, &out->signature_value)) 92 &out->signature_algorithm_tlv, &out->signature_value))
91 return false; 93 return false;
92 94
93 // Parse the signature algorithm contained in the Certificate (there is 95 // Parse the signature algorithm contained in the Certificate (there is
94 // another one in the TBSCertificate, which is checked later by 96 // another one in the TBSCertificate, which is checked later by
95 // VerifySignatureAlgorithmsMatch) 97 // VerifySignatureAlgorithmsMatch)
96 out->signature_algorithm = 98 out->signature_algorithm =
97 SignatureAlgorithm::CreateFromDer(out->signature_algorithm_tlv); 99 SignatureAlgorithm::CreateFromDer(out->signature_algorithm_tlv);
98 if (!out->signature_algorithm) 100 if (!out->signature_algorithm)
99 return false; 101 return false;
100 102
101 // Parse the TBSCertificate. 103 // Parse the TBSCertificate.
102 if (!ParseTbsCertificate(out->tbs_certificate_tlv, &out->tbs)) 104 if (!ParseTbsCertificate(out->tbs_certificate_tlv, options, &out->tbs))
103 return false; 105 return false;
104 106
105 // Reset state relating to extensions (which may not get overwritten). This is 107 // Reset state relating to extensions (which may not get overwritten). This is
106 // just a precaution, since in practice |out| will already be default 108 // just a precaution, since in practice |out| will already be default
107 // initialize. 109 // initialize.
108 out->has_basic_constraints = false; 110 out->has_basic_constraints = false;
109 out->has_key_usage = false; 111 out->has_key_usage = false;
110 out->unconsumed_extensions.clear(); 112 out->unconsumed_extensions.clear();
111 out->subject_alt_names.reset(); 113 out->subject_alt_names.reset();
112 out->has_name_constraints = false; 114 out->has_name_constraints = false;
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 } 498 }
497 499
498 } // namespace 500 } // namespace
499 501
500 TrustAnchor::TrustAnchor() {} 502 TrustAnchor::TrustAnchor() {}
501 TrustAnchor::~TrustAnchor() {} 503 TrustAnchor::~TrustAnchor() {}
502 504
503 std::unique_ptr<TrustAnchor> TrustAnchor::CreateFromCertificateData( 505 std::unique_ptr<TrustAnchor> TrustAnchor::CreateFromCertificateData(
504 const uint8_t* data, 506 const uint8_t* data,
505 size_t length, 507 size_t length,
508 const ParseCertificateOptions& options,
506 DataSource source) { 509 DataSource source) {
507 std::unique_ptr<TrustAnchor> result(new TrustAnchor); 510 std::unique_ptr<TrustAnchor> result(new TrustAnchor);
508 511
509 switch (source) { 512 switch (source) {
510 case DataSource::INTERNAL_COPY: 513 case DataSource::INTERNAL_COPY:
511 result->cert_data_.assign(data, data + length); 514 result->cert_data_.assign(data, data + length);
512 result->cert_ = 515 result->cert_ =
513 der::Input(result->cert_data_.data(), result->cert_data_.size()); 516 der::Input(result->cert_data_.data(), result->cert_data_.size());
514 break; 517 break;
515 case DataSource::EXTERNAL_REFERENCE: 518 case DataSource::EXTERNAL_REFERENCE:
516 result->cert_ = der::Input(data, length); 519 result->cert_ = der::Input(data, length);
517 break; 520 break;
518 } 521 }
519 522
520 // Parse the certificate to get its name. 523 // Parse the certificate to get its name.
521 der::Input tbs_certificate_tlv; 524 der::Input tbs_certificate_tlv;
522 der::Input signature_algorithm_tlv; 525 der::Input signature_algorithm_tlv;
523 der::BitString signature_value; 526 der::BitString signature_value;
524 if (!ParseCertificate(result->cert(), &tbs_certificate_tlv, 527 if (!ParseCertificate(result->cert(), &tbs_certificate_tlv,
525 &signature_algorithm_tlv, &signature_value)) 528 &signature_algorithm_tlv, &signature_value))
526 return nullptr; 529 return nullptr;
527 530
528 ParsedTbsCertificate tbs; 531 ParsedTbsCertificate tbs;
529 if (!ParseTbsCertificate(tbs_certificate_tlv, &tbs)) 532 if (!ParseTbsCertificate(tbs_certificate_tlv, options, &tbs))
530 return nullptr; 533 return nullptr;
531 534
532 result->name_ = tbs.subject_tlv; 535 result->name_ = tbs.subject_tlv;
533 536
534 // TODO(eroman): If adding a self-signed certificate, check that its 537 // TODO(eroman): If adding a self-signed certificate, check that its
535 // signature is correct? This check will not otherwise be done during 538 // signature is correct? This check will not otherwise be done during
536 // verification. 539 // verification.
537 540
538 return result; 541 return result;
539 } 542 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 for (const auto& anchor : anchors_) { 582 for (const auto& anchor : anchors_) {
580 if (anchor->cert() == cert_der) 583 if (anchor->cert() == cert_der)
581 return true; 584 return true;
582 } 585 }
583 return false; 586 return false;
584 } 587 }
585 588
586 bool TrustStore::AddTrustedCertificate(const uint8_t* data, 589 bool TrustStore::AddTrustedCertificate(const uint8_t* data,
587 size_t length, 590 size_t length,
588 TrustAnchor::DataSource source) { 591 TrustAnchor::DataSource source) {
589 auto anchor = TrustAnchor::CreateFromCertificateData(data, length, source); 592 auto anchor =
593 TrustAnchor::CreateFromCertificateData(data, length, {}, source);
590 if (!anchor) 594 if (!anchor)
591 return false; 595 return false;
592 anchors_.push_back(std::move(anchor)); 596 anchors_.push_back(std::move(anchor));
593 return true; 597 return true;
594 } 598 }
595 599
596 // TODO(eroman): Move this into existing anonymous namespace. 600 // TODO(eroman): Move this into existing anonymous namespace.
597 namespace { 601 namespace {
598 602
599 // This implementation is structured to mimic the description of certificate 603 // This implementation is structured to mimic the description of certificate
600 // path verification given by RFC 5280 section 6.1. 604 // path verification given by RFC 5280 section 6.1.
601 // 605 //
602 // Unlike RFC 5280, the trust anchor is specified as the root certificate in 606 // Unlike RFC 5280, the trust anchor is specified as the root certificate in
603 // the chain. This root certificate is assumed to be trusted, and neither its 607 // the chain. This root certificate is assumed to be trusted, and neither its
604 // signature nor issuer name are verified. (It needn't be self-signed). 608 // signature nor issuer name are verified. (It needn't be self-signed).
605 bool VerifyCertificateChainAssumingTrustedRoot( 609 bool VerifyCertificateChainAssumingTrustedRoot(
606 const std::vector<der::Input>& certs_der, 610 const std::vector<der::Input>& certs_der,
611 const ParseCertificateOptions& options,
607 // The trust store is only used for assertions. 612 // The trust store is only used for assertions.
608 const TrustStore& trust_store, 613 const TrustStore& trust_store,
609 const SignaturePolicy* signature_policy, 614 const SignaturePolicy* signature_policy,
610 const der::GeneralizedTime& time) { 615 const der::GeneralizedTime& time) {
611 // An empty chain is necessarily invalid. 616 // An empty chain is necessarily invalid.
612 if (certs_der.empty()) 617 if (certs_der.empty())
613 return false; 618 return false;
614 619
615 // IMPORTANT: the assumption being made is that the root certificate in 620 // IMPORTANT: the assumption being made is that the root certificate in
616 // the given path is the trust anchor (and has already been verified as 621 // the given path is the trust anchor (and has already been verified as
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 // end-entity certificate. 675 // end-entity certificate.
671 const bool is_target_cert = index_into_certs_der == 0; 676 const bool is_target_cert = index_into_certs_der == 0;
672 677
673 // |is_trust_anchor| is true if the current certificate is the trust 678 // |is_trust_anchor| is true if the current certificate is the trust
674 // anchor. This certificate is implicitly trusted. 679 // anchor. This certificate is implicitly trusted.
675 const bool is_trust_anchor = i == 0; 680 const bool is_trust_anchor = i == 0;
676 681
677 // Parse the current certificate into |cert|. 682 // Parse the current certificate into |cert|.
678 FullyParsedCert cert; 683 FullyParsedCert cert;
679 const der::Input& cert_der = certs_der[index_into_certs_der]; 684 const der::Input& cert_der = certs_der[index_into_certs_der];
680 if (!FullyParseCertificate(cert_der, &cert)) 685 if (!FullyParseCertificate(cert_der, options, &cert))
681 return false; 686 return false;
682 687
683 // Per RFC 5280 section 6.1: 688 // Per RFC 5280 section 6.1:
684 // * Do basic processing for each certificate 689 // * Do basic processing for each certificate
685 // * If it is the last certificate in the path (target certificate) 690 // * If it is the last certificate in the path (target certificate)
686 // - Then run "Wrap up" 691 // - Then run "Wrap up"
687 // - Otherwise run "Prepare for Next cert" 692 // - Otherwise run "Prepare for Next cert"
688 if (!BasicCertificateProcessing( 693 if (!BasicCertificateProcessing(
689 cert, is_target_cert, is_trust_anchor, signature_policy, time, 694 cert, is_target_cert, is_trust_anchor, signature_policy, time,
690 working_spki, working_issuer_name, name_constraints_list)) { 695 working_spki, working_issuer_name, name_constraints_list)) {
(...skipping 20 matching lines...) Expand all
711 } 716 }
712 717
713 // TODO(eroman): This function is a temporary hack in the absence of full 718 // TODO(eroman): This function is a temporary hack in the absence of full
714 // path building. It may insert 1 certificate at the root of the 719 // path building. It may insert 1 certificate at the root of the
715 // chain to ensure that the path's root certificate is a trust anchor. 720 // chain to ensure that the path's root certificate is a trust anchor.
716 // 721 //
717 // Beyond this no other verification is done on the chain. The caller is 722 // Beyond this no other verification is done on the chain. The caller is
718 // responsible for verifying the subsequent chain's correctness. 723 // responsible for verifying the subsequent chain's correctness.
719 WARN_UNUSED_RESULT bool BuildSimplePathToTrustAnchor( 724 WARN_UNUSED_RESULT bool BuildSimplePathToTrustAnchor(
720 const std::vector<der::Input>& certs_der, 725 const std::vector<der::Input>& certs_der,
726 const ParseCertificateOptions& options,
721 const TrustStore& trust_store, 727 const TrustStore& trust_store,
722 std::vector<der::Input>* certs_der_trusted_root) { 728 std::vector<der::Input>* certs_der_trusted_root) {
723 // Copy the input chain. 729 // Copy the input chain.
724 *certs_der_trusted_root = certs_der; 730 *certs_der_trusted_root = certs_der;
725 731
726 if (certs_der.empty()) 732 if (certs_der.empty())
727 return false; 733 return false;
728 734
729 // Check if the current root certificate is trusted. If it is then no 735 // Check if the current root certificate is trusted. If it is then no
730 // extra work is needed. 736 // extra work is needed.
731 if (trust_store.IsTrustedCertificate(certs_der_trusted_root->back())) 737 if (trust_store.IsTrustedCertificate(certs_der_trusted_root->back()))
732 return true; 738 return true;
733 739
734 // Otherwise if it is not trusted, check whether its issuer is trusted. If 740 // Otherwise if it is not trusted, check whether its issuer is trusted. If
735 // so, make *that* trusted certificate the root. If the issuer is not in 741 // so, make *that* trusted certificate the root. If the issuer is not in
736 // the trust store then give up and fail (this is not full path building). 742 // the trust store then give up and fail (this is not full path building).
737 der::Input tbs_certificate_tlv; 743 der::Input tbs_certificate_tlv;
738 der::Input signature_algorithm_tlv; 744 der::Input signature_algorithm_tlv;
739 der::BitString signature_value; 745 der::BitString signature_value;
740 ParsedTbsCertificate tbs; 746 ParsedTbsCertificate tbs;
741 if (!ParseCertificate(certs_der.back(), &tbs_certificate_tlv, 747 if (!ParseCertificate(certs_der.back(), &tbs_certificate_tlv,
742 &signature_algorithm_tlv, &signature_value) || 748 &signature_algorithm_tlv, &signature_value) ||
743 !ParseTbsCertificate(tbs_certificate_tlv, &tbs)) { 749 !ParseTbsCertificate(tbs_certificate_tlv, options, &tbs)) {
744 return false; 750 return false;
745 } 751 }
746 752
747 auto trust_anchor = trust_store.FindTrustAnchorByName(tbs.issuer_tlv); 753 auto trust_anchor = trust_store.FindTrustAnchorByName(tbs.issuer_tlv);
748 if (!trust_anchor) 754 if (!trust_anchor)
749 return false; 755 return false;
750 certs_der_trusted_root->push_back(trust_anchor->cert()); 756 certs_der_trusted_root->push_back(trust_anchor->cert());
751 return true; 757 return true;
752 } 758 }
753 759
754 } // namespace 760 } // namespace
755 761
756 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der, 762 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der,
763 const ParseCertificateOptions& options,
757 const TrustStore& trust_store, 764 const TrustStore& trust_store,
758 const SignaturePolicy* signature_policy, 765 const SignaturePolicy* signature_policy,
759 const der::GeneralizedTime& time) { 766 const der::GeneralizedTime& time) {
760 // Modify the certificate chain so that its root is a trusted certificate. 767 // Modify the certificate chain so that its root is a trusted certificate.
761 std::vector<der::Input> certs_der_trusted_root; 768 std::vector<der::Input> certs_der_trusted_root;
762 if (!BuildSimplePathToTrustAnchor(certs_der, trust_store, 769 if (!BuildSimplePathToTrustAnchor(certs_der, options, trust_store,
763 &certs_der_trusted_root)) { 770 &certs_der_trusted_root)) {
764 return false; 771 return false;
765 } 772 }
766 773
767 // Verify the chain. 774 // Verify the chain.
768 return VerifyCertificateChainAssumingTrustedRoot( 775 return VerifyCertificateChainAssumingTrustedRoot(
769 certs_der_trusted_root, trust_store, signature_policy, time); 776 certs_der_trusted_root, options, trust_store, signature_policy, time);
770 } 777 }
771 778
772 } // namespace net 779 } // 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