Home | History | Annotate | Download | only in socket
      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