| 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 scoped_refptr<net::ParsedCertificate> root = | 65 scoped_refptr<net::ParsedCertificate> cert = |
| 66 net::ParsedCertificate::CreateFromCertificateData( | 66 net::ParsedCertificate::CreateFromCertificateData( |
| 67 kCastCRLRootCaDer, sizeof(kCastCRLRootCaDer), | 67 kCastCRLRootCaDer, sizeof(kCastCRLRootCaDer), |
| 68 net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, {}); | 68 net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, {}); |
| 69 CHECK(root); | 69 CHECK(cert); |
| 70 store_.AddTrustedCertificate(std::move(root)); | 70 // TODO(crbug.com/635200): Support anchor constraints, and initialize the |
| 71 // anchor using constraints from the self-signed certificate. |
| 72 scoped_refptr<net::TrustAnchor> anchor = |
| 73 net::TrustAnchor::CreateFromCertificateNoConstraints(std::move(cert)); |
| 74 CHECK(anchor); |
| 75 store_.AddTrustAnchor(std::move(anchor)); |
| 71 } | 76 } |
| 72 | 77 |
| 73 net::TrustStore store_; | 78 net::TrustStore store_; |
| 74 DISALLOW_COPY_AND_ASSIGN(CastCRLTrustStore); | 79 DISALLOW_COPY_AND_ASSIGN(CastCRLTrustStore); |
| 75 }; | 80 }; |
| 76 | 81 |
| 77 // Converts a uint64_t unix timestamp to net::der::GeneralizedTime. | 82 // Converts a uint64_t unix timestamp to net::der::GeneralizedTime. |
| 78 bool ConvertTimeSeconds(uint64_t seconds, | 83 bool ConvertTimeSeconds(uint64_t seconds, |
| 79 net::der::GeneralizedTime* generalized_time) { | 84 net::der::GeneralizedTime* generalized_time) { |
| 80 base::Time unix_timestamp = | 85 base::Time unix_timestamp = |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 if (!ConvertTimeSeconds(tbs_crl.not_after_seconds(), ¬_after)) { | 164 if (!ConvertTimeSeconds(tbs_crl.not_after_seconds(), ¬_after)) { |
| 160 VLOG(2) << "CRL - Unable to parse not_after."; | 165 VLOG(2) << "CRL - Unable to parse not_after."; |
| 161 return false; | 166 return false; |
| 162 } | 167 } |
| 163 if ((verification_time < not_before) || (verification_time > not_after)) { | 168 if ((verification_time < not_before) || (verification_time > not_after)) { |
| 164 VLOG(2) << "CRL - Not time-valid."; | 169 VLOG(2) << "CRL - Not time-valid."; |
| 165 return false; | 170 return false; |
| 166 } | 171 } |
| 167 | 172 |
| 168 // Set CRL expiry to the earliest of the cert chain expiry and CRL expiry. | 173 // Set CRL expiry to the earliest of the cert chain expiry and CRL expiry. |
| 174 // Note that the trust anchor is not part of this loop. |
| 175 // "expiration" of the trust anchor is handled instead by its |
| 176 // presence in the trust store. |
| 169 *overall_not_after = not_after; | 177 *overall_not_after = not_after; |
| 170 for (const auto& cert : result.paths[result.best_result_index]->path) { | 178 for (const auto& cert : result.paths[result.best_result_index]->path.certs) { |
| 171 net::der::GeneralizedTime cert_not_after = cert->tbs().validity_not_after; | 179 net::der::GeneralizedTime cert_not_after = cert->tbs().validity_not_after; |
| 172 if (cert_not_after < *overall_not_after) | 180 if (cert_not_after < *overall_not_after) |
| 173 *overall_not_after = cert_not_after; | 181 *overall_not_after = cert_not_after; |
| 174 } | 182 } |
| 175 | 183 |
| 176 // Perform sanity check on serial numbers. | 184 // Perform sanity check on serial numbers. |
| 177 for (const auto& range : tbs_crl.revoked_serial_number_ranges()) { | 185 for (const auto& range : tbs_crl.revoked_serial_number_ranges()) { |
| 178 uint64_t first_serial_number = range.first_serial_number(); | 186 uint64_t first_serial_number = range.first_serial_number(); |
| 179 uint64_t last_serial_number = range.last_serial_number(); | 187 uint64_t last_serial_number = range.last_serial_number(); |
| 180 if (last_serial_number < first_serial_number) { | 188 if (last_serial_number < first_serial_number) { |
| 181 VLOG(2) << "CRL - Malformed serial number range."; | 189 VLOG(2) << "CRL - Malformed serial number range."; |
| 182 return false; | 190 return false; |
| 183 } | 191 } |
| 184 } | 192 } |
| 185 return true; | 193 return true; |
| 186 } | 194 } |
| 187 | 195 |
| 188 class CastCRLImpl : public CastCRL { | 196 class CastCRLImpl : public CastCRL { |
| 189 public: | 197 public: |
| 190 CastCRLImpl(const TbsCrl& tbs_crl, | 198 CastCRLImpl(const TbsCrl& tbs_crl, |
| 191 const net::der::GeneralizedTime& overall_not_after); | 199 const net::der::GeneralizedTime& overall_not_after); |
| 192 ~CastCRLImpl() override; | 200 ~CastCRLImpl() override; |
| 193 | 201 |
| 194 bool CheckRevocation(const net::ParsedCertificateList& trusted_chain, | 202 bool CheckRevocation(const net::CertPath& trusted_chain, |
| 195 const base::Time& time) const override; | 203 const base::Time& time) const override; |
| 196 | 204 |
| 197 private: | 205 private: |
| 198 struct SerialNumberRange { | 206 struct SerialNumberRange { |
| 199 uint64_t first_serial; | 207 uint64_t first_serial; |
| 200 uint64_t last_serial; | 208 uint64_t last_serial; |
| 201 }; | 209 }; |
| 202 | 210 |
| 203 net::der::GeneralizedTime not_before_; | 211 net::der::GeneralizedTime not_before_; |
| 204 net::der::GeneralizedTime not_after_; | 212 net::der::GeneralizedTime not_after_; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 uint64_t last_serial_number = range.last_serial_number(); | 246 uint64_t last_serial_number = range.last_serial_number(); |
| 239 auto& serial_number_range = revoked_serial_numbers_[issuer_hash]; | 247 auto& serial_number_range = revoked_serial_numbers_[issuer_hash]; |
| 240 serial_number_range.push_back({first_serial_number, last_serial_number}); | 248 serial_number_range.push_back({first_serial_number, last_serial_number}); |
| 241 } | 249 } |
| 242 } | 250 } |
| 243 | 251 |
| 244 CastCRLImpl::~CastCRLImpl() {} | 252 CastCRLImpl::~CastCRLImpl() {} |
| 245 | 253 |
| 246 // Verifies the revocation status of the certificate chain, at the specified | 254 // Verifies the revocation status of the certificate chain, at the specified |
| 247 // time. | 255 // time. |
| 248 bool CastCRLImpl::CheckRevocation( | 256 bool CastCRLImpl::CheckRevocation(const net::CertPath& trusted_chain, |
| 249 const net::ParsedCertificateList& trusted_chain, | 257 const base::Time& time) const { |
| 250 const base::Time& time) const { | 258 if (trusted_chain.IsEmpty()) |
| 251 if (trusted_chain.empty()) | |
| 252 return false; | 259 return false; |
| 253 | 260 |
| 261 DCHECK(trusted_chain.trust_anchor); |
| 262 |
| 254 // Check the validity of the CRL at the specified time. | 263 // Check the validity of the CRL at the specified time. |
| 255 net::der::GeneralizedTime verification_time; | 264 net::der::GeneralizedTime verification_time; |
| 256 if (!net::der::EncodeTimeAsGeneralizedTime(time, &verification_time)) { | 265 if (!net::der::EncodeTimeAsGeneralizedTime(time, &verification_time)) { |
| 257 VLOG(2) << "CRL verification time malformed."; | 266 VLOG(2) << "CRL verification time malformed."; |
| 258 return false; | 267 return false; |
| 259 } | 268 } |
| 260 if ((verification_time < not_before_) || (verification_time > not_after_)) { | 269 if ((verification_time < not_before_) || (verification_time > not_after_)) { |
| 261 VLOG(2) << "CRL not time-valid. Perform hard fail."; | 270 VLOG(2) << "CRL not time-valid. Perform hard fail."; |
| 262 return false; | 271 return false; |
| 263 } | 272 } |
| 264 | 273 |
| 265 // Check revocation. | 274 // Check revocation. Note that this loop has "+ 1" in order to also loop |
| 266 for (size_t i = 0; i < trusted_chain.size(); ++i) { | 275 // over the trust anchor (which is treated specially). |
| 267 const auto& parsed_cert = trusted_chain[i]; | 276 for (size_t i = 0; i < trusted_chain.certs.size() + 1; ++i) { |
| 277 // This loop iterates over both certificates AND then the trust |
| 278 // anchor after exhausing the certs. |
| 279 net::der::Input spki_tlv; |
| 280 if (i == trusted_chain.certs.size()) { |
| 281 spki_tlv = trusted_chain.trust_anchor->spki(); |
| 282 } else { |
| 283 spki_tlv = trusted_chain.certs[i]->tbs().spki_tlv; |
| 284 } |
| 285 |
| 268 // Calculate the public key's hash to check for revocation. | 286 // Calculate the public key's hash to check for revocation. |
| 269 std::string spki_hash = | 287 std::string spki_hash = crypto::SHA256HashString(spki_tlv.AsString()); |
| 270 crypto::SHA256HashString(parsed_cert->tbs().spki_tlv.AsString()); | |
| 271 if (revoked_hashes_.find(spki_hash) != revoked_hashes_.end()) { | 288 if (revoked_hashes_.find(spki_hash) != revoked_hashes_.end()) { |
| 272 VLOG(2) << "Public key is revoked."; | 289 VLOG(2) << "Public key is revoked."; |
| 273 return false; | 290 return false; |
| 274 } | 291 } |
| 275 | 292 |
| 276 // Check if the subordinate certificate was revoked by serial number. | 293 // Check if the subordinate certificate was revoked by serial number. |
| 277 if (i > 0) { | 294 if (i > 0) { |
| 278 auto issuer_iter = revoked_serial_numbers_.find(spki_hash); | 295 auto issuer_iter = revoked_serial_numbers_.find(spki_hash); |
| 279 if (issuer_iter != revoked_serial_numbers_.end()) { | 296 if (issuer_iter != revoked_serial_numbers_.end()) { |
| 280 const auto& subordinate = trusted_chain[i - 1]; | 297 const auto& subordinate = trusted_chain.certs[i - 1]; |
| 281 uint64_t serial_number; | 298 uint64_t serial_number; |
| 282 // Only Google generated device certificates will be revoked by range. | 299 // Only Google generated device certificates will be revoked by range. |
| 283 // These will always be less than 64 bits in length. | 300 // These will always be less than 64 bits in length. |
| 284 if (!net::der::ParseUint64(subordinate->tbs().serial_number, | 301 if (!net::der::ParseUint64(subordinate->tbs().serial_number, |
| 285 &serial_number)) { | 302 &serial_number)) { |
| 286 continue; | 303 continue; |
| 287 } | 304 } |
| 288 for (const auto& revoked_serial : issuer_iter->second) { | 305 for (const auto& revoked_serial : issuer_iter->second) { |
| 289 if (revoked_serial.first_serial <= serial_number && | 306 if (revoked_serial.first_serial <= serial_number && |
| 290 revoked_serial.last_serial >= serial_number) { | 307 revoked_serial.last_serial >= serial_number) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 } | 353 } |
| 337 | 354 |
| 338 std::unique_ptr<CastCRL> ParseAndVerifyCRLForTest( | 355 std::unique_ptr<CastCRL> ParseAndVerifyCRLForTest( |
| 339 const std::string& crl_proto, | 356 const std::string& crl_proto, |
| 340 const base::Time& time, | 357 const base::Time& time, |
| 341 net::TrustStore* trust_store) { | 358 net::TrustStore* trust_store) { |
| 342 return ParseAndVerifyCRL(crl_proto, time, trust_store); | 359 return ParseAndVerifyCRL(crl_proto, time, trust_store); |
| 343 } | 360 } |
| 344 | 361 |
| 345 } // namespace cast_certificate | 362 } // namespace cast_certificate |
| OLD | NEW |