| 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |