| 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 "base/memory/ptr_util.h" |
| 11 #include "net/cert/internal/cert_error_params.h" |
| 12 #include "net/cert/internal/cert_error_scoper.h" |
| 10 #include "net/cert/internal/cert_errors.h" | 13 #include "net/cert/internal/cert_errors.h" |
| 11 #include "net/cert/internal/name_constraints.h" | 14 #include "net/cert/internal/name_constraints.h" |
| 12 #include "net/cert/internal/parse_certificate.h" | 15 #include "net/cert/internal/parse_certificate.h" |
| 13 #include "net/cert/internal/signature_algorithm.h" | 16 #include "net/cert/internal/signature_algorithm.h" |
| 14 #include "net/cert/internal/signature_policy.h" | 17 #include "net/cert/internal/signature_policy.h" |
| 15 #include "net/cert/internal/trust_store.h" | 18 #include "net/cert/internal/trust_store.h" |
| 16 #include "net/cert/internal/verify_signed_data.h" | 19 #include "net/cert/internal/verify_signed_data.h" |
| 17 #include "net/der/input.h" | 20 #include "net/der/input.h" |
| 18 #include "net/der/parser.h" | 21 #include "net/der/parser.h" |
| 19 | 22 |
| 20 namespace net { | 23 namespace net { |
| 21 | 24 |
| 22 using namespace verify_certificate_chain_errors; | 25 using namespace verify_certificate_chain_errors; |
| 23 | 26 |
| 24 namespace { | 27 namespace { |
| 25 | 28 |
| 29 DEFINE_CERT_ERROR_ID(kContextTrustAnchor, "Processing Trust Anchor"); |
| 30 DEFINE_CERT_ERROR_ID(kContextCertificate, "Processing Certificate"); |
| 31 |
| 32 // This class changes the error scope to indicate which certificate in the |
| 33 // chain is currently being processed. |
| 34 class CertErrorScoperForCert : public CertErrorScoper { |
| 35 public: |
| 36 CertErrorScoperForCert(CertErrors* parent_errors, size_t index) |
| 37 : CertErrorScoper(parent_errors), index_(index) {} |
| 38 |
| 39 std::unique_ptr<CertErrorNode> BuildRootNode() override { |
| 40 return base::MakeUnique<CertErrorNode>( |
| 41 CertErrorNodeType::TYPE_CONTEXT, kContextCertificate, |
| 42 CreateCertErrorParamsSizeT("index", index_)); |
| 43 } |
| 44 |
| 45 private: |
| 46 size_t index_; |
| 47 |
| 48 DISALLOW_COPY_AND_ASSIGN(CertErrorScoperForCert); |
| 49 }; |
| 50 |
| 26 // Returns true if the certificate does not contain any unconsumed _critical_ | 51 // Returns true if the certificate does not contain any unconsumed _critical_ |
| 27 // extensions. | 52 // extensions. |
| 28 WARN_UNUSED_RESULT bool VerifyNoUnconsumedCriticalExtensions( | 53 WARN_UNUSED_RESULT bool VerifyNoUnconsumedCriticalExtensions( |
| 29 const ParsedCertificate& cert, | 54 const ParsedCertificate& cert, |
| 30 CertErrors* errors) { | 55 CertErrors* errors) { |
| 31 bool has_unconsumed_critical_extensions = false; | 56 bool has_unconsumed_critical_extensions = false; |
| 32 | 57 |
| 33 for (const auto& entry : cert.unparsed_extensions()) { | 58 for (const auto& entry : cert.unparsed_extensions()) { |
| 34 if (entry.second.critical) { | 59 if (entry.second.critical) { |
| 35 has_unconsumed_critical_extensions = true; | 60 has_unconsumed_critical_extensions = true; |
| 36 errors->AddWith2DerParams(kUnconsumedCriticalExtension, entry.second.oid, | 61 errors->AddError(kUnconsumedCriticalExtension, |
| 37 entry.second.value); | 62 CreateCertErrorParams2Der("oid", entry.second.oid, |
| 63 "value", entry.second.value)); |
| 38 } | 64 } |
| 39 } | 65 } |
| 40 | 66 |
| 41 return !has_unconsumed_critical_extensions; | 67 return !has_unconsumed_critical_extensions; |
| 42 } | 68 } |
| 43 | 69 |
| 44 // Returns true if |cert| was self-issued. The definition of self-issuance | 70 // Returns true if |cert| was self-issued. The definition of self-issuance |
| 45 // comes from RFC 5280 section 6.1: | 71 // comes from RFC 5280 section 6.1: |
| 46 // | 72 // |
| 47 // A certificate is self-issued if the same DN appears in the subject | 73 // A certificate is self-issued if the same DN appears in the subject |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 const der::Input& alg2_tlv = cert.tbs().signature_algorithm_tlv; | 143 const der::Input& alg2_tlv = cert.tbs().signature_algorithm_tlv; |
| 118 | 144 |
| 119 // Ensure that the two DER-encoded signature algorithms are byte-for-byte | 145 // Ensure that the two DER-encoded signature algorithms are byte-for-byte |
| 120 // equal. | 146 // equal. |
| 121 if (alg1_tlv == alg2_tlv) | 147 if (alg1_tlv == alg2_tlv) |
| 122 return true; | 148 return true; |
| 123 | 149 |
| 124 // But make a compatibility concession for RSA with SHA1. | 150 // But make a compatibility concession for RSA with SHA1. |
| 125 if (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && | 151 if (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && |
| 126 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)) { | 152 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)) { |
| 127 errors->AddWith2DerParams(kSignatureAlgorithmsDifferentEncoding, alg1_tlv, | 153 errors->AddWarning( |
| 128 alg2_tlv); | 154 kSignatureAlgorithmsDifferentEncoding, |
| 155 CreateCertErrorParams2Der("Certificate.algorithm", alg1_tlv, |
| 156 "TBSCertificate.signature", alg2_tlv)); |
| 129 return true; | 157 return true; |
| 130 } | 158 } |
| 131 | 159 |
| 132 errors->AddWith2DerParams(kSignatureAlgorithmMismatch, alg1_tlv, alg2_tlv); | 160 errors->AddError( |
| 161 kSignatureAlgorithmMismatch, |
| 162 CreateCertErrorParams2Der("Certificate.algorithm", alg1_tlv, |
| 163 "TBSCertificate.signature", alg2_tlv)); |
| 133 | 164 |
| 134 return false; | 165 return false; |
| 135 } | 166 } |
| 136 | 167 |
| 137 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate | 168 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate |
| 138 // Processing" procedure. | 169 // Processing" procedure. |
| 139 WARN_UNUSED_RESULT bool BasicCertificateProcessing( | 170 WARN_UNUSED_RESULT bool BasicCertificateProcessing( |
| 140 const ParsedCertificate& cert, | 171 const ParsedCertificate& cert, |
| 141 bool is_target_cert, | 172 bool is_target_cert, |
| 142 const SignaturePolicy* signature_policy, | 173 const SignaturePolicy* signature_policy, |
| 143 const der::GeneralizedTime& time, | 174 const der::GeneralizedTime& time, |
| 144 const der::Input& working_spki, | 175 const der::Input& working_spki, |
| 145 const der::Input& working_normalized_issuer_name, | 176 const der::Input& working_normalized_issuer_name, |
| 146 const std::vector<const NameConstraints*>& name_constraints_list, | 177 const std::vector<const NameConstraints*>& name_constraints_list, |
| 147 CertErrors* errors) { | 178 CertErrors* errors) { |
| 148 // Check that the signature algorithms in Certificate vs TBSCertificate | 179 // Check that the signature algorithms in Certificate vs TBSCertificate |
| 149 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by | 180 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by |
| 150 // sections 4.1.1.2 and 4.1.2.3. | 181 // sections 4.1.1.2 and 4.1.2.3. |
| 151 if (!VerifySignatureAlgorithmsMatch(cert, errors)) | 182 if (!VerifySignatureAlgorithmsMatch(cert, errors)) |
| 152 return false; | 183 return false; |
| 153 | 184 |
| 154 // Verify the digital signature using the previous certificate's key (RFC | 185 // Verify the digital signature using the previous certificate's key (RFC |
| 155 // 5280 section 6.1.3 step a.1). | 186 // 5280 section 6.1.3 step a.1). |
| 156 if (!cert.has_valid_supported_signature_algorithm()) { | 187 if (!cert.has_valid_supported_signature_algorithm()) { |
| 157 errors->AddWith1DerParam(kInvalidOrUnsupportedAlgorithm, | 188 errors->AddError( |
| 158 cert.signature_algorithm_tlv()); | 189 kInvalidOrUnsupportedSignatureAlgorithm, |
| 190 CreateCertErrorParams1Der("algorithm", cert.signature_algorithm_tlv())); |
| 159 return false; | 191 return false; |
| 160 } | 192 } |
| 161 | 193 |
| 162 if (!VerifySignedData(cert.signature_algorithm(), cert.tbs_certificate_tlv(), | 194 if (!VerifySignedData(cert.signature_algorithm(), cert.tbs_certificate_tlv(), |
| 163 cert.signature_value(), working_spki, signature_policy, | 195 cert.signature_value(), working_spki, signature_policy, |
| 164 errors)) { | 196 errors)) { |
| 165 errors->Add(kVerifySignedDataFailed); | 197 errors->Add(kVerifySignedDataFailed); |
| 166 return false; | 198 return false; |
| 167 } | 199 } |
| 168 | 200 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 } | 419 } |
| 388 | 420 |
| 389 // Initializes the path validation algorithm given anchor constraints. This | 421 // Initializes the path validation algorithm given anchor constraints. This |
| 390 // follows the description in RFC 5937 | 422 // follows the description in RFC 5937 |
| 391 WARN_UNUSED_RESULT bool ProcessTrustAnchorConstraints( | 423 WARN_UNUSED_RESULT bool ProcessTrustAnchorConstraints( |
| 392 const TrustAnchor& trust_anchor, | 424 const TrustAnchor& trust_anchor, |
| 393 size_t* max_path_length_ptr, | 425 size_t* max_path_length_ptr, |
| 394 std::vector<const NameConstraints*>* name_constraints_list, | 426 std::vector<const NameConstraints*>* name_constraints_list, |
| 395 CertErrors* errors) { | 427 CertErrors* errors) { |
| 396 // Set the trust anchor as the current context for any subsequent errors. | 428 // Set the trust anchor as the current context for any subsequent errors. |
| 397 ScopedCertErrorsTrustAnchorContext error_context(errors, &trust_anchor); | 429 CertErrorScoperNoParams error_context(errors, kContextTrustAnchor); |
| 398 | 430 |
| 399 // In RFC 5937 the enforcement of anchor constraints is governed by the input | 431 // In RFC 5937 the enforcement of anchor constraints is governed by the input |
| 400 // enforceTrustAnchorConstraints to path validation. In our implementation | 432 // enforceTrustAnchorConstraints to path validation. In our implementation |
| 401 // this is always on, and enforcement is controlled solely by whether or not | 433 // this is always on, and enforcement is controlled solely by whether or not |
| 402 // the trust anchor specified constraints. | 434 // the trust anchor specified constraints. |
| 403 if (!trust_anchor.enforces_constraints()) | 435 if (!trust_anchor.enforces_constraints()) |
| 404 return true; | 436 return true; |
| 405 | 437 |
| 406 // Anchor constraints are encoded via the attached certificate. | 438 // Anchor constraints are encoded via the attached certificate. |
| 407 const ParsedCertificate& cert = *trust_anchor.cert(); | 439 const ParsedCertificate& cert = *trust_anchor.cert(); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 const size_t index_into_certs = certs.size() - i - 1; | 554 const size_t index_into_certs = certs.size() - i - 1; |
| 523 | 555 |
| 524 // |is_target_cert| is true if the current certificate is the target | 556 // |is_target_cert| is true if the current certificate is the target |
| 525 // certificate being verified. The target certificate isn't necessarily an | 557 // certificate being verified. The target certificate isn't necessarily an |
| 526 // end-entity certificate. | 558 // end-entity certificate. |
| 527 const bool is_target_cert = index_into_certs == 0; | 559 const bool is_target_cert = index_into_certs == 0; |
| 528 | 560 |
| 529 const ParsedCertificate& cert = *certs[index_into_certs]; | 561 const ParsedCertificate& cert = *certs[index_into_certs]; |
| 530 | 562 |
| 531 // Set the current certificate as the context for any subsequent errors. | 563 // Set the current certificate as the context for any subsequent errors. |
| 532 ScopedCertErrorsCertContext error_context(errors, &cert, i); | 564 CertErrorScoperForCert error_context(errors, i); |
| 533 | 565 |
| 534 // Per RFC 5280 section 6.1: | 566 // Per RFC 5280 section 6.1: |
| 535 // * Do basic processing for each certificate | 567 // * Do basic processing for each certificate |
| 536 // * If it is the last certificate in the path (target certificate) | 568 // * If it is the last certificate in the path (target certificate) |
| 537 // - Then run "Wrap up" | 569 // - Then run "Wrap up" |
| 538 // - Otherwise run "Prepare for Next cert" | 570 // - Otherwise run "Prepare for Next cert" |
| 539 if (!BasicCertificateProcessing( | 571 if (!BasicCertificateProcessing( |
| 540 cert, is_target_cert, signature_policy, time, working_spki, | 572 cert, is_target_cert, signature_policy, time, working_spki, |
| 541 working_normalized_issuer_name, name_constraints_list, errors)) { | 573 working_normalized_issuer_name, name_constraints_list, errors)) { |
| 542 return false; | 574 return false; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 556 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: | 588 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: |
| 557 // | 589 // |
| 558 // A certificate MUST NOT appear more than once in a prospective | 590 // A certificate MUST NOT appear more than once in a prospective |
| 559 // certification path. | 591 // certification path. |
| 560 | 592 |
| 561 return true; | 593 return true; |
| 562 } | 594 } |
| 563 | 595 |
| 564 namespace verify_certificate_chain_errors { | 596 namespace verify_certificate_chain_errors { |
| 565 | 597 |
| 566 DEFINE_CERT_ERROR_TYPE( | 598 DEFINE_CERT_ERROR_ID( |
| 567 kSignatureAlgorithmMismatch, | 599 kSignatureAlgorithmMismatch, |
| 568 "Certificate.signatureAlgorithm != TBSCertificate.signature"); | 600 "Certificate.signatureAlgorithm != TBSCertificate.signature"); |
| 569 DEFINE_CERT_ERROR_TYPE(kInvalidOrUnsupportedAlgorithm, | 601 DEFINE_CERT_ERROR_ID(kInvalidOrUnsupportedSignatureAlgorithm, |
| 570 "Invalid or unsupported signature algorithm"); | 602 "Invalid or unsupported signature algorithm"); |
| 571 DEFINE_CERT_ERROR_TYPE(kChainIsEmpty, "Chain is empty"); | 603 DEFINE_CERT_ERROR_ID(kChainIsEmpty, "Chain is empty"); |
| 572 DEFINE_CERT_ERROR_TYPE(kUnconsumedCriticalExtension, | 604 DEFINE_CERT_ERROR_ID(kUnconsumedCriticalExtension, |
| 573 "Unconsumed critical extension"); | 605 "Unconsumed critical extension"); |
| 574 DEFINE_CERT_ERROR_TYPE( | 606 DEFINE_CERT_ERROR_ID( |
| 575 kTargetCertInconsistentCaBits, | 607 kTargetCertInconsistentCaBits, |
| 576 "Target certificate looks like a CA but does not set all CA properties"); | 608 "Target certificate looks like a CA but does not set all CA properties"); |
| 577 DEFINE_CERT_ERROR_TYPE(kKeyCertSignBitNotSet, "keyCertSign bit is not set"); | 609 DEFINE_CERT_ERROR_ID(kKeyCertSignBitNotSet, "keyCertSign bit is not set"); |
| 578 DEFINE_CERT_ERROR_TYPE(kMaxPathLengthViolated, "max_path_length reached"); | 610 DEFINE_CERT_ERROR_ID(kMaxPathLengthViolated, "max_path_length reached"); |
| 579 DEFINE_CERT_ERROR_TYPE(kBasicConstraintsIndicatesNotCa, | 611 DEFINE_CERT_ERROR_ID(kBasicConstraintsIndicatesNotCa, |
| 580 "Basic Constraints indicates not a CA"); | 612 "Basic Constraints indicates not a CA"); |
| 581 DEFINE_CERT_ERROR_TYPE(kMissingBasicConstraints, | 613 DEFINE_CERT_ERROR_ID(kMissingBasicConstraints, |
| 582 "Does not have Basic Constraints"); | 614 "Does not have Basic Constraints"); |
| 583 DEFINE_CERT_ERROR_TYPE(kNotPermittedByNameConstraints, | 615 DEFINE_CERT_ERROR_ID(kNotPermittedByNameConstraints, |
| 584 "Not permitted by name constraints"); | 616 "Not permitted by name constraints"); |
| 585 DEFINE_CERT_ERROR_TYPE(kSubjectDoesNotMatchIssuer, | 617 DEFINE_CERT_ERROR_ID(kSubjectDoesNotMatchIssuer, |
| 586 "subject does not match issuer"); | 618 "subject does not match issuer"); |
| 587 DEFINE_CERT_ERROR_TYPE(kVerifySignedDataFailed, "VerifySignedData failed"); | 619 DEFINE_CERT_ERROR_ID(kVerifySignedDataFailed, "VerifySignedData failed"); |
| 588 DEFINE_CERT_ERROR_TYPE(kValidityFailedNotAfter, "Time is after notAfter"); | 620 DEFINE_CERT_ERROR_ID(kValidityFailedNotAfter, "Time is after notAfter"); |
| 589 DEFINE_CERT_ERROR_TYPE(kValidityFailedNotBefore, "Time is before notBefore"); | 621 DEFINE_CERT_ERROR_ID(kValidityFailedNotBefore, "Time is before notBefore"); |
| 590 DEFINE_CERT_ERROR_TYPE(kSignatureAlgorithmsDifferentEncoding, | 622 DEFINE_CERT_ERROR_ID(kSignatureAlgorithmsDifferentEncoding, |
| 591 "Certificate.signatureAlgorithm is encoded differently " | 623 "Certificate.signatureAlgorithm is encoded differently " |
| 592 "than TBSCertificate.signature"); | 624 "than TBSCertificate.signature"); |
| 593 | 625 |
| 594 } // verify_certificate_chain_errors | 626 } // verify_certificate_chain_errors |
| 595 | 627 |
| 596 } // namespace net | 628 } // namespace net |
| OLD | NEW |