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

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

Issue 2485653002: Cleanup and minor refactoring of LogDnsClient (Closed)
Patch Set: Created 4 years, 1 month 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/log_dns_client.h" 5 #include "components/certificate_transparency/log_dns_client.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/location.h" 10 #include "base/location.h"
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 100
101 // Encapsulates the state machine required to get an audit proof from a Merkle 101 // Encapsulates the state machine required to get an audit proof from a Merkle
102 // leaf hash. This requires a DNS request to obtain the leaf index, then a 102 // leaf hash. This requires a DNS request to obtain the leaf index, then a
103 // series of DNS requests to get the nodes of the proof. 103 // series of DNS requests to get the nodes of the proof.
104 class LogDnsClient::AuditProofQuery { 104 class LogDnsClient::AuditProofQuery {
105 public: 105 public:
106 // The LogDnsClient is guaranteed to outlive the AuditProofQuery, so it's safe 106 // The LogDnsClient is guaranteed to outlive the AuditProofQuery, so it's safe
107 // to leave ownership of |dns_client| with LogDnsClient. 107 // to leave ownership of |dns_client| with LogDnsClient.
108 AuditProofQuery(net::DnsClient* dns_client, 108 AuditProofQuery(net::DnsClient* dns_client,
109 const std::string& domain_for_log, 109 const std::string& domain_for_log,
110 uint64_t tree_size,
111 const net::NetLogWithSource& net_log); 110 const net::NetLogWithSource& net_log);
112 111
113 // Begins the process of getting an audit |proof| for the CT log entry with a 112 // Begins the process of getting an audit proof for the CT log entry with a
114 // leaf hash of |leaf_hash|. If it cannot be obtained synchronously, 113 // leaf hash of |leaf_hash|. The proof will be for a tree of size |tree_size|.
115 // net::ERR_IO_PENDING will be returned and |callback| will be invoked when 114 // If it cannot be obtained synchronously, net::ERR_IO_PENDING will be
116 // the operation has completed asynchronously. 115 // returned and |callback| will be invoked when the operation has completed
117 // Ownership of |proof| remains with the caller, and it must not be deleted 116 // asynchronously. Ownership of |proof| remains with the caller, and it must
118 // until the operation is complete. 117 // not be deleted until the operation is complete.
119 net::Error Start(std::string leaf_hash, 118 net::Error Start(std::string leaf_hash,
119 uint64_t tree_size,
120 const net::CompletionCallback& callback, 120 const net::CompletionCallback& callback,
121 net::ct::MerkleAuditProof* proof); 121 net::ct::MerkleAuditProof* out_proof);
122 122
123 private: 123 private:
124 enum class State { 124 enum class State {
125 NONE, 125 NONE,
126 REQUEST_LEAF_INDEX, 126 REQUEST_LEAF_INDEX,
127 REQUEST_LEAF_INDEX_COMPLETE, 127 REQUEST_LEAF_INDEX_COMPLETE,
128 REQUEST_AUDIT_PROOF_NODES, 128 REQUEST_AUDIT_PROOF_NODES,
129 REQUEST_AUDIT_PROOF_NODES_COMPLETE, 129 REQUEST_AUDIT_PROOF_NODES_COMPLETE,
130 }; 130 };
131 131
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 // Returns true if the request could be started. 171 // Returns true if the request could be started.
172 // OnDnsTransactionComplete() will be invoked with the result of the request. 172 // OnDnsTransactionComplete() will be invoked with the result of the request.
173 bool StartDnsTransaction(const std::string& qname); 173 bool StartDnsTransaction(const std::string& qname);
174 174
175 // The next state that this query will enter. 175 // The next state that this query will enter.
176 State next_state_; 176 State next_state_;
177 // The DNS domain of the CT log that is being queried. 177 // The DNS domain of the CT log that is being queried.
178 std::string domain_for_log_; 178 std::string domain_for_log_;
179 // The Merkle leaf hash of the CT log entry an audit proof is required for. 179 // The Merkle leaf hash of the CT log entry an audit proof is required for.
180 std::string leaf_hash_; 180 std::string leaf_hash_;
181 // The size of the CT log's tree, from which the proof is requested.
182 // TODO(robpercival): Remove |tree_size| once |proof_| has a tree_size member.
183 uint64_t tree_size_;
184 // The audit proof to populate. 181 // The audit proof to populate.
185 net::ct::MerkleAuditProof* proof_; 182 net::ct::MerkleAuditProof* proof_;
186 // The callback to invoke when the query is complete. 183 // The callback to invoke when the query is complete.
187 net::CompletionCallback callback_; 184 net::CompletionCallback callback_;
188 // The DnsClient to use for sending DNS requests to the CT log. 185 // The DnsClient to use for sending DNS requests to the CT log.
189 net::DnsClient* dns_client_; 186 net::DnsClient* dns_client_;
190 // The most recent DNS request. Null if no DNS requests have been made. 187 // The most recent DNS request. Null if no DNS requests have been made.
191 std::unique_ptr<net::DnsTransaction> current_dns_transaction_; 188 std::unique_ptr<net::DnsTransaction> current_dns_transaction_;
192 // The most recent DNS response. Only valid so long as the corresponding DNS 189 // The most recent DNS response. Only valid so long as the corresponding DNS
193 // request is stored in |current_dns_transaction_|. 190 // request is stored in |current_dns_transaction_|.
194 const net::DnsResponse* last_dns_response_; 191 const net::DnsResponse* last_dns_response_;
195 // The NetLog that DNS transactions will log to. 192 // The NetLog that DNS transactions will log to.
196 net::NetLogWithSource net_log_; 193 net::NetLogWithSource net_log_;
197 // Produces WeakPtrs to |this| for binding callbacks. 194 // Produces WeakPtrs to |this| for binding callbacks.
198 base::WeakPtrFactory<AuditProofQuery> weak_ptr_factory_; 195 base::WeakPtrFactory<AuditProofQuery> weak_ptr_factory_;
199 }; 196 };
200 197
201 LogDnsClient::AuditProofQuery::AuditProofQuery( 198 LogDnsClient::AuditProofQuery::AuditProofQuery(
202 net::DnsClient* dns_client, 199 net::DnsClient* dns_client,
203 const std::string& domain_for_log, 200 const std::string& domain_for_log,
204 uint64_t tree_size,
205 const net::NetLogWithSource& net_log) 201 const net::NetLogWithSource& net_log)
206 : next_state_(State::NONE), 202 : next_state_(State::NONE),
207 domain_for_log_(domain_for_log), 203 domain_for_log_(domain_for_log),
208 tree_size_(tree_size),
209 dns_client_(dns_client), 204 dns_client_(dns_client),
210 net_log_(net_log), 205 net_log_(net_log),
211 weak_ptr_factory_(this) { 206 weak_ptr_factory_(this) {
212 DCHECK(dns_client_); 207 DCHECK(dns_client_);
213 DCHECK(!domain_for_log_.empty()); 208 DCHECK(!domain_for_log_.empty());
214 } 209 }
215 210
216 // |leaf_hash| is not a const-ref to allow callers to std::move that string into 211 // |leaf_hash| is not a const-ref to allow callers to std::move that string into
217 // the method, avoiding the need to make a copy. 212 // the method, avoiding the need to make a copy.
218 net::Error LogDnsClient::AuditProofQuery::Start( 213 net::Error LogDnsClient::AuditProofQuery::Start(
219 std::string leaf_hash, 214 std::string leaf_hash,
215 uint64_t tree_size,
220 const net::CompletionCallback& callback, 216 const net::CompletionCallback& callback,
221 net::ct::MerkleAuditProof* proof) { 217 net::ct::MerkleAuditProof* proof) {
222 // It should not already be in progress. 218 // It should not already be in progress.
223 DCHECK_EQ(State::NONE, next_state_); 219 DCHECK_EQ(State::NONE, next_state_);
224 proof_ = proof; 220 proof_ = proof;
221 proof_->tree_size = tree_size;
225 leaf_hash_ = std::move(leaf_hash); 222 leaf_hash_ = std::move(leaf_hash);
226 callback_ = callback; 223 callback_ = callback;
227 // The first step in the query is to request the leaf index corresponding to 224 // The first step in the query is to request the leaf index corresponding to
228 // |leaf_hash| from the CT log. 225 // |leaf_hash| from the CT log.
229 next_state_ = State::REQUEST_LEAF_INDEX; 226 next_state_ = State::REQUEST_LEAF_INDEX;
230 // Begin the state machine. 227 // Begin the state machine.
231 return DoLoop(net::OK); 228 return DoLoop(net::OK);
232 } 229 }
233 230
234 net::Error LogDnsClient::AuditProofQuery::DoLoop(net::Error result) { 231 net::Error LogDnsClient::AuditProofQuery::DoLoop(net::Error result) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 if (!ParseLeafIndex(*last_dns_response_, &proof_->leaf_index)) { 302 if (!ParseLeafIndex(*last_dns_response_, &proof_->leaf_index)) {
306 return net::ERR_DNS_MALFORMED_RESPONSE; 303 return net::ERR_DNS_MALFORMED_RESPONSE;
307 } 304 }
308 305
309 // Reject leaf index if it is out-of-range. 306 // Reject leaf index if it is out-of-range.
310 // This indicates either: 307 // This indicates either:
311 // a) the wrong tree_size was provided. 308 // a) the wrong tree_size was provided.
312 // b) the wrong leaf hash was provided. 309 // b) the wrong leaf hash was provided.
313 // c) there is a bug server-side. 310 // c) there is a bug server-side.
314 // The first two are more likely, so return ERR_INVALID_ARGUMENT. 311 // The first two are more likely, so return ERR_INVALID_ARGUMENT.
315 if (proof_->leaf_index >= tree_size_) { 312 if (proof_->leaf_index >= proof_->tree_size) {
316 return net::ERR_INVALID_ARGUMENT; 313 return net::ERR_INVALID_ARGUMENT;
317 } 314 }
318 315
319 next_state_ = State::REQUEST_AUDIT_PROOF_NODES; 316 next_state_ = State::REQUEST_AUDIT_PROOF_NODES;
320 return net::OK; 317 return net::OK;
321 } 318 }
322 319
323 net::Error LogDnsClient::AuditProofQuery::RequestAuditProofNodes() { 320 net::Error LogDnsClient::AuditProofQuery::RequestAuditProofNodes() {
324 // Test pre-conditions (should be guaranteed by DNS response validation). 321 // Test pre-conditions (should be guaranteed by DNS response validation).
325 if (proof_->leaf_index >= tree_size_ || 322 if (proof_->leaf_index >= proof_->tree_size ||
326 proof_->nodes.size() >= 323 proof_->nodes.size() >= net::ct::CalculateAuditPathLength(
327 net::ct::CalculateAuditPathLength(proof_->leaf_index, tree_size_)) { 324 proof_->leaf_index, proof_->tree_size)) {
328 return net::ERR_UNEXPECTED; 325 return net::ERR_UNEXPECTED;
329 } 326 }
330 327
331 std::string qname = base::StringPrintf( 328 std::string qname = base::StringPrintf(
332 "%zu.%" PRIu64 ".%" PRIu64 ".tree.%s.", proof_->nodes.size(), 329 "%zu.%" PRIu64 ".%" PRIu64 ".tree.%s.", proof_->nodes.size(),
333 proof_->leaf_index, tree_size_, domain_for_log_.c_str()); 330 proof_->leaf_index, proof_->tree_size, domain_for_log_.c_str());
334 331
335 if (!StartDnsTransaction(qname)) { 332 if (!StartDnsTransaction(qname)) {
336 return net::ERR_NAME_RESOLUTION_FAILED; 333 return net::ERR_NAME_RESOLUTION_FAILED;
337 } 334 }
338 335
339 next_state_ = State::REQUEST_AUDIT_PROOF_NODES_COMPLETE; 336 next_state_ = State::REQUEST_AUDIT_PROOF_NODES_COMPLETE;
340 return net::ERR_IO_PENDING; 337 return net::ERR_IO_PENDING;
341 } 338 }
342 339
343 net::Error LogDnsClient::AuditProofQuery::RequestAuditProofNodesComplete( 340 net::Error LogDnsClient::AuditProofQuery::RequestAuditProofNodesComplete(
344 net::Error result) { 341 net::Error result) {
345 if (result != net::OK) { 342 if (result != net::OK) {
346 return result; 343 return result;
347 } 344 }
348 345
349 const uint64_t audit_path_length = 346 const uint64_t audit_path_length =
350 net::ct::CalculateAuditPathLength(proof_->leaf_index, tree_size_); 347 net::ct::CalculateAuditPathLength(proof_->leaf_index, proof_->tree_size);
351 348
352 // The calculated |audit_path_length| can't ever be greater than 64, so 349 // The calculated |audit_path_length| can't ever be greater than 64, so
353 // deriving the amount of memory to reserve from the untrusted |leaf_index| 350 // deriving the amount of memory to reserve from the untrusted |leaf_index|
354 // is safe. 351 // is safe.
355 proof_->nodes.reserve(audit_path_length); 352 proof_->nodes.reserve(audit_path_length);
356 353
357 DCHECK(last_dns_response_); 354 DCHECK(last_dns_response_);
358 if (!ParseAuditPath(*last_dns_response_, proof_)) { 355 if (!ParseAuditPath(*last_dns_response_, proof_)) {
359 return net::ERR_DNS_MALFORMED_RESPONSE; 356 return net::ERR_DNS_MALFORMED_RESPONSE;
360 } 357 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 422
426 if (domain_for_log.empty() || leaf_hash.size() != crypto::kSHA256Length) { 423 if (domain_for_log.empty() || leaf_hash.size() != crypto::kSHA256Length) {
427 return net::ERR_INVALID_ARGUMENT; 424 return net::ERR_INVALID_ARGUMENT;
428 } 425 }
429 426
430 if (HasMaxConcurrentQueriesInProgress()) { 427 if (HasMaxConcurrentQueriesInProgress()) {
431 return net::ERR_TEMPORARILY_THROTTLED; 428 return net::ERR_TEMPORARILY_THROTTLED;
432 } 429 }
433 430
434 AuditProofQuery* query = new AuditProofQuery( 431 AuditProofQuery* query = new AuditProofQuery(
435 dns_client_.get(), domain_for_log.as_string(), tree_size, net_log_); 432 dns_client_.get(), domain_for_log.as_string(), net_log_);
436 // Transfers ownership of |query| to |audit_proof_queries_|. 433 // Transfers ownership of |query| to |audit_proof_queries_|.
437 audit_proof_queries_.emplace_back(query); 434 audit_proof_queries_.emplace_back(query);
438 435
439 return query->Start(std::move(leaf_hash), 436 return query->Start(std::move(leaf_hash), tree_size,
440 base::Bind(&LogDnsClient::QueryAuditProofComplete, 437 base::Bind(&LogDnsClient::QueryAuditProofComplete,
441 weak_ptr_factory_.GetWeakPtr(), 438 weak_ptr_factory_.GetWeakPtr(),
442 base::Unretained(query), callback), 439 base::Unretained(query), callback),
443 proof); 440 proof);
444 } 441 }
445 442
446 void LogDnsClient::QueryAuditProofComplete( 443 void LogDnsClient::QueryAuditProofComplete(
447 AuditProofQuery* query, 444 AuditProofQuery* query,
448 const net::CompletionCallback& callback, 445 const net::CompletionCallback& callback,
449 int net_error) { 446 int net_error) {
(...skipping 23 matching lines...) Expand all
473 } 470 }
474 471
475 void LogDnsClient::UpdateDnsConfig() { 472 void LogDnsClient::UpdateDnsConfig() {
476 net::DnsConfig config; 473 net::DnsConfig config;
477 net::NetworkChangeNotifier::GetDnsConfig(&config); 474 net::NetworkChangeNotifier::GetDnsConfig(&config);
478 if (config.IsValid()) 475 if (config.IsValid())
479 dns_client_->SetConfig(config); 476 dns_client_->SetConfig(config);
480 } 477 }
481 478
482 } // namespace certificate_transparency 479 } // namespace certificate_transparency
OLDNEW
« no previous file with comments | « components/certificate_transparency/log_dns_client.h ('k') | components/certificate_transparency/log_dns_client_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698