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

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

Issue 1405293009: Certificate Transparency: Fetching consistency proofs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix compilation on Android Created 5 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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_proof_fetcher.h" 5 #include "components/certificate_transparency/log_proof_fetcher.h"
6 6
7 #include <iterator> 7 #include <iterator>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/strings/stringprintf.h"
12 #include "base/values.h" 13 #include "base/values.h"
13 #include "components/safe_json/safe_json_parser.h" 14 #include "components/safe_json/safe_json_parser.h"
14 #include "net/base/io_buffer.h" 15 #include "net/base/io_buffer.h"
15 #include "net/base/load_flags.h" 16 #include "net/base/load_flags.h"
16 #include "net/base/net_errors.h" 17 #include "net/base/net_errors.h"
17 #include "net/base/request_priority.h" 18 #include "net/base/request_priority.h"
18 #include "net/cert/ct_log_response_parser.h" 19 #include "net/cert/ct_log_response_parser.h"
19 #include "net/cert/signed_tree_head.h" 20 #include "net/cert/signed_tree_head.h"
20 #include "net/http/http_status_code.h" 21 #include "net/http/http_status_code.h"
21 #include "net/url_request/url_request_context.h" 22 #include "net/url_request/url_request_context.h"
(...skipping 11 matching lines...) Expand all
33 case net::URLRequestStatus::CANCELED: 34 case net::URLRequestStatus::CANCELED:
34 return net::ERR_ABORTED; 35 return net::ERR_ABORTED;
35 case net::URLRequestStatus::FAILED: 36 case net::URLRequestStatus::FAILED:
36 return status.error(); 37 return status.error();
37 default: 38 default:
38 NOTREACHED(); 39 NOTREACHED();
39 return net::ERR_FAILED; 40 return net::ERR_FAILED;
40 } 41 }
41 } 42 }
42 43
44 enum LogRequestType { SIGNED_TREE_HEAD, CONSISTENCY_PROOF };
45
43 } // namespace 46 } // namespace
44 47
45 struct LogProofFetcher::FetchState { 48 struct LogProofFetcher::FetchState {
46 FetchState(const std::string& log_id, 49 FetchState(const std::string& log_id,
47 const SignedTreeHeadFetchedCallback& fetched_callback, 50 LogRequestType request_type,
51 const SignedTreeHeadFetchedCallback& sth_fetch_callback,
52 const ConsistencyProofFetchedCallback& proof_fetch_callback,
48 const FetchFailedCallback& failed_callback); 53 const FetchFailedCallback& failed_callback);
49 ~FetchState(); 54 ~FetchState();
50 55
51 std::string log_id; 56 std::string log_id;
52 SignedTreeHeadFetchedCallback fetched_callback; 57 LogRequestType request_type;
58 SignedTreeHeadFetchedCallback sth_fetch_callback;
59 ConsistencyProofFetchedCallback proof_fetch_callback;
53 FetchFailedCallback failed_callback; 60 FetchFailedCallback failed_callback;
54 scoped_refptr<net::IOBufferWithSize> response_buffer; 61 scoped_refptr<net::IOBufferWithSize> response_buffer;
55 std::string assembled_response; 62 std::string assembled_response;
56 }; 63 };
57 64
58 LogProofFetcher::FetchState::FetchState( 65 LogProofFetcher::FetchState::FetchState(
59 const std::string& log_id, 66 const std::string& log_id,
60 const SignedTreeHeadFetchedCallback& fetched_callback, 67 LogRequestType request_type,
68 const SignedTreeHeadFetchedCallback& sth_fetch_callback,
69 const ConsistencyProofFetchedCallback& proof_fetch_callback,
61 const FetchFailedCallback& failed_callback) 70 const FetchFailedCallback& failed_callback)
62 : log_id(log_id), 71 : log_id(log_id),
63 fetched_callback(fetched_callback), 72 request_type(request_type),
73 sth_fetch_callback(sth_fetch_callback),
74 proof_fetch_callback(proof_fetch_callback),
64 failed_callback(failed_callback), 75 failed_callback(failed_callback),
65 response_buffer(new net::IOBufferWithSize(kMaxLogResponseSizeInBytes)) {} 76 response_buffer(new net::IOBufferWithSize(kMaxLogResponseSizeInBytes)) {
77 DCHECK(!(sth_fetch_callback.is_null() && proof_fetch_callback.is_null()));
78 }
66 79
67 LogProofFetcher::FetchState::~FetchState() {} 80 LogProofFetcher::FetchState::~FetchState() {}
68 81
69 LogProofFetcher::LogProofFetcher(net::URLRequestContext* request_context) 82 LogProofFetcher::LogProofFetcher(net::URLRequestContext* request_context)
70 : request_context_(request_context), weak_factory_(this) { 83 : request_context_(request_context), weak_factory_(this) {
71 DCHECK(request_context); 84 DCHECK(request_context);
72 } 85 }
73 86
74 LogProofFetcher::~LogProofFetcher() { 87 LogProofFetcher::~LogProofFetcher() {
75 STLDeleteContainerPairPointers(inflight_requests_.begin(), 88 STLDeleteContainerPairPointers(inflight_requests_.begin(),
76 inflight_requests_.end()); 89 inflight_requests_.end());
77 } 90 }
78 91
79 void LogProofFetcher::FetchSignedTreeHead( 92 void LogProofFetcher::FetchSignedTreeHead(
80 const GURL& base_log_url, 93 const GURL& base_log_url,
81 const std::string& log_id, 94 const std::string& log_id,
82 const SignedTreeHeadFetchedCallback& fetched_callback, 95 const SignedTreeHeadFetchedCallback& fetched_callback,
83 const FetchFailedCallback& failed_callback) { 96 const FetchFailedCallback& failed_callback) {
mmenke 2015/11/18 19:25:15 Suggest putting everything in this method except t
Eran Messeri 2015/11/24 22:53:38 Done. I note that the use of two callbacks is a sm
mmenke 2015/11/25 17:40:28 Could also make a single callback that takes a val
Eran Messeri 2015/11/26 22:07:12 Should be fixed now that I've switched to using a
84 DCHECK(base_log_url.SchemeIsHTTPOrHTTPS()); 97 DCHECK(base_log_url.SchemeIsHTTPOrHTTPS());
85 GURL fetch_url(base_log_url.Resolve("ct/v1/get-sth")); 98 GURL fetch_url(base_log_url.Resolve("ct/v1/get-sth"));
86 scoped_ptr<net::URLRequest> request = 99 net::URLRequest* request = CreateRequest(fetch_url);
87 request_context_->CreateRequest(fetch_url, net::DEFAULT_PRIORITY, this);
88 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
89 net::LOAD_DO_NOT_SAVE_COOKIES |
90 net::LOAD_DO_NOT_SEND_AUTH_DATA);
91 100
92 FetchState* fetch_state = 101 FetchState* fetch_state =
93 new FetchState(log_id, fetched_callback, failed_callback); 102 new FetchState(log_id, LogRequestType::SIGNED_TREE_HEAD, fetched_callback,
103 ConsistencyProofFetchedCallback(), failed_callback);
94 request->Start(); 104 request->Start();
95 inflight_requests_.insert(std::make_pair(request.release(), fetch_state)); 105 inflight_requests_.insert(std::make_pair(request, fetch_state));
106 }
107
108 void LogProofFetcher::FetchConsistencyProof(
109 const GURL& base_log_url,
110 const std::string& log_id,
111 size_t old_tree_size,
112 size_t new_tree_size,
113 const ConsistencyProofFetchedCallback& fetched_callback,
114 const FetchFailedCallback& failed_callback) {
115 DCHECK(base_log_url.SchemeIsHTTPOrHTTPS());
116
117 std::string relative =
118 base::StringPrintf("ct/v1/get-sth-consistency?first=%lu&second=%lu",
119 static_cast<unsigned long>(old_tree_size),
120 static_cast<unsigned long>(new_tree_size));
mmenke 2015/11/18 19:25:15 include format_macros.h and use PRIuS to use print
Eran Messeri 2015/11/24 22:53:38 Done. These are size_t - they indicate size of a M
121 GURL fetch_url = base_log_url.Resolve(relative);
122
123 net::URLRequest* request = CreateRequest(fetch_url);
124
125 FetchState* fetch_state = new FetchState(
126 log_id, LogRequestType::CONSISTENCY_PROOF,
127 SignedTreeHeadFetchedCallback(), fetched_callback, failed_callback);
128 request->Start();
129 inflight_requests_.insert(std::make_pair(request, fetch_state));
96 } 130 }
97 131
98 void LogProofFetcher::OnResponseStarted(net::URLRequest* request) { 132 void LogProofFetcher::OnResponseStarted(net::URLRequest* request) {
99 net::URLRequestStatus status(request->status()); 133 net::URLRequestStatus status(request->status());
100 DCHECK(inflight_requests_.count(request)); 134 DCHECK(inflight_requests_.count(request));
101 FetchState* fetch_state = inflight_requests_.find(request)->second; 135 FetchState* fetch_state = inflight_requests_.find(request)->second;
102 136
103 if (!status.is_success() || request->GetResponseCode() != net::HTTP_OK) { 137 if (!status.is_success() || request->GetResponseCode() != net::HTTP_OK) {
104 int net_error = net::OK; 138 int net_error = net::OK;
105 int http_response_code = request->GetResponseCode(); 139 int http_response_code = request->GetResponseCode();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 } 212 }
179 } 213 }
180 214
181 void LogProofFetcher::RequestComplete(net::URLRequest* request) { 215 void LogProofFetcher::RequestComplete(net::URLRequest* request) {
182 DCHECK(inflight_requests_.count(request)); 216 DCHECK(inflight_requests_.count(request));
183 217
184 FetchState* fetch_state = inflight_requests_.find(request)->second; 218 FetchState* fetch_state = inflight_requests_.find(request)->second;
185 219
186 // Get rid of the buffer as it really isn't necessary. 220 // Get rid of the buffer as it really isn't necessary.
187 fetch_state->response_buffer = nullptr; 221 fetch_state->response_buffer = nullptr;
188 safe_json::SafeJsonParser::Parse( 222 if (fetch_state->request_type == LogRequestType::SIGNED_TREE_HEAD) {
189 fetch_state->assembled_response, 223 safe_json::SafeJsonParser::Parse(
190 base::Bind(&LogProofFetcher::OnSTHJsonParseSuccess, 224 fetch_state->assembled_response,
191 weak_factory_.GetWeakPtr(), request), 225 base::Bind(&LogProofFetcher::OnSTHJsonParseSuccess,
192 base::Bind(&LogProofFetcher::OnSTHJsonParseError, 226 weak_factory_.GetWeakPtr(), request),
193 weak_factory_.GetWeakPtr(), request)); 227 base::Bind(&LogProofFetcher::OnSTHJsonParseError,
228 weak_factory_.GetWeakPtr(), request));
229 } else if (fetch_state->request_type == LogRequestType::CONSISTENCY_PROOF) {
230 safe_json::SafeJsonParser::Parse(
231 fetch_state->assembled_response,
232 base::Bind(&LogProofFetcher::OnConsistencyProofJsonParseSuccess,
233 weak_factory_.GetWeakPtr(), request),
234 base::Bind(&LogProofFetcher::OnConsistencyProofJsonParseError,
235 weak_factory_.GetWeakPtr(), request));
236 } else {
237 NOTREACHED();
238 }
194 } 239 }
195 240
196 void LogProofFetcher::CleanupRequest(net::URLRequest* request) { 241 void LogProofFetcher::CleanupRequest(net::URLRequest* request) {
197 DVLOG(1) << "Cleaning up request to " << request->original_url(); 242 DVLOG(1) << "Cleaning up request to " << request->original_url();
198 auto it = inflight_requests_.find(request); 243 auto it = inflight_requests_.find(request);
199 DCHECK(it != inflight_requests_.end()); 244 DCHECK(it != inflight_requests_.end());
200 auto next_it = it; 245 auto next_it = it;
201 std::advance(next_it, 1); 246 std::advance(next_it, 1);
202 247
203 // Delete FetchState and URLRequest, then the entry from inflight_requests_. 248 // Delete FetchState and URLRequest, then the entry from inflight_requests_.
(...skipping 13 matching lines...) Expand all
217 CleanupRequest(request); 262 CleanupRequest(request);
218 } 263 }
219 264
220 void LogProofFetcher::OnSTHJsonParseSuccess( 265 void LogProofFetcher::OnSTHJsonParseSuccess(
221 net::URLRequest* request, 266 net::URLRequest* request,
222 scoped_ptr<base::Value> parsed_json) { 267 scoped_ptr<base::Value> parsed_json) {
223 DCHECK(inflight_requests_.count(request)); 268 DCHECK(inflight_requests_.count(request));
224 269
225 FetchState* fetch_state = inflight_requests_.find(request)->second; 270 FetchState* fetch_state = inflight_requests_.find(request)->second;
226 net::ct::SignedTreeHead signed_tree_head; 271 net::ct::SignedTreeHead signed_tree_head;
227 if (net::ct::FillSignedTreeHead(*parsed_json.get(), &signed_tree_head)) { 272 if (net::ct::FillSignedTreeHead(*parsed_json.get(), &signed_tree_head)) {
mmenke 2015/11/18 19:25:15 nit: While you're here, .get() isn't needed.
Eran Messeri 2015/11/24 22:53:38 Done.
228 fetch_state->fetched_callback.Run(fetch_state->log_id, signed_tree_head); 273 DCHECK(!(fetch_state->sth_fetch_callback.is_null()));
mmenke 2015/11/18 19:25:15 This DCHECK makes much more sense in FetchSignedTr
Eran Messeri 2015/11/24 22:53:38 Good point - DCHECK made much earlier on, removed
274 fetch_state->sth_fetch_callback.Run(fetch_state->log_id, signed_tree_head);
229 } else { 275 } else {
230 fetch_state->failed_callback.Run(fetch_state->log_id, 276 fetch_state->failed_callback.Run(fetch_state->log_id,
231 net::ERR_CT_STH_INCOMPLETE, net::HTTP_OK); 277 net::ERR_CT_STH_INCOMPLETE, net::HTTP_OK);
232 } 278 }
233 279
234 CleanupRequest(request); 280 CleanupRequest(request);
235 } 281 }
236 282
237 void LogProofFetcher::OnSTHJsonParseError(net::URLRequest* request, 283 void LogProofFetcher::OnSTHJsonParseError(net::URLRequest* request,
238 const std::string& error) { 284 const std::string& error) {
239 InvokeFailureCallback(request, net::ERR_CT_STH_PARSING_FAILED, net::HTTP_OK); 285 InvokeFailureCallback(request, net::ERR_CT_STH_PARSING_FAILED, net::HTTP_OK);
240 } 286 }
241 287
288 void LogProofFetcher::OnConsistencyProofJsonParseSuccess(
289 net::URLRequest* request,
290 scoped_ptr<base::Value> parsed_json) {
291 DCHECK(inflight_requests_.count(request));
292 FetchState* fetch_state = inflight_requests_.find(request)->second;
293 std::vector<std::string> consistency_proof;
294 if (net::ct::FillConsistencyProof(*parsed_json.get(), &consistency_proof)) {
mmenke 2015/11/18 19:25:15 See comment in OnSTHJsonParseSuccess.
Eran Messeri 2015/11/24 22:53:38 Done.
295 DCHECK(!(fetch_state->proof_fetch_callback.is_null()));
mmenke 2015/11/18 19:25:15 See comment in OnSTHJsonParseSuccess.
Eran Messeri 2015/11/24 22:53:38 Done (removed unnecessary DCHECKs here as they are
296 fetch_state->proof_fetch_callback.Run(fetch_state->log_id,
297 consistency_proof);
298 } else {
299 fetch_state->failed_callback.Run(
300 fetch_state->log_id, net::ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED,
301 net::HTTP_OK);
302 }
303
304 CleanupRequest(request);
305 }
306
307 void LogProofFetcher::OnConsistencyProofJsonParseError(
308 net::URLRequest* request,
309 const std::string& error) {
310 InvokeFailureCallback(request, net::ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED,
311 net::HTTP_OK);
312 }
313
314 net::URLRequest* LogProofFetcher::CreateRequest(const GURL& url) {
315 scoped_ptr<net::URLRequest> request =
316 request_context_->CreateRequest(url, net::DEFAULT_PRIORITY, this);
317 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
318 net::LOAD_DO_NOT_SAVE_COOKIES |
319 net::LOAD_DO_NOT_SEND_AUTH_DATA);
320 return request.release();
321 }
322
242 } // namespace certificate_transparency 323 } // namespace certificate_transparency
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698