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

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

Issue 266243004: Clang format slam. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include <certt.h> 7 #include <certt.h>
8 #include <certdb.h> 8 #include <certdb.h>
9 #include <ocsp.h> 9 #include <ocsp.h>
10 #include <nspr.h> 10 #include <nspr.h>
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
100 100
101 private: 101 private:
102 friend struct base::DefaultLazyInstanceTraits<OCSPIOLoop>; 102 friend struct base::DefaultLazyInstanceTraits<OCSPIOLoop>;
103 103
104 OCSPIOLoop(); 104 OCSPIOLoop();
105 ~OCSPIOLoop(); 105 ~OCSPIOLoop();
106 106
107 void CancelAllRequests(); 107 void CancelAllRequests();
108 108
109 mutable base::Lock lock_; 109 mutable base::Lock lock_;
110 bool shutdown_; // Protected by |lock_|. 110 bool shutdown_; // Protected by |lock_|.
111 std::set<OCSPRequestSession*> requests_; // Protected by |lock_|. 111 std::set<OCSPRequestSession*> requests_; // Protected by |lock_|.
112 bool used_; // Protected by |lock_|. 112 bool used_; // Protected by |lock_|.
113 // This should not be modified after |used_|. 113 // This should not be modified after |used_|.
114 base::MessageLoopForIO* io_loop_; // Protected by |lock_|. 114 base::MessageLoopForIO* io_loop_; // Protected by |lock_|.
115 base::ThreadChecker thread_checker_; 115 base::ThreadChecker thread_checker_;
116 116
117 DISALLOW_COPY_AND_ASSIGN(OCSPIOLoop); 117 DISALLOW_COPY_AND_ASSIGN(OCSPIOLoop);
118 }; 118 };
119 119
120 base::LazyInstance<OCSPIOLoop>::Leaky 120 base::LazyInstance<OCSPIOLoop>::Leaky g_ocsp_io_loop =
121 g_ocsp_io_loop = LAZY_INSTANCE_INITIALIZER; 121 LAZY_INSTANCE_INITIALIZER;
122 122
123 const int kRecvBufferSize = 4096; 123 const int kRecvBufferSize = 4096;
124 124
125 // All OCSP handlers should be called in the context of 125 // All OCSP handlers should be called in the context of
126 // CertVerifier's thread (i.e. worker pool, not on the I/O thread). 126 // CertVerifier's thread (i.e. worker pool, not on the I/O thread).
127 // It supports blocking mode only. 127 // It supports blocking mode only.
128 128
129 SECStatus OCSPCreateSession(const char* host, PRUint16 portnum, 129 SECStatus OCSPCreateSession(const char* host,
130 PRUint16 portnum,
130 SEC_HTTP_SERVER_SESSION* pSession); 131 SEC_HTTP_SERVER_SESSION* pSession);
131 SECStatus OCSPKeepAliveSession(SEC_HTTP_SERVER_SESSION session, 132 SECStatus OCSPKeepAliveSession(SEC_HTTP_SERVER_SESSION session,
132 PRPollDesc **pPollDesc); 133 PRPollDesc** pPollDesc);
133 SECStatus OCSPFreeSession(SEC_HTTP_SERVER_SESSION session); 134 SECStatus OCSPFreeSession(SEC_HTTP_SERVER_SESSION session);
134 135
135 SECStatus OCSPCreate(SEC_HTTP_SERVER_SESSION session, 136 SECStatus OCSPCreate(SEC_HTTP_SERVER_SESSION session,
136 const char* http_protocol_variant, 137 const char* http_protocol_variant,
137 const char* path_and_query_string, 138 const char* path_and_query_string,
138 const char* http_request_method, 139 const char* http_request_method,
139 const PRIntervalTime timeout, 140 const PRIntervalTime timeout,
140 SEC_HTTP_REQUEST_SESSION* pRequest); 141 SEC_HTTP_REQUEST_SESSION* pRequest);
141 SECStatus OCSPSetPostData(SEC_HTTP_REQUEST_SESSION request, 142 SECStatus OCSPSetPostData(SEC_HTTP_REQUEST_SESSION request,
142 const char* http_data, 143 const char* http_data,
143 const PRUint32 http_data_len, 144 const PRUint32 http_data_len,
144 const char* http_content_type); 145 const char* http_content_type);
145 SECStatus OCSPAddHeader(SEC_HTTP_REQUEST_SESSION request, 146 SECStatus OCSPAddHeader(SEC_HTTP_REQUEST_SESSION request,
146 const char* http_header_name, 147 const char* http_header_name,
147 const char* http_header_value); 148 const char* http_header_value);
148 SECStatus OCSPTrySendAndReceive(SEC_HTTP_REQUEST_SESSION request, 149 SECStatus OCSPTrySendAndReceive(SEC_HTTP_REQUEST_SESSION request,
149 PRPollDesc** pPollDesc, 150 PRPollDesc** pPollDesc,
150 PRUint16* http_response_code, 151 PRUint16* http_response_code,
151 const char** http_response_content_type, 152 const char** http_response_content_type,
152 const char** http_response_headers, 153 const char** http_response_headers,
153 const char** http_response_data, 154 const char** http_response_data,
154 PRUint32* http_response_data_len); 155 PRUint32* http_response_data_len);
155 SECStatus OCSPFree(SEC_HTTP_REQUEST_SESSION request); 156 SECStatus OCSPFree(SEC_HTTP_REQUEST_SESSION request);
156 157
157 char* GetAlternateOCSPAIAInfo(CERTCertificate *cert); 158 char* GetAlternateOCSPAIAInfo(CERTCertificate* cert);
158 159
159 class OCSPNSSInitialization { 160 class OCSPNSSInitialization {
160 private: 161 private:
161 friend struct base::DefaultLazyInstanceTraits<OCSPNSSInitialization>; 162 friend struct base::DefaultLazyInstanceTraits<OCSPNSSInitialization>;
162 163
163 OCSPNSSInitialization(); 164 OCSPNSSInitialization();
164 ~OCSPNSSInitialization(); 165 ~OCSPNSSInitialization();
165 166
166 SEC_HttpClientFcn client_fcn_; 167 SEC_HttpClientFcn client_fcn_;
167 168
(...skipping 18 matching lines...) Expand all
186 : url_(url), 187 : url_(url),
187 http_request_method_(http_request_method), 188 http_request_method_(http_request_method),
188 timeout_(timeout), 189 timeout_(timeout),
189 request_(NULL), 190 request_(NULL),
190 buffer_(new IOBuffer(kRecvBufferSize)), 191 buffer_(new IOBuffer(kRecvBufferSize)),
191 response_code_(-1), 192 response_code_(-1),
192 cv_(&lock_), 193 cv_(&lock_),
193 io_loop_(NULL), 194 io_loop_(NULL),
194 finished_(false) {} 195 finished_(false) {}
195 196
196 void SetPostData(const char* http_data, PRUint32 http_data_len, 197 void SetPostData(const char* http_data,
198 PRUint32 http_data_len,
197 const char* http_content_type) { 199 const char* http_content_type) {
198 // |upload_content_| should not be modified if |request_| is active. 200 // |upload_content_| should not be modified if |request_| is active.
199 DCHECK(!request_); 201 DCHECK(!request_);
200 upload_content_.assign(http_data, http_data_len); 202 upload_content_.assign(http_data, http_data_len);
201 upload_content_type_.assign(http_content_type); 203 upload_content_type_.assign(http_content_type);
202 } 204 }
203 205
204 void AddHeader(const char* http_header_name, const char* http_header_value) { 206 void AddHeader(const char* http_header_name, const char* http_header_value) {
205 extra_request_headers_.SetHeader(http_header_name, 207 extra_request_headers_.SetHeader(http_header_name, http_header_value);
206 http_header_value);
207 } 208 }
208 209
209 void Start() { 210 void Start() {
210 // At this point, it runs on worker thread. 211 // At this point, it runs on worker thread.
211 // |io_loop_| was initialized to be NULL in constructor, and 212 // |io_loop_| was initialized to be NULL in constructor, and
212 // set only in StartURLRequest, so no need to lock |lock_| here. 213 // set only in StartURLRequest, so no need to lock |lock_| here.
213 DCHECK(!io_loop_); 214 DCHECK(!io_loop_);
214 g_ocsp_io_loop.Get().PostTaskToIOLoop( 215 g_ocsp_io_loop.Get().PostTaskToIOLoop(
215 FROM_HERE, 216 FROM_HERE, base::Bind(&OCSPRequestSession::StartURLRequest, this));
216 base::Bind(&OCSPRequestSession::StartURLRequest, this));
217 } 217 }
218 218
219 bool Started() const { 219 bool Started() const { return request_ != NULL; }
220 return request_ != NULL;
221 }
222 220
223 void Cancel() { 221 void Cancel() {
224 // IO thread may set |io_loop_| to NULL, so protect by |lock_|. 222 // IO thread may set |io_loop_| to NULL, so protect by |lock_|.
225 base::AutoLock autolock(lock_); 223 base::AutoLock autolock(lock_);
226 CancelLocked(); 224 CancelLocked();
227 } 225 }
228 226
229 bool Finished() const { 227 bool Finished() const {
230 base::AutoLock autolock(lock_); 228 base::AutoLock autolock(lock_);
231 return finished_; 229 return finished_;
(...skipping 11 matching lines...) Expand all
243 if (timeout < base::TimeDelta()) { 241 if (timeout < base::TimeDelta()) {
244 VLOG(1) << "OCSP Timed out"; 242 VLOG(1) << "OCSP Timed out";
245 if (!finished_) 243 if (!finished_)
246 CancelLocked(); 244 CancelLocked();
247 break; 245 break;
248 } 246 }
249 } 247 }
250 return finished_; 248 return finished_;
251 } 249 }
252 250
253 const GURL& url() const { 251 const GURL& url() const { return url_; }
254 return url_;
255 }
256 252
257 const std::string& http_request_method() const { 253 const std::string& http_request_method() const {
258 return http_request_method_; 254 return http_request_method_;
259 } 255 }
260 256
261 base::TimeDelta timeout() const { 257 base::TimeDelta timeout() const { return timeout_; }
262 return timeout_;
263 }
264 258
265 PRUint16 http_response_code() const { 259 PRUint16 http_response_code() const {
266 DCHECK(finished_); 260 DCHECK(finished_);
267 return response_code_; 261 return response_code_;
268 } 262 }
269 263
270 const std::string& http_response_content_type() const { 264 const std::string& http_response_content_type() const {
271 DCHECK(finished_); 265 DCHECK(finished_);
272 return response_content_type_; 266 return response_content_type_;
273 } 267 }
(...skipping 28 matching lines...) Expand all
302 int bytes_read = 0; 296 int bytes_read = 0;
303 if (request->status().is_success()) { 297 if (request->status().is_success()) {
304 response_code_ = request_->GetResponseCode(); 298 response_code_ = request_->GetResponseCode();
305 response_headers_ = request_->response_headers(); 299 response_headers_ = request_->response_headers();
306 response_headers_->GetMimeType(&response_content_type_); 300 response_headers_->GetMimeType(&response_content_type_);
307 request_->Read(buffer_.get(), kRecvBufferSize, &bytes_read); 301 request_->Read(buffer_.get(), kRecvBufferSize, &bytes_read);
308 } 302 }
309 OnReadCompleted(request_, bytes_read); 303 OnReadCompleted(request_, bytes_read);
310 } 304 }
311 305
312 virtual void OnReadCompleted(URLRequest* request, 306 virtual void OnReadCompleted(URLRequest* request, int bytes_read) OVERRIDE {
313 int bytes_read) OVERRIDE {
314 DCHECK_EQ(request, request_); 307 DCHECK_EQ(request, request_);
315 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_); 308 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
316 309
317 do { 310 do {
318 if (!request_->status().is_success() || bytes_read <= 0) 311 if (!request_->status().is_success() || bytes_read <= 0)
319 break; 312 break;
320 data_.append(buffer_->data(), bytes_read); 313 data_.append(buffer_->data(), bytes_read);
321 } while (request_->Read(buffer_.get(), kRecvBufferSize, &bytes_read)); 314 } while (request_->Read(buffer_.get(), kRecvBufferSize, &bytes_read));
322 315
323 if (!request_->status().is_io_pending()) { 316 if (!request_->status().is_io_pending()) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 // |lock_| here. 360 // |lock_| here.
368 DCHECK(!request_); 361 DCHECK(!request_);
369 DCHECK(!io_loop_); 362 DCHECK(!io_loop_);
370 } 363 }
371 364
372 // Must call this method while holding |lock_|. 365 // Must call this method while holding |lock_|.
373 void CancelLocked() { 366 void CancelLocked() {
374 lock_.AssertAcquired(); 367 lock_.AssertAcquired();
375 if (io_loop_) { 368 if (io_loop_) {
376 io_loop_->PostTask( 369 io_loop_->PostTask(
377 FROM_HERE, 370 FROM_HERE, base::Bind(&OCSPRequestSession::CancelURLRequest, this));
378 base::Bind(&OCSPRequestSession::CancelURLRequest, this));
379 } 371 }
380 } 372 }
381 373
382 // Runs on |g_ocsp_io_loop|'s IO loop. 374 // Runs on |g_ocsp_io_loop|'s IO loop.
383 void StartURLRequest() { 375 void StartURLRequest() {
384 DCHECK(!request_); 376 DCHECK(!request_);
385 377
386 pthread_mutex_lock(&g_request_context_lock); 378 pthread_mutex_lock(&g_request_context_lock);
387 URLRequestContext* url_request_context = g_request_context; 379 URLRequestContext* url_request_context = g_request_context;
388 pthread_mutex_unlock(&g_request_context_lock); 380 pthread_mutex_unlock(&g_request_context_lock);
(...skipping 12 matching lines...) Expand all
401 new URLRequest(url_, DEFAULT_PRIORITY, this, url_request_context); 393 new URLRequest(url_, DEFAULT_PRIORITY, this, url_request_context);
402 // To meet the privacy requirements of incognito mode. 394 // To meet the privacy requirements of incognito mode.
403 request_->SetLoadFlags(LOAD_DISABLE_CACHE | LOAD_DO_NOT_SAVE_COOKIES | 395 request_->SetLoadFlags(LOAD_DISABLE_CACHE | LOAD_DO_NOT_SAVE_COOKIES |
404 LOAD_DO_NOT_SEND_COOKIES); 396 LOAD_DO_NOT_SEND_COOKIES);
405 397
406 if (http_request_method_ == "POST") { 398 if (http_request_method_ == "POST") {
407 DCHECK(!upload_content_.empty()); 399 DCHECK(!upload_content_.empty());
408 DCHECK(!upload_content_type_.empty()); 400 DCHECK(!upload_content_type_.empty());
409 401
410 request_->set_method("POST"); 402 request_->set_method("POST");
411 extra_request_headers_.SetHeader( 403 extra_request_headers_.SetHeader(HttpRequestHeaders::kContentType,
412 HttpRequestHeaders::kContentType, upload_content_type_); 404 upload_content_type_);
413 405
414 scoped_ptr<UploadElementReader> reader(new UploadBytesElementReader( 406 scoped_ptr<UploadElementReader> reader(new UploadBytesElementReader(
415 upload_content_.data(), upload_content_.size())); 407 upload_content_.data(), upload_content_.size()));
416 request_->set_upload(make_scoped_ptr( 408 request_->set_upload(make_scoped_ptr(
417 UploadDataStream::CreateWithReader(reader.Pass(), 0))); 409 UploadDataStream::CreateWithReader(reader.Pass(), 0)));
418 } 410 }
419 if (!extra_request_headers_.IsEmpty()) 411 if (!extra_request_headers_.IsEmpty())
420 request_->SetExtraRequestHeaders(extra_request_headers_); 412 request_->SetExtraRequestHeaders(extra_request_headers_);
421 413
422 request_->Start(); 414 request_->Start();
423 AddRef(); // Release after |request_| deleted. 415 AddRef(); // Release after |request_| deleted.
424 } 416 }
425 417
426 GURL url_; // The URL we eventually wound up at 418 GURL url_; // The URL we eventually wound up at
427 std::string http_request_method_; 419 std::string http_request_method_;
428 base::TimeDelta timeout_; // The timeout for OCSP 420 base::TimeDelta timeout_; // The timeout for OCSP
429 URLRequest* request_; // The actual request this wraps 421 URLRequest* request_; // The actual request this wraps
430 scoped_refptr<IOBuffer> buffer_; // Read buffer 422 scoped_refptr<IOBuffer> buffer_; // Read buffer
431 HttpRequestHeaders extra_request_headers_; 423 HttpRequestHeaders extra_request_headers_;
432 424
433 // HTTP POST payload. |request_| reads bytes from this. 425 // HTTP POST payload. |request_| reads bytes from this.
434 std::string upload_content_; 426 std::string upload_content_;
435 std::string upload_content_type_; // MIME type of POST payload 427 std::string upload_content_type_; // MIME type of POST payload
436 428
437 int response_code_; // HTTP status code for the request 429 int response_code_; // HTTP status code for the request
438 std::string response_content_type_; 430 std::string response_content_type_;
439 scoped_refptr<HttpResponseHeaders> response_headers_; 431 scoped_refptr<HttpResponseHeaders> response_headers_;
440 std::string data_; // Results of the request 432 std::string data_; // Results of the request
441 433
442 // |lock_| protects |finished_| and |io_loop_|. 434 // |lock_| protects |finished_| and |io_loop_|.
443 mutable base::Lock lock_; 435 mutable base::Lock lock_;
444 base::ConditionVariable cv_; 436 base::ConditionVariable cv_;
445 437
446 base::MessageLoop* io_loop_; // Message loop of the IO thread 438 base::MessageLoop* io_loop_; // Message loop of the IO thread
447 bool finished_; 439 bool finished_;
448 440
449 DISALLOW_COPY_AND_ASSIGN(OCSPRequestSession); 441 DISALLOW_COPY_AND_ASSIGN(OCSPRequestSession);
450 }; 442 };
(...skipping 10 matching lines...) Expand all
461 const char* http_request_method, 453 const char* http_request_method,
462 const PRIntervalTime timeout) { 454 const PRIntervalTime timeout) {
463 // We dont' support "https" because we haven't thought about 455 // We dont' support "https" because we haven't thought about
464 // whether it's safe to re-enter this code from talking to an OCSP 456 // whether it's safe to re-enter this code from talking to an OCSP
465 // responder over SSL. 457 // responder over SSL.
466 if (strcmp(http_protocol_variant, "http") != 0) { 458 if (strcmp(http_protocol_variant, "http") != 0) {
467 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); 459 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
468 return NULL; 460 return NULL;
469 } 461 }
470 462
471 std::string url_string(base::StringPrintf( 463 std::string url_string(base::StringPrintf("%s://%s%s",
472 "%s://%s%s", 464 http_protocol_variant,
473 http_protocol_variant, 465 host_and_port_.ToString().c_str(),
474 host_and_port_.ToString().c_str(), 466 path_and_query_string));
475 path_and_query_string));
476 VLOG(1) << "URL [" << url_string << "]"; 467 VLOG(1) << "URL [" << url_string << "]";
477 GURL url(url_string); 468 GURL url(url_string);
478 469
479 // NSS does not expose public functions to adjust the fetch timeout when 470 // NSS does not expose public functions to adjust the fetch timeout when
480 // using libpkix, so hardcode the upper limit for network fetches. 471 // using libpkix, so hardcode the upper limit for network fetches.
481 base::TimeDelta actual_timeout = std::min( 472 base::TimeDelta actual_timeout = std::min(
482 base::TimeDelta::FromSeconds(kNetworkFetchTimeoutInSecs), 473 base::TimeDelta::FromSeconds(kNetworkFetchTimeoutInSecs),
483 base::TimeDelta::FromMilliseconds(PR_IntervalToMilliseconds(timeout))); 474 base::TimeDelta::FromMilliseconds(PR_IntervalToMilliseconds(timeout)));
484 475
485 return new OCSPRequestSession(url, http_request_method, actual_timeout); 476 return new OCSPRequestSession(url, http_request_method, actual_timeout);
486 } 477 }
487 478
488
489 private: 479 private:
490 HostPortPair host_and_port_; 480 HostPortPair host_and_port_;
491 481
492 DISALLOW_COPY_AND_ASSIGN(OCSPServerSession); 482 DISALLOW_COPY_AND_ASSIGN(OCSPServerSession);
493 }; 483 };
494 484
495 OCSPIOLoop::OCSPIOLoop() 485 OCSPIOLoop::OCSPIOLoop() : shutdown_(false), used_(false), io_loop_(NULL) {
496 : shutdown_(false),
497 used_(false),
498 io_loop_(NULL) {
499 } 486 }
500 487
501 OCSPIOLoop::~OCSPIOLoop() { 488 OCSPIOLoop::~OCSPIOLoop() {
502 // IO thread was already deleted before the singleton is deleted 489 // IO thread was already deleted before the singleton is deleted
503 // in AtExitManager. 490 // in AtExitManager.
504 { 491 {
505 base::AutoLock autolock(lock_); 492 base::AutoLock autolock(lock_);
506 DCHECK(!io_loop_); 493 DCHECK(!io_loop_);
507 DCHECK(!used_); 494 DCHECK(!used_);
508 DCHECK(shutdown_); 495 DCHECK(shutdown_);
(...skipping 16 matching lines...) Expand all
525 shutdown_ = true; 512 shutdown_ = true;
526 } 513 }
527 514
528 CancelAllRequests(); 515 CancelAllRequests();
529 516
530 pthread_mutex_lock(&g_request_context_lock); 517 pthread_mutex_lock(&g_request_context_lock);
531 g_request_context = NULL; 518 g_request_context = NULL;
532 pthread_mutex_unlock(&g_request_context_lock); 519 pthread_mutex_unlock(&g_request_context_lock);
533 } 520 }
534 521
535 void OCSPIOLoop::PostTaskToIOLoop( 522 void OCSPIOLoop::PostTaskToIOLoop(const tracked_objects::Location& from_here,
536 const tracked_objects::Location& from_here, const base::Closure& task) { 523 const base::Closure& task) {
537 base::AutoLock autolock(lock_); 524 base::AutoLock autolock(lock_);
538 if (io_loop_) 525 if (io_loop_)
539 io_loop_->PostTask(from_here, task); 526 io_loop_->PostTask(from_here, task);
540 } 527 }
541 528
542 void OCSPIOLoop::EnsureIOLoop() { 529 void OCSPIOLoop::EnsureIOLoop() {
543 base::AutoLock autolock(lock_); 530 base::AutoLock autolock(lock_);
544 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_); 531 DCHECK_EQ(base::MessageLoopForIO::current(), io_loop_);
545 } 532 }
546 533
(...skipping 13 matching lines...) Expand all
560 while (!requests_.empty()) 547 while (!requests_.empty())
561 (*requests_.begin())->CancelURLRequest(); 548 (*requests_.begin())->CancelURLRequest();
562 } 549 }
563 550
564 OCSPNSSInitialization::OCSPNSSInitialization() { 551 OCSPNSSInitialization::OCSPNSSInitialization() {
565 // NSS calls the functions in the function table to download certificates 552 // NSS calls the functions in the function table to download certificates
566 // or CRLs or talk to OCSP responders over HTTP. These functions must 553 // or CRLs or talk to OCSP responders over HTTP. These functions must
567 // set an NSS/NSPR error code when they fail. Otherwise NSS will get the 554 // set an NSS/NSPR error code when they fail. Otherwise NSS will get the
568 // residual error code from an earlier failed function call. 555 // residual error code from an earlier failed function call.
569 client_fcn_.version = 1; 556 client_fcn_.version = 1;
570 SEC_HttpClientFcnV1Struct *ft = &client_fcn_.fcnTable.ftable1; 557 SEC_HttpClientFcnV1Struct* ft = &client_fcn_.fcnTable.ftable1;
571 ft->createSessionFcn = OCSPCreateSession; 558 ft->createSessionFcn = OCSPCreateSession;
572 ft->keepAliveSessionFcn = OCSPKeepAliveSession; 559 ft->keepAliveSessionFcn = OCSPKeepAliveSession;
573 ft->freeSessionFcn = OCSPFreeSession; 560 ft->freeSessionFcn = OCSPFreeSession;
574 ft->createFcn = OCSPCreate; 561 ft->createFcn = OCSPCreate;
575 ft->setPostDataFcn = OCSPSetPostData; 562 ft->setPostDataFcn = OCSPSetPostData;
576 ft->addHeaderFcn = OCSPAddHeader; 563 ft->addHeaderFcn = OCSPAddHeader;
577 ft->trySendAndReceiveFcn = OCSPTrySendAndReceive; 564 ft->trySendAndReceiveFcn = OCSPTrySendAndReceive;
578 ft->cancelFcn = NULL; 565 ft->cancelFcn = NULL;
579 ft->freeFcn = OCSPFree; 566 ft->freeFcn = OCSPFree;
580 SECStatus status = SEC_RegisterDefaultHttpClient(&client_fcn_); 567 SECStatus status = SEC_RegisterDefaultHttpClient(&client_fcn_);
581 if (status != SECSuccess) { 568 if (status != SECSuccess) {
582 NOTREACHED() << "Error initializing OCSP: " << PR_GetError(); 569 NOTREACHED() << "Error initializing OCSP: " << PR_GetError();
583 } 570 }
584 571
585 // Work around NSS bugs 524013 and 564334. NSS incorrectly thinks the 572 // Work around NSS bugs 524013 and 564334. NSS incorrectly thinks the
586 // CRLs for Network Solutions Certificate Authority have bad signatures, 573 // CRLs for Network Solutions Certificate Authority have bad signatures,
587 // which causes certificates issued by that CA to be reported as revoked. 574 // which causes certificates issued by that CA to be reported as revoked.
588 // By using OCSP for those certificates, which don't have AIA extensions, 575 // By using OCSP for those certificates, which don't have AIA extensions,
589 // we can work around these bugs. See http://crbug.com/41730. 576 // we can work around these bugs. See http://crbug.com/41730.
590 CERT_StringFromCertFcn old_callback = NULL; 577 CERT_StringFromCertFcn old_callback = NULL;
591 status = CERT_RegisterAlternateOCSPAIAInfoCallBack( 578 status = CERT_RegisterAlternateOCSPAIAInfoCallBack(GetAlternateOCSPAIAInfo,
592 GetAlternateOCSPAIAInfo, &old_callback); 579 &old_callback);
593 if (status == SECSuccess) { 580 if (status == SECSuccess) {
594 DCHECK(!old_callback); 581 DCHECK(!old_callback);
595 } else { 582 } else {
596 NOTREACHED() << "Error initializing OCSP: " << PR_GetError(); 583 NOTREACHED() << "Error initializing OCSP: " << PR_GetError();
597 } 584 }
598 } 585 }
599 586
600 OCSPNSSInitialization::~OCSPNSSInitialization() { 587 OCSPNSSInitialization::~OCSPNSSInitialization() {
601 SECStatus status = CERT_RegisterAlternateOCSPAIAInfoCallBack(NULL, NULL); 588 SECStatus status = CERT_RegisterAlternateOCSPAIAInfoCallBack(NULL, NULL);
602 if (status != SECSuccess) { 589 if (status != SECSuccess) {
603 LOG(ERROR) << "Error unregistering OCSP: " << PR_GetError(); 590 LOG(ERROR) << "Error unregistering OCSP: " << PR_GetError();
604 } 591 }
605 } 592 }
606 593
607
608 // OCSP Http Client functions. 594 // OCSP Http Client functions.
609 // Our Http Client functions operate in blocking mode. 595 // Our Http Client functions operate in blocking mode.
610 SECStatus OCSPCreateSession(const char* host, PRUint16 portnum, 596 SECStatus OCSPCreateSession(const char* host,
597 PRUint16 portnum,
611 SEC_HTTP_SERVER_SESSION* pSession) { 598 SEC_HTTP_SERVER_SESSION* pSession) {
612 VLOG(1) << "OCSP create session: host=" << host << " port=" << portnum; 599 VLOG(1) << "OCSP create session: host=" << host << " port=" << portnum;
613 pthread_mutex_lock(&g_request_context_lock); 600 pthread_mutex_lock(&g_request_context_lock);
614 URLRequestContext* request_context = g_request_context; 601 URLRequestContext* request_context = g_request_context;
615 pthread_mutex_unlock(&g_request_context_lock); 602 pthread_mutex_unlock(&g_request_context_lock);
616 if (request_context == NULL) { 603 if (request_context == NULL) {
617 LOG(ERROR) << "No URLRequestContext for NSS HTTP handler. host: " << host; 604 LOG(ERROR) << "No URLRequestContext for NSS HTTP handler. host: " << host;
618 // The application failed to call SetURLRequestContextForNSSHttpIO or 605 // The application failed to call SetURLRequestContextForNSSHttpIO or
619 // has already called ShutdownNSSHttpIO, so we can't create and use 606 // has already called ShutdownNSSHttpIO, so we can't create and use
620 // URLRequest. PR_NOT_IMPLEMENTED_ERROR is not an accurate error 607 // URLRequest. PR_NOT_IMPLEMENTED_ERROR is not an accurate error
621 // code for these error conditions, but is close enough. 608 // code for these error conditions, but is close enough.
622 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); 609 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
623 return SECFailure; 610 return SECFailure;
624 } 611 }
625 *pSession = new OCSPServerSession(host, portnum); 612 *pSession = new OCSPServerSession(host, portnum);
626 return SECSuccess; 613 return SECSuccess;
627 } 614 }
628 615
629 SECStatus OCSPKeepAliveSession(SEC_HTTP_SERVER_SESSION session, 616 SECStatus OCSPKeepAliveSession(SEC_HTTP_SERVER_SESSION session,
630 PRPollDesc **pPollDesc) { 617 PRPollDesc** pPollDesc) {
631 VLOG(1) << "OCSP keep alive"; 618 VLOG(1) << "OCSP keep alive";
632 if (pPollDesc) 619 if (pPollDesc)
633 *pPollDesc = NULL; 620 *pPollDesc = NULL;
634 return SECSuccess; 621 return SECSuccess;
635 } 622 }
636 623
637 SECStatus OCSPFreeSession(SEC_HTTP_SERVER_SESSION session) { 624 SECStatus OCSPFreeSession(SEC_HTTP_SERVER_SESSION session) {
638 VLOG(1) << "OCSP free session"; 625 VLOG(1) << "OCSP free session";
639 delete reinterpret_cast<OCSPServerSession*>(session); 626 delete reinterpret_cast<OCSPServerSession*>(session);
640 return SECSuccess; 627 return SECSuccess;
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 767
781 // We want to know if this was: 768 // We want to know if this was:
782 // 1) An OCSP request 769 // 1) An OCSP request
783 // 2) A CRL request 770 // 2) A CRL request
784 // 3) A request for a missing intermediate certificate 771 // 3) A request for a missing intermediate certificate
785 // There's no sure way to do this, so we use heuristics like MIME type and 772 // There's no sure way to do this, so we use heuristics like MIME type and
786 // URL. 773 // URL.
787 const char* mime_type = ""; 774 const char* mime_type = "";
788 if (ok) 775 if (ok)
789 mime_type = req->http_response_content_type().c_str(); 776 mime_type = req->http_response_content_type().c_str();
790 bool is_ocsp = 777 bool is_ocsp = strcasecmp(mime_type, "application/ocsp-response") == 0;
791 strcasecmp(mime_type, "application/ocsp-response") == 0;
792 bool is_crl = strcasecmp(mime_type, "application/x-pkcs7-crl") == 0 || 778 bool is_crl = strcasecmp(mime_type, "application/x-pkcs7-crl") == 0 ||
793 strcasecmp(mime_type, "application/x-x509-crl") == 0 || 779 strcasecmp(mime_type, "application/x-x509-crl") == 0 ||
794 strcasecmp(mime_type, "application/pkix-crl") == 0; 780 strcasecmp(mime_type, "application/pkix-crl") == 0;
795 bool is_cert = 781 bool is_cert = strcasecmp(mime_type, "application/x-x509-ca-cert") == 0 ||
796 strcasecmp(mime_type, "application/x-x509-ca-cert") == 0 || 782 strcasecmp(mime_type, "application/x-x509-server-cert") == 0 ||
797 strcasecmp(mime_type, "application/x-x509-server-cert") == 0 || 783 strcasecmp(mime_type, "application/pkix-cert") == 0 ||
798 strcasecmp(mime_type, "application/pkix-cert") == 0 || 784 strcasecmp(mime_type, "application/pkcs7-mime") == 0;
799 strcasecmp(mime_type, "application/pkcs7-mime") == 0;
800 785
801 if (!is_cert && !is_crl && !is_ocsp) { 786 if (!is_cert && !is_crl && !is_ocsp) {
802 // We didn't get a hint from the MIME type, so do the best that we can. 787 // We didn't get a hint from the MIME type, so do the best that we can.
803 const std::string path = req->url().path(); 788 const std::string path = req->url().path();
804 const std::string host = req->url().host(); 789 const std::string host = req->url().host();
805 is_crl = strcasestr(path.c_str(), ".crl") != NULL; 790 is_crl = strcasestr(path.c_str(), ".crl") != NULL;
806 is_cert = strcasestr(path.c_str(), ".crt") != NULL || 791 is_cert = strcasestr(path.c_str(), ".crt") != NULL ||
807 strcasestr(path.c_str(), ".p7c") != NULL || 792 strcasestr(path.c_str(), ".p7c") != NULL ||
808 strcasestr(path.c_str(), ".cer") != NULL; 793 strcasestr(path.c_str(), ".cer") != NULL;
809 is_ocsp = strcasestr(host.c_str(), "ocsp") != NULL || 794 is_ocsp = strcasestr(host.c_str(), "ocsp") != NULL ||
(...skipping 22 matching lines...) Expand all
832 } else { 817 } else {
833 if (ok) 818 if (ok)
834 UMA_HISTOGRAM_TIMES("Net.UnknownTypeRequestTimeMs", duration); 819 UMA_HISTOGRAM_TIMES("Net.UnknownTypeRequestTimeMs", duration);
835 } 820 }
836 821
837 if (!request_ok) { 822 if (!request_ok) {
838 PORT_SetError(SEC_ERROR_BAD_HTTP_RESPONSE); // Simple approximation. 823 PORT_SetError(SEC_ERROR_BAD_HTTP_RESPONSE); // Simple approximation.
839 return SECFailure; 824 return SECFailure;
840 } 825 }
841 826
842 return OCSPSetResponse( 827 return OCSPSetResponse(req,
843 req, http_response_code, 828 http_response_code,
844 http_response_content_type, 829 http_response_content_type,
845 http_response_headers, 830 http_response_headers,
846 http_response_data, 831 http_response_data,
847 http_response_data_len); 832 http_response_data_len);
848 } 833 }
849 834
850 SECStatus OCSPFree(SEC_HTTP_REQUEST_SESSION request) { 835 SECStatus OCSPFree(SEC_HTTP_REQUEST_SESSION request) {
851 VLOG(1) << "OCSP free"; 836 VLOG(1) << "OCSP free";
852 OCSPRequestSession* req = reinterpret_cast<OCSPRequestSession*>(request); 837 OCSPRequestSession* req = reinterpret_cast<OCSPRequestSession*>(request);
853 req->Cancel(); 838 req->Cancel();
854 req->Release(); 839 req->Release();
855 return SECSuccess; 840 return SECSuccess;
856 } 841 }
857 842
858 // Data for GetAlternateOCSPAIAInfo. 843 // Data for GetAlternateOCSPAIAInfo.
859 844
860 // CN=Network Solutions Certificate Authority,O=Network Solutions L.L.C.,C=US 845 // CN=Network Solutions Certificate Authority,O=Network Solutions L.L.C.,C=US
861 // 846 //
862 // There are two CAs with this name. Their key IDs are listed next. 847 // There are two CAs with this name. Their key IDs are listed next.
863 const unsigned char network_solutions_ca_name[] = { 848 const unsigned char network_solutions_ca_name[] = {
864 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 849 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
865 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1f, 0x06, 850 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a,
866 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x4e, 0x65, 0x74, 0x77, 851 0x13, 0x18, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x53, 0x6f,
867 0x6f, 0x72, 0x6b, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 852 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x4c, 0x2e, 0x4c, 0x2e,
868 0x6f, 0x6e, 0x73, 0x20, 0x4c, 0x2e, 0x4c, 0x2e, 0x43, 0x2e, 853 0x43, 0x2e, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
869 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 854 0x27, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x53, 0x6f, 0x6c,
870 0x27, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x53, 855 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
871 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x43, 856 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
872 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 857 0x72, 0x69, 0x74, 0x79};
873 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79
874 };
875 const unsigned int network_solutions_ca_name_len = 100; 858 const unsigned int network_solutions_ca_name_len = 100;
876 859
877 // This CA is an intermediate CA, subordinate to UTN-USERFirst-Hardware. 860 // This CA is an intermediate CA, subordinate to UTN-USERFirst-Hardware.
878 const unsigned char network_solutions_ca_key_id[] = { 861 const unsigned char network_solutions_ca_key_id[] = {
879 0x3c, 0x41, 0xe2, 0x8f, 0x08, 0x08, 0xa9, 0x4c, 0x25, 0x89, 862 0x3c, 0x41, 0xe2, 0x8f, 0x08, 0x08, 0xa9, 0x4c, 0x25, 0x89,
880 0x8d, 0x6d, 0xc5, 0x38, 0xd0, 0xfc, 0x85, 0x8c, 0x62, 0x17 863 0x8d, 0x6d, 0xc5, 0x38, 0xd0, 0xfc, 0x85, 0x8c, 0x62, 0x17};
881 };
882 const unsigned int network_solutions_ca_key_id_len = 20; 864 const unsigned int network_solutions_ca_key_id_len = 20;
883 865
884 // This CA is a root CA. It is also cross-certified by 866 // This CA is a root CA. It is also cross-certified by
885 // UTN-USERFirst-Hardware. 867 // UTN-USERFirst-Hardware.
886 const unsigned char network_solutions_ca_key_id2[] = { 868 const unsigned char network_solutions_ca_key_id2[] = {
887 0x21, 0x30, 0xc9, 0xfb, 0x00, 0xd7, 0x4e, 0x98, 0xda, 0x87, 869 0x21, 0x30, 0xc9, 0xfb, 0x00, 0xd7, 0x4e, 0x98, 0xda, 0x87,
888 0xaa, 0x2a, 0xd0, 0xa7, 0x2e, 0xb1, 0x40, 0x31, 0xa7, 0x4c 870 0xaa, 0x2a, 0xd0, 0xa7, 0x2e, 0xb1, 0x40, 0x31, 0xa7, 0x4c};
889 };
890 const unsigned int network_solutions_ca_key_id2_len = 20; 871 const unsigned int network_solutions_ca_key_id2_len = 20;
891 872
892 // An entry in our OCSP responder table. |issuer| and |issuer_key_id| are 873 // An entry in our OCSP responder table. |issuer| and |issuer_key_id| are
893 // the key. |ocsp_url| is the value. 874 // the key. |ocsp_url| is the value.
894 struct OCSPResponderTableEntry { 875 struct OCSPResponderTableEntry {
895 SECItem issuer; 876 SECItem issuer;
896 SECItem issuer_key_id; 877 SECItem issuer_key_id;
897 const char *ocsp_url; 878 const char* ocsp_url;
898 }; 879 };
899 880
900 const OCSPResponderTableEntry g_ocsp_responder_table[] = { 881 const OCSPResponderTableEntry g_ocsp_responder_table[] = {
901 { 882 {{siBuffer, const_cast<unsigned char*>(network_solutions_ca_name),
902 { 883 network_solutions_ca_name_len},
903 siBuffer, 884 {siBuffer, const_cast<unsigned char*>(network_solutions_ca_key_id),
904 const_cast<unsigned char*>(network_solutions_ca_name), 885 network_solutions_ca_key_id_len},
905 network_solutions_ca_name_len 886 "http://ocsp.netsolssl.com"},
906 }, 887 {{siBuffer, const_cast<unsigned char*>(network_solutions_ca_name),
907 { 888 network_solutions_ca_name_len},
908 siBuffer, 889 {siBuffer, const_cast<unsigned char*>(network_solutions_ca_key_id2),
909 const_cast<unsigned char*>(network_solutions_ca_key_id), 890 network_solutions_ca_key_id2_len},
910 network_solutions_ca_key_id_len 891 "http://ocsp.netsolssl.com"}};
911 },
912 "http://ocsp.netsolssl.com"
913 },
914 {
915 {
916 siBuffer,
917 const_cast<unsigned char*>(network_solutions_ca_name),
918 network_solutions_ca_name_len
919 },
920 {
921 siBuffer,
922 const_cast<unsigned char*>(network_solutions_ca_key_id2),
923 network_solutions_ca_key_id2_len
924 },
925 "http://ocsp.netsolssl.com"
926 }
927 };
928 892
929 char* GetAlternateOCSPAIAInfo(CERTCertificate *cert) { 893 char* GetAlternateOCSPAIAInfo(CERTCertificate* cert) {
930 if (cert && !cert->isRoot && cert->authKeyID) { 894 if (cert && !cert->isRoot && cert->authKeyID) {
931 for (unsigned int i=0; i < arraysize(g_ocsp_responder_table); i++) { 895 for (unsigned int i = 0; i < arraysize(g_ocsp_responder_table); i++) {
932 if (SECITEM_CompareItem(&g_ocsp_responder_table[i].issuer, 896 if (SECITEM_CompareItem(&g_ocsp_responder_table[i].issuer,
933 &cert->derIssuer) == SECEqual && 897 &cert->derIssuer) == SECEqual &&
934 SECITEM_CompareItem(&g_ocsp_responder_table[i].issuer_key_id, 898 SECITEM_CompareItem(&g_ocsp_responder_table[i].issuer_key_id,
935 &cert->authKeyID->keyID) == SECEqual) { 899 &cert->authKeyID->keyID) == SECEqual) {
936 return PORT_Strdup(g_ocsp_responder_table[i].ocsp_url); 900 return PORT_Strdup(g_ocsp_responder_table[i].ocsp_url);
937 } 901 }
938 } 902 }
939 } 903 }
940 904
941 return NULL; 905 return NULL;
(...skipping 28 matching lines...) Expand all
970 void SetURLRequestContextForNSSHttpIO(URLRequestContext* request_context) { 934 void SetURLRequestContextForNSSHttpIO(URLRequestContext* request_context) {
971 pthread_mutex_lock(&g_request_context_lock); 935 pthread_mutex_lock(&g_request_context_lock);
972 if (request_context) { 936 if (request_context) {
973 DCHECK(!g_request_context); 937 DCHECK(!g_request_context);
974 } 938 }
975 g_request_context = request_context; 939 g_request_context = request_context;
976 pthread_mutex_unlock(&g_request_context_lock); 940 pthread_mutex_unlock(&g_request_context_lock);
977 } 941 }
978 942
979 } // namespace net 943 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698