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