| 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 |