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

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 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/format_macros.h"
9 #include "base/logging.h" 10 #include "base/logging.h"
10 #include "base/memory/ref_counted.h" 11 #include "base/memory/ref_counted.h"
11 #include "base/stl_util.h" 12 #include "base/stl_util.h"
13 #include "base/strings/stringprintf.h"
12 #include "base/values.h" 14 #include "base/values.h"
13 #include "components/safe_json/safe_json_parser.h" 15 #include "components/safe_json/safe_json_parser.h"
14 #include "net/base/io_buffer.h" 16 #include "net/base/io_buffer.h"
15 #include "net/base/load_flags.h" 17 #include "net/base/load_flags.h"
16 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
17 #include "net/base/request_priority.h" 19 #include "net/base/request_priority.h"
18 #include "net/cert/ct_log_response_parser.h" 20 #include "net/cert/ct_log_response_parser.h"
19 #include "net/cert/signed_tree_head.h" 21 #include "net/cert/signed_tree_head.h"
20 #include "net/http/http_status_code.h" 22 #include "net/http/http_status_code.h"
21 #include "net/url_request/url_request_context.h" 23 #include "net/url_request/url_request_context.h"
(...skipping 11 matching lines...) Expand all
33 case net::URLRequestStatus::CANCELED: 35 case net::URLRequestStatus::CANCELED:
34 return net::ERR_ABORTED; 36 return net::ERR_ABORTED;
35 case net::URLRequestStatus::FAILED: 37 case net::URLRequestStatus::FAILED:
36 return status.error(); 38 return status.error();
37 default: 39 default:
38 NOTREACHED(); 40 NOTREACHED();
39 return net::ERR_FAILED; 41 return net::ERR_FAILED;
40 } 42 }
41 } 43 }
42 44
45 enum LogRequestType { SIGNED_TREE_HEAD, CONSISTENCY_PROOF };
Ryan Sleevi 2015/11/26 00:50:09 Document
Eran Messeri 2015/11/26 22:07:13 Obsolete.
46
43 } // namespace 47 } // namespace
44 48
45 struct LogProofFetcher::FetchState { 49 struct LogProofFetcher::FetchState {
46 FetchState(const std::string& log_id, 50 FetchState(const std::string& log_id,
47 const SignedTreeHeadFetchedCallback& fetched_callback, 51 LogRequestType request_type,
52 const SignedTreeHeadFetchedCallback& sth_fetch_callback,
53 const ConsistencyProofFetchedCallback& proof_fetch_callback,
48 const FetchFailedCallback& failed_callback); 54 const FetchFailedCallback& failed_callback);
49 ~FetchState(); 55 ~FetchState();
50 56
51 std::string log_id; 57 std::string log_id;
52 SignedTreeHeadFetchedCallback fetched_callback; 58 LogRequestType request_type;
59 SignedTreeHeadFetchedCallback sth_fetch_callback;
60 ConsistencyProofFetchedCallback proof_fetch_callback;
53 FetchFailedCallback failed_callback; 61 FetchFailedCallback failed_callback;
54 scoped_refptr<net::IOBufferWithSize> response_buffer; 62 scoped_refptr<net::IOBufferWithSize> response_buffer;
55 std::string assembled_response; 63 std::string assembled_response;
56 }; 64 };
57 65
58 LogProofFetcher::FetchState::FetchState( 66 LogProofFetcher::FetchState::FetchState(
59 const std::string& log_id, 67 const std::string& log_id,
60 const SignedTreeHeadFetchedCallback& fetched_callback, 68 LogRequestType request_type,
69 const SignedTreeHeadFetchedCallback& sth_fetch_callback,
70 const ConsistencyProofFetchedCallback& proof_fetch_callback,
61 const FetchFailedCallback& failed_callback) 71 const FetchFailedCallback& failed_callback)
62 : log_id(log_id), 72 : log_id(log_id),
63 fetched_callback(fetched_callback), 73 request_type(request_type),
74 sth_fetch_callback(sth_fetch_callback),
75 proof_fetch_callback(proof_fetch_callback),
64 failed_callback(failed_callback), 76 failed_callback(failed_callback),
65 response_buffer(new net::IOBufferWithSize(kMaxLogResponseSizeInBytes)) {} 77 response_buffer(new net::IOBufferWithSize(kMaxLogResponseSizeInBytes)) {
78 DCHECK(!(sth_fetch_callback.is_null() && proof_fetch_callback.is_null()));
Ryan Sleevi 2015/11/26 00:50:09 Past experience has shown mixing state objects lik
Eran Messeri 2015/11/26 22:07:13 Agreed - this is indeed a smell. I've completely c
79 }
66 80
67 LogProofFetcher::FetchState::~FetchState() {} 81 LogProofFetcher::FetchState::~FetchState() {}
68 82
69 LogProofFetcher::LogProofFetcher(net::URLRequestContext* request_context) 83 LogProofFetcher::LogProofFetcher(net::URLRequestContext* request_context)
70 : request_context_(request_context), weak_factory_(this) { 84 : request_context_(request_context), weak_factory_(this) {
71 DCHECK(request_context); 85 DCHECK(request_context);
72 } 86 }
73 87
74 LogProofFetcher::~LogProofFetcher() { 88 LogProofFetcher::~LogProofFetcher() {
75 STLDeleteContainerPairPointers(inflight_requests_.begin(), 89 STLDeleteContainerPairPointers(inflight_requests_.begin(),
76 inflight_requests_.end()); 90 inflight_requests_.end());
77 } 91 }
78 92
79 void LogProofFetcher::FetchSignedTreeHead( 93 void LogProofFetcher::FetchSignedTreeHead(
80 const GURL& base_log_url, 94 const GURL& base_log_url,
81 const std::string& log_id, 95 const std::string& log_id,
82 const SignedTreeHeadFetchedCallback& fetched_callback, 96 const SignedTreeHeadFetchedCallback& fetched_callback,
83 const FetchFailedCallback& failed_callback) { 97 const FetchFailedCallback& failed_callback) {
98 GURL fetch_url(base_log_url.Resolve("ct/v1/get-sth"));
99
100 FetchFromLog(fetch_url, log_id, fetched_callback,
101 ConsistencyProofFetchedCallback(), failed_callback);
102 }
103
104 void LogProofFetcher::FetchConsistencyProof(
105 const GURL& base_log_url,
106 const std::string& log_id,
107 size_t old_tree_size,
Ryan Sleevi 2015/11/26 00:50:09 BUG: I'm fairly sure these should be uint64_t type
Eran Messeri 2015/11/26 22:07:13 Correct, fixed.
108 size_t new_tree_size,
109 const ConsistencyProofFetchedCallback& fetched_callback,
110 const FetchFailedCallback& failed_callback) {
84 DCHECK(base_log_url.SchemeIsHTTPOrHTTPS()); 111 DCHECK(base_log_url.SchemeIsHTTPOrHTTPS());
85 GURL fetch_url(base_log_url.Resolve("ct/v1/get-sth")); 112
113 std::string relative = base::StringPrintf(
114 "ct/v1/get-sth-consistency?first=%" PRIuS "&second=%" PRIuS,
115 old_tree_size, new_tree_size);
116 GURL fetch_url = base_log_url.Resolve(relative);
117
118 FetchFromLog(fetch_url, log_id, SignedTreeHeadFetchedCallback(),
119 fetched_callback, failed_callback);
120 }
121
122 void LogProofFetcher::FetchFromLog(
123 const GURL& request_url,
124 const std::string& log_id,
125 const SignedTreeHeadFetchedCallback& sth_fetched_callback,
126 const ConsistencyProofFetchedCallback& proof_fetched_callback,
127 const FetchFailedCallback& failed_callback) {
128 DCHECK(request_url.SchemeIsHTTPOrHTTPS());
129 DCHECK(!failed_callback.is_null());
130
131 LogRequestType request_type;
132 if (!sth_fetched_callback.is_null()) {
133 request_type = LogRequestType::SIGNED_TREE_HEAD;
134 } else {
135 DCHECK(!proof_fetched_callback.is_null());
136 request_type = LogRequestType::CONSISTENCY_PROOF;
137 }
mmenke 2015/11/25 17:40:28 optional: May be cleaner as an argument...Or mayb
Eran Messeri 2015/11/26 22:07:13 Obsolete - see restructuring of the code.
138
86 scoped_ptr<net::URLRequest> request = 139 scoped_ptr<net::URLRequest> request =
87 request_context_->CreateRequest(fetch_url, net::DEFAULT_PRIORITY, this); 140 request_context_->CreateRequest(request_url, net::DEFAULT_PRIORITY, this);
88 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | 141 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
89 net::LOAD_DO_NOT_SAVE_COOKIES | 142 net::LOAD_DO_NOT_SAVE_COOKIES |
90 net::LOAD_DO_NOT_SEND_AUTH_DATA); 143 net::LOAD_DO_NOT_SEND_AUTH_DATA);
91 144
92 FetchState* fetch_state = 145 FetchState* fetch_state =
93 new FetchState(log_id, fetched_callback, failed_callback); 146 new FetchState(log_id, request_type, sth_fetched_callback,
147 proof_fetched_callback, failed_callback);
94 request->Start(); 148 request->Start();
95 inflight_requests_.insert(std::make_pair(request.release(), fetch_state)); 149 inflight_requests_.insert(std::make_pair(request.release(), fetch_state));
96 } 150 }
97 151
98 void LogProofFetcher::OnResponseStarted(net::URLRequest* request) { 152 void LogProofFetcher::OnResponseStarted(net::URLRequest* request) {
99 net::URLRequestStatus status(request->status()); 153 net::URLRequestStatus status(request->status());
100 DCHECK(inflight_requests_.count(request)); 154 DCHECK(inflight_requests_.count(request));
101 FetchState* fetch_state = inflight_requests_.find(request)->second; 155 FetchState* fetch_state = inflight_requests_.find(request)->second;
102 156
103 if (!status.is_success() || request->GetResponseCode() != net::HTTP_OK) { 157 if (!status.is_success() || request->GetResponseCode() != net::HTTP_OK) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 } 232 }
179 } 233 }
180 234
181 void LogProofFetcher::RequestComplete(net::URLRequest* request) { 235 void LogProofFetcher::RequestComplete(net::URLRequest* request) {
182 DCHECK(inflight_requests_.count(request)); 236 DCHECK(inflight_requests_.count(request));
183 237
184 FetchState* fetch_state = inflight_requests_.find(request)->second; 238 FetchState* fetch_state = inflight_requests_.find(request)->second;
185 239
186 // Get rid of the buffer as it really isn't necessary. 240 // Get rid of the buffer as it really isn't necessary.
187 fetch_state->response_buffer = nullptr; 241 fetch_state->response_buffer = nullptr;
188 safe_json::SafeJsonParser::Parse( 242 if (fetch_state->request_type == LogRequestType::SIGNED_TREE_HEAD) {
189 fetch_state->assembled_response, 243 safe_json::SafeJsonParser::Parse(
190 base::Bind(&LogProofFetcher::OnSTHJsonParseSuccess, 244 fetch_state->assembled_response,
191 weak_factory_.GetWeakPtr(), request), 245 base::Bind(&LogProofFetcher::OnSTHJsonParseSuccess,
192 base::Bind(&LogProofFetcher::OnSTHJsonParseError, 246 weak_factory_.GetWeakPtr(), request),
193 weak_factory_.GetWeakPtr(), request)); 247 base::Bind(&LogProofFetcher::OnSTHJsonParseError,
248 weak_factory_.GetWeakPtr(), request));
249 } else if (fetch_state->request_type == LogRequestType::CONSISTENCY_PROOF) {
250 safe_json::SafeJsonParser::Parse(
251 fetch_state->assembled_response,
252 base::Bind(&LogProofFetcher::OnConsistencyProofJsonParseSuccess,
253 weak_factory_.GetWeakPtr(), request),
254 base::Bind(&LogProofFetcher::OnConsistencyProofJsonParseError,
255 weak_factory_.GetWeakPtr(), request));
256 } else {
257 NOTREACHED();
258 }
194 } 259 }
195 260
196 void LogProofFetcher::CleanupRequest(net::URLRequest* request) { 261 void LogProofFetcher::CleanupRequest(net::URLRequest* request) {
197 DVLOG(1) << "Cleaning up request to " << request->original_url(); 262 DVLOG(1) << "Cleaning up request to " << request->original_url();
198 auto it = inflight_requests_.find(request); 263 auto it = inflight_requests_.find(request);
199 DCHECK(it != inflight_requests_.end()); 264 DCHECK(it != inflight_requests_.end());
200 auto next_it = it; 265 auto next_it = it;
201 std::advance(next_it, 1); 266 std::advance(next_it, 1);
202 267
203 // Delete FetchState and URLRequest, then the entry from inflight_requests_. 268 // Delete FetchState and URLRequest, then the entry from inflight_requests_.
(...skipping 13 matching lines...) Expand all
217 CleanupRequest(request); 282 CleanupRequest(request);
218 } 283 }
219 284
220 void LogProofFetcher::OnSTHJsonParseSuccess( 285 void LogProofFetcher::OnSTHJsonParseSuccess(
221 net::URLRequest* request, 286 net::URLRequest* request,
222 scoped_ptr<base::Value> parsed_json) { 287 scoped_ptr<base::Value> parsed_json) {
223 DCHECK(inflight_requests_.count(request)); 288 DCHECK(inflight_requests_.count(request));
224 289
225 FetchState* fetch_state = inflight_requests_.find(request)->second; 290 FetchState* fetch_state = inflight_requests_.find(request)->second;
226 net::ct::SignedTreeHead signed_tree_head; 291 net::ct::SignedTreeHead signed_tree_head;
227 if (net::ct::FillSignedTreeHead(*parsed_json.get(), &signed_tree_head)) { 292 if (net::ct::FillSignedTreeHead(*parsed_json, &signed_tree_head)) {
228 fetch_state->fetched_callback.Run(fetch_state->log_id, signed_tree_head); 293 fetch_state->sth_fetch_callback.Run(fetch_state->log_id, signed_tree_head);
229 } else { 294 } else {
230 fetch_state->failed_callback.Run(fetch_state->log_id, 295 fetch_state->failed_callback.Run(fetch_state->log_id,
231 net::ERR_CT_STH_INCOMPLETE, net::HTTP_OK); 296 net::ERR_CT_STH_INCOMPLETE, net::HTTP_OK);
232 } 297 }
233 298
234 CleanupRequest(request); 299 CleanupRequest(request);
235 } 300 }
236 301
237 void LogProofFetcher::OnSTHJsonParseError(net::URLRequest* request, 302 void LogProofFetcher::OnSTHJsonParseError(net::URLRequest* request,
238 const std::string& error) { 303 const std::string& error) {
239 InvokeFailureCallback(request, net::ERR_CT_STH_PARSING_FAILED, net::HTTP_OK); 304 InvokeFailureCallback(request, net::ERR_CT_STH_PARSING_FAILED, net::HTTP_OK);
240 } 305 }
241 306
307 void LogProofFetcher::OnConsistencyProofJsonParseSuccess(
308 net::URLRequest* request,
309 scoped_ptr<base::Value> parsed_json) {
310 DCHECK(inflight_requests_.count(request));
311 FetchState* fetch_state = inflight_requests_.find(request)->second;
312 std::vector<std::string> consistency_proof;
313 if (net::ct::FillConsistencyProof(*parsed_json, &consistency_proof)) {
314 fetch_state->proof_fetch_callback.Run(fetch_state->log_id,
315 consistency_proof);
316 } else {
317 fetch_state->failed_callback.Run(
318 fetch_state->log_id, net::ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED,
319 net::HTTP_OK);
320 }
321
322 CleanupRequest(request);
323 }
324
325 void LogProofFetcher::OnConsistencyProofJsonParseError(
326 net::URLRequest* request,
327 const std::string& error) {
328 InvokeFailureCallback(request, net::ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED,
329 net::HTTP_OK);
330 }
331
242 } // namespace certificate_transparency 332 } // namespace certificate_transparency
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698