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