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" |
11 #include "net/cert/internal/parse_certificate.h" | 11 #include "net/cert/internal/parse_certificate.h" |
12 #include "net/cert/internal/signature_algorithm.h" | 12 #include "net/cert/internal/signature_algorithm.h" |
13 #include "net/cert/internal/signature_policy.h" | 13 #include "net/cert/internal/signature_policy.h" |
14 #include "net/cert/internal/verify_name_match.h" | 14 #include "net/cert/internal/verify_name_match.h" |
15 #include "net/cert/internal/verify_signed_data.h" | 15 #include "net/cert/internal/verify_signed_data.h" |
16 #include "net/der/input.h" | 16 #include "net/der/input.h" |
17 #include "net/der/parser.h" | 17 #include "net/der/parser.h" |
18 | 18 |
19 namespace net { | 19 namespace net { |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 // Map from OID to ParsedExtension. | 23 // Map from OID to ParsedExtension. |
24 using ExtensionsMap = std::map<der::Input, ParsedExtension>; | 24 using ExtensionsMap = std::map<der::Input, ParsedExtension>; |
25 | 25 |
26 // Describes all parsed properties of a certificate that are relevant for | 26 // Describes all parsed properties of a certificate that are relevant for |
27 // certificate verification. | 27 // certificate verification. |
28 struct FullyParsedCert { | 28 struct FullyParsedCert { |
29 ParsedCertificate cert; | 29 der::Input tbs_certificate_tlv; |
| 30 der::Input signature_algorithm_tlv; |
| 31 der::BitString signature_value; |
30 ParsedTbsCertificate tbs; | 32 ParsedTbsCertificate tbs; |
31 | 33 |
32 std::unique_ptr<SignatureAlgorithm> signature_algorithm; | 34 std::unique_ptr<SignatureAlgorithm> signature_algorithm; |
33 | 35 |
34 // Standard extensions that were parsed. | 36 // Standard extensions that were parsed. |
35 bool has_basic_constraints = false; | 37 bool has_basic_constraints = false; |
36 ParsedBasicConstraints basic_constraints; | 38 ParsedBasicConstraints basic_constraints; |
37 | 39 |
38 bool has_key_usage = false; | 40 bool has_key_usage = false; |
39 der::BitString key_usage; | 41 der::BitString key_usage; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 der::Input* value) { | 79 der::Input* value) { |
78 der::Parser parser(tlv); | 80 der::Parser parser(tlv); |
79 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); | 81 return parser.ReadTag(der::kSequence, value) && !parser.HasMore(); |
80 } | 82 } |
81 | 83 |
82 // Parses an X.509 Certificate fully (including the TBSCertificate and | 84 // Parses an X.509 Certificate fully (including the TBSCertificate and |
83 // standard extensions), saving all the properties to |out_|. | 85 // standard extensions), saving all the properties to |out_|. |
84 WARN_UNUSED_RESULT bool FullyParseCertificate(const der::Input& cert_tlv, | 86 WARN_UNUSED_RESULT bool FullyParseCertificate(const der::Input& cert_tlv, |
85 FullyParsedCert* out) { | 87 FullyParsedCert* out) { |
86 // Parse the outer Certificate. | 88 // Parse the outer Certificate. |
87 if (!ParseCertificate(cert_tlv, &out->cert)) | 89 if (!ParseCertificate(cert_tlv, &out->tbs_certificate_tlv, |
| 90 &out->signature_algorithm_tlv, &out->signature_value)) |
88 return false; | 91 return false; |
89 | 92 |
90 // Parse the signature algorithm contained in the Certificate (there is | 93 // Parse the signature algorithm contained in the Certificate (there is |
91 // another one in the TBSCertificate, which is checked later by | 94 // another one in the TBSCertificate, which is checked later by |
92 // VerifySignatureAlgorithmsMatch) | 95 // VerifySignatureAlgorithmsMatch) |
93 out->signature_algorithm = | 96 out->signature_algorithm = |
94 SignatureAlgorithm::CreateFromDer(out->cert.signature_algorithm_tlv); | 97 SignatureAlgorithm::CreateFromDer(out->signature_algorithm_tlv); |
95 if (!out->signature_algorithm) | 98 if (!out->signature_algorithm) |
96 return false; | 99 return false; |
97 | 100 |
98 // Parse the TBSCertificate. | 101 // Parse the TBSCertificate. |
99 if (!ParseTbsCertificate(out->cert.tbs_certificate_tlv, &out->tbs)) | 102 if (!ParseTbsCertificate(out->tbs_certificate_tlv, &out->tbs)) |
100 return false; | 103 return false; |
101 | 104 |
102 // Reset state relating to extensions (which may not get overwritten). This is | 105 // Reset state relating to extensions (which may not get overwritten). This is |
103 // just a precaution, since in practice |out| will already be default | 106 // just a precaution, since in practice |out| will already be default |
104 // initialize. | 107 // initialize. |
105 out->has_basic_constraints = false; | 108 out->has_basic_constraints = false; |
106 out->has_key_usage = false; | 109 out->has_key_usage = false; |
107 out->unconsumed_extensions.clear(); | 110 out->unconsumed_extensions.clear(); |
108 out->subject_alt_names.reset(); | 111 out->subject_alt_names.reset(); |
109 out->has_name_constraints = false; | 112 out->has_name_constraints = false; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 // | 240 // |
238 // The spec is not explicit about what "the same algorithm identifier" means. | 241 // The spec is not explicit about what "the same algorithm identifier" means. |
239 // Our interpretation is that the two DER-encoded fields must be byte-for-byte | 242 // Our interpretation is that the two DER-encoded fields must be byte-for-byte |
240 // identical. | 243 // identical. |
241 // | 244 // |
242 // In practice however there are certificates which use different encodings for | 245 // In practice however there are certificates which use different encodings for |
243 // specifying RSA with SHA1 (different OIDs). This is special-cased for | 246 // specifying RSA with SHA1 (different OIDs). This is special-cased for |
244 // compatibility sake. | 247 // compatibility sake. |
245 WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch( | 248 WARN_UNUSED_RESULT bool VerifySignatureAlgorithmsMatch( |
246 const FullyParsedCert& cert) { | 249 const FullyParsedCert& cert) { |
247 const der::Input& alg1_tlv = cert.cert.signature_algorithm_tlv; | 250 const der::Input& alg1_tlv = cert.signature_algorithm_tlv; |
248 const der::Input& alg2_tlv = cert.tbs.signature_algorithm_tlv; | 251 const der::Input& alg2_tlv = cert.tbs.signature_algorithm_tlv; |
249 | 252 |
250 // Ensure that the two DER-encoded signature algorithms are byte-for-byte | 253 // Ensure that the two DER-encoded signature algorithms are byte-for-byte |
251 // equal, but make a compatibility concession for RSA with SHA1. | 254 // equal, but make a compatibility concession for RSA with SHA1. |
252 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && | 255 return alg1_tlv == alg2_tlv || (IsRsaWithSha1SignatureAlgorithm(alg1_tlv) && |
253 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)); | 256 IsRsaWithSha1SignatureAlgorithm(alg2_tlv)); |
254 } | 257 } |
255 | 258 |
256 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate | 259 // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate |
257 // Processing" procedure. | 260 // Processing" procedure. |
(...skipping 14 matching lines...) Expand all Loading... |
272 name_constraints_list) { | 275 name_constraints_list) { |
273 // Check that the signature algorithms in Certificate vs TBSCertificate | 276 // Check that the signature algorithms in Certificate vs TBSCertificate |
274 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by | 277 // match. This isn't part of RFC 5280 section 6.1.3, but is mandated by |
275 // sections 4.1.1.2 and 4.1.2.3. | 278 // sections 4.1.1.2 and 4.1.2.3. |
276 if (!VerifySignatureAlgorithmsMatch(cert)) | 279 if (!VerifySignatureAlgorithmsMatch(cert)) |
277 return false; | 280 return false; |
278 | 281 |
279 // Verify the digital signature using the previous certificate's key (RFC | 282 // Verify the digital signature using the previous certificate's key (RFC |
280 // 5280 section 6.1.3 step a.1). | 283 // 5280 section 6.1.3 step a.1). |
281 if (!skip_issuer_checks) { | 284 if (!skip_issuer_checks) { |
282 if (!VerifySignedData( | 285 if (!VerifySignedData(*cert.signature_algorithm, cert.tbs_certificate_tlv, |
283 *cert.signature_algorithm, cert.cert.tbs_certificate_tlv, | 286 cert.signature_value, working_spki, |
284 cert.cert.signature_value, working_spki, signature_policy)) { | 287 signature_policy)) { |
285 return false; | 288 return false; |
286 } | 289 } |
287 } | 290 } |
288 | 291 |
289 // Check the time range for the certificate's validity, ensuring it is valid | 292 // Check the time range for the certificate's validity, ensuring it is valid |
290 // at |time|. | 293 // at |time|. |
291 // (RFC 5280 section 6.1.3 step a.2) | 294 // (RFC 5280 section 6.1.3 step a.2) |
292 if (!VerifyTimeValidity(cert, time)) | 295 if (!VerifyTimeValidity(cert, time)) |
293 return false; | 296 return false; |
294 | 297 |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 result->cert_data_.assign(data, data + length); | 511 result->cert_data_.assign(data, data + length); |
509 result->cert_ = | 512 result->cert_ = |
510 der::Input(result->cert_data_.data(), result->cert_data_.size()); | 513 der::Input(result->cert_data_.data(), result->cert_data_.size()); |
511 break; | 514 break; |
512 case DataSource::EXTERNAL_REFERENCE: | 515 case DataSource::EXTERNAL_REFERENCE: |
513 result->cert_ = der::Input(data, length); | 516 result->cert_ = der::Input(data, length); |
514 break; | 517 break; |
515 } | 518 } |
516 | 519 |
517 // Parse the certificate to get its name. | 520 // Parse the certificate to get its name. |
518 ParsedCertificate cert; | 521 der::Input tbs_certificate_tlv; |
519 if (!ParseCertificate(result->cert(), &cert)) | 522 der::Input signature_algorithm_tlv; |
| 523 der::BitString signature_value; |
| 524 if (!ParseCertificate(result->cert(), &tbs_certificate_tlv, |
| 525 &signature_algorithm_tlv, &signature_value)) |
520 return nullptr; | 526 return nullptr; |
521 | 527 |
522 ParsedTbsCertificate tbs; | 528 ParsedTbsCertificate tbs; |
523 if (!ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) | 529 if (!ParseTbsCertificate(tbs_certificate_tlv, &tbs)) |
524 return nullptr; | 530 return nullptr; |
525 | 531 |
526 result->name_ = tbs.subject_tlv; | 532 result->name_ = tbs.subject_tlv; |
527 | 533 |
528 // TODO(eroman): If adding a self-signed certificate, check that its | 534 // TODO(eroman): If adding a self-signed certificate, check that its |
529 // signature is correct? This check will not otherwise be done during | 535 // signature is correct? This check will not otherwise be done during |
530 // verification. | 536 // verification. |
531 | 537 |
532 return result; | 538 return result; |
533 } | 539 } |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 return false; | 727 return false; |
722 | 728 |
723 // Check if the current root certificate is trusted. If it is then no | 729 // Check if the current root certificate is trusted. If it is then no |
724 // extra work is needed. | 730 // extra work is needed. |
725 if (trust_store.IsTrustedCertificate(certs_der_trusted_root->back())) | 731 if (trust_store.IsTrustedCertificate(certs_der_trusted_root->back())) |
726 return true; | 732 return true; |
727 | 733 |
728 // Otherwise if it is not trusted, check whether its issuer is trusted. If | 734 // Otherwise if it is not trusted, check whether its issuer is trusted. If |
729 // so, make *that* trusted certificate the root. If the issuer is not in | 735 // so, make *that* trusted certificate the root. If the issuer is not in |
730 // the trust store then give up and fail (this is not full path building). | 736 // the trust store then give up and fail (this is not full path building). |
731 ParsedCertificate cert; | 737 der::Input tbs_certificate_tlv; |
| 738 der::Input signature_algorithm_tlv; |
| 739 der::BitString signature_value; |
732 ParsedTbsCertificate tbs; | 740 ParsedTbsCertificate tbs; |
733 if (!ParseCertificate(certs_der.back(), &cert) || | 741 if (!ParseCertificate(certs_der.back(), &tbs_certificate_tlv, |
734 !ParseTbsCertificate(cert.tbs_certificate_tlv, &tbs)) { | 742 &signature_algorithm_tlv, &signature_value) || |
| 743 !ParseTbsCertificate(tbs_certificate_tlv, &tbs)) { |
735 return false; | 744 return false; |
736 } | 745 } |
737 | 746 |
738 auto trust_anchor = trust_store.FindTrustAnchorByName(tbs.issuer_tlv); | 747 auto trust_anchor = trust_store.FindTrustAnchorByName(tbs.issuer_tlv); |
739 if (!trust_anchor) | 748 if (!trust_anchor) |
740 return false; | 749 return false; |
741 certs_der_trusted_root->push_back(trust_anchor->cert()); | 750 certs_der_trusted_root->push_back(trust_anchor->cert()); |
742 return true; | 751 return true; |
743 } | 752 } |
744 | 753 |
745 } // namespace | 754 } // namespace |
746 | 755 |
747 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der, | 756 bool VerifyCertificateChain(const std::vector<der::Input>& certs_der, |
748 const TrustStore& trust_store, | 757 const TrustStore& trust_store, |
749 const SignaturePolicy* signature_policy, | 758 const SignaturePolicy* signature_policy, |
750 const der::GeneralizedTime& time) { | 759 const der::GeneralizedTime& time) { |
751 // Modify the certificate chain so that its root is a trusted certificate. | 760 // Modify the certificate chain so that its root is a trusted certificate. |
752 std::vector<der::Input> certs_der_trusted_root; | 761 std::vector<der::Input> certs_der_trusted_root; |
753 if (!BuildSimplePathToTrustAnchor(certs_der, trust_store, | 762 if (!BuildSimplePathToTrustAnchor(certs_der, trust_store, |
754 &certs_der_trusted_root)) { | 763 &certs_der_trusted_root)) { |
755 return false; | 764 return false; |
756 } | 765 } |
757 | 766 |
758 // Verify the chain. | 767 // Verify the chain. |
759 return VerifyCertificateChainAssumingTrustedRoot( | 768 return VerifyCertificateChainAssumingTrustedRoot( |
760 certs_der_trusted_root, trust_store, signature_policy, time); | 769 certs_der_trusted_root, trust_store, signature_policy, time); |
761 } | 770 } |
762 | 771 |
763 } // namespace net | 772 } // namespace net |
OLD | NEW |