| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/cast_certificate/cast_cert_validator.h" | 5 #include "components/cast_certificate/cast_cert_validator.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 return base::Singleton<CastTrustStore, | 49 return base::Singleton<CastTrustStore, |
| 50 base::LeakySingletonTraits<CastTrustStore>>::get(); | 50 base::LeakySingletonTraits<CastTrustStore>>::get(); |
| 51 } | 51 } |
| 52 | 52 |
| 53 static net::TrustStore& Get() { return GetInstance()->store_; } | 53 static net::TrustStore& Get() { return GetInstance()->store_; } |
| 54 | 54 |
| 55 private: | 55 private: |
| 56 friend struct base::DefaultSingletonTraits<CastTrustStore>; | 56 friend struct base::DefaultSingletonTraits<CastTrustStore>; |
| 57 | 57 |
| 58 CastTrustStore() { | 58 CastTrustStore() { |
| 59 // Initialize the trust store with two root certificates. | 59 AddAnchor(kCastRootCaDer); |
| 60 AddAnchor(kEurekaRootCaDer); |
| 61 } |
| 62 |
| 63 // Adds a trust anchor given a DER-encoded certificate from static |
| 64 // storage. |
| 65 template <size_t N> |
| 66 void AddAnchor(const uint8_t (&data)[N]) { |
| 60 scoped_refptr<net::ParsedCertificate> root = | 67 scoped_refptr<net::ParsedCertificate> root = |
| 61 net::ParsedCertificate::CreateFromCertificateData( | 68 net::ParsedCertificate::CreateFromCertificateData( |
| 62 kCastRootCaDer, sizeof(kCastRootCaDer), | 69 data, N, net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, |
| 63 net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE); | 70 {}); |
| 64 CHECK(root); | |
| 65 store_.AddTrustedCertificate(std::move(root)); | |
| 66 | |
| 67 root = net::ParsedCertificate::CreateFromCertificateData( | |
| 68 kEurekaRootCaDer, sizeof(kEurekaRootCaDer), | |
| 69 net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE); | |
| 70 CHECK(root); | 71 CHECK(root); |
| 71 store_.AddTrustedCertificate(std::move(root)); | 72 store_.AddTrustedCertificate(std::move(root)); |
| 72 } | 73 } |
| 73 | 74 |
| 74 net::TrustStore store_; | 75 net::TrustStore store_; |
| 75 DISALLOW_COPY_AND_ASSIGN(CastTrustStore); | 76 DISALLOW_COPY_AND_ASSIGN(CastTrustStore); |
| 76 }; | 77 }; |
| 77 | 78 |
| 78 using ExtensionsMap = std::map<net::der::Input, net::ParsedExtension>; | 79 using ExtensionsMap = std::map<net::der::Input, net::ParsedExtension>; |
| 79 | 80 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 : certs_(certs) {} | 252 : certs_(certs) {} |
| 252 ~ScopedCheckUnreferencedCerts() { | 253 ~ScopedCheckUnreferencedCerts() { |
| 253 for (const auto& cert : *certs_) | 254 for (const auto& cert : *certs_) |
| 254 DCHECK(cert->HasOneRef()); | 255 DCHECK(cert->HasOneRef()); |
| 255 } | 256 } |
| 256 | 257 |
| 257 private: | 258 private: |
| 258 std::vector<scoped_refptr<net::ParsedCertificate>>* certs_; | 259 std::vector<scoped_refptr<net::ParsedCertificate>>* certs_; |
| 259 }; | 260 }; |
| 260 | 261 |
| 262 // Returns the parsing options used for Cast certificates. |
| 263 net::ParseCertificateOptions GetCertParsingOptions() { |
| 264 net::ParseCertificateOptions options; |
| 265 |
| 266 // Some cast intermediate certificates contain serial numbers that are |
| 267 // 21 octets long, and might also not use valid DER encoding for an |
| 268 // INTEGER (non-minimal encoding). |
| 269 // |
| 270 // Allow these sorts of serial numbers. |
| 271 // |
| 272 // TODO(eroman): At some point in the future this workaround will no longer be |
| 273 // necessary. Should revisit this for removal in 2017 if not earlier. |
| 274 options.allow_invalid_serial_numbers = true; |
| 275 return options; |
| 276 } |
| 277 |
| 261 } // namespace | 278 } // namespace |
| 262 | 279 |
| 263 bool VerifyDeviceCert(const std::vector<std::string>& certs, | 280 bool VerifyDeviceCert(const std::vector<std::string>& certs, |
| 264 const base::Time::Exploded& time, | 281 const base::Time::Exploded& time, |
| 265 std::unique_ptr<CertVerificationContext>* context, | 282 std::unique_ptr<CertVerificationContext>* context, |
| 266 CastDeviceCertPolicy* policy) { | 283 CastDeviceCertPolicy* policy) { |
| 267 // The underlying verification function expects a sequence of | 284 // The underlying verification function expects a sequence of |
| 268 // ParsedCertificate. | 285 // ParsedCertificate. |
| 269 std::vector<scoped_refptr<net::ParsedCertificate>> input_chain; | 286 std::vector<scoped_refptr<net::ParsedCertificate>> input_chain; |
| 270 // Verify that nothing saves a reference to the input certs, since the backing | 287 // Verify that nothing saves a reference to the input certs, since the backing |
| 271 // data will go out of scope when the function finishes. | 288 // data will go out of scope when the function finishes. |
| 272 ScopedCheckUnreferencedCerts ref_checker(&input_chain); | 289 ScopedCheckUnreferencedCerts ref_checker(&input_chain); |
| 273 | 290 |
| 274 for (const auto& cert_der : certs) { | 291 for (const auto& cert_der : certs) { |
| 275 // No reference to the ParsedCertificate is kept past the end of this | 292 // No reference to the ParsedCertificate is kept past the end of this |
| 276 // function, so using EXTERNAL_REFERENCE here is safe. | 293 // function, so using EXTERNAL_REFERENCE here is safe. |
| 277 if (!net::ParsedCertificate::CreateAndAddToVector( | 294 if (!net::ParsedCertificate::CreateAndAddToVector( |
| 278 reinterpret_cast<const uint8_t*>(cert_der.data()), cert_der.size(), | 295 reinterpret_cast<const uint8_t*>(cert_der.data()), cert_der.size(), |
| 279 net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, | 296 net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, |
| 280 &input_chain)) { | 297 GetCertParsingOptions(), &input_chain)) { |
| 281 return false; | 298 return false; |
| 282 } | 299 } |
| 283 } | 300 } |
| 284 | 301 |
| 285 // Use a signature policy compatible with Cast's PKI. | 302 // Use a signature policy compatible with Cast's PKI. |
| 286 auto signature_policy = CreateCastSignaturePolicy(); | 303 auto signature_policy = CreateCastSignaturePolicy(); |
| 287 | 304 |
| 288 // Do RFC 5280 compatible certificate verification using the two Cast | 305 // Do RFC 5280 compatible certificate verification using the two Cast |
| 289 // trust anchors and Cast signature policy. | 306 // trust anchors and Cast signature policy. |
| 290 if (!net::VerifyCertificateChain(input_chain, CastTrustStore::Get(), | 307 if (!net::VerifyCertificateChain(input_chain, CastTrustStore::Get(), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 302 const base::StringPiece& spki) { | 319 const base::StringPiece& spki) { |
| 303 // Use a bogus CommonName, since this is just exposed for testing signature | 320 // Use a bogus CommonName, since this is just exposed for testing signature |
| 304 // verification by unittests. | 321 // verification by unittests. |
| 305 return base::WrapUnique( | 322 return base::WrapUnique( |
| 306 new CertVerificationContextImpl(net::der::Input(spki), "CommonName")); | 323 new CertVerificationContextImpl(net::der::Input(spki), "CommonName")); |
| 307 } | 324 } |
| 308 | 325 |
| 309 bool AddTrustAnchorForTest(const uint8_t* data, size_t length) { | 326 bool AddTrustAnchorForTest(const uint8_t* data, size_t length) { |
| 310 scoped_refptr<net::ParsedCertificate> anchor( | 327 scoped_refptr<net::ParsedCertificate> anchor( |
| 311 net::ParsedCertificate::CreateFromCertificateData( | 328 net::ParsedCertificate::CreateFromCertificateData( |
| 312 data, length, | 329 data, length, net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, |
| 313 net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE)); | 330 GetCertParsingOptions())); |
| 314 if (!anchor) | 331 if (!anchor) |
| 315 return false; | 332 return false; |
| 316 CastTrustStore::Get().AddTrustedCertificate(std::move(anchor)); | 333 CastTrustStore::Get().AddTrustedCertificate(std::move(anchor)); |
| 317 return true; | 334 return true; |
| 318 } | 335 } |
| 319 | 336 |
| 320 } // namespace cast_certificate | 337 } // namespace cast_certificate |
| OLD | NEW |