| 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" |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure", | 329 // The following check is NOT part of RFC 5280 6.1.5's "Wrap-Up Procedure", |
| 330 // however is implied by RFC 5280 section 4.2.1.9. | 330 // however is implied by RFC 5280 section 4.2.1.9. |
| 331 if (!VerifyTargetCertHasConsistentCaBits(cert)) | 331 if (!VerifyTargetCertHasConsistentCaBits(cert)) |
| 332 return false; | 332 return false; |
| 333 | 333 |
| 334 return true; | 334 return true; |
| 335 } | 335 } |
| 336 | 336 |
| 337 } // namespace | 337 } // namespace |
| 338 | 338 |
| 339 // TODO(eroman): Move this into existing anonymous namespace. | |
| 340 namespace { | |
| 341 | |
| 342 // This implementation is structured to mimic the description of certificate | 339 // This implementation is structured to mimic the description of certificate |
| 343 // path verification given by RFC 5280 section 6.1. | 340 // path verification given by RFC 5280 section 6.1. |
| 344 // | 341 // |
| 345 // Unlike RFC 5280, the trust anchor is specified as the root certificate in | 342 // Unlike RFC 5280, the trust anchor is specified as the root certificate in |
| 346 // the chain. This root certificate is assumed to be trusted, and neither its | 343 // the chain. This root certificate is assumed to be trusted, and neither its |
| 347 // signature nor issuer name are verified. (It needn't be self-signed). | 344 // signature nor issuer name are verified. (It needn't be self-signed). |
| 348 bool VerifyCertificateChainAssumingTrustedRoot( | 345 bool VerifyCertificateChainAssumingTrustedRoot( |
| 349 const std::vector<scoped_refptr<ParsedCertificate>>& certs, | 346 const std::vector<scoped_refptr<ParsedCertificate>>& certs, |
| 350 // The trust store is only used for assertions. | 347 // The trust store is only used for assertions. |
| 351 const TrustStore& trust_store, | 348 const TrustStore& trust_store, |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 } | 440 } |
| 444 | 441 |
| 445 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: | 442 // TODO(eroman): RFC 5280 forbids duplicate certificates per section 6.1: |
| 446 // | 443 // |
| 447 // A certificate MUST NOT appear more than once in a prospective | 444 // A certificate MUST NOT appear more than once in a prospective |
| 448 // certification path. | 445 // certification path. |
| 449 | 446 |
| 450 return true; | 447 return true; |
| 451 } | 448 } |
| 452 | 449 |
| 453 // TODO(eroman): This function is a temporary hack in the absence of full | |
| 454 // path building. It may insert 1 certificate at the root of the | |
| 455 // chain to ensure that the path's root certificate is a trust anchor. | |
| 456 // | |
| 457 // Beyond this no other verification is done on the chain. The caller is | |
| 458 // responsible for verifying the subsequent chain's correctness. | |
| 459 WARN_UNUSED_RESULT bool BuildSimplePathToTrustAnchor( | |
| 460 const TrustStore& trust_store, | |
| 461 std::vector<scoped_refptr<ParsedCertificate>>* certs) { | |
| 462 if (certs->empty()) | |
| 463 return false; | |
| 464 | |
| 465 // Check if the current root certificate is trusted. If it is then no | |
| 466 // extra work is needed. | |
| 467 if (trust_store.IsTrustedCertificate(certs->back().get())) | |
| 468 return true; | |
| 469 | |
| 470 std::vector<scoped_refptr<ParsedCertificate>> trust_anchors; | |
| 471 trust_store.FindTrustAnchorsByNormalizedName( | |
| 472 certs->back()->normalized_issuer(), &trust_anchors); | |
| 473 if (trust_anchors.empty()) | |
| 474 return false; | |
| 475 // TODO(mattm): this only tries the first match, even if there are multiple. | |
| 476 certs->push_back(std::move(trust_anchors[0])); | |
| 477 return true; | |
| 478 } | |
| 479 | |
| 480 } // namespace | |
| 481 | |
| 482 bool VerifyCertificateChain( | |
| 483 const std::vector<scoped_refptr<ParsedCertificate>>& cert_chain, | |
| 484 const TrustStore& trust_store, | |
| 485 const SignaturePolicy* signature_policy, | |
| 486 const der::GeneralizedTime& time, | |
| 487 std::vector<scoped_refptr<ParsedCertificate>>* trusted_chain_out) { | |
| 488 if (cert_chain.empty()) | |
| 489 return false; | |
| 490 | |
| 491 std::vector<scoped_refptr<ParsedCertificate>> full_chain = cert_chain; | |
| 492 | |
| 493 // Modify the certificate chain so that its root is a trusted certificate. | |
| 494 if (!BuildSimplePathToTrustAnchor(trust_store, &full_chain)) | |
| 495 return false; | |
| 496 | |
| 497 // Verify the chain. | |
| 498 bool success = VerifyCertificateChainAssumingTrustedRoot( | |
| 499 full_chain, trust_store, signature_policy, time); | |
| 500 if (success && trusted_chain_out != nullptr) | |
| 501 *trusted_chain_out = std::move(full_chain); | |
| 502 return success; | |
| 503 } | |
| 504 | |
| 505 } // namespace net | 450 } // namespace net |
| OLD | NEW |