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

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: Switched to using RunLoop 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 class LogRequest {
46 public:
47 LogRequest(const LogProofFetcher::FetchFailedCallback& failure_callback);
mmenke 2015/12/01 16:23:49 explicit
Eran Messeri 2015/12/04 11:41:44 N/A anymore.
48 virtual ~LogRequest();
49
50 virtual void HandleParsedJson(const std::string& log_id,
51 const base::Value& parsed_json) = 0;
52
53 virtual void HandleFailure(const std::string& log_id,
54 int net_error,
55 int http_response_code);
56
57 virtual const std::string& RequestSuffix() = 0;
58
59 protected:
60 LogProofFetcher::FetchFailedCallback failure_callback_;
mmenke 2015/12/01 16:23:49 const?
Eran Messeri 2015/12/04 11:41:44 Done.
61 };
62
63 LogRequest::LogRequest(
64 const LogProofFetcher::FetchFailedCallback& failure_callback)
65 : failure_callback_(failure_callback) {
66 DCHECK(!failure_callback_.is_null());
67 }
68
69 LogRequest::~LogRequest() {}
70
71 void LogRequest::HandleFailure(const std::string& log_id,
72 int net_error,
73 int http_response_code) {
74 failure_callback_.Run(log_id, net_error, http_response_code);
75 }
76
77 class GetSTHLogRequest : public LogRequest {
78 public:
79 GetSTHLogRequest(
80 const LogProofFetcher::SignedTreeHeadFetchedCallback& sth_fetch_callback,
81 const LogProofFetcher::FetchFailedCallback& failure_callback)
82 : LogRequest(failure_callback), sth_fetched_(sth_fetch_callback) {}
83
84 void HandleParsedJson(const std::string& log_id,
85 const base::Value& parsed_json) override {
86 net::ct::SignedTreeHead signed_tree_head;
87 if (net::ct::FillSignedTreeHead(parsed_json, &signed_tree_head)) {
88 sth_fetched_.Run(log_id, signed_tree_head);
89 } else {
90 failure_callback_.Run(log_id, net::ERR_CT_STH_INCOMPLETE, net::HTTP_OK);
91 }
92 }
93
94 const std::string& RequestSuffix() override {
95 static const std::string get_sth("ct/v1/get-sth");
96 return get_sth;
97 }
98
99 private:
100 LogProofFetcher::SignedTreeHeadFetchedCallback sth_fetched_;
101 };
102
103 class GetConsistencyProofLogRequest : public LogRequest {
104 public:
105 GetConsistencyProofLogRequest(
106 uint64_t first_tree_size,
107 uint64_t second_tree_size,
108 const LogProofFetcher::ConsistencyProofFetchedCallback&
109 proof_fetch_callback,
110 const LogProofFetcher::FetchFailedCallback& failure_callback)
111 : LogRequest(failure_callback), proof_fetched_(proof_fetch_callback) {
112 fetch_suffix_ =
113 base::StringPrintf("ct/v1/get-sth-consistency?first=%lu&second=%lu",
114 first_tree_size, second_tree_size);
115 }
116
117 void HandleParsedJson(const std::string& log_id,
118 const base::Value& parsed_json) override {
119 std::vector<std::string> consistency_proof;
120 if (net::ct::FillConsistencyProof(parsed_json, &consistency_proof)) {
121 proof_fetched_.Run(log_id, consistency_proof);
122 } else {
123 failure_callback_.Run(
124 log_id, net::ERR_CT_CONSISTENCY_PROOF_PARSING_FAILED, net::HTTP_OK);
125 }
126 }
127
128 const std::string& RequestSuffix() override { return fetch_suffix_; }
129
130 private:
131 LogProofFetcher::ConsistencyProofFetchedCallback proof_fetched_;
132 std::string fetch_suffix_;
133 };
134
43 } // namespace 135 } // namespace
44 136
45 struct LogProofFetcher::FetchState { 137 struct LogProofFetcher::FetchState {
46 FetchState(const std::string& log_id, 138 // Takes ownership of the |request_handler|
47 const SignedTreeHeadFetchedCallback& fetched_callback, 139 FetchState(const std::string& log_id, LogRequest* request_handler);
mmenke 2015/12/01 16:23:49 Do we really need both a FetchState and a LogReque
Eran Messeri 2015/12/04 11:41:44 As discussed offline, I think the separation betwe
48 const FetchFailedCallback& failed_callback);
49 ~FetchState(); 140 ~FetchState();
50 141
51 std::string log_id; 142 std::string log_id;
52 SignedTreeHeadFetchedCallback fetched_callback; 143 scoped_ptr<LogRequest> request_handler;
53 FetchFailedCallback failed_callback;
54 scoped_refptr<net::IOBufferWithSize> response_buffer; 144 scoped_refptr<net::IOBufferWithSize> response_buffer;
55 std::string assembled_response; 145 std::string assembled_response;
56 }; 146 };
57 147
58 LogProofFetcher::FetchState::FetchState( 148 LogProofFetcher::FetchState::FetchState(const std::string& log_id,
59 const std::string& log_id, 149 LogRequest* request_handler)
60 const SignedTreeHeadFetchedCallback& fetched_callback,
61 const FetchFailedCallback& failed_callback)
62 : log_id(log_id), 150 : log_id(log_id),
63 fetched_callback(fetched_callback), 151 request_handler(request_handler),
64 failed_callback(failed_callback),
65 response_buffer(new net::IOBufferWithSize(kMaxLogResponseSizeInBytes)) {} 152 response_buffer(new net::IOBufferWithSize(kMaxLogResponseSizeInBytes)) {}
66 153
67 LogProofFetcher::FetchState::~FetchState() {} 154 LogProofFetcher::FetchState::~FetchState() {}
68 155
69 LogProofFetcher::LogProofFetcher(net::URLRequestContext* request_context) 156 LogProofFetcher::LogProofFetcher(net::URLRequestContext* request_context)
70 : request_context_(request_context), weak_factory_(this) { 157 : request_context_(request_context), weak_factory_(this) {
71 DCHECK(request_context); 158 DCHECK(request_context);
72 } 159 }
73 160
74 LogProofFetcher::~LogProofFetcher() { 161 LogProofFetcher::~LogProofFetcher() {
75 STLDeleteContainerPairPointers(inflight_requests_.begin(), 162 STLDeleteContainerPairPointers(inflight_requests_.begin(),
76 inflight_requests_.end()); 163 inflight_requests_.end());
77 } 164 }
78 165
79 void LogProofFetcher::FetchSignedTreeHead( 166 void LogProofFetcher::FetchSignedTreeHead(
80 const GURL& base_log_url, 167 const GURL& base_log_url,
81 const std::string& log_id, 168 const std::string& log_id,
82 const SignedTreeHeadFetchedCallback& fetched_callback, 169 const SignedTreeHeadFetchedCallback& fetched_callback,
83 const FetchFailedCallback& failed_callback) { 170 const FetchFailedCallback& failed_callback) {
171 FetchState* fetch_state = new FetchState(
172 log_id, new GetSTHLogRequest(fetched_callback, failed_callback));
173 FetchFromLog(base_log_url, log_id, fetch_state);
174 }
175
176 void LogProofFetcher::FetchConsistencyProof(
177 const GURL& base_log_url,
178 const std::string& log_id,
179 uint64_t old_tree_size,
180 uint64_t new_tree_size,
181 const ConsistencyProofFetchedCallback& fetched_callback,
182 const FetchFailedCallback& failed_callback) {
183 FetchState* fetch_state = new FetchState(
184 log_id,
185 new GetConsistencyProofLogRequest(old_tree_size, new_tree_size,
186 fetched_callback, failed_callback));
187 FetchFromLog(base_log_url, log_id, fetch_state);
188 }
189
190 void LogProofFetcher::FetchFromLog(const GURL& base_log_url,
191 const std::string& log_id,
192 FetchState* fetch_state) {
84 DCHECK(base_log_url.SchemeIsHTTPOrHTTPS()); 193 DCHECK(base_log_url.SchemeIsHTTPOrHTTPS());
85 GURL fetch_url(base_log_url.Resolve("ct/v1/get-sth")); 194
195 GURL request_url =
196 base_log_url.Resolve(fetch_state->request_handler->RequestSuffix());
197
86 scoped_ptr<net::URLRequest> request = 198 scoped_ptr<net::URLRequest> request =
87 request_context_->CreateRequest(fetch_url, net::DEFAULT_PRIORITY, this); 199 request_context_->CreateRequest(request_url, net::DEFAULT_PRIORITY, this);
88 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | 200 request->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
89 net::LOAD_DO_NOT_SAVE_COOKIES | 201 net::LOAD_DO_NOT_SAVE_COOKIES |
90 net::LOAD_DO_NOT_SEND_AUTH_DATA); 202 net::LOAD_DO_NOT_SEND_AUTH_DATA);
91 203
92 FetchState* fetch_state =
93 new FetchState(log_id, fetched_callback, failed_callback);
94 request->Start(); 204 request->Start();
95 inflight_requests_.insert(std::make_pair(request.release(), fetch_state)); 205 inflight_requests_.insert(std::make_pair(request.release(), fetch_state));
96 } 206 }
97 207
98 void LogProofFetcher::OnResponseStarted(net::URLRequest* request) { 208 void LogProofFetcher::OnResponseStarted(net::URLRequest* request) {
99 net::URLRequestStatus status(request->status()); 209 net::URLRequestStatus status(request->status());
100 DCHECK(inflight_requests_.count(request)); 210 DCHECK(inflight_requests_.count(request));
101 FetchState* fetch_state = inflight_requests_.find(request)->second; 211 FetchState* fetch_state = inflight_requests_.find(request)->second;
102 212
103 if (!status.is_success() || request->GetResponseCode() != net::HTTP_OK) { 213 if (!status.is_success() || request->GetResponseCode() != net::HTTP_OK) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 290
181 void LogProofFetcher::RequestComplete(net::URLRequest* request) { 291 void LogProofFetcher::RequestComplete(net::URLRequest* request) {
182 DCHECK(inflight_requests_.count(request)); 292 DCHECK(inflight_requests_.count(request));
183 293
184 FetchState* fetch_state = inflight_requests_.find(request)->second; 294 FetchState* fetch_state = inflight_requests_.find(request)->second;
185 295
186 // Get rid of the buffer as it really isn't necessary. 296 // Get rid of the buffer as it really isn't necessary.
187 fetch_state->response_buffer = nullptr; 297 fetch_state->response_buffer = nullptr;
188 safe_json::SafeJsonParser::Parse( 298 safe_json::SafeJsonParser::Parse(
189 fetch_state->assembled_response, 299 fetch_state->assembled_response,
190 base::Bind(&LogProofFetcher::OnSTHJsonParseSuccess, 300 base::Bind(&LogProofFetcher::OnJsonParseSuccess,
191 weak_factory_.GetWeakPtr(), request), 301 weak_factory_.GetWeakPtr(), request),
192 base::Bind(&LogProofFetcher::OnSTHJsonParseError, 302 base::Bind(&LogProofFetcher::OnJsonParseError, weak_factory_.GetWeakPtr(),
193 weak_factory_.GetWeakPtr(), request)); 303 request));
194 } 304 }
195 305
196 void LogProofFetcher::CleanupRequest(net::URLRequest* request) { 306 void LogProofFetcher::CleanupRequest(net::URLRequest* request) {
197 DVLOG(1) << "Cleaning up request to " << request->original_url(); 307 DVLOG(1) << "Cleaning up request to " << request->original_url();
198 auto it = inflight_requests_.find(request); 308 auto it = inflight_requests_.find(request);
199 DCHECK(it != inflight_requests_.end()); 309 DCHECK(it != inflight_requests_.end());
200 auto next_it = it; 310 auto next_it = it;
201 std::advance(next_it, 1); 311 std::advance(next_it, 1);
202 312
203 // Delete FetchState and URLRequest, then the entry from inflight_requests_. 313 // Delete FetchState and URLRequest, then the entry from inflight_requests_.
204 STLDeleteContainerPairPointers(it, next_it); 314 STLDeleteContainerPairPointers(it, next_it);
205 inflight_requests_.erase(it); 315 inflight_requests_.erase(it);
206 } 316 }
207 317
208 void LogProofFetcher::InvokeFailureCallback(net::URLRequest* request, 318 void LogProofFetcher::InvokeFailureCallback(net::URLRequest* request,
209 int net_error, 319 int net_error,
210 int http_response_code) { 320 int http_response_code) {
211 DCHECK(inflight_requests_.count(request)); 321 DCHECK(inflight_requests_.count(request));
212 auto it = inflight_requests_.find(request); 322 auto it = inflight_requests_.find(request);
213 FetchState* fetch_state = it->second; 323 FetchState* fetch_state = it->second;
214 324
215 fetch_state->failed_callback.Run(fetch_state->log_id, net_error, 325 fetch_state->request_handler->HandleFailure(fetch_state->log_id, net_error,
216 http_response_code); 326 http_response_code);
217 CleanupRequest(request); 327 CleanupRequest(request);
218 } 328 }
219 329
220 void LogProofFetcher::OnSTHJsonParseSuccess( 330 void LogProofFetcher::OnJsonParseSuccess(net::URLRequest* request,
221 net::URLRequest* request, 331 scoped_ptr<base::Value> parsed_json) {
222 scoped_ptr<base::Value> parsed_json) {
223 DCHECK(inflight_requests_.count(request)); 332 DCHECK(inflight_requests_.count(request));
224 333
225 FetchState* fetch_state = inflight_requests_.find(request)->second; 334 FetchState* fetch_state = inflight_requests_.find(request)->second;
226 net::ct::SignedTreeHead signed_tree_head; 335 fetch_state->request_handler->HandleParsedJson(fetch_state->log_id,
227 if (net::ct::FillSignedTreeHead(*parsed_json.get(), &signed_tree_head)) { 336 *parsed_json);
228 fetch_state->fetched_callback.Run(fetch_state->log_id, signed_tree_head);
229 } else {
230 fetch_state->failed_callback.Run(fetch_state->log_id,
231 net::ERR_CT_STH_INCOMPLETE, net::HTTP_OK);
232 }
233 337
234 CleanupRequest(request); 338 CleanupRequest(request);
235 } 339 }
236 340
237 void LogProofFetcher::OnSTHJsonParseError(net::URLRequest* request, 341 void LogProofFetcher::OnJsonParseError(net::URLRequest* request,
238 const std::string& error) { 342 const std::string& error) {
239 InvokeFailureCallback(request, net::ERR_CT_STH_PARSING_FAILED, net::HTTP_OK); 343 InvokeFailureCallback(request, net::ERR_CT_STH_PARSING_FAILED, net::HTTP_OK);
240 } 344 }
241 345
242 } // namespace certificate_transparency 346 } // namespace certificate_transparency
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698