| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |