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

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

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

Powered by Google App Engine
This is Rietveld 408576698