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