ssl_server_socket_nss.cc revision f2477e01787aa58f445919b809d89e252beef54f
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.
46static const int kRecvBufferSize = 17 * 1024;
47static const int kSendBufferSize = 17 * 1024;
48
49#define GotoState(s) next_handshake_state_ = s
50
51namespace net {
52
53namespace {
54
55bool g_nss_server_sockets_init = false;
56
57class 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
72static base::LazyInstance<NSSSSLServerInitSingleton>
73    g_nss_ssl_server_init_singleton = LAZY_INSTANCE_INITIALIZER;
74
75}  // namespace
76
77void EnableSSLServerSockets() {
78  g_nss_ssl_server_init_singleton.Get();
79}
80
81scoped_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
93SSLServerSocketNSS::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
116SSLServerSocketNSS::~SSLServerSocketNSS() {
117  if (nss_fd_ != NULL) {
118    PR_Close(nss_fd_);
119    nss_fd_ = NULL;
120  }
121}
122
123int 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
157int 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
175int 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
191int SSLServerSocketNSS::Connect(const CompletionCallback& callback) {
192  NOTIMPLEMENTED();
193  return ERR_NOT_IMPLEMENTED;
194}
195
196int 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
220int 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
241bool SSLServerSocketNSS::SetReceiveBufferSize(int32 size) {
242  return transport_socket_->SetReceiveBufferSize(size);
243}
244
245bool SSLServerSocketNSS::SetSendBufferSize(int32 size) {
246  return transport_socket_->SetSendBufferSize(size);
247}
248
249bool SSLServerSocketNSS::IsConnected() const {
250  return completed_handshake_;
251}
252
253void SSLServerSocketNSS::Disconnect() {
254  transport_socket_->Disconnect();
255}
256
257bool SSLServerSocketNSS::IsConnectedAndIdle() const {
258  return completed_handshake_ && transport_socket_->IsConnectedAndIdle();
259}
260
261int SSLServerSocketNSS::GetPeerAddress(IPEndPoint* address) const {
262  if (!IsConnected())
263    return ERR_SOCKET_NOT_CONNECTED;
264  return transport_socket_->GetPeerAddress(address);
265}
266
267int SSLServerSocketNSS::GetLocalAddress(IPEndPoint* address) const {
268  if (!IsConnected())
269    return ERR_SOCKET_NOT_CONNECTED;
270  return transport_socket_->GetLocalAddress(address);
271}
272
273const BoundNetLog& SSLServerSocketNSS::NetLog() const {
274  return net_log_;
275}
276
277void SSLServerSocketNSS::SetSubresourceSpeculation() {
278  transport_socket_->SetSubresourceSpeculation();
279}
280
281void SSLServerSocketNSS::SetOmniboxSpeculation() {
282  transport_socket_->SetOmniboxSpeculation();
283}
284
285bool SSLServerSocketNSS::WasEverUsed() const {
286  return transport_socket_->WasEverUsed();
287}
288
289bool SSLServerSocketNSS::UsingTCPFastOpen() const {
290  return transport_socket_->UsingTCPFastOpen();
291}
292
293bool SSLServerSocketNSS::WasNpnNegotiated() const {
294  return false;
295}
296
297NextProto SSLServerSocketNSS::GetNegotiatedProtocol() const {
298  // NPN is not supported by this class.
299  return kProtoUnknown;
300}
301
302bool SSLServerSocketNSS::GetSSLInfo(SSLInfo* ssl_info) {
303  NOTIMPLEMENTED();
304  return false;
305}
306
307int 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
493void 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
513void 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
530void 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).
542int 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
572void SSLServerSocketNSS::BufferSendComplete(int result) {
573  memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result));
574  transport_send_busy_ = false;
575  OnSendComplete(result);
576}
577
578int 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
606void 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).
621bool 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
638int 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
654int 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
669int 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
702int 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
726int 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
750int 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
773void 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
781void 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
794void 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.
813SECStatus 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.
825void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket,
826                                           void* arg) {
827  // TODO(hclam): Implement.
828}
829
830int 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