Home | History | Annotate | Download | only in socket
      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
      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/lazy_instance.h"
     33 #include "base/memory/ref_counted.h"
     34 #include "crypto/rsa_private_key.h"
     35 #include "crypto/nss_util_internal.h"
     36 #include "net/base/io_buffer.h"
     37 #include "net/base/net_errors.h"
     38 #include "net/base/net_log.h"
     39 #include "net/socket/nss_ssl_util.h"
     40 #include "net/socket/ssl_error_params.h"
     41 
     42 // SSL plaintext fragments are shorter than 16KB. Although the record layer
     43 // overhead is allowed to be 2K + 5 bytes, in practice the overhead is much
     44 // smaller than 1KB. So a 17KB buffer should be large enough to hold an
     45 // entire SSL record.
     46 static const int kRecvBufferSize = 17 * 1024;
     47 static const int kSendBufferSize = 17 * 1024;
     48 
     49 #define GotoState(s) next_handshake_state_ = s
     50 
     51 namespace net {
     52 
     53 namespace {
     54 
     55 bool g_nss_server_sockets_init = false;
     56 
     57 class NSSSSLServerInitSingleton {
     58  public:
     59   NSSSSLServerInitSingleton() {
     60     EnsureNSSSSLInit();
     61 
     62     SSL_ConfigServerSessionIDCache(1024, 5, 5, NULL);
     63     g_nss_server_sockets_init = true;
     64   }
     65 
     66   ~NSSSSLServerInitSingleton() {
     67     SSL_ShutdownServerSessionIDCache();
     68     g_nss_server_sockets_init = false;
     69   }
     70 };
     71 
     72 static base::LazyInstance<NSSSSLServerInitSingleton>
     73     g_nss_ssl_server_init_singleton = LAZY_INSTANCE_INITIALIZER;
     74 
     75 }  // namespace
     76 
     77 void EnableSSLServerSockets() {
     78   g_nss_ssl_server_init_singleton.Get();
     79 }
     80 
     81 SSLServerSocket* CreateSSLServerSocket(
     82     StreamSocket* socket,
     83     X509Certificate* cert,
     84     crypto::RSAPrivateKey* key,
     85     const SSLConfig& ssl_config) {
     86   DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been"
     87                                     << "called yet!";
     88 
     89   return new SSLServerSocketNSS(socket, cert, key, ssl_config);
     90 }
     91 
     92 SSLServerSocketNSS::SSLServerSocketNSS(
     93     StreamSocket* transport_socket,
     94     scoped_refptr<X509Certificate> cert,
     95     crypto::RSAPrivateKey* key,
     96     const SSLConfig& ssl_config)
     97     : transport_send_busy_(false),
     98       transport_recv_busy_(false),
     99       user_read_buf_len_(0),
    100       user_write_buf_len_(0),
    101       nss_fd_(NULL),
    102       nss_bufs_(NULL),
    103       transport_socket_(transport_socket),
    104       ssl_config_(ssl_config),
    105       cert_(cert),
    106       next_handshake_state_(STATE_NONE),
    107       completed_handshake_(false) {
    108   ssl_config_.false_start_enabled = false;
    109   ssl_config_.version_min = SSL_PROTOCOL_VERSION_SSL3;
    110   ssl_config_.version_max = SSL_PROTOCOL_VERSION_TLS1_1;
    111 
    112   // TODO(hclam): Need a better way to clone a key.
    113   std::vector<uint8> key_bytes;
    114   CHECK(key->ExportPrivateKey(&key_bytes));
    115   key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes));
    116   CHECK(key_.get());
    117 }
    118 
    119 SSLServerSocketNSS::~SSLServerSocketNSS() {
    120   if (nss_fd_ != NULL) {
    121     PR_Close(nss_fd_);
    122     nss_fd_ = NULL;
    123   }
    124 }
    125 
    126 int SSLServerSocketNSS::Handshake(const CompletionCallback& callback) {
    127   net_log_.BeginEvent(NetLog::TYPE_SSL_SERVER_HANDSHAKE);
    128 
    129   int rv = Init();
    130   if (rv != OK) {
    131     LOG(ERROR) << "Failed to initialize NSS";
    132     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv);
    133     return rv;
    134   }
    135 
    136   rv = InitializeSSLOptions();
    137   if (rv != OK) {
    138     LOG(ERROR) << "Failed to initialize SSL options";
    139     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv);
    140     return rv;
    141   }
    142 
    143   // Set peer address. TODO(hclam): This should be in a separate method.
    144   PRNetAddr peername;
    145   memset(&peername, 0, sizeof(peername));
    146   peername.raw.family = AF_INET;
    147   memio_SetPeerName(nss_fd_, &peername);
    148 
    149   GotoState(STATE_HANDSHAKE);
    150   rv = DoHandshakeLoop(OK);
    151   if (rv == ERR_IO_PENDING) {
    152     user_handshake_callback_ = callback;
    153   } else {
    154     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv);
    155   }
    156 
    157   return rv > OK ? OK : rv;
    158 }
    159 
    160 int SSLServerSocketNSS::ExportKeyingMaterial(const base::StringPiece& label,
    161                                              bool has_context,
    162                                              const base::StringPiece& context,
    163                                              unsigned char* out,
    164                                              unsigned int outlen) {
    165   if (!IsConnected())
    166     return ERR_SOCKET_NOT_CONNECTED;
    167   SECStatus result = SSL_ExportKeyingMaterial(
    168       nss_fd_, label.data(), label.size(), has_context,
    169       reinterpret_cast<const unsigned char*>(context.data()),
    170       context.length(), out, outlen);
    171   if (result != SECSuccess) {
    172     LogFailedNSSFunction(net_log_, "SSL_ExportKeyingMaterial", "");
    173     return MapNSSError(PORT_GetError());
    174   }
    175   return OK;
    176 }
    177 
    178 int SSLServerSocketNSS::GetTLSUniqueChannelBinding(std::string* out) {
    179   if (!IsConnected())
    180     return ERR_SOCKET_NOT_CONNECTED;
    181   unsigned char buf[64];
    182   unsigned int len;
    183   SECStatus result = SSL_GetChannelBinding(nss_fd_,
    184                                            SSL_CHANNEL_BINDING_TLS_UNIQUE,
    185                                            buf, &len, arraysize(buf));
    186   if (result != SECSuccess) {
    187     LogFailedNSSFunction(net_log_, "SSL_GetChannelBinding", "");
    188     return MapNSSError(PORT_GetError());
    189   }
    190   out->assign(reinterpret_cast<char*>(buf), len);
    191   return OK;
    192 }
    193 
    194 int SSLServerSocketNSS::Connect(const CompletionCallback& callback) {
    195   NOTIMPLEMENTED();
    196   return ERR_NOT_IMPLEMENTED;
    197 }
    198 
    199 int SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len,
    200                              const CompletionCallback& callback) {
    201   DCHECK(user_read_callback_.is_null());
    202   DCHECK(user_handshake_callback_.is_null());
    203   DCHECK(!user_read_buf_.get());
    204   DCHECK(nss_bufs_);
    205   DCHECK(!callback.is_null());
    206 
    207   user_read_buf_ = buf;
    208   user_read_buf_len_ = buf_len;
    209 
    210   DCHECK(completed_handshake_);
    211 
    212   int rv = DoReadLoop(OK);
    213 
    214   if (rv == ERR_IO_PENDING) {
    215     user_read_callback_ = callback;
    216   } else {
    217     user_read_buf_ = NULL;
    218     user_read_buf_len_ = 0;
    219   }
    220   return rv;
    221 }
    222 
    223 int SSLServerSocketNSS::Write(IOBuffer* buf, int buf_len,
    224                               const CompletionCallback& callback) {
    225   DCHECK(user_write_callback_.is_null());
    226   DCHECK(!user_write_buf_.get());
    227   DCHECK(nss_bufs_);
    228   DCHECK(!callback.is_null());
    229 
    230   user_write_buf_ = buf;
    231   user_write_buf_len_ = buf_len;
    232 
    233   int rv = DoWriteLoop(OK);
    234 
    235   if (rv == ERR_IO_PENDING) {
    236     user_write_callback_ = callback;
    237   } else {
    238     user_write_buf_ = NULL;
    239     user_write_buf_len_ = 0;
    240   }
    241   return rv;
    242 }
    243 
    244 bool SSLServerSocketNSS::SetReceiveBufferSize(int32 size) {
    245   return transport_socket_->SetReceiveBufferSize(size);
    246 }
    247 
    248 bool SSLServerSocketNSS::SetSendBufferSize(int32 size) {
    249   return transport_socket_->SetSendBufferSize(size);
    250 }
    251 
    252 bool SSLServerSocketNSS::IsConnected() const {
    253   return completed_handshake_;
    254 }
    255 
    256 void SSLServerSocketNSS::Disconnect() {
    257   transport_socket_->Disconnect();
    258 }
    259 
    260 bool SSLServerSocketNSS::IsConnectedAndIdle() const {
    261   return completed_handshake_ && transport_socket_->IsConnectedAndIdle();
    262 }
    263 
    264 int SSLServerSocketNSS::GetPeerAddress(IPEndPoint* address) const {
    265   if (!IsConnected())
    266     return ERR_SOCKET_NOT_CONNECTED;
    267   return transport_socket_->GetPeerAddress(address);
    268 }
    269 
    270 int SSLServerSocketNSS::GetLocalAddress(IPEndPoint* address) const {
    271   if (!IsConnected())
    272     return ERR_SOCKET_NOT_CONNECTED;
    273   return transport_socket_->GetLocalAddress(address);
    274 }
    275 
    276 const BoundNetLog& SSLServerSocketNSS::NetLog() const {
    277   return net_log_;
    278 }
    279 
    280 void SSLServerSocketNSS::SetSubresourceSpeculation() {
    281   transport_socket_->SetSubresourceSpeculation();
    282 }
    283 
    284 void SSLServerSocketNSS::SetOmniboxSpeculation() {
    285   transport_socket_->SetOmniboxSpeculation();
    286 }
    287 
    288 bool SSLServerSocketNSS::WasEverUsed() const {
    289   return transport_socket_->WasEverUsed();
    290 }
    291 
    292 bool SSLServerSocketNSS::UsingTCPFastOpen() const {
    293   return transport_socket_->UsingTCPFastOpen();
    294 }
    295 
    296 bool SSLServerSocketNSS::WasNpnNegotiated() const {
    297   return false;
    298 }
    299 
    300 NextProto SSLServerSocketNSS::GetNegotiatedProtocol() const {
    301   // NPN is not supported by this class.
    302   return kProtoUnknown;
    303 }
    304 
    305 bool SSLServerSocketNSS::GetSSLInfo(SSLInfo* ssl_info) {
    306   NOTIMPLEMENTED();
    307   return false;
    308 }
    309 
    310 int SSLServerSocketNSS::InitializeSSLOptions() {
    311   // Transport connected, now hook it up to nss
    312   nss_fd_ = memio_CreateIOLayer(kRecvBufferSize, kSendBufferSize);
    313   if (nss_fd_ == NULL) {
    314     return ERR_OUT_OF_MEMORY;  // TODO(port): map NSPR error code.
    315   }
    316 
    317   // Grab pointer to buffers
    318   nss_bufs_ = memio_GetSecret(nss_fd_);
    319 
    320   /* Create SSL state machine */
    321   /* Push SSL onto our fake I/O socket */
    322   nss_fd_ = SSL_ImportFD(NULL, nss_fd_);
    323   if (nss_fd_ == NULL) {
    324     LogFailedNSSFunction(net_log_, "SSL_ImportFD", "");
    325     return ERR_OUT_OF_MEMORY;  // TODO(port): map NSPR/NSS error code.
    326   }
    327   // TODO(port): set more ssl options!  Check errors!
    328 
    329   int rv;
    330 
    331   rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE);
    332   if (rv != SECSuccess) {
    333     LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY");
    334     return ERR_UNEXPECTED;
    335   }
    336 
    337   rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE);
    338   if (rv != SECSuccess) {
    339     LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2");
    340     return ERR_UNEXPECTED;
    341   }
    342 
    343   SSLVersionRange version_range;
    344   version_range.min = ssl_config_.version_min;
    345   version_range.max = ssl_config_.version_max;
    346   rv = SSL_VersionRangeSet(nss_fd_, &version_range);
    347   if (rv != SECSuccess) {
    348     LogFailedNSSFunction(net_log_, "SSL_VersionRangeSet", "");
    349     return ERR_NO_SSL_VERSIONS_ENABLED;
    350   }
    351 
    352   for (std::vector<uint16>::const_iterator it =
    353            ssl_config_.disabled_cipher_suites.begin();
    354        it != ssl_config_.disabled_cipher_suites.end(); ++it) {
    355     // This will fail if the specified cipher is not implemented by NSS, but
    356     // the failure is harmless.
    357     SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE);
    358   }
    359 
    360   // Server socket doesn't need session tickets.
    361   rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_FALSE);
    362   if (rv != SECSuccess) {
    363     LogFailedNSSFunction(
    364         net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS");
    365   }
    366 
    367   // Doing this will force PR_Accept perform handshake as server.
    368   rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_FALSE);
    369   if (rv != SECSuccess) {
    370     LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT");
    371     return ERR_UNEXPECTED;
    372   }
    373 
    374   rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_SERVER, PR_TRUE);
    375   if (rv != SECSuccess) {
    376     LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_SERVER");
    377     return ERR_UNEXPECTED;
    378   }
    379 
    380   rv = SSL_OptionSet(nss_fd_, SSL_REQUEST_CERTIFICATE, PR_FALSE);
    381   if (rv != SECSuccess) {
    382     LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUEST_CERTIFICATE");
    383     return ERR_UNEXPECTED;
    384   }
    385 
    386   rv = SSL_OptionSet(nss_fd_, SSL_REQUIRE_CERTIFICATE, PR_FALSE);
    387   if (rv != SECSuccess) {
    388     LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUIRE_CERTIFICATE");
    389     return ERR_UNEXPECTED;
    390   }
    391 
    392   rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this);
    393   if (rv != SECSuccess) {
    394     LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", "");
    395     return ERR_UNEXPECTED;
    396   }
    397 
    398   rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this);
    399   if (rv != SECSuccess) {
    400     LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", "");
    401     return ERR_UNEXPECTED;
    402   }
    403 
    404   // Get a certificate of CERTCertificate structure.
    405   std::string der_string;
    406   if (!X509Certificate::GetDEREncoded(cert_->os_cert_handle(), &der_string))
    407     return ERR_UNEXPECTED;
    408 
    409   SECItem der_cert;
    410   der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(
    411       der_string.data()));
    412   der_cert.len  = der_string.length();
    413   der_cert.type = siDERCertBuffer;
    414 
    415   // Parse into a CERTCertificate structure.
    416   CERTCertificate* cert = CERT_NewTempCertificate(
    417       CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE);
    418   if (!cert) {
    419     LogFailedNSSFunction(net_log_, "CERT_NewTempCertificate", "");
    420     return MapNSSError(PORT_GetError());
    421   }
    422 
    423   // Get a key of SECKEYPrivateKey* structure.
    424   std::vector<uint8> key_vector;
    425   if (!key_->ExportPrivateKey(&key_vector)) {
    426     CERT_DestroyCertificate(cert);
    427     return ERR_UNEXPECTED;
    428   }
    429 
    430   SECKEYPrivateKeyStr* private_key = NULL;
    431   PK11SlotInfo* slot = crypto::GetPrivateNSSKeySlot();
    432   if (!slot) {
    433     CERT_DestroyCertificate(cert);
    434     return ERR_UNEXPECTED;
    435   }
    436 
    437   SECItem der_private_key_info;
    438   der_private_key_info.data =
    439       const_cast<unsigned char*>(&key_vector.front());
    440   der_private_key_info.len = key_vector.size();
    441   // The server's RSA private key must be imported into NSS with the
    442   // following key usage bits:
    443   // - KU_KEY_ENCIPHERMENT, required for the RSA key exchange algorithm.
    444   // - KU_DIGITAL_SIGNATURE, required for the DHE_RSA and ECDHE_RSA key
    445   //   exchange algorithms.
    446   const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DIGITAL_SIGNATURE;
    447   rv =  PK11_ImportDERPrivateKeyInfoAndReturnKey(
    448       slot, &der_private_key_info, NULL, NULL, PR_FALSE, PR_FALSE,
    449       key_usage, &private_key, NULL);
    450   PK11_FreeSlot(slot);
    451   if (rv != SECSuccess) {
    452     CERT_DestroyCertificate(cert);
    453     return ERR_UNEXPECTED;
    454   }
    455 
    456   // Assign server certificate and private key.
    457   SSLKEAType cert_kea = NSS_FindCertKEAType(cert);
    458   rv = SSL_ConfigSecureServer(nss_fd_, cert, private_key, cert_kea);
    459   CERT_DestroyCertificate(cert);
    460   SECKEY_DestroyPrivateKey(private_key);
    461 
    462   if (rv != SECSuccess) {
    463     PRErrorCode prerr = PR_GetError();
    464     LOG(ERROR) << "Failed to config SSL server: " << prerr;
    465     LogFailedNSSFunction(net_log_, "SSL_ConfigureSecureServer", "");
    466     return ERR_UNEXPECTED;
    467   }
    468 
    469   // Tell SSL we're a server; needed if not letting NSPR do socket I/O
    470   rv = SSL_ResetHandshake(nss_fd_, PR_TRUE);
    471   if (rv != SECSuccess) {
    472     LogFailedNSSFunction(net_log_, "SSL_ResetHandshake", "");
    473     return ERR_UNEXPECTED;
    474   }
    475 
    476   return OK;
    477 }
    478 
    479 void SSLServerSocketNSS::OnSendComplete(int result) {
    480   if (next_handshake_state_ == STATE_HANDSHAKE) {
    481     // In handshake phase.
    482     OnHandshakeIOComplete(result);
    483     return;
    484   }
    485 
    486   if (!completed_handshake_)
    487     return;
    488 
    489   if (user_write_buf_.get()) {
    490     int rv = DoWriteLoop(result);
    491     if (rv != ERR_IO_PENDING)
    492       DoWriteCallback(rv);
    493   } else {
    494     // Ensure that any queued ciphertext is flushed.
    495     DoTransportIO();
    496   }
    497 }
    498 
    499 void SSLServerSocketNSS::OnRecvComplete(int result) {
    500   if (next_handshake_state_ == STATE_HANDSHAKE) {
    501     // In handshake phase.
    502     OnHandshakeIOComplete(result);
    503     return;
    504   }
    505 
    506   // Network layer received some data, check if client requested to read
    507   // decrypted data.
    508   if (!user_read_buf_.get() || !completed_handshake_)
    509     return;
    510 
    511   int rv = DoReadLoop(result);
    512   if (rv != ERR_IO_PENDING)
    513     DoReadCallback(rv);
    514 }
    515 
    516 void SSLServerSocketNSS::OnHandshakeIOComplete(int result) {
    517   int rv = DoHandshakeLoop(result);
    518   if (rv != ERR_IO_PENDING) {
    519     net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv);
    520     if (!user_handshake_callback_.is_null())
    521       DoHandshakeCallback(rv);
    522   }
    523 }
    524 
    525 // Return 0 for EOF,
    526 // > 0 for bytes transferred immediately,
    527 // < 0 for error (or the non-error ERR_IO_PENDING).
    528 int SSLServerSocketNSS::BufferSend(void) {
    529   if (transport_send_busy_)
    530     return ERR_IO_PENDING;
    531 
    532   const char* buf1;
    533   const char* buf2;
    534   unsigned int len1, len2;
    535   memio_GetWriteParams(nss_bufs_, &buf1, &len1, &buf2, &len2);
    536   const unsigned int len = len1 + len2;
    537 
    538   int rv = 0;
    539   if (len) {
    540     scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len));
    541     memcpy(send_buffer->data(), buf1, len1);
    542     memcpy(send_buffer->data() + len1, buf2, len2);
    543     rv = transport_socket_->Write(
    544         send_buffer.get(),
    545         len,
    546         base::Bind(&SSLServerSocketNSS::BufferSendComplete,
    547                    base::Unretained(this)));
    548     if (rv == ERR_IO_PENDING) {
    549       transport_send_busy_ = true;
    550     } else {
    551       memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv));
    552     }
    553   }
    554 
    555   return rv;
    556 }
    557 
    558 void SSLServerSocketNSS::BufferSendComplete(int result) {
    559   memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result));
    560   transport_send_busy_ = false;
    561   OnSendComplete(result);
    562 }
    563 
    564 int SSLServerSocketNSS::BufferRecv(void) {
    565   if (transport_recv_busy_) return ERR_IO_PENDING;
    566 
    567   char* buf;
    568   int nb = memio_GetReadParams(nss_bufs_, &buf);
    569   int rv;
    570   if (!nb) {
    571     // buffer too full to read into, so no I/O possible at moment
    572     rv = ERR_IO_PENDING;
    573   } else {
    574     recv_buffer_ = new IOBuffer(nb);
    575     rv = transport_socket_->Read(
    576         recv_buffer_.get(),
    577         nb,
    578         base::Bind(&SSLServerSocketNSS::BufferRecvComplete,
    579                    base::Unretained(this)));
    580     if (rv == ERR_IO_PENDING) {
    581       transport_recv_busy_ = true;
    582     } else {
    583       if (rv > 0)
    584         memcpy(buf, recv_buffer_->data(), rv);
    585       memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv));
    586       recv_buffer_ = NULL;
    587     }
    588   }
    589   return rv;
    590 }
    591 
    592 void SSLServerSocketNSS::BufferRecvComplete(int result) {
    593   if (result > 0) {
    594     char* buf;
    595     memio_GetReadParams(nss_bufs_, &buf);
    596     memcpy(buf, recv_buffer_->data(), result);
    597   }
    598   recv_buffer_ = NULL;
    599   memio_PutReadResult(nss_bufs_, MapErrorToNSS(result));
    600   transport_recv_busy_ = false;
    601   OnRecvComplete(result);
    602 }
    603 
    604 // Do as much network I/O as possible between the buffer and the
    605 // transport socket. Return true if some I/O performed, false
    606 // otherwise (error or ERR_IO_PENDING).
    607 bool SSLServerSocketNSS::DoTransportIO() {
    608   bool network_moved = false;
    609   if (nss_bufs_ != NULL) {
    610     int rv;
    611     // Read and write as much data as we can. The loop is neccessary
    612     // because Write() may return synchronously.
    613     do {
    614       rv = BufferSend();
    615       if (rv > 0)
    616         network_moved = true;
    617     } while (rv > 0);
    618     if (BufferRecv() >= 0)
    619       network_moved = true;
    620   }
    621   return network_moved;
    622 }
    623 
    624 int SSLServerSocketNSS::DoPayloadRead() {
    625   DCHECK(user_read_buf_.get());
    626   DCHECK_GT(user_read_buf_len_, 0);
    627   int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
    628   if (rv >= 0)
    629     return rv;
    630   PRErrorCode prerr = PR_GetError();
    631   if (prerr == PR_WOULD_BLOCK_ERROR) {
    632     return ERR_IO_PENDING;
    633   }
    634   rv = MapNSSError(prerr);
    635   net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
    636                     CreateNetLogSSLErrorCallback(rv, prerr));
    637   return rv;
    638 }
    639 
    640 int SSLServerSocketNSS::DoPayloadWrite() {
    641   DCHECK(user_write_buf_.get());
    642   int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_);
    643   if (rv >= 0)
    644     return rv;
    645   PRErrorCode prerr = PR_GetError();
    646   if (prerr == PR_WOULD_BLOCK_ERROR) {
    647     return ERR_IO_PENDING;
    648   }
    649   rv = MapNSSError(prerr);
    650   net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
    651                     CreateNetLogSSLErrorCallback(rv, prerr));
    652   return rv;
    653 }
    654 
    655 int SSLServerSocketNSS::DoHandshakeLoop(int last_io_result) {
    656   int rv = last_io_result;
    657   do {
    658     // Default to STATE_NONE for next state.
    659     // (This is a quirk carried over from the windows
    660     // implementation.  It makes reading the logs a bit harder.)
    661     // State handlers can and often do call GotoState just
    662     // to stay in the current state.
    663     State state = next_handshake_state_;
    664     GotoState(STATE_NONE);
    665     switch (state) {
    666       case STATE_HANDSHAKE:
    667         rv = DoHandshake();
    668         break;
    669       case STATE_NONE:
    670       default:
    671         rv = ERR_UNEXPECTED;
    672         LOG(DFATAL) << "unexpected state " << state;
    673         break;
    674     }
    675 
    676     // Do the actual network I/O
    677     bool network_moved = DoTransportIO();
    678     if (network_moved && next_handshake_state_ == STATE_HANDSHAKE) {
    679       // In general we exit the loop if rv is ERR_IO_PENDING.  In this
    680       // special case we keep looping even if rv is ERR_IO_PENDING because
    681       // the transport IO may allow DoHandshake to make progress.
    682       rv = OK;  // This causes us to stay in the loop.
    683     }
    684   } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE);
    685   return rv;
    686 }
    687 
    688 int SSLServerSocketNSS::DoReadLoop(int result) {
    689   DCHECK(completed_handshake_);
    690   DCHECK(next_handshake_state_ == STATE_NONE);
    691 
    692   if (result < 0)
    693     return result;
    694 
    695   if (!nss_bufs_) {
    696     LOG(DFATAL) << "!nss_bufs_";
    697     int rv = ERR_UNEXPECTED;
    698     net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
    699                       CreateNetLogSSLErrorCallback(rv, 0));
    700     return rv;
    701   }
    702 
    703   bool network_moved;
    704   int rv;
    705   do {
    706     rv = DoPayloadRead();
    707     network_moved = DoTransportIO();
    708   } while (rv == ERR_IO_PENDING && network_moved);
    709   return rv;
    710 }
    711 
    712 int SSLServerSocketNSS::DoWriteLoop(int result) {
    713   DCHECK(completed_handshake_);
    714   DCHECK(next_handshake_state_ == STATE_NONE);
    715 
    716   if (result < 0)
    717     return result;
    718 
    719   if (!nss_bufs_) {
    720     LOG(DFATAL) << "!nss_bufs_";
    721     int rv = ERR_UNEXPECTED;
    722     net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
    723                       CreateNetLogSSLErrorCallback(rv, 0));
    724     return rv;
    725   }
    726 
    727   bool network_moved;
    728   int rv;
    729   do {
    730     rv = DoPayloadWrite();
    731     network_moved = DoTransportIO();
    732   } while (rv == ERR_IO_PENDING && network_moved);
    733   return rv;
    734 }
    735 
    736 int SSLServerSocketNSS::DoHandshake() {
    737   int net_error = OK;
    738   SECStatus rv = SSL_ForceHandshake(nss_fd_);
    739 
    740   if (rv == SECSuccess) {
    741     completed_handshake_ = true;
    742   } else {
    743     PRErrorCode prerr = PR_GetError();
    744     net_error = MapNSSError(prerr);
    745 
    746     // If not done, stay in this state
    747     if (net_error == ERR_IO_PENDING) {
    748       GotoState(STATE_HANDSHAKE);
    749     } else {
    750       LOG(ERROR) << "handshake failed; NSS error code " << prerr
    751                  << ", net_error " << net_error;
    752       net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR,
    753                         CreateNetLogSSLErrorCallback(net_error, prerr));
    754     }
    755   }
    756   return net_error;
    757 }
    758 
    759 void SSLServerSocketNSS::DoHandshakeCallback(int rv) {
    760   DCHECK_NE(rv, ERR_IO_PENDING);
    761 
    762   CompletionCallback c = user_handshake_callback_;
    763   user_handshake_callback_.Reset();
    764   c.Run(rv > OK ? OK : rv);
    765 }
    766 
    767 void SSLServerSocketNSS::DoReadCallback(int rv) {
    768   DCHECK(rv != ERR_IO_PENDING);
    769   DCHECK(!user_read_callback_.is_null());
    770 
    771   // Since Run may result in Read being called, clear |user_read_callback_|
    772   // up front.
    773   CompletionCallback c = user_read_callback_;
    774   user_read_callback_.Reset();
    775   user_read_buf_ = NULL;
    776   user_read_buf_len_ = 0;
    777   c.Run(rv);
    778 }
    779 
    780 void SSLServerSocketNSS::DoWriteCallback(int rv) {
    781   DCHECK(rv != ERR_IO_PENDING);
    782   DCHECK(!user_write_callback_.is_null());
    783 
    784   // Since Run may result in Write being called, clear |user_write_callback_|
    785   // up front.
    786   CompletionCallback c = user_write_callback_;
    787   user_write_callback_.Reset();
    788   user_write_buf_ = NULL;
    789   user_write_buf_len_ = 0;
    790   c.Run(rv);
    791 }
    792 
    793 // static
    794 // NSS calls this if an incoming certificate needs to be verified.
    795 // Do nothing but return SECSuccess.
    796 // This is called only in full handshake mode.
    797 // Peer certificate is retrieved in HandshakeCallback() later, which is called
    798 // in full handshake mode or in resumption handshake mode.
    799 SECStatus SSLServerSocketNSS::OwnAuthCertHandler(void* arg,
    800                                                  PRFileDesc* socket,
    801                                                  PRBool checksig,
    802                                                  PRBool is_server) {
    803   // TODO(hclam): Implement.
    804   // Tell NSS to not verify the certificate.
    805   return SECSuccess;
    806 }
    807 
    808 // static
    809 // NSS calls this when handshake is completed.
    810 // After the SSL handshake is finished we need to verify the certificate.
    811 void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket,
    812                                            void* arg) {
    813   // TODO(hclam): Implement.
    814 }
    815 
    816 int SSLServerSocketNSS::Init() {
    817   // Initialize the NSS SSL library in a threadsafe way.  This also
    818   // initializes the NSS base library.
    819   EnsureNSSSSLInit();
    820   if (!NSS_IsInitialized())
    821     return ERR_UNEXPECTED;
    822 
    823   EnableSSLServerSockets();
    824   return OK;
    825 }
    826 
    827 }  // namespace net
    828