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

Side by Side Diff: components/certificate_transparency/single_tree_tracker.cc

Issue 2650803004: Wire NetLog into the TreeStateTracker (Closed)
Patch Set: Adding NetLog usage, tests Created 3 years, 10 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/certificate_transparency/single_tree_tracker.h" 5 #include "components/certificate_transparency/single_tree_tracker.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <iterator> 8 #include <iterator>
9 #include <list> 9 #include <list>
10 #include <utility> 10 #include <utility>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/metrics/histogram_macros.h" 13 #include "base/metrics/histogram_macros.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/values.h"
14 #include "components/certificate_transparency/log_dns_client.h" 16 #include "components/certificate_transparency/log_dns_client.h"
15 #include "crypto/sha2.h" 17 #include "crypto/sha2.h"
16 #include "net/base/hash_value.h" 18 #include "net/base/hash_value.h"
17 #include "net/base/net_errors.h" 19 #include "net/base/net_errors.h"
18 #include "net/cert/ct_log_verifier.h" 20 #include "net/cert/ct_log_verifier.h"
19 #include "net/cert/merkle_audit_proof.h" 21 #include "net/cert/merkle_audit_proof.h"
20 #include "net/cert/merkle_tree_leaf.h" 22 #include "net/cert/merkle_tree_leaf.h"
21 #include "net/cert/signed_certificate_timestamp.h" 23 #include "net/cert/signed_certificate_timestamp.h"
22 #include "net/cert/x509_certificate.h" 24 #include "net/cert/x509_certificate.h"
25 #include "net/log/net_log.h"
23 26
24 using net::SHA256HashValue; 27 using net::SHA256HashValue;
25 using net::ct::LogEntry; 28 using net::ct::LogEntry;
26 using net::ct::MerkleAuditProof; 29 using net::ct::MerkleAuditProof;
27 using net::ct::MerkleTreeLeaf; 30 using net::ct::MerkleTreeLeaf;
28 using net::ct::SignedCertificateTimestamp; 31 using net::ct::SignedCertificateTimestamp;
29 using net::ct::SignedTreeHead; 32 using net::ct::SignedTreeHead;
30 33
31 // Overview of the process for auditing CT log entries 34 // Overview of the process for auditing CT log entries
32 // 35 //
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 constexpr base::TimeDelta kMaximumMergeDelay = base::TimeDelta::FromHours(24); 162 constexpr base::TimeDelta kMaximumMergeDelay = base::TimeDelta::FromHours(24);
160 163
161 // The log MUST incorporate the a certificate in the tree within the Maximum 164 // The log MUST incorporate the a certificate in the tree within the Maximum
162 // Merge Delay, so an entry can be audited once the timestamp from the SCT + 165 // Merge Delay, so an entry can be audited once the timestamp from the SCT +
163 // MMD has passed. 166 // MMD has passed.
164 // Returns true if the timestamp from the STH is newer than SCT timestamp + MMD. 167 // Returns true if the timestamp from the STH is newer than SCT timestamp + MMD.
165 bool IsSCTReadyForAudit(base::Time sth_timestamp, base::Time sct_timestamp) { 168 bool IsSCTReadyForAudit(base::Time sth_timestamp, base::Time sct_timestamp) {
166 return sct_timestamp + kMaximumMergeDelay < sth_timestamp; 169 return sct_timestamp + kMaximumMergeDelay < sth_timestamp;
167 } 170 }
168 171
172 std::unique_ptr<base::Value> NetLogEntryAuditingEventCallback(
173 const SHA256HashValue* log_entry,
174 base::StringPiece log_id,
175 bool success,
176 net::NetLogCaptureMode capture_mode) {
177 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
178
179 dict->SetString("log_entry",
180 base::HexEncode(log_entry->data, crypto::kSHA256Length));
181 dict->SetString("log_id", base::HexEncode(log_id.data(), log_id.size()));
182 dict->SetBoolean("success", success);
183
184 return std::move(dict);
185 }
186
169 } // namespace 187 } // namespace
170 188
171 // The entry that is being audited. 189 // The entry that is being audited.
172 struct SingleTreeTracker::EntryToAudit { 190 struct SingleTreeTracker::EntryToAudit {
173 base::Time sct_timestamp; 191 base::Time sct_timestamp;
174 SHA256HashValue leaf_hash; 192 SHA256HashValue leaf_hash;
175 193
176 explicit EntryToAudit(base::Time timestamp) : sct_timestamp(timestamp) {} 194 explicit EntryToAudit(base::Time timestamp) : sct_timestamp(timestamp) {}
177 }; 195 };
178 196
(...skipping 28 matching lines...) Expand all
207 const EntryToAudit& lhs, 225 const EntryToAudit& lhs,
208 const EntryToAudit& rhs) const { 226 const EntryToAudit& rhs) const {
209 if (lhs.sct_timestamp != rhs.sct_timestamp) 227 if (lhs.sct_timestamp != rhs.sct_timestamp)
210 return lhs.sct_timestamp < rhs.sct_timestamp; 228 return lhs.sct_timestamp < rhs.sct_timestamp;
211 229
212 return net::SHA256HashValueLessThan()(lhs.leaf_hash, rhs.leaf_hash); 230 return net::SHA256HashValueLessThan()(lhs.leaf_hash, rhs.leaf_hash);
213 } 231 }
214 232
215 SingleTreeTracker::SingleTreeTracker( 233 SingleTreeTracker::SingleTreeTracker(
216 scoped_refptr<const net::CTLogVerifier> ct_log, 234 scoped_refptr<const net::CTLogVerifier> ct_log,
217 LogDnsClient* dns_client) 235 LogDnsClient* dns_client,
236 net::NetLog* net_log)
218 : ct_log_(std::move(ct_log)), 237 : ct_log_(std::move(ct_log)),
219 checked_entries_(kCheckedEntriesCacheSize), 238 checked_entries_(kCheckedEntriesCacheSize),
220 dns_client_(dns_client), 239 dns_client_(dns_client),
240 net_log_(net::NetLogWithSource::Make(
241 net_log,
242 net::NetLogSourceType::CT_TREE_STATE_TRACKER)),
221 weak_factory_(this) { 243 weak_factory_(this) {
222 memory_pressure_listener_.reset(new base::MemoryPressureListener(base::Bind( 244 memory_pressure_listener_.reset(new base::MemoryPressureListener(base::Bind(
223 &SingleTreeTracker::OnMemoryPressure, base::Unretained(this)))); 245 &SingleTreeTracker::OnMemoryPressure, base::Unretained(this))));
224 } 246 }
225 247
226 SingleTreeTracker::~SingleTreeTracker() {} 248 SingleTreeTracker::~SingleTreeTracker() {}
227 249
228 void SingleTreeTracker::OnSCTVerified(net::X509Certificate* cert, 250 void SingleTreeTracker::OnSCTVerified(net::X509Certificate* cert,
229 const SignedCertificateTimestamp* sct) { 251 const SignedCertificateTimestamp* sct) {
230 DCHECK_EQ(ct_log_->key_id(), sct->log_id); 252 DCHECK_EQ(ct_log_->key_id(), sct->log_id);
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 it->second.state = INCLUSION_PROOF_REQUESTED; 383 it->second.state = INCLUSION_PROOF_REQUESTED;
362 } else if (result == net::ERR_TEMPORARILY_THROTTLED) { 384 } else if (result == net::ERR_TEMPORARILY_THROTTLED) {
363 dns_client_->NotifyWhenNotThrottled( 385 dns_client_->NotifyWhenNotThrottled(
364 base::Bind(&SingleTreeTracker::ProcessPendingEntries, 386 base::Bind(&SingleTreeTracker::ProcessPendingEntries,
365 weak_factory_.GetWeakPtr())); 387 weak_factory_.GetWeakPtr()));
366 // Exit the loop since all subsequent calls to QueryAuditProof 388 // Exit the loop since all subsequent calls to QueryAuditProof
367 // will be throttled. 389 // will be throttled.
368 break; 390 break;
369 } else if (result == net::ERR_NAME_RESOLUTION_FAILED) { 391 } else if (result == net::ERR_NAME_RESOLUTION_FAILED) {
370 LogInclusionCheckResult(DNS_QUERY_NOT_POSSIBLE); 392 LogInclusionCheckResult(DNS_QUERY_NOT_POSSIBLE);
393 LogAuditResultToNetLog(it->first, false);
371 // Lookup failed due to bad DNS configuration, erase the entry and 394 // Lookup failed due to bad DNS configuration, erase the entry and
372 // continue to the next one. 395 // continue to the next one.
373 it = pending_entries_.erase(it); 396 it = pending_entries_.erase(it);
374 // Break here if it's the last entry to avoid |it| being incremented 397 // Break here if it's the last entry to avoid |it| being incremented
375 // by the for loop. 398 // by the for loop.
376 if (it == pending_entries_.end()) 399 if (it == pending_entries_.end())
377 break; 400 break;
378 } else { 401 } else {
379 // BUG: an invalid argument was provided or an unexpected error 402 // BUG: an invalid argument was provided or an unexpected error
380 // was returned from LogDnsClient. 403 // was returned from LogDnsClient.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 int net_error) { 435 int net_error) {
413 auto it = pending_entries_.find(entry); 436 auto it = pending_entries_.find(entry);
414 // The entry may not be present if it was evacuated due to low memory 437 // The entry may not be present if it was evacuated due to low memory
415 // pressure. 438 // pressure.
416 if (it == pending_entries_.end()) 439 if (it == pending_entries_.end())
417 return; 440 return;
418 441
419 DCHECK_EQ(it->second.state, INCLUSION_PROOF_REQUESTED); 442 DCHECK_EQ(it->second.state, INCLUSION_PROOF_REQUESTED);
420 443
421 if (net_error != net::OK) { 444 if (net_error != net::OK) {
422 // XXX(eranm): Should failures be cached? For now, they are not. 445 // XXX(eranm): Should failures be cached? For now, they are not.
eroman 2017/01/31 19:24:25 Can you update this to TODO(eranm) ?
Eran Messeri 2017/01/31 21:18:25 Done.
423 LogInclusionCheckResult(FAILED_GETTING_INCLUSION_PROOF); 446 LogInclusionCheckResult(FAILED_GETTING_INCLUSION_PROOF);
447 LogAuditResultToNetLog(entry, false);
424 pending_entries_.erase(it); 448 pending_entries_.erase(it);
425 return; 449 return;
426 } 450 }
427 451
428 std::string leaf_hash(reinterpret_cast<const char*>(entry.leaf_hash.data), 452 std::string leaf_hash(reinterpret_cast<const char*>(entry.leaf_hash.data),
429 crypto::kSHA256Length); 453 crypto::kSHA256Length);
430 454
431 bool verified = ct_log_->VerifyAuditProof(it->second.proof, 455 bool verified = ct_log_->VerifyAuditProof(it->second.proof,
432 it->second.root_hash, leaf_hash); 456 it->second.root_hash, leaf_hash);
457 LogAuditResultToNetLog(entry, verified);
433 458
434 if (!verified) { 459 if (!verified) {
435 LogInclusionCheckResult(GOT_INVALID_INCLUSION_PROOF); 460 LogInclusionCheckResult(GOT_INVALID_INCLUSION_PROOF);
436 } else { 461 } else {
437 LogInclusionCheckResult(GOT_VALID_INCLUSION_PROOF); 462 LogInclusionCheckResult(GOT_VALID_INCLUSION_PROOF);
438 checked_entries_.Put(entry.leaf_hash, EntryAuditResult()); 463 checked_entries_.Put(entry.leaf_hash, EntryAuditResult());
439 } 464 }
440 465
441 pending_entries_.erase(it); 466 pending_entries_.erase(it);
442 } 467 }
443 468
444 void SingleTreeTracker::OnMemoryPressure( 469 void SingleTreeTracker::OnMemoryPressure(
445 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) { 470 base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
446 switch (memory_pressure_level) { 471 switch (memory_pressure_level) {
447 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE: 472 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
448 break; 473 break;
449 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL: 474 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
450 pending_entries_.clear(); 475 pending_entries_.clear();
451 // Fall through to clearing the other cache. 476 // Fall through to clearing the other cache.
452 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE: 477 case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
453 checked_entries_.Clear(); 478 checked_entries_.Clear();
454 break; 479 break;
455 } 480 }
456 } 481 }
457 482
483 void SingleTreeTracker::LogAuditResultToNetLog(const EntryToAudit& entry,
484 bool success) {
485 net::NetLogParametersCallback net_log_callback =
486 base::Bind(&NetLogEntryAuditingEventCallback, &entry.leaf_hash,
487 ct_log_->key_id(), success);
488
489 net_log_.AddEvent(net::NetLogEventType::CT_LOG_ENTRY_AUDITED,
490 net_log_callback);
491 }
492
458 } // namespace certificate_transparency 493 } // namespace certificate_transparency
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698