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

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

Issue 2367523002: Merge LogDnsClient's QueryLeafIndex and QueryAuditProof methods (Closed)
Patch Set: Rebase Created 4 years, 2 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/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/format_macros.h" 8 #include "base/format_macros.h"
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/ptr_util.h"
11 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
13 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
14 #include "base/threading/thread_task_runner_handle.h" 15 #include "base/threading/thread_task_runner_handle.h"
15 #include "base/time/time.h" 16 #include "base/time/time.h"
16 #include "components/base32/base32.h" 17 #include "components/base32/base32.h"
17 #include "crypto/sha2.h" 18 #include "crypto/sha2.h"
18 #include "net/base/net_errors.h" 19 #include "net/base/net_errors.h"
19 #include "net/cert/merkle_audit_proof.h" 20 #include "net/cert/merkle_audit_proof.h"
20 #include "net/dns/dns_client.h" 21 #include "net/dns/dns_client.h"
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 91
91 for (size_t i = 0; i < audit_path.size(); i += crypto::kSHA256Length) { 92 for (size_t i = 0; i < audit_path.size(); i += crypto::kSHA256Length) {
92 proof->nodes.push_back(audit_path.substr(i, crypto::kSHA256Length)); 93 proof->nodes.push_back(audit_path.substr(i, crypto::kSHA256Length));
93 } 94 }
94 95
95 return true; 96 return true;
96 } 97 }
97 98
98 } // namespace 99 } // namespace
99 100
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
103 // series of DNS requests to get the nodes of the proof.
104 class LogDnsClient::AuditProofQuery {
105 public:
106 using CompletionCallback =
107 base::Callback<void(int net_error, AuditProofQuery* query)>;
108
109 // The LogDnsClient is guaranteed to outlive the AuditProofQuery, so it's safe
110 // to leave ownership of |dns_client| with LogDnsClient.
111 AuditProofQuery(net::DnsClient* dns_client,
112 const std::string& domain_for_log,
113 uint64_t tree_size,
114 const net::NetLogWithSource& net_log);
115
116 // Begins the process of getting an audit proof for the CT log entry with a
117 // leaf hash of |leaf_hash|. The |callback| will be invoked when finished.
118 void Start(base::StringPiece leaf_hash, CompletionCallback callback);
119
120 // Transfers the audit proof to the caller.
121 // Only call this once the query has completed, otherwise the proof will be
122 // incomplete.
123 std::unique_ptr<net::ct::MerkleAuditProof> TakeProof();
124
125 private:
126 // Requests the leaf index of the CT log entry with |leaf_hash|.
127 void QueryLeafIndex(base::StringPiece leaf_hash);
128
129 // Processes the response to a leaf index request.
130 // The received leaf index will be added to the proof.
131 void QueryLeafIndexComplete(net::DnsTransaction* transaction,
132 int net_error,
133 const net::DnsResponse* response);
134
135 // Queries a CT log to retrieve part of an audit proof. The |node_index|
136 // indicates which node of the audit proof/ should be requested. The CT log
137 // may return up to 7 nodes, starting from |node_index| (this is the maximum
138 // that will fit in a DNS UDP packet). The nodes will be appended to the
139 // proof.
140 void QueryAuditProofNodes(uint64_t node_index);
141
142 // Processes the response to an audit proof request.
143 // This will contain some, but not necessarily all, of the audit proof nodes.
144 void QueryAuditProofNodesComplete(net::DnsTransaction* transaction,
145 int net_error,
146 const net::DnsResponse* response);
147
148 std::string domain_for_log_;
149 // TODO(robpercival): Remove |tree_size| once |proof_| has a tree_size member.
150 uint64_t tree_size_;
151 std::unique_ptr<net::ct::MerkleAuditProof> proof_;
152 CompletionCallback callback_;
153 net::DnsClient* dns_client_;
154 std::unique_ptr<net::DnsTransaction> current_dns_transaction_;
155 net::NetLogWithSource net_log_;
156 base::WeakPtrFactory<AuditProofQuery> weak_ptr_factory_;
157 };
158
159 LogDnsClient::AuditProofQuery::AuditProofQuery(
160 net::DnsClient* dns_client,
161 const std::string& domain_for_log,
162 uint64_t tree_size,
163 const net::NetLogWithSource& net_log)
164 : domain_for_log_(domain_for_log),
165 tree_size_(tree_size),
166 dns_client_(dns_client),
167 net_log_(net_log),
168 weak_ptr_factory_(this) {
169 DCHECK(dns_client_);
170 DCHECK(!domain_for_log_.empty());
171 }
172
173 void LogDnsClient::AuditProofQuery::Start(base::StringPiece leaf_hash,
174 CompletionCallback callback) {
175 current_dns_transaction_.reset();
176 proof_ = base::MakeUnique<net::ct::MerkleAuditProof>();
177 callback_ = callback;
178 QueryLeafIndex(leaf_hash);
179 }
180
181 std::unique_ptr<net::ct::MerkleAuditProof>
182 LogDnsClient::AuditProofQuery::TakeProof() {
183 return std::move(proof_);
184 }
185
186 void LogDnsClient::AuditProofQuery::QueryLeafIndex(
187 base::StringPiece leaf_hash) {
188 std::string encoded_leaf_hash =
189 base32::Base32Encode(leaf_hash, base32::Base32EncodePolicy::OMIT_PADDING);
190 DCHECK_EQ(encoded_leaf_hash.size(), 52u);
191
192 std::string qname = base::StringPrintf(
193 "%s.hash.%s.", encoded_leaf_hash.c_str(), domain_for_log_.data());
194
195 net::DnsTransactionFactory* factory = dns_client_->GetTransactionFactory();
196 if (factory == nullptr) {
197 base::ThreadTaskRunnerHandle::Get()->PostTask(
198 FROM_HERE, base::Bind(callback_, net::Error::ERR_NAME_RESOLUTION_FAILED,
199 base::Unretained(this)));
200 return;
201 }
202
203 net::DnsTransactionFactory::CallbackType transaction_callback =
204 base::Bind(&LogDnsClient::AuditProofQuery::QueryLeafIndexComplete,
205 weak_ptr_factory_.GetWeakPtr());
206
207 current_dns_transaction_ = factory->CreateTransaction(
208 qname, net::dns_protocol::kTypeTXT, transaction_callback, net_log_);
209
210 current_dns_transaction_->Start();
211 }
212
213 void LogDnsClient::AuditProofQuery::QueryLeafIndexComplete(
214 net::DnsTransaction* transaction,
215 int net_error,
216 const net::DnsResponse* response) {
217 // If we've received no response but no net::error either (shouldn't
218 // happen),
219 // report the response as invalid.
220 if (response == nullptr && net_error == net::OK) {
221 net_error = net::ERR_INVALID_RESPONSE;
222 }
223
224 if (net_error != net::OK) {
225 base::ThreadTaskRunnerHandle::Get()->PostTask(
226 FROM_HERE, base::Bind(callback_, net_error, base::Unretained(this)));
227 return;
228 }
229
230 if (!ParseLeafIndex(*response, &proof_->leaf_index)) {
231 base::ThreadTaskRunnerHandle::Get()->PostTask(
232 FROM_HERE, base::Bind(callback_, net::ERR_DNS_MALFORMED_RESPONSE,
233 base::Unretained(this)));
234 return;
235 }
236
237 // Reject leaf index if it is out-of-range.
238 // This indicates either:
239 // a) the wrong tree_size was provided.
240 // b) the wrong leaf hash was provided.
241 // c) there is a bug server-side.
242 // The first two are more likely, so return ERR_INVALID_ARGUMENT.
243 if (proof_->leaf_index >= tree_size_) {
244 base::ThreadTaskRunnerHandle::Get()->PostTask(
245 FROM_HERE, base::Bind(callback_, net::ERR_INVALID_ARGUMENT,
246 base::Unretained(this)));
247 return;
248 }
249
250 // QueryAuditProof for the first batch of audit proof_ nodes (i.e. starting
251 // from 0).
252 QueryAuditProofNodes(0 /* start node index */);
253 }
254
255 void LogDnsClient::AuditProofQuery::QueryAuditProofNodes(uint64_t node_index) {
256 DCHECK_LT(proof_->leaf_index, tree_size_);
257 DCHECK_LT(node_index,
258 net::ct::CalculateAuditPathLength(proof_->leaf_index, tree_size_));
259
260 std::string qname = base::StringPrintf(
261 "%" PRIu64 ".%" PRIu64 ".%" PRIu64 ".tree.%s.", node_index,
262 proof_->leaf_index, tree_size_, domain_for_log_.data());
263
264 net::DnsTransactionFactory* factory = dns_client_->GetTransactionFactory();
265 if (factory == nullptr) {
266 base::ThreadTaskRunnerHandle::Get()->PostTask(
267 FROM_HERE, base::Bind(callback_, net::Error::ERR_NAME_RESOLUTION_FAILED,
268 base::Unretained(this)));
269 return;
270 }
271
272 net::DnsTransactionFactory::CallbackType transaction_callback =
273 base::Bind(&LogDnsClient::AuditProofQuery::QueryAuditProofNodesComplete,
274 weak_ptr_factory_.GetWeakPtr());
275
276 current_dns_transaction_ = factory->CreateTransaction(
277 qname, net::dns_protocol::kTypeTXT, transaction_callback, net_log_);
278 current_dns_transaction_->Start();
279 }
280
281 void LogDnsClient::AuditProofQuery::QueryAuditProofNodesComplete(
282 net::DnsTransaction* transaction,
283 int net_error,
284 const net::DnsResponse* response) {
285 // If we receive no response but no net::error either (shouldn't happen),
286 // report the response as invalid.
287 if (response == nullptr && net_error == net::OK) {
288 net_error = net::ERR_INVALID_RESPONSE;
289 }
290
291 if (net_error != net::OK) {
292 base::ThreadTaskRunnerHandle::Get()->PostTask(
293 FROM_HERE, base::Bind(callback_, net_error, base::Unretained(this)));
294 return;
295 }
296
297 const uint64_t audit_path_length =
298 net::ct::CalculateAuditPathLength(proof_->leaf_index, tree_size_);
299 // The calculated |audit_path_length| can't ever be greater than 64, so
300 // deriving the amount of memory to reserve from the untrusted |leaf_index|
301 // is safe.
302 proof_->nodes.reserve(audit_path_length);
303
304 if (!ParseAuditPath(*response, proof_.get())) {
305 base::ThreadTaskRunnerHandle::Get()->PostTask(
306 FROM_HERE, base::Bind(callback_, net::ERR_DNS_MALFORMED_RESPONSE,
307 base::Unretained(this)));
308 return;
309 }
310
311 const uint64_t audit_path_nodes_received = proof_->nodes.size();
312 if (audit_path_nodes_received < audit_path_length) {
313 QueryAuditProofNodes(audit_path_nodes_received);
314 return;
315 }
316
317 base::ThreadTaskRunnerHandle::Get()->PostTask(
318 FROM_HERE, base::Bind(callback_, net::OK, base::Unretained(this)));
319 }
320
100 LogDnsClient::LogDnsClient(std::unique_ptr<net::DnsClient> dns_client, 321 LogDnsClient::LogDnsClient(std::unique_ptr<net::DnsClient> dns_client,
101 const net::NetLogWithSource& net_log, 322 const net::NetLogWithSource& net_log,
102 size_t max_concurrent_queries) 323 size_t max_concurrent_queries)
103 : dns_client_(std::move(dns_client)), 324 : dns_client_(std::move(dns_client)),
104 net_log_(net_log), 325 net_log_(net_log),
105 max_concurrent_queries_(max_concurrent_queries), 326 max_concurrent_queries_(max_concurrent_queries),
106 weak_ptr_factory_(this) { 327 weak_ptr_factory_(this) {
107 CHECK(dns_client_); 328 CHECK(dns_client_);
108 net::NetworkChangeNotifier::AddDNSObserver(this); 329 net::NetworkChangeNotifier::AddDNSObserver(this);
109 UpdateDnsConfig(); 330 UpdateDnsConfig();
110 } 331 }
111 332
112 LogDnsClient::~LogDnsClient() { 333 LogDnsClient::~LogDnsClient() {
113 net::NetworkChangeNotifier::RemoveDNSObserver(this); 334 net::NetworkChangeNotifier::RemoveDNSObserver(this);
114 } 335 }
115 336
116 void LogDnsClient::OnDNSChanged() { 337 void LogDnsClient::OnDNSChanged() {
117 UpdateDnsConfig(); 338 UpdateDnsConfig();
118 } 339 }
119 340
120 void LogDnsClient::OnInitialDNSConfigRead() { 341 void LogDnsClient::OnInitialDNSConfigRead() {
121 UpdateDnsConfig(); 342 UpdateDnsConfig();
122 } 343 }
123 344
124 void LogDnsClient::QueryLeafIndex(base::StringPiece domain_for_log,
125 base::StringPiece leaf_hash,
126 const LeafIndexCallback& callback) {
127 if (domain_for_log.empty() || leaf_hash.size() != crypto::kSHA256Length) {
128 base::ThreadTaskRunnerHandle::Get()->PostTask(
129 FROM_HERE, base::Bind(callback, net::Error::ERR_INVALID_ARGUMENT, 0));
130 return;
131 }
132
133 if (HasMaxConcurrentQueriesInProgress()) {
134 base::ThreadTaskRunnerHandle::Get()->PostTask(
135 FROM_HERE,
136 base::Bind(callback, net::Error::ERR_TEMPORARILY_THROTTLED, 0));
137 return;
138 }
139
140 std::string encoded_leaf_hash =
141 base32::Base32Encode(leaf_hash, base32::Base32EncodePolicy::OMIT_PADDING);
142 DCHECK_EQ(encoded_leaf_hash.size(), 52u);
143
144 net::DnsTransactionFactory* factory = dns_client_->GetTransactionFactory();
145 if (factory == nullptr) {
146 base::ThreadTaskRunnerHandle::Get()->PostTask(
147 FROM_HERE,
148 base::Bind(callback, net::Error::ERR_NAME_RESOLUTION_FAILED, 0));
149 return;
150 }
151
152 std::string qname = base::StringPrintf(
153 "%s.hash.%s.", encoded_leaf_hash.c_str(), domain_for_log.data());
154
155 net::DnsTransactionFactory::CallbackType transaction_callback = base::Bind(
156 &LogDnsClient::QueryLeafIndexComplete, weak_ptr_factory_.GetWeakPtr());
157
158 std::unique_ptr<net::DnsTransaction> dns_transaction =
159 factory->CreateTransaction(qname, net::dns_protocol::kTypeTXT,
160 transaction_callback, net_log_);
161
162 dns_transaction->Start();
163 leaf_index_queries_.push_back({std::move(dns_transaction), callback});
164 }
165
166 // The performance of this could be improved by sending all of the expected 345 // The performance of this could be improved by sending all of the expected
167 // queries up front. Each response can contain a maximum of 7 audit path nodes, 346 // queries up front. Each response can contain a maximum of 7 audit path nodes,
168 // so for an audit proof of size 20, it could send 3 queries (for nodes 0-6, 347 // so for an audit proof of size 20, it could send 3 queries (for nodes 0-6,
169 // 7-13 and 14-19) immediately. Currently, it sends only the first and then, 348 // 7-13 and 14-19) immediately. Currently, it sends only the first and then,
170 // based on the number of nodes received, sends the next query. The complexity 349 // based on the number of nodes received, sends the next query. The complexity
171 // of the code would increase though, as it would need to detect gaps in the 350 // of the code would increase though, as it would need to detect gaps in the
172 // audit proof caused by the server not responding with the anticipated number 351 // audit proof caused by the server not responding with the anticipated number
173 // of nodes. Ownership of the proof would need to change, as it would be shared 352 // of nodes. Ownership of the proof would need to change, as it would be shared
174 // between simultaneous DNS transactions. Throttling of queries would also need 353 // between simultaneous DNS transactions. Throttling of queries would also need
175 // to take into account this increase in parallelism. 354 // to take into account this increase in parallelism.
176 void LogDnsClient::QueryAuditProof(base::StringPiece domain_for_log, 355 void LogDnsClient::QueryAuditProof(const std::string& domain_for_log,
177 uint64_t leaf_index, 356 base::StringPiece leaf_hash,
178 uint64_t tree_size, 357 uint64_t tree_size,
179 const AuditProofCallback& callback) { 358 const AuditProofCallback& callback) {
180 if (domain_for_log.empty() || leaf_index >= tree_size) { 359 if (domain_for_log.empty() || leaf_hash.size() != crypto::kSHA256Length) {
181 base::ThreadTaskRunnerHandle::Get()->PostTask( 360 base::ThreadTaskRunnerHandle::Get()->PostTask(
182 FROM_HERE, 361 FROM_HERE,
183 base::Bind(callback, net::Error::ERR_INVALID_ARGUMENT, nullptr)); 362 base::Bind(callback, net::Error::ERR_INVALID_ARGUMENT, nullptr));
184 return; 363 return;
185 } 364 }
186 365
187 if (HasMaxConcurrentQueriesInProgress()) { 366 if (HasMaxConcurrentQueriesInProgress()) {
188 base::ThreadTaskRunnerHandle::Get()->PostTask( 367 base::ThreadTaskRunnerHandle::Get()->PostTask(
189 FROM_HERE, 368 FROM_HERE,
190 base::Bind(callback, net::Error::ERR_TEMPORARILY_THROTTLED, nullptr)); 369 base::Bind(callback, net::Error::ERR_TEMPORARILY_THROTTLED, nullptr));
191 return; 370 return;
192 } 371 }
193 372
194 std::unique_ptr<net::ct::MerkleAuditProof> proof( 373 audit_proof_queries_.emplace_back(new AuditProofQuery(
195 new net::ct::MerkleAuditProof); 374 dns_client_.get(), domain_for_log, tree_size, net_log_));
196 proof->leaf_index = leaf_index;
197 // TODO(robpercival): Once a "tree_size" field is added to MerkleAuditProof,
198 // pass |tree_size| to QueryAuditProofNodes using that.
199 375
200 // Query for the first batch of audit proof nodes (i.e. starting from 0). 376 AuditProofQuery::CompletionCallback internal_callback =
201 QueryAuditProofNodes(std::move(proof), domain_for_log, tree_size, 0, 377 base::Bind(&LogDnsClient::QueryAuditProofComplete,
202 callback); 378 weak_ptr_factory_.GetWeakPtr(), callback);
379
380 audit_proof_queries_.back()->Start(leaf_hash, internal_callback);
203 } 381 }
204 382
205 void LogDnsClient::QueryLeafIndexComplete(net::DnsTransaction* transaction, 383 void LogDnsClient::QueryAuditProofComplete(const AuditProofCallback& callback,
206 int net_error, 384 int result,
207 const net::DnsResponse* response) { 385 AuditProofQuery* query) {
208 auto query_iterator = 386 DCHECK(query);
209 std::find_if(leaf_index_queries_.begin(), leaf_index_queries_.end(),
210 [transaction](const Query<LeafIndexCallback>& query) {
211 return query.transaction.get() == transaction;
212 });
213 if (query_iterator == leaf_index_queries_.end()) {
214 NOTREACHED();
215 return;
216 }
217 const Query<LeafIndexCallback> query = std::move(*query_iterator);
218 leaf_index_queries_.erase(query_iterator);
219 387
220 // If we've received no response but no net::error either (shouldn't happen), 388 std::unique_ptr<net::ct::MerkleAuditProof> proof;
221 // report the response as invalid. 389 if (result == net::OK) {
222 if (response == nullptr && net_error == net::OK) { 390 proof = query->TakeProof();
223 net_error = net::ERR_INVALID_RESPONSE;
224 } 391 }
225 392
226 if (net_error != net::OK) { 393 // Finished with the query - destroy it.
227 base::ThreadTaskRunnerHandle::Get()->PostTask( 394 auto query_iterator =
228 FROM_HERE, base::Bind(query.callback, net_error, 0)); 395 std::find_if(audit_proof_queries_.begin(), audit_proof_queries_.end(),
229 return; 396 [query](const std::unique_ptr<AuditProofQuery>& p) {
230 } 397 return p.get() == query;
231 398 });
232 uint64_t leaf_index; 399 DCHECK(query_iterator != audit_proof_queries_.end());
233 if (!ParseLeafIndex(*response, &leaf_index)) { 400 audit_proof_queries_.erase(query_iterator);
234 base::ThreadTaskRunnerHandle::Get()->PostTask(
235 FROM_HERE,
236 base::Bind(query.callback, net::ERR_DNS_MALFORMED_RESPONSE, 0));
237 return;
238 }
239 401
240 base::ThreadTaskRunnerHandle::Get()->PostTask( 402 base::ThreadTaskRunnerHandle::Get()->PostTask(
241 FROM_HERE, base::Bind(query.callback, net::OK, leaf_index)); 403 FROM_HERE, base::Bind(callback, result, base::Passed(&proof)));
242 }
243
244 void LogDnsClient::QueryAuditProofNodes(
245 std::unique_ptr<net::ct::MerkleAuditProof> proof,
246 base::StringPiece domain_for_log,
247 uint64_t tree_size,
248 uint64_t node_index,
249 const AuditProofCallback& callback) {
250 // Preconditions that should be guaranteed internally by this class.
251 DCHECK(proof);
252 DCHECK(!domain_for_log.empty());
253 DCHECK_LT(proof->leaf_index, tree_size);
254 DCHECK_LT(node_index,
255 net::ct::CalculateAuditPathLength(proof->leaf_index, tree_size));
256
257 net::DnsTransactionFactory* factory = dns_client_->GetTransactionFactory();
258 if (factory == nullptr) {
259 base::ThreadTaskRunnerHandle::Get()->PostTask(
260 FROM_HERE,
261 base::Bind(callback, net::Error::ERR_NAME_RESOLUTION_FAILED, nullptr));
262 return;
263 }
264
265 std::string qname = base::StringPrintf(
266 "%" PRIu64 ".%" PRIu64 ".%" PRIu64 ".tree.%s.", node_index,
267 proof->leaf_index, tree_size, domain_for_log.data());
268
269 net::DnsTransactionFactory::CallbackType transaction_callback =
270 base::Bind(&LogDnsClient::QueryAuditProofNodesComplete,
271 weak_ptr_factory_.GetWeakPtr(), base::Passed(std::move(proof)),
272 domain_for_log, tree_size);
273
274 std::unique_ptr<net::DnsTransaction> dns_transaction =
275 factory->CreateTransaction(qname, net::dns_protocol::kTypeTXT,
276 transaction_callback, net_log_);
277 dns_transaction->Start();
278 audit_proof_queries_.push_back({std::move(dns_transaction), callback});
279 }
280
281 void LogDnsClient::QueryAuditProofNodesComplete(
282 std::unique_ptr<net::ct::MerkleAuditProof> proof,
283 base::StringPiece domain_for_log,
284 uint64_t tree_size,
285 net::DnsTransaction* transaction,
286 int net_error,
287 const net::DnsResponse* response) {
288 // Preconditions that should be guaranteed internally by this class.
289 DCHECK(proof);
290 DCHECK(!domain_for_log.empty());
291
292 auto query_iterator =
293 std::find_if(audit_proof_queries_.begin(), audit_proof_queries_.end(),
294 [transaction](const Query<AuditProofCallback>& query) {
295 return query.transaction.get() == transaction;
296 });
297
298 if (query_iterator == audit_proof_queries_.end()) {
299 NOTREACHED();
300 return;
301 }
302 const Query<AuditProofCallback> query = std::move(*query_iterator);
303 audit_proof_queries_.erase(query_iterator);
304
305 // If we've received no response but no net::error either (shouldn't happen),
306 // report the response as invalid.
307 if (response == nullptr && net_error == net::OK) {
308 net_error = net::ERR_INVALID_RESPONSE;
309 }
310
311 if (net_error != net::OK) {
312 base::ThreadTaskRunnerHandle::Get()->PostTask(
313 FROM_HERE, base::Bind(query.callback, net_error, nullptr));
314 return;
315 }
316
317 const uint64_t audit_path_length =
318 net::ct::CalculateAuditPathLength(proof->leaf_index, tree_size);
319 proof->nodes.reserve(audit_path_length);
320
321 if (!ParseAuditPath(*response, proof.get())) {
322 base::ThreadTaskRunnerHandle::Get()->PostTask(
323 FROM_HERE,
324 base::Bind(query.callback, net::ERR_DNS_MALFORMED_RESPONSE, nullptr));
325 return;
326 }
327
328 const uint64_t audit_path_nodes_received = proof->nodes.size();
329 if (audit_path_nodes_received < audit_path_length) {
330 QueryAuditProofNodes(std::move(proof), domain_for_log, tree_size,
331 audit_path_nodes_received, query.callback);
332 return;
333 }
334
335 base::ThreadTaskRunnerHandle::Get()->PostTask(
336 FROM_HERE,
337 base::Bind(query.callback, net::OK, base::Passed(std::move(proof))));
338 } 404 }
339 405
340 bool LogDnsClient::HasMaxConcurrentQueriesInProgress() const { 406 bool LogDnsClient::HasMaxConcurrentQueriesInProgress() const {
341 const size_t queries_in_progress =
342 leaf_index_queries_.size() + audit_proof_queries_.size();
343
344 return max_concurrent_queries_ != 0 && 407 return max_concurrent_queries_ != 0 &&
345 queries_in_progress >= max_concurrent_queries_; 408 audit_proof_queries_.size() >= max_concurrent_queries_;
346 } 409 }
347 410
348 void LogDnsClient::UpdateDnsConfig() { 411 void LogDnsClient::UpdateDnsConfig() {
349 net::DnsConfig config; 412 net::DnsConfig config;
350 net::NetworkChangeNotifier::GetDnsConfig(&config); 413 net::NetworkChangeNotifier::GetDnsConfig(&config);
351 if (config.IsValid()) 414 if (config.IsValid())
352 dns_client_->SetConfig(config); 415 dns_client_->SetConfig(config);
353 } 416 }
354 417
355 } // namespace certificate_transparency 418 } // 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