1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/socket/ssl_server_socket_nss.h"
6
7#if defined(OS_WIN)
8#include <winsock2.h>
9#endif
10
11#if defined(USE_SYSTEM_SSL)
12#include <dlfcn.h>
13#endif
14#if defined(OS_MACOSX)
15#include <Security/Security.h>
16#endif
17#include <certdb.h>
18#include <cryptohi.h>
19#include <hasht.h>
20#include <keyhi.h>
21#include <nspr.h>
22#include <nss.h>
23#include <pk11pub.h>
24#include <secerr.h>
25#include <sechash.h>
26#include <ssl.h>
27#include <sslerr.h>
28#include <sslproto.h>
29
30#include <limits>
31
32#include "base/memory/ref_counted.h"
33#include "crypto/rsa_private_key.h"
34#include "crypto/nss_util_internal.h"
35#include "net/base/io_buffer.h"
36#include "net/base/net_errors.h"
37#include "net/base/net_log.h"
38#include "net/ocsp/nss_ocsp.h"
39#include "net/socket/nss_ssl_util.h"
40#include "net/socket/ssl_error_params.h"
41
42static const int kRecvBufferSize = 4096;
43
44#define GotoState(s) next_handshake_state_ = s
45
46namespace net {
47
48SSLServerSocket* CreateSSLServerSocket(
49    Socket* socket, X509Certificate* cert, crypto::RSAPrivateKey* key,
50    const SSLConfig& ssl_config) {
51  return new SSLServerSocketNSS(socket, cert, key, ssl_config);
52}
53
54SSLServerSocketNSS::SSLServerSocketNSS(
55    Socket* transport_socket,
56    scoped_refptr<X509Certificate> cert,
57    crypto::RSAPrivateKey* key,
58    const SSLConfig& ssl_config)
59    : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_(
60          this, &SSLServerSocketNSS::BufferSendComplete)),
61      ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_(
62          this, &SSLServerSocketNSS::BufferRecvComplete)),
63      transport_send_busy_(false),
64      transport_recv_busy_(false),
65      user_accept_callback_(NULL),
66      user_read_callback_(NULL),
67      user_write_callback_(NULL),
68      nss_fd_(NULL),
69      nss_bufs_(NULL),
70      transport_socket_(transport_socket),
71      ssl_config_(ssl_config),
72      cert_(cert),
73      next_handshake_state_(STATE_NONE),
74      completed_handshake_(false) {
75  ssl_config_.false_start_enabled = false;
76  ssl_config_.ssl3_enabled = true;
77  ssl_config_.tls1_enabled = true;
78
79  // TODO(hclam): Need a better way to clone a key.
80  std::vector<uint8> key_bytes;
81  CHECK(key->ExportPrivateKey(&key_bytes));
82  key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes));
83  CHECK(key_.get());
84}
85
86SSLServerSocketNSS::~SSLServerSocketNSS() {
87  if (nss_fd_ != NULL) {
88    PR_Close(nss_fd_);
89    nss_fd_ = NULL;
90  }
91}
92
93int SSLServerSocketNSS::Accept(CompletionCallback* callback) {
94  net_log_.BeginEvent(NetLog::TYPE_SSL_ACCEPT, NULL);
95
96  int rv = Init();
97  if (rv != OK) {
98    LOG(ERROR) << "Failed to initialize NSS";
99    net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv);
100    return rv;
101  }
102
103  rv = InitializeSSLOptions();
104  if (rv != OK) {
105    LOG(ERROR) << "Failed to initialize SSL options";
106    net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv);
107    return rv;
108  }
109
110  // Set peer address. TODO(hclam): This should be in a separate method.
111  PRNetAddr peername;
112  memset(&peername, 0, sizeof(peername));
113  peername.raw.family = AF_INET;
114  memio_SetPeerName(nss_fd_, &peername);
115
116  GotoState(STATE_HANDSHAKE);
117  rv = DoHandshakeLoop(net::OK);
118  if (rv == ERR_IO_PENDING) {
119    user_accept_callback_ = callback;
120  } else {
121    net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv);
122  }
123
124  return rv > OK ? OK : rv;
125}
126
127int SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len,
128                             CompletionCallback* callback) {
129  DCHECK(!user_read_callback_);
130  DCHECK(!user_accept_callback_);
131  DCHECK(!user_read_buf_);
132  DCHECK(nss_bufs_);
133
134  user_read_buf_ = buf;
135  user_read_buf_len_ = buf_len;
136
137  DCHECK(completed_handshake_);
138
139  int rv = DoReadLoop(OK);
140
141  if (rv == ERR_IO_PENDING) {
142    user_read_callback_ = callback;
143  } else {
144    user_read_buf_ = NULL;
145    user_read_buf_len_ = 0;
146  }
147  return rv;
148}
149
150int SSLServerSocketNSS::Write(IOBuffer* buf, int buf_len,
151                              CompletionCallback* callback) {
152  DCHECK(!user_write_callback_);
153  DCHECK(!user_write_buf_);
154  DCHECK(nss_bufs_);
155
156  user_write_buf_ = buf;
157  user_write_buf_len_ = buf_len;
158
159  int rv = DoWriteLoop(OK);
160
161  if (rv == ERR_IO_PENDING) {
162    user_write_callback_ = callback;
163  } else {
164    user_write_buf_ = NULL;
165    user_write_buf_len_ = 0;
166  }
167  return rv;
168}
169
170bool SSLServerSocketNSS::SetReceiveBufferSize(int32 size) {
171  return false;
172}
173
174bool SSLServerSocketNSS::SetSendBufferSize(int32 size) {
175  return false;
176}
177
178int SSLServerSocketNSS::InitializeSSLOptions() {
179  // Transport connected, now hook it up to nss
180  // TODO(port): specify rx and tx buffer sizes separately
181  nss_fd_ = memio_CreateIOLayer(kRecvBufferSize);
182  if (nss_fd_ == NULL) {
183    return ERR_OUT_OF_MEMORY;  // TODO(port): map NSPR error code.
184  }
185
186  // Grab pointer to buffers
187  nss_bufs_ = memio_GetSecret(nss_fd_);
188
189  /* Create SSL state machine */
190  /* Push SSL onto our fake I/O socket */
191  nss_fd_ = SSL_ImportFD(NULL, nss_fd_);
192  if (nss_fd_ == NULL) {
193    LogFailedNSSFunction(net_log_, "SSL_ImportFD", "");
194    return ERR_OUT_OF_MEMORY;  // TODO(port): map NSPR/NSS error code.
195  }
196  // TODO(port): set more ssl options!  Check errors!
197
198  int rv;
199
200  rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE);
201  if (rv != SECSuccess) {
202    LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY");
203    return ERR_UNEXPECTED;
204  }
205
206  rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE);
207  if (rv != SECSuccess) {
208    LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2");
209    return ERR_UNEXPECTED;
210  }
211
212  rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL3, PR_TRUE);
213  if (rv != SECSuccess) {
214    LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL3");
215    return ERR_UNEXPECTED;
216  }
217
218  rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_TLS, ssl_config_.tls1_enabled);
219  if (rv != SECSuccess) {
220    LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_TLS");
221    return ERR_UNEXPECTED;
222  }
223
224  for (std::vector<uint16>::const_iterator it =
225           ssl_config_.disabled_cipher_suites.begin();
226       it != ssl_config_.disabled_cipher_suites.end(); ++it) {
227    // This will fail if the specified cipher is not implemented by NSS, but
228    // the failure is harmless.
229    SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE);
230  }
231
232  // Server socket doesn't need session tickets.
233  rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_FALSE);
234  if (rv != SECSuccess) {
235    LogFailedNSSFunction(
236        net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS");
237  }
238
239  // Doing this will force PR_Accept perform handshake as server.
240  rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_FALSE);
241  if (rv != SECSuccess) {
242    LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT");
243    return ERR_UNEXPECTED;
244  }
245
246  rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_SERVER, PR_TRUE);
247  if (rv != SECSuccess) {
248    LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_SERVER");
249    return ERR_UNEXPECTED;
250  }
251
252  rv = SSL_OptionSet(nss_fd_, SSL_REQUEST_CERTIFICATE, PR_FALSE);
253  if (rv != SECSuccess) {
254    LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUEST_CERTIFICATE");
255    return ERR_UNEXPECTED;
256  }
257
258  rv = SSL_OptionSet(nss_fd_, SSL_REQUIRE_CERTIFICATE, PR_FALSE);
259  if (rv != SECSuccess) {
260    LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUIRE_CERTIFICATE");
261    return ERR_UNEXPECTED;
262  }
263
264  rv = SSL_ConfigServerSessionIDCache(1024, 5, 5, NULL);
265  if (rv != SECSuccess) {
266    LogFailedNSSFunction(net_log_, "SSL_ConfigureServerSessionIDCache", "");
267    return ERR_UNEXPECTED;
268  }
269
270  rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this);
271  if (rv != SECSuccess) {
272    LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", "");
273    return ERR_UNEXPECTED;
274  }
275
276  rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this);
277  if (rv != SECSuccess) {
278    LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", "");
279    return ERR_UNEXPECTED;
280  }
281
282  // Get a certificate of CERTCertificate structure.
283  std::string der_string;
284  if (!cert_->GetDEREncoded(&der_string))
285    return ERR_UNEXPECTED;
286
287  SECItem der_cert;
288  der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>(
289      der_string.data()));
290  der_cert.len  = der_string.length();
291  der_cert.type = siDERCertBuffer;
292
293  // Parse into a CERTCertificate structure.
294  CERTCertificate* cert = CERT_NewTempCertificate(
295      CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE);
296
297  // Get a key of SECKEYPrivateKey* structure.
298  std::vector<uint8> key_vector;
299  if (!key_->ExportPrivateKey(&key_vector)) {
300    CERT_DestroyCertificate(cert);
301    return ERR_UNEXPECTED;
302  }
303
304  SECKEYPrivateKeyStr* private_key = NULL;
305  PK11SlotInfo* slot = crypto::GetPrivateNSSKeySlot();
306  if (!slot) {
307    CERT_DestroyCertificate(cert);
308    return ERR_UNEXPECTED;
309  }
310
311  SECItem der_private_key_info;
312  der_private_key_info.data =
313      const_cast<unsigned char*>(&key_vector.front());
314  der_private_key_info.len = key_vector.size();
315  // The server's RSA private key must be imported into NSS with the
316  // following key usage bits:
317  // - KU_KEY_ENCIPHERMENT, required for the RSA key exchange algorithm.
318  // - KU_DIGITAL_SIGNATURE, required for the DHE_RSA and ECDHE_RSA key
319  //   exchange algorithms.
320  const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DIGITAL_SIGNATURE;
321  rv =  PK11_ImportDERPrivateKeyInfoAndReturnKey(
322      slot, &der_private_key_info, NULL, NULL, PR_FALSE, PR_FALSE,
323      key_usage, &private_key, NULL);
324  PK11_FreeSlot(slot);
325  if (rv != SECSuccess) {
326    CERT_DestroyCertificate(cert);
327    return ERR_UNEXPECTED;
328  }
329
330  // Assign server certificate and private key.
331  SSLKEAType cert_kea = NSS_FindCertKEAType(cert);
332  rv = SSL_ConfigSecureServer(nss_fd_, cert, private_key, cert_kea);
333  CERT_DestroyCertificate(cert);
334  SECKEY_DestroyPrivateKey(private_key);
335
336  if (rv != SECSuccess) {
337    PRErrorCode prerr = PR_GetError();
338    LOG(ERROR) << "Failed to config SSL server: " << prerr;
339    LogFailedNSSFunction(net_log_, "SSL_ConfigureSecureServer", "");
340    return ERR_UNEXPECTED;
341  }
342
343  // Tell SSL we're a server; needed if not letting NSPR do socket I/O
344  rv = SSL_ResetHandshake(nss_fd_, PR_TRUE);
345  if (rv != SECSuccess) {
346    LogFailedNSSFunction(net_log_, "SSL_ResetHandshake", "");
347    return ERR_UNEXPECTED;
348  }
349
350  return OK;
351}
352
353void SSLServerSocketNSS::OnSendComplete(int result) {
354  if (next_handshake_state_ == STATE_HANDSHAKE) {
355    // In handshake phase.
356    OnHandshakeIOComplete(result);
357    return;
358  }
359
360  if (!user_write_buf_ || !completed_handshake_)
361    return;
362
363  int rv = DoWriteLoop(result);
364  if (rv != ERR_IO_PENDING)
365    DoWriteCallback(rv);
366}
367
368void SSLServerSocketNSS::OnRecvComplete(int result) {
369  if (next_handshake_state_ == STATE_HANDSHAKE) {
370    // In handshake phase.
371    OnHandshakeIOComplete(result);
372    return;
373  }
374
375  // Network layer received some data, check if client requested to read
376  // decrypted data.
377  if (!user_read_buf_ || !completed_handshake_)
378    return;
379
380  int rv = DoReadLoop(result);
381  if (rv != ERR_IO_PENDING)
382    DoReadCallback(rv);
383}
384
385void SSLServerSocketNSS::OnHandshakeIOComplete(int result) {
386  int rv = DoHandshakeLoop(result);
387  if (rv != ERR_IO_PENDING) {
388    net_log_.EndEventWithNetErrorCode(net::NetLog::TYPE_SSL_ACCEPT, rv);
389    if (user_accept_callback_)
390      DoAcceptCallback(rv);
391  }
392}
393
394// Return 0 for EOF,
395// > 0 for bytes transferred immediately,
396// < 0 for error (or the non-error ERR_IO_PENDING).
397int SSLServerSocketNSS::BufferSend(void) {
398  if (transport_send_busy_)
399    return ERR_IO_PENDING;
400
401  const char* buf1;
402  const char* buf2;
403  unsigned int len1, len2;
404  memio_GetWriteParams(nss_bufs_, &buf1, &len1, &buf2, &len2);
405  const unsigned int len = len1 + len2;
406
407  int rv = 0;
408  if (len) {
409    scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len));
410    memcpy(send_buffer->data(), buf1, len1);
411    memcpy(send_buffer->data() + len1, buf2, len2);
412    rv = transport_socket_->Write(send_buffer, len,
413                                  &buffer_send_callback_);
414    if (rv == ERR_IO_PENDING) {
415      transport_send_busy_ = true;
416    } else {
417      memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv));
418    }
419  }
420
421  return rv;
422}
423
424void SSLServerSocketNSS::BufferSendComplete(int result) {
425  memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result));
426  transport_send_busy_ = false;
427  OnSendComplete(result);
428}
429
430int SSLServerSocketNSS::BufferRecv(void) {
431  if (transport_recv_busy_) return ERR_IO_PENDING;
432
433  char *buf;
434  int nb = memio_GetReadParams(nss_bufs_, &buf);
435  int rv;
436  if (!nb) {
437    // buffer too full to read into, so no I/O possible at moment
438    rv = ERR_IO_PENDING;
439  } else {
440    recv_buffer_ = new IOBuffer(nb);
441    rv = transport_socket_->Read(recv_buffer_, nb, &buffer_recv_callback_);
442    if (rv == ERR_IO_PENDING) {
443      transport_recv_busy_ = true;
444    } else {
445      if (rv > 0)
446        memcpy(buf, recv_buffer_->data(), rv);
447      memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv));
448      recv_buffer_ = NULL;
449    }
450  }
451  return rv;
452}
453
454void SSLServerSocketNSS::BufferRecvComplete(int result) {
455  if (result > 0) {
456    char *buf;
457    memio_GetReadParams(nss_bufs_, &buf);
458    memcpy(buf, recv_buffer_->data(), result);
459  }
460  recv_buffer_ = NULL;
461  memio_PutReadResult(nss_bufs_, MapErrorToNSS(result));
462  transport_recv_busy_ = false;
463  OnRecvComplete(result);
464}
465
466// Do network I/O between the given buffer and the given socket.
467// Return true if some I/O performed, false otherwise (error or ERR_IO_PENDING)
468bool SSLServerSocketNSS::DoTransportIO() {
469  bool network_moved = false;
470  if (nss_bufs_ != NULL) {
471    int nsent = BufferSend();
472    int nreceived = BufferRecv();
473    network_moved = (nsent > 0 || nreceived >= 0);
474  }
475  return network_moved;
476}
477
478int SSLServerSocketNSS::DoPayloadRead() {
479  DCHECK(user_read_buf_);
480  DCHECK_GT(user_read_buf_len_, 0);
481  int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_);
482  if (rv >= 0)
483    return rv;
484  PRErrorCode prerr = PR_GetError();
485  if (prerr == PR_WOULD_BLOCK_ERROR) {
486    return ERR_IO_PENDING;
487  }
488  rv = MapNSSError(prerr);
489  net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
490                    make_scoped_refptr(new SSLErrorParams(rv, prerr)));
491  return rv;
492}
493
494int SSLServerSocketNSS::DoPayloadWrite() {
495  DCHECK(user_write_buf_);
496  int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_);
497  if (rv >= 0)
498    return rv;
499  PRErrorCode prerr = PR_GetError();
500  if (prerr == PR_WOULD_BLOCK_ERROR) {
501    return ERR_IO_PENDING;
502  }
503  rv = MapNSSError(prerr);
504  net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
505                    make_scoped_refptr(new SSLErrorParams(rv, prerr)));
506  return rv;
507}
508
509int SSLServerSocketNSS::DoHandshakeLoop(int last_io_result) {
510  bool network_moved;
511  int rv = last_io_result;
512  do {
513    // Default to STATE_NONE for next state.
514    // (This is a quirk carried over from the windows
515    // implementation.  It makes reading the logs a bit harder.)
516    // State handlers can and often do call GotoState just
517    // to stay in the current state.
518    State state = next_handshake_state_;
519    GotoState(STATE_NONE);
520    switch (state) {
521      case STATE_NONE:
522        // we're just pumping data between the buffer and the network
523        break;
524      case STATE_HANDSHAKE:
525        rv = DoHandshake();
526        break;
527      default:
528        rv = ERR_UNEXPECTED;
529        LOG(DFATAL) << "unexpected state " << state;
530        break;
531    }
532
533    // Do the actual network I/O
534    network_moved = DoTransportIO();
535  } while ((rv != ERR_IO_PENDING || network_moved) &&
536           next_handshake_state_ != STATE_NONE);
537  return rv;
538}
539
540int SSLServerSocketNSS::DoReadLoop(int result) {
541  DCHECK(completed_handshake_);
542  DCHECK(next_handshake_state_ == STATE_NONE);
543
544  if (result < 0)
545    return result;
546
547  if (!nss_bufs_) {
548    LOG(DFATAL) << "!nss_bufs_";
549    int rv = ERR_UNEXPECTED;
550    net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR,
551                      make_scoped_refptr(new SSLErrorParams(rv, 0)));
552    return rv;
553  }
554
555  bool network_moved;
556  int rv;
557  do {
558    rv = DoPayloadRead();
559    network_moved = DoTransportIO();
560  } while (rv == ERR_IO_PENDING && network_moved);
561  return rv;
562}
563
564int SSLServerSocketNSS::DoWriteLoop(int result) {
565  DCHECK(completed_handshake_);
566  DCHECK(next_handshake_state_ == STATE_NONE);
567
568  if (result < 0)
569    return result;
570
571  if (!nss_bufs_) {
572    LOG(DFATAL) << "!nss_bufs_";
573    int rv = ERR_UNEXPECTED;
574    net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR,
575                      make_scoped_refptr(new SSLErrorParams(rv, 0)));
576    return rv;
577  }
578
579  bool network_moved;
580  int rv;
581  do {
582    rv = DoPayloadWrite();
583    network_moved = DoTransportIO();
584  } while (rv == ERR_IO_PENDING && network_moved);
585  return rv;
586}
587
588int SSLServerSocketNSS::DoHandshake() {
589  int net_error = net::OK;
590  SECStatus rv = SSL_ForceHandshake(nss_fd_);
591
592  if (rv == SECSuccess) {
593    completed_handshake_ = true;
594  } else {
595    PRErrorCode prerr = PR_GetError();
596    net_error = MapNSSHandshakeError(prerr);
597
598    // If not done, stay in this state
599    if (net_error == ERR_IO_PENDING) {
600      GotoState(STATE_HANDSHAKE);
601    } else {
602      LOG(ERROR) << "handshake failed; NSS error code " << prerr
603                 << ", net_error " << net_error;
604      net_log_.AddEvent(
605          NetLog::TYPE_SSL_HANDSHAKE_ERROR,
606          make_scoped_refptr(new SSLErrorParams(net_error, prerr)));
607    }
608  }
609  return net_error;
610}
611
612void SSLServerSocketNSS::DoAcceptCallback(int rv) {
613  DCHECK_NE(rv, ERR_IO_PENDING);
614
615  CompletionCallback* c = user_accept_callback_;
616  user_accept_callback_ = NULL;
617  c->Run(rv > OK ? OK : rv);
618}
619
620void SSLServerSocketNSS::DoReadCallback(int rv) {
621  DCHECK(rv != ERR_IO_PENDING);
622  DCHECK(user_read_callback_);
623
624  // Since Run may result in Read being called, clear |user_read_callback_|
625  // up front.
626  CompletionCallback* c = user_read_callback_;
627  user_read_callback_ = NULL;
628  user_read_buf_ = NULL;
629  user_read_buf_len_ = 0;
630  c->Run(rv);
631}
632
633void SSLServerSocketNSS::DoWriteCallback(int rv) {
634  DCHECK(rv != ERR_IO_PENDING);
635  DCHECK(user_write_callback_);
636
637  // Since Run may result in Write being called, clear |user_write_callback_|
638  // up front.
639  CompletionCallback* c = user_write_callback_;
640  user_write_callback_ = NULL;
641  user_write_buf_ = NULL;
642  user_write_buf_len_ = 0;
643  c->Run(rv);
644}
645
646// static
647// NSS calls this if an incoming certificate needs to be verified.
648// Do nothing but return SECSuccess.
649// This is called only in full handshake mode.
650// Peer certificate is retrieved in HandshakeCallback() later, which is called
651// in full handshake mode or in resumption handshake mode.
652SECStatus SSLServerSocketNSS::OwnAuthCertHandler(void* arg,
653                                                 PRFileDesc* socket,
654                                                 PRBool checksig,
655                                                 PRBool is_server) {
656  // TODO(hclam): Implement.
657  // Tell NSS to not verify the certificate.
658  return SECSuccess;
659}
660
661// static
662// NSS calls this when handshake is completed.
663// After the SSL handshake is finished we need to verify the certificate.
664void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket,
665                                           void* arg) {
666  // TODO(hclam): Implement.
667}
668
669int SSLServerSocketNSS::Init() {
670  // Initialize the NSS SSL library in a threadsafe way.  This also
671  // initializes the NSS base library.
672  EnsureNSSSSLInit();
673  if (!NSS_IsInitialized())
674    return ERR_UNEXPECTED;
675#if !defined(OS_MACOSX) && !defined(OS_WIN)
676  // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop
677  // by MessageLoopForIO::current().
678  // X509Certificate::Verify() runs on a worker thread of CertVerifier.
679  EnsureOCSPInit();
680#endif
681
682  return OK;
683}
684
685}  // namespace net
686