OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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_crl.h" | 5 #include "components/cast_certificate/cast_crl.h" |
6 | 6 |
7 #include <unordered_map> | 7 #include <unordered_map> |
8 #include <unordered_set> | 8 #include <unordered_set> |
9 | 9 |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 CastCRLTrustStore>>::get(); | 55 CastCRLTrustStore>>::get(); |
56 } | 56 } |
57 | 57 |
58 static net::TrustStore& Get() { return GetInstance()->store_; } | 58 static net::TrustStore& Get() { return GetInstance()->store_; } |
59 | 59 |
60 private: | 60 private: |
61 friend struct base::DefaultSingletonTraits<CastCRLTrustStore>; | 61 friend struct base::DefaultSingletonTraits<CastCRLTrustStore>; |
62 | 62 |
63 CastCRLTrustStore() { | 63 CastCRLTrustStore() { |
64 // Initialize the trust store with the root certificate. | 64 // Initialize the trust store with the root certificate. |
65 // TODO(ryanchung): Add official Cast CRL Root here | 65 scoped_refptr<net::ParsedCertificate> root = |
66 // scoped_refptr<net::ParsedCertificate> root = net::ParsedCertificate:: | 66 net::ParsedCertificate::CreateFromCertificateData( |
67 // net::ParsedCertificate::CreateFromCertificateData( | 67 kCastCRLRootCaDer, sizeof(kCastCRLRootCaDer), |
68 // kCastCRLRootCaDer, sizeof(kCastCRLRootCaDer), | 68 net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, {}); |
69 // net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, {}); | 69 CHECK(root); |
70 // CHECK(root); | 70 store_.AddTrustedCertificate(std::move(root)); |
71 // store_.AddTrustedCertificate(std::move(root)); | |
72 } | 71 } |
73 | 72 |
74 net::TrustStore store_; | 73 net::TrustStore store_; |
75 DISALLOW_COPY_AND_ASSIGN(CastCRLTrustStore); | 74 DISALLOW_COPY_AND_ASSIGN(CastCRLTrustStore); |
76 }; | 75 }; |
77 | 76 |
78 // Converts a uint64_t unix timestamp to net::der::GeneralizedTime. | 77 // Converts a uint64_t unix timestamp to net::der::GeneralizedTime. |
79 bool ConvertTimeSeconds(uint64_t seconds, | 78 bool ConvertTimeSeconds(uint64_t seconds, |
80 net::der::GeneralizedTime* generalized_time) { | 79 net::der::GeneralizedTime* generalized_time) { |
81 base::Time unix_timestamp = | 80 base::Time unix_timestamp = |
(...skipping 12 matching lines...) Expand all Loading... |
94 | 93 |
95 // Verifies the CRL is signed by a trusted CRL authority at the time the CRL | 94 // Verifies the CRL is signed by a trusted CRL authority at the time the CRL |
96 // was issued. Verifies the signature of |tbs_crl| is valid based on the | 95 // was issued. Verifies the signature of |tbs_crl| is valid based on the |
97 // certificate and signature in |crl|. The validity of |tbs_crl| is verified | 96 // certificate and signature in |crl|. The validity of |tbs_crl| is verified |
98 // at |time|. The validity period of the CRL is adjusted to be the earliest | 97 // at |time|. The validity period of the CRL is adjusted to be the earliest |
99 // of the issuer certificate chain's expiration and the CRL's expiration and | 98 // of the issuer certificate chain's expiration and the CRL's expiration and |
100 // the result is stored in |overall_not_after|. | 99 // the result is stored in |overall_not_after|. |
101 bool VerifyCRL(const Crl& crl, | 100 bool VerifyCRL(const Crl& crl, |
102 const TbsCrl& tbs_crl, | 101 const TbsCrl& tbs_crl, |
103 const base::Time& time, | 102 const base::Time& time, |
| 103 net::TrustStore* trust_store, |
104 net::der::GeneralizedTime* overall_not_after) { | 104 net::der::GeneralizedTime* overall_not_after) { |
105 // Verify the trust of the CRL authority. | 105 // Verify the trust of the CRL authority. |
106 scoped_refptr<net::ParsedCertificate> parsed_cert = | 106 scoped_refptr<net::ParsedCertificate> parsed_cert = |
107 net::ParsedCertificate::CreateFromCertificateData( | 107 net::ParsedCertificate::CreateFromCertificateData( |
108 reinterpret_cast<const uint8_t*>(crl.signer_cert().data()), | 108 reinterpret_cast<const uint8_t*>(crl.signer_cert().data()), |
109 crl.signer_cert().size(), | 109 crl.signer_cert().size(), |
110 net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, {}); | 110 net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, {}); |
111 if (parsed_cert == nullptr) { | 111 if (parsed_cert == nullptr) { |
112 VLOG(2) << "CRL - Issuer certificate parsing failed."; | 112 VLOG(2) << "CRL - Issuer certificate parsing failed."; |
113 return false; | 113 return false; |
(...skipping 15 matching lines...) Expand all Loading... |
129 return false; | 129 return false; |
130 } | 130 } |
131 | 131 |
132 // Verify the issuer certificate. | 132 // Verify the issuer certificate. |
133 net::der::GeneralizedTime verification_time; | 133 net::der::GeneralizedTime verification_time; |
134 if (!net::der::EncodeTimeAsGeneralizedTime(time, &verification_time)) { | 134 if (!net::der::EncodeTimeAsGeneralizedTime(time, &verification_time)) { |
135 VLOG(2) << "CRL - Unable to parse verification time."; | 135 VLOG(2) << "CRL - Unable to parse verification time."; |
136 return false; | 136 return false; |
137 } | 137 } |
138 net::CertPathBuilder::Result result; | 138 net::CertPathBuilder::Result result; |
139 net::CertPathBuilder path_builder( | 139 net::CertPathBuilder path_builder(parsed_cert.get(), trust_store, |
140 parsed_cert.get(), &CastCRLTrustStore::Get(), signature_policy.get(), | 140 signature_policy.get(), verification_time, |
141 verification_time, &result); | 141 &result); |
142 net::CompletionStatus rv = path_builder.Run(base::Closure()); | 142 net::CompletionStatus rv = path_builder.Run(base::Closure()); |
143 DCHECK_EQ(rv, net::CompletionStatus::SYNC); | 143 DCHECK_EQ(rv, net::CompletionStatus::SYNC); |
144 if (!result.is_success() || result.paths.empty() || | 144 if (!result.is_success() || result.paths.empty() || |
145 !result.paths[result.best_result_index]->is_success()) { | 145 !result.paths[result.best_result_index]->is_success()) { |
146 VLOG(2) << "CRL - Issuer certificate verification failed."; | 146 VLOG(2) << "CRL - Issuer certificate verification failed."; |
147 return false; | 147 return false; |
148 } | 148 } |
149 // There are no requirements placed on the leaf certificate having any | 149 // There are no requirements placed on the leaf certificate having any |
150 // particular KeyUsages. Leaf certificate checks are bypassed. | 150 // particular KeyUsages. Leaf certificate checks are bypassed. |
151 | 151 |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 VLOG(2) << "Serial number is revoked"; | 291 VLOG(2) << "Serial number is revoked"; |
292 return false; | 292 return false; |
293 } | 293 } |
294 } | 294 } |
295 } | 295 } |
296 } | 296 } |
297 } | 297 } |
298 return true; | 298 return true; |
299 } | 299 } |
300 | 300 |
301 } // namespace | 301 // Parses and verifies the CRL used to verify the revocation status of |
302 | 302 // Cast device certificates. |
303 std::unique_ptr<CastCRL> ParseAndVerifyCRL(const std::string& crl_proto, | 303 std::unique_ptr<CastCRL> ParseAndVerifyCRL(const std::string& crl_proto, |
304 const base::Time& time) { | 304 const base::Time& time, |
| 305 net::TrustStore* trust_store) { |
305 CrlBundle crl_bundle; | 306 CrlBundle crl_bundle; |
306 if (!crl_bundle.ParseFromString(crl_proto)) { | 307 if (!crl_bundle.ParseFromString(crl_proto)) { |
307 LOG(ERROR) << "CRL - Binary could not be parsed."; | 308 LOG(ERROR) << "CRL - Binary could not be parsed."; |
308 return nullptr; | 309 return nullptr; |
309 } | 310 } |
310 for (auto const& crl : crl_bundle.crls()) { | 311 for (auto const& crl : crl_bundle.crls()) { |
311 TbsCrl tbs_crl; | 312 TbsCrl tbs_crl; |
312 if (!tbs_crl.ParseFromString(crl.tbs_crl())) { | 313 if (!tbs_crl.ParseFromString(crl.tbs_crl())) { |
313 LOG(WARNING) << "Binary TBS CRL could not be parsed."; | 314 LOG(WARNING) << "Binary TBS CRL could not be parsed."; |
314 continue; | 315 continue; |
315 } | 316 } |
316 if (tbs_crl.version() != CRL_VERSION_0) { | 317 if (tbs_crl.version() != CRL_VERSION_0) { |
317 continue; | 318 continue; |
318 } | 319 } |
319 net::der::GeneralizedTime overall_not_after; | 320 net::der::GeneralizedTime overall_not_after; |
320 if (!VerifyCRL(crl, tbs_crl, time, &overall_not_after)) { | 321 if (!VerifyCRL(crl, tbs_crl, time, trust_store, &overall_not_after)) { |
321 LOG(ERROR) << "CRL - Verification failed."; | 322 LOG(ERROR) << "CRL - Verification failed."; |
322 return nullptr; | 323 return nullptr; |
323 } | 324 } |
324 return base::WrapUnique(new CastCRLImpl(tbs_crl, overall_not_after)); | 325 return base::WrapUnique(new CastCRLImpl(tbs_crl, overall_not_after)); |
325 } | 326 } |
326 LOG(ERROR) << "No supported version of revocation data."; | 327 LOG(ERROR) << "No supported version of revocation data."; |
327 return nullptr; | 328 return nullptr; |
328 } | 329 } |
329 | 330 |
330 bool SetCRLTrustAnchorForTest(const std::string& cert) { | 331 } // namespace |
331 scoped_refptr<net::ParsedCertificate> anchor( | 332 |
332 net::ParsedCertificate::CreateFromCertificateCopy(cert, {})); | 333 std::unique_ptr<CastCRL> ParseAndVerifyCRL(const std::string& crl_proto, |
333 if (!anchor) | 334 const base::Time& time) { |
334 return false; | 335 return ParseAndVerifyCRL(crl_proto, time, &CastCRLTrustStore::Get()); |
335 CastCRLTrustStore::Get().Clear(); | 336 } |
336 CastCRLTrustStore::Get().AddTrustedCertificate(std::move(anchor)); | 337 |
337 return true; | 338 std::unique_ptr<CastCRL> ParseAndVerifyCRLForTest( |
| 339 const std::string& crl_proto, |
| 340 const base::Time& time, |
| 341 net::TrustStore* trust_store) { |
| 342 return ParseAndVerifyCRL(crl_proto, time, trust_store); |
338 } | 343 } |
339 | 344 |
340 } // namespace cast_certificate | 345 } // namespace cast_certificate |
OLD | NEW |