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

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: Addressing review comments. 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 SignedTreeHeadFetchedCallback sth_fetch_callback,
52 ConsistencyProofFetchedCallback proof_fetch_callback,
svaldez 2015/11/16 17:33:07 const ...FetchedCallback&
Eran Messeri 2015/11/17 10:47:31 Done.
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 SignedTreeHeadFetchedCallback sth_fetch_callback,
69 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) {
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);
svaldez 2015/11/16 17:33:07 Might be able to just pass 'nullptr'?
Eran Messeri 2015/11/17 10:47:31 Can't - Callback doesn't have a single argument c'
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 old_tree_size, new_tree_size);
120 GURL fetch_url = base_log_url.Resolve(relative);
121
122 net::URLRequest* request = CreateRequest(fetch_url);
123
124 FetchState* fetch_state = new FetchState(
125 log_id, LogRequestType::CONSISTENCY_PROOF,
126 SignedTreeHeadFetchedCallback(), fetched_callback, failed_callback);
svaldez 2015/11/16 17:33:07 ditto.
Eran Messeri 2015/11/17 10:47:31 See comment above.
127 request->Start();
128 inflight_requests_.insert(std::make_pair(request, fetch_state));
96 } 129 }
97 130
98 void LogProofFetcher::OnResponseStarted(net::URLRequest* request) { 131 void LogProofFetcher::OnResponseStarted(net::URLRequest* request) {
99 net::URLRequestStatus status(request->status()); 132 net::URLRequestStatus status(request->status());
100 DCHECK(inflight_requests_.count(request)); 133 DCHECK(inflight_requests_.count(request));
101 FetchState* fetch_state = inflight_requests_.find(request)->second; 134 FetchState* fetch_state = inflight_requests_.find(request)->second;
102 135
103 if (!status.is_success() || request->GetResponseCode() != net::HTTP_OK) { 136 if (!status.is_success() || request->GetResponseCode() != net::HTTP_OK) {
104 int net_error = net::OK; 137 int net_error = net::OK;
105 int http_response_code = request->GetResponseCode(); 138 int http_response_code = request->GetResponseCode();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 } 211 }
179 } 212 }
180 213
181 void LogProofFetcher::RequestComplete(net::URLRequest* request) { 214 void LogProofFetcher::RequestComplete(net::URLRequest* request) {
182 DCHECK(inflight_requests_.count(request)); 215 DCHECK(inflight_requests_.count(request));
183 216
184 FetchState* fetch_state = inflight_requests_.find(request)->second; 217 FetchState* fetch_state = inflight_requests_.find(request)->second;
185 218
186 // Get rid of the buffer as it really isn't necessary. 219 // Get rid of the buffer as it really isn't necessary.
187 fetch_state->response_buffer = nullptr; 220 fetch_state->response_buffer = nullptr;
188 safe_json::SafeJsonParser::Parse( 221 if (fetch_state->request_type == LogRequestType::SIGNED_TREE_HEAD) {
189 fetch_state->assembled_response, 222 safe_json::SafeJsonParser::Parse(
190 base::Bind(&LogProofFetcher::OnSTHJsonParseSuccess, 223 fetch_state->assembled_response,
191 weak_factory_.GetWeakPtr(), request), 224 base::Bind(&LogProofFetcher::OnSTHJsonParseSuccess,
192 base::Bind(&LogProofFetcher::OnSTHJsonParseError, 225 weak_factory_.GetWeakPtr(), request),
193 weak_factory_.GetWeakPtr(), request)); 226 base::Bind(&LogProofFetcher::OnSTHJsonParseError,
227 weak_factory_.GetWeakPtr(), request));
228 } else if (fetch_state->request_type == LogRequestType::CONSISTENCY_PROOF) {
229 safe_json::SafeJsonParser::Parse(
230 fetch_state->assembled_response,
231 base::Bind(&LogProofFetcher::OnConsistencyProofJsonParseSuccess,
232 weak_factory_.GetWeakPtr(), request),
233 base::Bind(&LogProofFetcher::OnConsistencyProofJsonParseError,
234 weak_factory_.GetWeakPtr(), request));
235 } else {
236 NOTREACHED();
237 }
194 } 238 }
195 239
196 void LogProofFetcher::CleanupRequest(net::URLRequest* request) { 240 void LogProofFetcher::CleanupRequest(net::URLRequest* request) {
197 DVLOG(1) << "Cleaning up request to " << request->original_url(); 241 DVLOG(1) << "Cleaning up request to " << request->original_url();
198 auto it = inflight_requests_.find(request); 242 auto it = inflight_requests_.find(request);
199 DCHECK(it != inflight_requests_.end()); 243 DCHECK(it != inflight_requests_.end());
200 auto next_it = it; 244 auto next_it = it;
201 std::advance(next_it, 1); 245 std::advance(next_it, 1);
202 246
203 // Delete FetchState and URLRequest, then the entry from inflight_requests_. 247 // Delete FetchState and URLRequest, then the entry from inflight_requests_.
(...skipping 14 matching lines...) Expand all
218 } 262 }
219 263
220 void LogProofFetcher::OnSTHJsonParseSuccess( 264 void LogProofFetcher::OnSTHJsonParseSuccess(
221 net::URLRequest* request, 265 net::URLRequest* request,
222 scoped_ptr<base::Value> parsed_json) { 266 scoped_ptr<base::Value> parsed_json) {
223 DCHECK(inflight_requests_.count(request)); 267 DCHECK(inflight_requests_.count(request));
224 268
225 FetchState* fetch_state = inflight_requests_.find(request)->second; 269 FetchState* fetch_state = inflight_requests_.find(request)->second;
226 net::ct::SignedTreeHead signed_tree_head; 270 net::ct::SignedTreeHead signed_tree_head;
227 if (net::ct::FillSignedTreeHead(*parsed_json.get(), &signed_tree_head)) { 271 if (net::ct::FillSignedTreeHead(*parsed_json.get(), &signed_tree_head)) {
228 fetch_state->fetched_callback.Run(fetch_state->log_id, signed_tree_head); 272 DCHECK(!(fetch_state->sth_fetch_callback.is_null()));
273 fetch_state->sth_fetch_callback.Run(fetch_state->log_id, signed_tree_head);
229 } else { 274 } else {
230 fetch_state->failed_callback.Run(fetch_state->log_id, 275 fetch_state->failed_callback.Run(fetch_state->log_id,
231 net::ERR_CT_STH_INCOMPLETE, net::HTTP_OK); 276 net::ERR_CT_STH_INCOMPLETE, net::HTTP_OK);
232 } 277 }
233 278
234 CleanupRequest(request); 279 CleanupRequest(request);
235 } 280 }
236 281
237 void LogProofFetcher::OnSTHJsonParseError(net::URLRequest* request, 282 void LogProofFetcher::OnSTHJsonParseError(net::URLRequest* request,
238 const std::string& error) { 283 const std::string& error) {
239 InvokeFailureCallback(request, net::ERR_CT_STH_PARSING_FAILED, net::HTTP_OK); 284 InvokeFailureCallback(request, net::ERR_CT_STH_PARSING_FAILED, net::HTTP_OK);
240 } 285 }
241 286
287 void LogProofFetcher::OnConsistencyProofJsonParseSuccess(
288 net::URLRequest* request,
289 scoped_ptr<base::Value> parsed_json) {
290 DCHECK(inflight_requests_.count(request));
291 FetchState* fetch_state = inflight_requests_.find(request)->second;
292 std::vector<std::string> consistency_proof;
293 if (net::ct::FillConsistencyProof(*parsed_json.get(), &consistency_proof)) {
294 DCHECK(!(fetch_state->proof_fetch_callback.is_null()));
295 fetch_state->proof_fetch_callback.Run(fetch_state->log_id,
296 consistency_proof);
297 } else {
298 fetch_state->failed_callback.Run(
299 fetch_state->log_id, net::ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED,
300 net::HTTP_OK);
301 }
302
303 CleanupRequest(request);
304 }
305
306 void LogProofFetcher::OnConsistencyProofJsonParseError(
307 net::URLRequest* request,
308 const std::string& error) {
309 InvokeFailureCallback(request, net::ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED,
310 net::HTTP_OK);
311 }
312
313 net::URLRequest* LogProofFetcher::CreateRequest(const GURL& url) {
314 scoped_ptr<net::URLRequest> request =
315 request_context_->CreateRequest(url, net::DEFAULT_PRIORITY, this);
316 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
317 net::LOAD_DO_NOT_SAVE_COOKIES |
318 net::LOAD_DO_NOT_SEND_AUTH_DATA);
319 return request.release();
320 }
321
242 } // namespace certificate_transparency 322 } // namespace certificate_transparency
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698