1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/socket/ssl_server_socket_nss.h" 6 7 #if defined(OS_WIN) 8 #include <winsock2.h> 9 #endif 10 11 #if defined(USE_SYSTEM_SSL) 12 #include <dlfcn.h> 13 #endif 14 #if defined(OS_MACOSX) 15 #include <Security/Security.h> 16 #endif 17 #include <certdb.h> 18 #include <cryptohi.h> 19 #include <hasht.h> 20 #include <keyhi.h> 21 #include <nspr.h> 22 #include <nss.h> 23 #include <pk11pub.h> 24 #include <secerr.h> 25 #include <sechash.h> 26 #include <ssl.h> 27 #include <sslerr.h> 28 #include <sslproto.h> 29 30 #include <limits> 31 32 #include "base/memory/ref_counted.h" 33 #include "crypto/rsa_private_key.h" 34 #include "crypto/nss_util_internal.h" 35 #include "net/base/io_buffer.h" 36 #include "net/base/net_errors.h" 37 #include "net/base/net_log.h" 38 #include "net/ocsp/nss_ocsp.h" 39 #include "net/socket/nss_ssl_util.h" 40 #include "net/socket/ssl_error_params.h" 41 42 static const int kRecvBufferSize = 4096; 43 44 #define GotoState(s) next_handshake_state_ = s 45 46 namespace net { 47 48 SSLServerSocket* CreateSSLServerSocket( 49 Socket* socket, X509Certificate* cert, crypto::RSAPrivateKey* key, 50 const SSLConfig& ssl_config) { 51 return new SSLServerSocketNSS(socket, cert, key, ssl_config); 52 } 53 54 SSLServerSocketNSS::SSLServerSocketNSS( 55 Socket* transport_socket, 56 scoped_refptr<X509Certificate> cert, 57 crypto::RSAPrivateKey* key, 58 const SSLConfig& ssl_config) 59 : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_( 60 this, &SSLServerSocketNSS::BufferSendComplete)), 61 ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_( 62 this, &SSLServerSocketNSS::BufferRecvComplete)), 63 transport_send_busy_(false), 64 transport_recv_busy_(false), 65 user_accept_callback_(NULL), 66 user_read_callback_(NULL), 67 user_write_callback_(NULL), 68 nss_fd_(NULL), 69 nss_bufs_(NULL), 70 transport_socket_(transport_socket), 71 ssl_config_(ssl_config), 72 cert_(cert), 73 next_handshake_state_(STATE_NONE), 74 completed_handshake_(false) { 75 ssl_config_.false_start_enabled = false; 76 ssl_config_.ssl3_enabled = true; 77 ssl_config_.tls1_enabled = true; 78 79 // TODO(hclam): Need a better way to clone a key. 80 std::vector<uint8> key_bytes; 81 CHECK(key->ExportPrivateKey(&key_bytes)); 82 key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes)); 83 CHECK(key_.get()); 84 } 85 86 SSLServerSocketNSS::~SSLServerSocketNSS() { 87 if (nss_fd_ != NULL) { 88 PR_Close(nss_fd_); 89 nss_fd_ = NULL; 90 } 91 } 92 93 int SSLServerSocketNSS::Accept(CompletionCallback* callback) { 94 net_log_.BeginEvent(NetLog::TYPE_SSL_ACCEPT, NULL); 95 96 int rv = Init(); 97 if (rv != OK) { 98 LOG(ERROR) << "Failed to initialize NSS"; 99 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv); 100 return rv; 101 } 102 103 rv = InitializeSSLOptions(); 104 if (rv != OK) { 105 LOG(ERROR) << "Failed to initialize SSL options"; 106 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv); 107 return rv; 108 } 109 110 // Set peer address. TODO(hclam): This should be in a separate method. 111 PRNetAddr peername; 112 memset(&peername, 0, sizeof(peername)); 113 peername.raw.family = AF_INET; 114 memio_SetPeerName(nss_fd_, &peername); 115 116 GotoState(STATE_HANDSHAKE); 117 rv = DoHandshakeLoop(net::OK); 118 if (rv == ERR_IO_PENDING) { 119 user_accept_callback_ = callback; 120 } else { 121 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv); 122 } 123 124 return rv > OK ? OK : rv; 125 } 126 127 int SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len, 128 CompletionCallback* callback) { 129 DCHECK(!user_read_callback_); 130 DCHECK(!user_accept_callback_); 131 DCHECK(!user_read_buf_); 132 DCHECK(nss_bufs_); 133 134 user_read_buf_ = buf; 135 user_read_buf_len_ = buf_len; 136 137 DCHECK(completed_handshake_); 138 139 int rv = DoReadLoop(OK); 140 141 if (rv == ERR_IO_PENDING) { 142 user_read_callback_ = callback; 143 } else { 144 user_read_buf_ = NULL; 145 user_read_buf_len_ = 0; 146 } 147 return rv; 148 } 149 150 int SSLServerSocketNSS::Write(IOBuffer* buf, int buf_len, 151 CompletionCallback* callback) { 152 DCHECK(!user_write_callback_); 153 DCHECK(!user_write_buf_); 154 DCHECK(nss_bufs_); 155 156 user_write_buf_ = buf; 157 user_write_buf_len_ = buf_len; 158 159 int rv = DoWriteLoop(OK); 160 161 if (rv == ERR_IO_PENDING) { 162 user_write_callback_ = callback; 163 } else { 164 user_write_buf_ = NULL; 165 user_write_buf_len_ = 0; 166 } 167 return rv; 168 } 169 170 bool SSLServerSocketNSS::SetReceiveBufferSize(int32 size) { 171 return false; 172 } 173 174 bool SSLServerSocketNSS::SetSendBufferSize(int32 size) { 175 return false; 176 } 177 178 int SSLServerSocketNSS::InitializeSSLOptions() { 179 // Transport connected, now hook it up to nss 180 // TODO(port): specify rx and tx buffer sizes separately 181 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize); 182 if (nss_fd_ == NULL) { 183 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code. 184 } 185 186 // Grab pointer to buffers 187 nss_bufs_ = memio_GetSecret(nss_fd_); 188 189 /* Create SSL state machine */ 190 /* Push SSL onto our fake I/O socket */ 191 nss_fd_ = SSL_ImportFD(NULL, nss_fd_); 192 if (nss_fd_ == NULL) { 193 LogFailedNSSFunction(net_log_, "SSL_ImportFD", ""); 194 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code. 195 } 196 // TODO(port): set more ssl options! Check errors! 197 198 int rv; 199 200 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE); 201 if (rv != SECSuccess) { 202 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY"); 203 return ERR_UNEXPECTED; 204 } 205 206 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE); 207 if (rv != SECSuccess) { 208 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2"); 209 return ERR_UNEXPECTED; 210 } 211 212 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, PR_TRUE); 213 if (rv != SECSuccess) { 214 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL3"); 215 return ERR_UNEXPECTED; 216 } 217 218 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_TLS, ssl_config_.tls1_enabled); 219 if (rv != SECSuccess) { 220 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_TLS"); 221 return ERR_UNEXPECTED; 222 } 223 224 for (std::vector<uint16>::const_iterator it = 225 ssl_config_.disabled_cipher_suites.begin(); 226 it != ssl_config_.disabled_cipher_suites.end(); ++it) { 227 // This will fail if the specified cipher is not implemented by NSS, but 228 // the failure is harmless. 229 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE); 230 } 231 232 // Server socket doesn't need session tickets. 233 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_FALSE); 234 if (rv != SECSuccess) { 235 LogFailedNSSFunction( 236 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS"); 237 } 238 239 // Doing this will force PR_Accept perform handshake as server. 240 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_FALSE); 241 if (rv != SECSuccess) { 242 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); 243 return ERR_UNEXPECTED; 244 } 245 246 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_SERVER, PR_TRUE); 247 if (rv != SECSuccess) { 248 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_SERVER"); 249 return ERR_UNEXPECTED; 250 } 251 252 rv = SSL_OptionSet(nss_fd_, SSL_REQUEST_CERTIFICATE, PR_FALSE); 253 if (rv != SECSuccess) { 254 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUEST_CERTIFICATE"); 255 return ERR_UNEXPECTED; 256 } 257 258 rv = SSL_OptionSet(nss_fd_, SSL_REQUIRE_CERTIFICATE, PR_FALSE); 259 if (rv != SECSuccess) { 260 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUIRE_CERTIFICATE"); 261 return ERR_UNEXPECTED; 262 } 263 264 rv = SSL_ConfigServerSessionIDCache(1024, 5, 5, NULL); 265 if (rv != SECSuccess) { 266 LogFailedNSSFunction(net_log_, "SSL_ConfigureServerSessionIDCache", ""); 267 return ERR_UNEXPECTED; 268 } 269 270 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); 271 if (rv != SECSuccess) { 272 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", ""); 273 return ERR_UNEXPECTED; 274 } 275 276 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this); 277 if (rv != SECSuccess) { 278 LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", ""); 279 return ERR_UNEXPECTED; 280 } 281 282 // Get a certificate of CERTCertificate structure. 283 std::string der_string; 284 if (!cert_->GetDEREncoded(&der_string)) 285 return ERR_UNEXPECTED; 286 287 SECItem der_cert; 288 der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>( 289 der_string.data())); 290 der_cert.len = der_string.length(); 291 der_cert.type = siDERCertBuffer; 292 293 // Parse into a CERTCertificate structure. 294 CERTCertificate* cert = CERT_NewTempCertificate( 295 CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE); 296 297 // Get a key of SECKEYPrivateKey* structure. 298 std::vector<uint8> key_vector; 299 if (!key_->ExportPrivateKey(&key_vector)) { 300 CERT_DestroyCertificate(cert); 301 return ERR_UNEXPECTED; 302 } 303 304 SECKEYPrivateKeyStr* private_key = NULL; 305 PK11SlotInfo* slot = crypto::GetPrivateNSSKeySlot(); 306 if (!slot) { 307 CERT_DestroyCertificate(cert); 308 return ERR_UNEXPECTED; 309 } 310 311 SECItem der_private_key_info; 312 der_private_key_info.data = 313 const_cast<unsigned char*>(&key_vector.front()); 314 der_private_key_info.len = key_vector.size(); 315 // The server's RSA private key must be imported into NSS with the 316 // following key usage bits: 317 // - KU_KEY_ENCIPHERMENT, required for the RSA key exchange algorithm. 318 // - KU_DIGITAL_SIGNATURE, required for the DHE_RSA and ECDHE_RSA key 319 // exchange algorithms. 320 const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DIGITAL_SIGNATURE; 321 rv = PK11_ImportDERPrivateKeyInfoAndReturnKey( 322 slot, &der_private_key_info, NULL, NULL, PR_FALSE, PR_FALSE, 323 key_usage, &private_key, NULL); 324 PK11_FreeSlot(slot); 325 if (rv != SECSuccess) { 326 CERT_DestroyCertificate(cert); 327 return ERR_UNEXPECTED; 328 } 329 330 // Assign server certificate and private key. 331 SSLKEAType cert_kea = NSS_FindCertKEAType(cert); 332 rv = SSL_ConfigSecureServer(nss_fd_, cert, private_key, cert_kea); 333 CERT_DestroyCertificate(cert); 334 SECKEY_DestroyPrivateKey(private_key); 335 336 if (rv != SECSuccess) { 337 PRErrorCode prerr = PR_GetError(); 338 LOG(ERROR) << "Failed to config SSL server: " << prerr; 339 LogFailedNSSFunction(net_log_, "SSL_ConfigureSecureServer", ""); 340 return ERR_UNEXPECTED; 341 } 342 343 // Tell SSL we're a server; needed if not letting NSPR do socket I/O 344 rv = SSL_ResetHandshake(nss_fd_, PR_TRUE); 345 if (rv != SECSuccess) { 346 LogFailedNSSFunction(net_log_, "SSL_ResetHandshake", ""); 347 return ERR_UNEXPECTED; 348 } 349 350 return OK; 351 } 352 353 void SSLServerSocketNSS::OnSendComplete(int result) { 354 if (next_handshake_state_ == STATE_HANDSHAKE) { 355 // In handshake phase. 356 OnHandshakeIOComplete(result); 357 return; 358 } 359 360 if (!user_write_buf_ || !completed_handshake_) 361 return; 362 363 int rv = DoWriteLoop(result); 364 if (rv != ERR_IO_PENDING) 365 DoWriteCallback(rv); 366 } 367 368 void SSLServerSocketNSS::OnRecvComplete(int result) { 369 if (next_handshake_state_ == STATE_HANDSHAKE) { 370 // In handshake phase. 371 OnHandshakeIOComplete(result); 372 return; 373 } 374 375 // Network layer received some data, check if client requested to read 376 // decrypted data. 377 if (!user_read_buf_ || !completed_handshake_) 378 return; 379 380 int rv = DoReadLoop(result); 381 if (rv != ERR_IO_PENDING) 382 DoReadCallback(rv); 383 } 384 385 void SSLServerSocketNSS::OnHandshakeIOComplete(int result) { 386 int rv = DoHandshakeLoop(result); 387 if (rv != ERR_IO_PENDING) { 388 net_log_.EndEventWithNetErrorCode(net::NetLog::TYPE_SSL_ACCEPT, rv); 389 if (user_accept_callback_) 390 DoAcceptCallback(rv); 391 } 392 } 393 394 // Return 0 for EOF, 395 // > 0 for bytes transferred immediately, 396 // < 0 for error (or the non-error ERR_IO_PENDING). 397 int SSLServerSocketNSS::BufferSend(void) { 398 if (transport_send_busy_) 399 return ERR_IO_PENDING; 400 401 const char* buf1; 402 const char* buf2; 403 unsigned int len1, len2; 404 memio_GetWriteParams(nss_bufs_, &buf1, &len1, &buf2, &len2); 405 const unsigned int len = len1 + len2; 406 407 int rv = 0; 408 if (len) { 409 scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len)); 410 memcpy(send_buffer->data(), buf1, len1); 411 memcpy(send_buffer->data() + len1, buf2, len2); 412 rv = transport_socket_->Write(send_buffer, len, 413 &buffer_send_callback_); 414 if (rv == ERR_IO_PENDING) { 415 transport_send_busy_ = true; 416 } else { 417 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv)); 418 } 419 } 420 421 return rv; 422 } 423 424 void SSLServerSocketNSS::BufferSendComplete(int result) { 425 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result)); 426 transport_send_busy_ = false; 427 OnSendComplete(result); 428 } 429 430 int SSLServerSocketNSS::BufferRecv(void) { 431 if (transport_recv_busy_) return ERR_IO_PENDING; 432 433 char *buf; 434 int nb = memio_GetReadParams(nss_bufs_, &buf); 435 int rv; 436 if (!nb) { 437 // buffer too full to read into, so no I/O possible at moment 438 rv = ERR_IO_PENDING; 439 } else { 440 recv_buffer_ = new IOBuffer(nb); 441 rv = transport_socket_->Read(recv_buffer_, nb, &buffer_recv_callback_); 442 if (rv == ERR_IO_PENDING) { 443 transport_recv_busy_ = true; 444 } else { 445 if (rv > 0) 446 memcpy(buf, recv_buffer_->data(), rv); 447 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv)); 448 recv_buffer_ = NULL; 449 } 450 } 451 return rv; 452 } 453 454 void SSLServerSocketNSS::BufferRecvComplete(int result) { 455 if (result > 0) { 456 char *buf; 457 memio_GetReadParams(nss_bufs_, &buf); 458 memcpy(buf, recv_buffer_->data(), result); 459 } 460 recv_buffer_ = NULL; 461 memio_PutReadResult(nss_bufs_, MapErrorToNSS(result)); 462 transport_recv_busy_ = false; 463 OnRecvComplete(result); 464 } 465 466 // Do network I/O between the given buffer and the given socket. 467 // Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING) 468 bool SSLServerSocketNSS::DoTransportIO() { 469 bool network_moved = false; 470 if (nss_bufs_ != NULL) { 471 int nsent = BufferSend(); 472 int nreceived = BufferRecv(); 473 network_moved = (nsent > 0 || nreceived >= 0); 474 } 475 return network_moved; 476 } 477 478 int SSLServerSocketNSS::DoPayloadRead() { 479 DCHECK(user_read_buf_); 480 DCHECK_GT(user_read_buf_len_, 0); 481 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_); 482 if (rv >= 0) 483 return rv; 484 PRErrorCode prerr = PR_GetError(); 485 if (prerr == PR_WOULD_BLOCK_ERROR) { 486 return ERR_IO_PENDING; 487 } 488 rv = MapNSSError(prerr); 489 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR, 490 make_scoped_refptr(new SSLErrorParams(rv, prerr))); 491 return rv; 492 } 493 494 int SSLServerSocketNSS::DoPayloadWrite() { 495 DCHECK(user_write_buf_); 496 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_); 497 if (rv >= 0) 498 return rv; 499 PRErrorCode prerr = PR_GetError(); 500 if (prerr == PR_WOULD_BLOCK_ERROR) { 501 return ERR_IO_PENDING; 502 } 503 rv = MapNSSError(prerr); 504 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR, 505 make_scoped_refptr(new SSLErrorParams(rv, prerr))); 506 return rv; 507 } 508 509 int SSLServerSocketNSS::DoHandshakeLoop(int last_io_result) { 510 bool network_moved; 511 int rv = last_io_result; 512 do { 513 // Default to STATE_NONE for next state. 514 // (This is a quirk carried over from the windows 515 // implementation. It makes reading the logs a bit harder.) 516 // State handlers can and often do call GotoState just 517 // to stay in the current state. 518 State state = next_handshake_state_; 519 GotoState(STATE_NONE); 520 switch (state) { 521 case STATE_NONE: 522 // we're just pumping data between the buffer and the network 523 break; 524 case STATE_HANDSHAKE: 525 rv = DoHandshake(); 526 break; 527 default: 528 rv = ERR_UNEXPECTED; 529 LOG(DFATAL) << "unexpected state " << state; 530 break; 531 } 532 533 // Do the actual network I/O 534 network_moved = DoTransportIO(); 535 } while ((rv != ERR_IO_PENDING || network_moved) && 536 next_handshake_state_ != STATE_NONE); 537 return rv; 538 } 539 540 int SSLServerSocketNSS::DoReadLoop(int result) { 541 DCHECK(completed_handshake_); 542 DCHECK(next_handshake_state_ == STATE_NONE); 543 544 if (result < 0) 545 return result; 546 547 if (!nss_bufs_) { 548 LOG(DFATAL) << "!nss_bufs_"; 549 int rv = ERR_UNEXPECTED; 550 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR, 551 make_scoped_refptr(new SSLErrorParams(rv, 0))); 552 return rv; 553 } 554 555 bool network_moved; 556 int rv; 557 do { 558 rv = DoPayloadRead(); 559 network_moved = DoTransportIO(); 560 } while (rv == ERR_IO_PENDING && network_moved); 561 return rv; 562 } 563 564 int SSLServerSocketNSS::DoWriteLoop(int result) { 565 DCHECK(completed_handshake_); 566 DCHECK(next_handshake_state_ == STATE_NONE); 567 568 if (result < 0) 569 return result; 570 571 if (!nss_bufs_) { 572 LOG(DFATAL) << "!nss_bufs_"; 573 int rv = ERR_UNEXPECTED; 574 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR, 575 make_scoped_refptr(new SSLErrorParams(rv, 0))); 576 return rv; 577 } 578 579 bool network_moved; 580 int rv; 581 do { 582 rv = DoPayloadWrite(); 583 network_moved = DoTransportIO(); 584 } while (rv == ERR_IO_PENDING && network_moved); 585 return rv; 586 } 587 588 int SSLServerSocketNSS::DoHandshake() { 589 int net_error = net::OK; 590 SECStatus rv = SSL_ForceHandshake(nss_fd_); 591 592 if (rv == SECSuccess) { 593 completed_handshake_ = true; 594 } else { 595 PRErrorCode prerr = PR_GetError(); 596 net_error = MapNSSHandshakeError(prerr); 597 598 // If not done, stay in this state 599 if (net_error == ERR_IO_PENDING) { 600 GotoState(STATE_HANDSHAKE); 601 } else { 602 LOG(ERROR) << "handshake failed; NSS error code " << prerr 603 << ", net_error " << net_error; 604 net_log_.AddEvent( 605 NetLog::TYPE_SSL_HANDSHAKE_ERROR, 606 make_scoped_refptr(new SSLErrorParams(net_error, prerr))); 607 } 608 } 609 return net_error; 610 } 611 612 void SSLServerSocketNSS::DoAcceptCallback(int rv) { 613 DCHECK_NE(rv, ERR_IO_PENDING); 614 615 CompletionCallback* c = user_accept_callback_; 616 user_accept_callback_ = NULL; 617 c->Run(rv > OK ? OK : rv); 618 } 619 620 void SSLServerSocketNSS::DoReadCallback(int rv) { 621 DCHECK(rv != ERR_IO_PENDING); 622 DCHECK(user_read_callback_); 623 624 // Since Run may result in Read being called, clear |user_read_callback_| 625 // up front. 626 CompletionCallback* c = user_read_callback_; 627 user_read_callback_ = NULL; 628 user_read_buf_ = NULL; 629 user_read_buf_len_ = 0; 630 c->Run(rv); 631 } 632 633 void SSLServerSocketNSS::DoWriteCallback(int rv) { 634 DCHECK(rv != ERR_IO_PENDING); 635 DCHECK(user_write_callback_); 636 637 // Since Run may result in Write being called, clear |user_write_callback_| 638 // up front. 639 CompletionCallback* c = user_write_callback_; 640 user_write_callback_ = NULL; 641 user_write_buf_ = NULL; 642 user_write_buf_len_ = 0; 643 c->Run(rv); 644 } 645 646 // static 647 // NSS calls this if an incoming certificate needs to be verified. 648 // Do nothing but return SECSuccess. 649 // This is called only in full handshake mode. 650 // Peer certificate is retrieved in HandshakeCallback() later, which is called 651 // in full handshake mode or in resumption handshake mode. 652 SECStatus SSLServerSocketNSS::OwnAuthCertHandler(void* arg, 653 PRFileDesc* socket, 654 PRBool checksig, 655 PRBool is_server) { 656 // TODO(hclam): Implement. 657 // Tell NSS to not verify the certificate. 658 return SECSuccess; 659 } 660 661 // static 662 // NSS calls this when handshake is completed. 663 // After the SSL handshake is finished we need to verify the certificate. 664 void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, 665 void* arg) { 666 // TODO(hclam): Implement. 667 } 668 669 int SSLServerSocketNSS::Init() { 670 // Initialize the NSS SSL library in a threadsafe way. This also 671 // initializes the NSS base library. 672 EnsureNSSSSLInit(); 673 if (!NSS_IsInitialized()) 674 return ERR_UNEXPECTED; 675 #if !defined(OS_MACOSX) && !defined(OS_WIN) 676 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop 677 // by MessageLoopForIO::current(). 678 // X509Certificate::Verify() runs on a worker thread of CertVerifier. 679 EnsureOCSPInit(); 680 #endif 681 682 return OK; 683 } 684 685 } // namespace net 686