Index: components/cast_certificate/cast_cert_validator.cc |
diff --git a/components/cast_certificate/cast_cert_validator.cc b/components/cast_certificate/cast_cert_validator.cc |
index 6a81c84d562b56aa48c2fcbcc3e7d9e1e312578b..ec1fae2ee850d8a9b230ef0bb2cfc0b4d7debc6b 100644 |
--- a/components/cast_certificate/cast_cert_validator.cc |
+++ b/components/cast_certificate/cast_cert_validator.cc |
@@ -13,15 +13,16 @@ |
#include "base/memory/ptr_util.h" |
#include "base/memory/singleton.h" |
+#include "net/cert/internal/cert_issuer_source_static.h" |
#include "net/cert/internal/certificate_policies.h" |
#include "net/cert/internal/extended_key_usage.h" |
#include "net/cert/internal/parse_certificate.h" |
#include "net/cert/internal/parse_name.h" |
#include "net/cert/internal/parsed_certificate.h" |
+#include "net/cert/internal/path_builder.h" |
#include "net/cert/internal/signature_algorithm.h" |
#include "net/cert/internal/signature_policy.h" |
#include "net/cert/internal/trust_store.h" |
-#include "net/cert/internal/verify_certificate_chain.h" |
#include "net/cert/internal/verify_signed_data.h" |
#include "net/der/input.h" |
@@ -245,20 +246,6 @@ net::der::GeneralizedTime ConvertExplodedTime( |
return result; |
} |
-class ScopedCheckUnreferencedCerts { |
- public: |
- explicit ScopedCheckUnreferencedCerts( |
- std::vector<scoped_refptr<net::ParsedCertificate>>* certs) |
- : certs_(certs) {} |
- ~ScopedCheckUnreferencedCerts() { |
- for (const auto& cert : *certs_) |
- DCHECK(cert->HasOneRef()); |
- } |
- |
- private: |
- std::vector<scoped_refptr<net::ParsedCertificate>>* certs_; |
-}; |
- |
// Returns the parsing options used for Cast certificates. |
net::ParseCertificateOptions GetCertParsingOptions() { |
net::ParseCertificateOptions options; |
@@ -281,38 +268,46 @@ bool VerifyDeviceCert(const std::vector<std::string>& certs, |
const base::Time::Exploded& time, |
std::unique_ptr<CertVerificationContext>* context, |
CastDeviceCertPolicy* policy) { |
- // The underlying verification function expects a sequence of |
- // ParsedCertificate. |
- std::vector<scoped_refptr<net::ParsedCertificate>> input_chain; |
- // Verify that nothing saves a reference to the input certs, since the backing |
- // data will go out of scope when the function finishes. |
- ScopedCheckUnreferencedCerts ref_checker(&input_chain); |
- |
- for (const auto& cert_der : certs) { |
- // No reference to the ParsedCertificate is kept past the end of this |
- // function, so using EXTERNAL_REFERENCE here is safe. |
- if (!net::ParsedCertificate::CreateAndAddToVector( |
- reinterpret_cast<const uint8_t*>(cert_der.data()), cert_der.size(), |
+ if (certs.empty()) |
+ return false; |
+ |
+ // No reference to these ParsedCertificates is kept past the end of this |
+ // function, so using EXTERNAL_REFERENCE here is safe. |
+ scoped_refptr<net::ParsedCertificate> target_cert; |
+ net::CertIssuerSourceStatic intermediate_cert_issuer_source; |
+ for (size_t i = 0; i < certs.size(); ++i) { |
+ scoped_refptr<net::ParsedCertificate> cert( |
+ net::ParsedCertificate::CreateFromCertificateData( |
+ reinterpret_cast<const uint8_t*>(certs[i].data()), certs[i].size(), |
net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, |
- GetCertParsingOptions(), &input_chain)) { |
+ GetCertParsingOptions())); |
+ if (!cert) |
return false; |
- } |
+ |
+ if (i == 0) |
+ target_cert = std::move(cert); |
+ else |
+ intermediate_cert_issuer_source.AddCert(std::move(cert)); |
} |
// Use a signature policy compatible with Cast's PKI. |
auto signature_policy = CreateCastSignaturePolicy(); |
- // Do RFC 5280 compatible certificate verification using the two Cast |
- // trust anchors and Cast signature policy. |
- if (!net::VerifyCertificateChain(input_chain, CastTrustStore::Get(), |
- signature_policy.get(), |
- ConvertExplodedTime(time), nullptr)) { |
+ // Do path building and RFC 5280 compatible certificate verification using the |
+ // two Cast trust anchors and Cast signature policy. |
+ net::CertPathBuilder::Result result; |
+ net::CertPathBuilder path_builder(target_cert.get(), &CastTrustStore::Get(), |
+ signature_policy.get(), |
+ ConvertExplodedTime(time), &result); |
+ path_builder.AddCertIssuerSource(&intermediate_cert_issuer_source); |
+ net::CompletionStatus rv = path_builder.Run(base::Closure()); |
+ DCHECK_EQ(rv, net::CompletionStatus::SYNC); |
+ if (!result.is_success()) |
return false; |
- } |
// Check properties of the leaf certificate (key usage, policy), and construct |
// a CertVerificationContext that uses its public key. |
- return CheckTargetCertificate(input_chain[0].get(), context, policy); |
+ return CheckTargetCertificate(target_cert.get(), context, policy); |
} |
std::unique_ptr<CertVerificationContext> CertVerificationContextImplForTest( |