Chromium Code Reviews| 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 10 matching lines...) Expand all Loading... | |
| 21 #include "net/cert/internal/signature_algorithm.h" | 21 #include "net/cert/internal/signature_algorithm.h" |
| 22 #include "net/cert/internal/signature_policy.h" | 22 #include "net/cert/internal/signature_policy.h" |
| 23 #include "net/cert/internal/trust_store.h" | 23 #include "net/cert/internal/trust_store.h" |
| 24 #include "net/cert/internal/verify_certificate_chain.h" | 24 #include "net/cert/internal/verify_certificate_chain.h" |
| 25 #include "net/cert/internal/verify_signed_data.h" | 25 #include "net/cert/internal/verify_signed_data.h" |
| 26 #include "net/der/input.h" | 26 #include "net/der/input.h" |
| 27 | 27 |
| 28 namespace cast_certificate { | 28 namespace cast_certificate { |
| 29 namespace { | 29 namespace { |
| 30 | 30 |
| 31 // Returns the parsing options used for Cast certificates. | |
| 32 net::ParseCertificateOptions GetCertParsingOptions() { | |
| 33 net::ParseCertificateOptions options; | |
| 34 | |
| 35 // Some cast intermediate certificates contain serial numbers that are | |
| 36 // 21 octets long, and might also not use valid DER encoding for an | |
| 37 // INTEGER (non-minimal encoding). | |
| 38 // | |
| 39 // Allow these sorts of serial numbers. | |
| 40 // | |
| 41 // TODO(eroman): At some point in the future this workaround will no longer be | |
| 42 // necessary. Should revisit this for removal in 2017 if not earlier. | |
| 43 options.allow_invalid_serial_numbers = true; | |
| 44 return options; | |
| 45 } | |
| 46 | |
| 31 // ------------------------------------------------------------------------- | 47 // ------------------------------------------------------------------------- |
| 32 // Cast trust anchors. | 48 // Cast trust anchors. |
| 33 // ------------------------------------------------------------------------- | 49 // ------------------------------------------------------------------------- |
| 34 | 50 |
| 35 // There are two trusted roots for Cast certificate chains: | 51 // There are two trusted roots for Cast certificate chains: |
| 36 // | 52 // |
| 37 // (1) CN=Cast Root CA (kCastRootCaDer) | 53 // (1) CN=Cast Root CA (kCastRootCaDer) |
| 38 // (2) CN=Eureka Root CA (kEurekaRootCaDer) | 54 // (2) CN=Eureka Root CA (kEurekaRootCaDer) |
| 39 // | 55 // |
| 40 // These constants are defined by the files included next: | 56 // These constants are defined by the files included next: |
| 41 | 57 |
| 42 #include "components/cast_certificate/cast_root_ca_cert_der-inc.h" | 58 #include "components/cast_certificate/cast_root_ca_cert_der-inc.h" |
| 43 #include "components/cast_certificate/eureka_root_ca_der-inc.h" | 59 #include "components/cast_certificate/eureka_root_ca_der-inc.h" |
| 44 | 60 |
| 45 // Singleton for the Cast trust store. | 61 // Singleton for the Cast trust store. |
| 46 class CastTrustStore { | 62 class CastTrustStore { |
| 47 public: | 63 public: |
| 48 static CastTrustStore* GetInstance() { | 64 static CastTrustStore* GetInstance() { |
| 49 return base::Singleton<CastTrustStore, | 65 return base::Singleton<CastTrustStore, |
| 50 base::LeakySingletonTraits<CastTrustStore>>::get(); | 66 base::LeakySingletonTraits<CastTrustStore>>::get(); |
| 51 } | 67 } |
| 52 | 68 |
| 53 static net::TrustStore& Get() { return GetInstance()->store_; } | 69 static net::TrustStore& Get() { return GetInstance()->store_; } |
| 54 | 70 |
| 55 private: | 71 private: |
| 56 friend struct base::DefaultSingletonTraits<CastTrustStore>; | 72 friend struct base::DefaultSingletonTraits<CastTrustStore>; |
| 57 | 73 |
| 58 CastTrustStore() { | 74 CastTrustStore() { |
| 59 // Initialize the trust store with two root certificates. | 75 AddAnchor(kCastRootCaDer); |
| 76 AddAnchor(kEurekaRootCaDer); | |
| 77 } | |
| 78 | |
| 79 // Adds a trust anchor given a DER-encoded certificate from static | |
| 80 // storage. | |
| 81 template <size_t N> | |
| 82 void AddAnchor(const uint8_t (&data)[N]) { | |
| 60 scoped_refptr<net::ParsedCertificate> root = | 83 scoped_refptr<net::ParsedCertificate> root = |
| 61 net::ParsedCertificate::CreateFromCertificateData( | 84 net::ParsedCertificate::CreateFromCertificateData( |
| 62 kCastRootCaDer, sizeof(kCastRootCaDer), | 85 data, N, net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, |
| 63 net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE); | 86 GetCertParsingOptions()); |
|
mattm
2016/06/20 23:42:12
Since these are statically included and verified b
eroman
2016/06/20 23:45:45
That is correct.
I added it anyway for consistenc
mattm
2016/06/20 23:55:04
I'd prefer limiting the places we allow exceptions
eroman
2016/06/21 00:19:31
Done.
| |
| 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); | 87 CHECK(root); |
| 71 store_.AddTrustedCertificate(std::move(root)); | 88 store_.AddTrustedCertificate(std::move(root)); |
| 72 } | 89 } |
| 73 | 90 |
| 74 net::TrustStore store_; | 91 net::TrustStore store_; |
| 75 DISALLOW_COPY_AND_ASSIGN(CastTrustStore); | 92 DISALLOW_COPY_AND_ASSIGN(CastTrustStore); |
| 76 }; | 93 }; |
| 77 | 94 |
| 78 using ExtensionsMap = std::map<net::der::Input, net::ParsedExtension>; | 95 using ExtensionsMap = std::map<net::der::Input, net::ParsedExtension>; |
| 79 | 96 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 |