Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: components/cast_certificate/cast_crl.cc

Issue 2225493003: Don't treat trust anchors as certificates during path building. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address moar feedback Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
159 if (!ConvertTimeSeconds(tbs_crl.not_after_seconds(), &not_after)) { 164 if (!ConvertTimeSeconds(tbs_crl.not_after_seconds(), &not_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
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
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
OLDNEW
« no previous file with comments | « components/cast_certificate/cast_crl.h ('k') | components/cast_certificate/cast_crl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698