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

Side by Side Diff: net/ocsp/nss_ocsp.cc

Issue 165362: Try to fix crash in OCSP handlers. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « net/base/x509_certificate_nss.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 "net/ocsp/nss_ocsp.h" 5 #include "net/ocsp/nss_ocsp.h"
6 6
7 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424 7 // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=455424
8 // until NSS 3.12.2 comes out and we update to it. 8 // until NSS 3.12.2 comes out and we update to it.
9 #define Lock FOO_NSS_Lock 9 #define Lock FOO_NSS_Lock
10 #include <certt.h> 10 #include <certt.h>
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 }; 73 };
74 74
75 scoped_refptr<URLRequestContext> OCSPInitSingleton::request_context_; 75 scoped_refptr<URLRequestContext> OCSPInitSingleton::request_context_;
76 76
77 // Concrete class for SEC_HTTP_REQUEST_SESSION. 77 // Concrete class for SEC_HTTP_REQUEST_SESSION.
78 class OCSPRequestSession { 78 class OCSPRequestSession {
79 public: 79 public:
80 OCSPRequestSession(const GURL& url, 80 OCSPRequestSession(const GURL& url,
81 const char* http_request_method, 81 const char* http_request_method,
82 base::TimeDelta timeout); 82 base::TimeDelta timeout);
83 ~OCSPRequestSession() {} 83 ~OCSPRequestSession();
84 84
85 void SetPostData(const char* http_data, 85 void SetPostData(const char* http_data,
86 const PRUint32 http_data_len, 86 const PRUint32 http_data_len,
87 const char* http_content_type); 87 const char* http_content_type);
88 88
89 void AddHeader(const char* http_header_name, 89 void AddHeader(const char* http_header_name,
90 const char* http_header_value); 90 const char* http_header_value);
91 91
92 void Start(); 92 void Start();
93 bool Started() const; 93 bool Started() const;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 // This class is the real guts of OCSP handlers. 130 // This class is the real guts of OCSP handlers.
131 // Public methods except virtual methods of URLRequest::Delegate (On* methods) 131 // Public methods except virtual methods of URLRequest::Delegate (On* methods)
132 // run on certificate verifier thread (worker thread). 132 // run on certificate verifier thread (worker thread).
133 // Virtual methods of URLRequest::Delegate and private methods run 133 // Virtual methods of URLRequest::Delegate and private methods run
134 // on IO thread. 134 // on IO thread.
135 class OCSPRequestSession::Core 135 class OCSPRequestSession::Core
136 : public base::RefCountedThreadSafe<OCSPRequestSession::Core>, 136 : public base::RefCountedThreadSafe<OCSPRequestSession::Core>,
137 public URLRequest::Delegate { 137 public URLRequest::Delegate {
138 public: 138 public:
139 explicit Core(OCSPRequestSession* req) 139 explicit Core(OCSPRequestSession* req)
140 : ocsp_req_(req), 140 : url_(req->url()),
141 url_(ocsp_req_->url()), 141 http_request_method_(req->http_request_method()),
142 timeout_(req->timeout()),
142 io_loop_(Singleton<OCSPInitSingleton>::get()->io_thread()), 143 io_loop_(Singleton<OCSPInitSingleton>::get()->io_thread()),
143 request_(NULL), 144 request_(NULL),
144 buffer_(new net::IOBuffer(kRecvBufferSize)), 145 buffer_(new net::IOBuffer(kRecvBufferSize)),
145 response_code_(-1), 146 response_code_(-1),
146 cv_(&lock_), 147 cv_(&lock_),
147 finished_(false) {} 148 finished_(false) {}
148 virtual ~Core() {} 149 virtual ~Core() {
150 DCHECK(!request_);
151 }
149 152
150 void SetPostData(const char* http_data, PRUint32 http_data_len, 153 void SetPostData(const char* http_data, PRUint32 http_data_len,
151 const char* http_content_type) { 154 const char* http_content_type) {
152 upload_content_.assign(http_data, http_data_len); 155 upload_content_.assign(http_data, http_data_len);
153 upload_content_type_.assign(http_content_type); 156 upload_content_type_.assign(http_content_type);
154 } 157 }
155 158
156 void AddHeader(const char* http_header_name, const char* http_header_value) { 159 void AddHeader(const char* http_header_name, const char* http_header_value) {
157 if (!extra_request_headers_.empty()) 160 if (!extra_request_headers_.empty())
158 extra_request_headers_ += "\r\n"; 161 extra_request_headers_ += "\r\n";
(...skipping 15 matching lines...) Expand all
174 AutoLock autolock(lock_); 177 AutoLock autolock(lock_);
175 return finished_; 178 return finished_;
176 } 179 }
177 180
178 void Cancel() { 181 void Cancel() {
179 io_loop_->PostTask(FROM_HERE, 182 io_loop_->PostTask(FROM_HERE,
180 NewRunnableMethod(this, &Core::CancelURLRequest)); 183 NewRunnableMethod(this, &Core::CancelURLRequest));
181 } 184 }
182 185
183 bool Wait() { 186 bool Wait() {
184 base::TimeDelta timeout = ocsp_req_->timeout(); 187 base::TimeDelta timeout = timeout_;
185 AutoLock autolock(lock_); 188 AutoLock autolock(lock_);
186 while (!finished_) { 189 while (!finished_) {
187 base::TimeTicks last_time = base::TimeTicks::Now(); 190 base::TimeTicks last_time = base::TimeTicks::Now();
188 cv_.TimedWait(timeout); 191 cv_.TimedWait(timeout);
189 // Check elapsed time 192 // Check elapsed time
190 base::TimeDelta elapsed_time = base::TimeTicks::Now() - last_time; 193 base::TimeDelta elapsed_time = base::TimeTicks::Now() - last_time;
191 timeout -= elapsed_time; 194 timeout -= elapsed_time;
192 if (timeout < base::TimeDelta()) { 195 if (timeout < base::TimeDelta()) {
193 LOG(INFO) << "OCSP Timed out"; 196 LOG(INFO) << "OCSP Timed out";
194 if (!finished_) 197 if (!finished_)
(...skipping 24 matching lines...) Expand all
219 return data_; 222 return data_;
220 } 223 }
221 224
222 // Follow rediect. 225 // Follow rediect.
223 virtual void OnReceivedRedirect(URLRequest* request, 226 virtual void OnReceivedRedirect(URLRequest* request,
224 const GURL& new_url) {} 227 const GURL& new_url) {}
225 228
226 virtual void OnResponseStarted(URLRequest* request) { 229 virtual void OnResponseStarted(URLRequest* request) {
227 DCHECK(request == request_); 230 DCHECK(request == request_);
228 DCHECK(MessageLoopForIO::current() == io_loop_); 231 DCHECK(MessageLoopForIO::current() == io_loop_);
232
229 int bytes_read = 0; 233 int bytes_read = 0;
230 if (request->status().is_success()) { 234 if (request->status().is_success()) {
231 response_code_ = request_->GetResponseCode(); 235 response_code_ = request_->GetResponseCode();
232 response_headers_ = request_->response_headers(); 236 response_headers_ = request_->response_headers();
233 response_headers_->GetMimeType(&response_content_type_); 237 response_headers_->GetMimeType(&response_content_type_);
234 request_->Read(buffer_, kRecvBufferSize, &bytes_read); 238 request_->Read(buffer_, kRecvBufferSize, &bytes_read);
235 } 239 }
236 OnReadCompleted(request_, bytes_read); 240 OnReadCompleted(request_, bytes_read);
237 } 241 }
238 242
(...skipping 23 matching lines...) Expand all
262 DCHECK(MessageLoopForIO::current() == io_loop_); 266 DCHECK(MessageLoopForIO::current() == io_loop_);
263 DCHECK(!request_); 267 DCHECK(!request_);
264 268
265 request_ = new URLRequest(url_, this); 269 request_ = new URLRequest(url_, this);
266 request_->set_context( 270 request_->set_context(
267 Singleton<OCSPInitSingleton>::get()->url_request_context()); 271 Singleton<OCSPInitSingleton>::get()->url_request_context());
268 // To meet the privacy requirements of off-the-record mode. 272 // To meet the privacy requirements of off-the-record mode.
269 request_->set_load_flags( 273 request_->set_load_flags(
270 net::LOAD_DISABLE_CACHE|net::LOAD_DO_NOT_SAVE_COOKIES); 274 net::LOAD_DISABLE_CACHE|net::LOAD_DO_NOT_SAVE_COOKIES);
271 275
272 if (ocsp_req_->http_request_method() == "POST") { 276 if (http_request_method_ == "POST") {
273 DCHECK(!upload_content_.empty()); 277 DCHECK(!upload_content_.empty());
274 DCHECK(!upload_content_type_.empty()); 278 DCHECK(!upload_content_type_.empty());
275 279
276 request_->set_method("POST"); 280 request_->set_method("POST");
277 if (!extra_request_headers_.empty()) 281 if (!extra_request_headers_.empty())
278 extra_request_headers_ += "\r\n"; 282 extra_request_headers_ += "\r\n";
279 StringAppendF(&extra_request_headers_, 283 StringAppendF(&extra_request_headers_,
280 "Content-Type: %s", upload_content_type_.c_str()); 284 "Content-Type: %s", upload_content_type_.c_str());
281 request_->AppendBytesToUpload(upload_content_.data(), 285 request_->AppendBytesToUpload(upload_content_.data(),
282 static_cast<int>(upload_content_.size())); 286 static_cast<int>(upload_content_.size()));
283 } 287 }
284 if (!extra_request_headers_.empty()) 288 if (!extra_request_headers_.empty())
285 request_->SetExtraRequestHeaders(extra_request_headers_); 289 request_->SetExtraRequestHeaders(extra_request_headers_);
286 290
287 request_->Start(); 291 request_->Start();
288 } 292 }
289 293
290 void CancelURLRequest() { 294 void CancelURLRequest() {
291 DCHECK(MessageLoopForIO::current() == io_loop_); 295 DCHECK(MessageLoopForIO::current() == io_loop_);
292 if (request_) { 296 if (request_) {
297 request_->Cancel();
293 delete request_; 298 delete request_;
294 request_ = NULL; 299 request_ = NULL;
295 } 300 }
296 } 301 }
297 302
298 OCSPRequestSession* ocsp_req_; // corresponding OCSP session
299 GURL url_; // The URL we eventually wound up at 303 GURL url_; // The URL we eventually wound up at
304 std::string http_request_method_;
305 base::TimeDelta timeout_; // The timeout for OCSP
300 MessageLoop* io_loop_; // Message loop of the IO thread 306 MessageLoop* io_loop_; // Message loop of the IO thread
301 URLRequest* request_; // The actual request this wraps 307 URLRequest* request_; // The actual request this wraps
302 scoped_refptr<net::IOBuffer> buffer_; // Read buffer 308 scoped_refptr<net::IOBuffer> buffer_; // Read buffer
303 std::string extra_request_headers_; // Extra headers for the request, if any 309 std::string extra_request_headers_; // Extra headers for the request, if any
304 std::string upload_content_; // HTTP POST payload 310 std::string upload_content_; // HTTP POST payload
305 std::string upload_content_type_; // MIME type of POST payload 311 std::string upload_content_type_; // MIME type of POST payload
306 312
307 int response_code_; // HTTP status code for the request 313 int response_code_; // HTTP status code for the request
308 std::string response_content_type_; 314 std::string response_content_type_;
309 scoped_refptr<net::HttpResponseHeaders> response_headers_; 315 scoped_refptr<net::HttpResponseHeaders> response_headers_;
310 std::string data_; // Results of the requst 316 std::string data_; // Results of the requst
311 317
312 // |lock_| protects |finished_| only. 318 // |lock_| protects |finished_| only.
313 mutable Lock lock_; 319 mutable Lock lock_;
314 ConditionVariable cv_; 320 ConditionVariable cv_;
315 321
316 bool finished_; 322 bool finished_;
317 323
318 DISALLOW_COPY_AND_ASSIGN(Core); 324 DISALLOW_COPY_AND_ASSIGN(Core);
319 }; 325 };
320 326
321 OCSPRequestSession::OCSPRequestSession(const GURL& url, 327 OCSPRequestSession::OCSPRequestSession(const GURL& url,
322 const char* http_request_method, 328 const char* http_request_method,
323 base::TimeDelta timeout) 329 base::TimeDelta timeout)
324 : url_(url), http_request_method_(http_request_method), 330 : url_(url), http_request_method_(http_request_method),
325 timeout_(timeout), 331 timeout_(timeout),
326 ALLOW_THIS_IN_INITIALIZER_LIST(core_(new Core(this))) { 332 ALLOW_THIS_IN_INITIALIZER_LIST(core_(new Core(this))) {
327 } 333 }
328 334
335 OCSPRequestSession::~OCSPRequestSession() {
336 core_->Cancel();
337 }
338
329 void OCSPRequestSession::SetPostData(const char* http_data, 339 void OCSPRequestSession::SetPostData(const char* http_data,
330 const PRUint32 http_data_len, 340 const PRUint32 http_data_len,
331 const char* http_content_type) { 341 const char* http_content_type) {
332 core_->SetPostData(http_data, http_data_len, http_content_type); 342 core_->SetPostData(http_data, http_data_len, http_content_type);
333 } 343 }
334 344
335 void OCSPRequestSession::AddHeader(const char* http_header_name, 345 void OCSPRequestSession::AddHeader(const char* http_header_name,
336 const char* http_header_value) { 346 const char* http_header_value) {
337 core_->AddHeader(http_header_name, http_header_value); 347 core_->AddHeader(http_header_name, http_header_value);
338 } 348 }
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 DCHECK(req->Finished()); 511 DCHECK(req->Finished());
502 const std::string& data = req->http_response_data(); 512 const std::string& data = req->http_response_data();
503 if (http_response_data_len && *http_response_data_len) { 513 if (http_response_data_len && *http_response_data_len) {
504 if (*http_response_data_len < data.size()) { 514 if (*http_response_data_len < data.size()) {
505 LOG(ERROR) << "data size too large: " << *http_response_data_len 515 LOG(ERROR) << "data size too large: " << *http_response_data_len
506 << " < " << data.size(); 516 << " < " << data.size();
507 *http_response_data_len = 1; 517 *http_response_data_len = 1;
508 return false; 518 return false;
509 } 519 }
510 } 520 }
511 LOG(INFO) << "OSCP response " 521 LOG(INFO) << "OCSP response "
512 << " response_code=" << req->http_response_code() 522 << " response_code=" << req->http_response_code()
513 << " content_type=" << req->http_response_content_type() 523 << " content_type=" << req->http_response_content_type()
514 << " header=" << req->http_response_headers() 524 << " header=" << req->http_response_headers()
515 << " data_len=" << data.size(); 525 << " data_len=" << data.size();
516 if (http_response_code) 526 if (http_response_code)
517 *http_response_code = req->http_response_code(); 527 *http_response_code = req->http_response_code();
518 if (http_response_content_type) 528 if (http_response_content_type)
519 *http_response_content_type = req->http_response_content_type().c_str(); 529 *http_response_content_type = req->http_response_content_type().c_str();
520 if (http_response_headers) 530 if (http_response_headers)
521 *http_response_headers = req->http_response_headers().c_str(); 531 *http_response_headers = req->http_response_headers().c_str();
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 void EnsureOCSPInit() { 601 void EnsureOCSPInit() {
592 Singleton<OCSPInitSingleton>::get(); 602 Singleton<OCSPInitSingleton>::get();
593 } 603 }
594 604
595 // This function would be called before NSS initialization. 605 // This function would be called before NSS initialization.
596 void SetURLRequestContextForOCSP(URLRequestContext* request_context) { 606 void SetURLRequestContextForOCSP(URLRequestContext* request_context) {
597 OCSPInitSingleton::set_url_request_context(request_context); 607 OCSPInitSingleton::set_url_request_context(request_context);
598 } 608 }
599 609
600 } // namespace net 610 } // namespace net
OLDNEW
« no previous file with comments | « net/base/x509_certificate_nss.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698