• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
42 static const int kRecvBufferSize = 4096;
43 
44 #define GotoState(s) next_handshake_state_ = s
45 
46 namespace net {
47 
CreateSSLServerSocket(Socket * socket,X509Certificate * cert,crypto::RSAPrivateKey * key,const SSLConfig & ssl_config)48 SSLServerSocket* 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 
SSLServerSocketNSS(Socket * transport_socket,scoped_refptr<X509Certificate> cert,crypto::RSAPrivateKey * key,const SSLConfig & ssl_config)54 SSLServerSocketNSS::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 
~SSLServerSocketNSS()86 SSLServerSocketNSS::~SSLServerSocketNSS() {
87   if (nss_fd_ != NULL) {
88     PR_Close(nss_fd_);
89     nss_fd_ = NULL;
90   }
91 }
92 
Accept(CompletionCallback * callback)93 int 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 
Read(IOBuffer * buf,int buf_len,CompletionCallback * callback)127 int 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 
Write(IOBuffer * buf,int buf_len,CompletionCallback * callback)150 int 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 
SetReceiveBufferSize(int32 size)170 bool SSLServerSocketNSS::SetReceiveBufferSize(int32 size) {
171   return false;
172 }
173 
SetSendBufferSize(int32 size)174 bool SSLServerSocketNSS::SetSendBufferSize(int32 size) {
175   return false;
176 }
177 
InitializeSSLOptions()178 int 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 
OnSendComplete(int result)353 void 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 
OnRecvComplete(int result)368 void 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 
OnHandshakeIOComplete(int result)385 void 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).
BufferSend(void)397 int 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 
BufferSendComplete(int result)424 void SSLServerSocketNSS::BufferSendComplete(int result) {
425   memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result));
426   transport_send_busy_ = false;
427   OnSendComplete(result);
428 }
429 
BufferRecv(void)430 int 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 
BufferRecvComplete(int result)454 void 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)
DoTransportIO()468 bool 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 
DoPayloadRead()478 int 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 
DoPayloadWrite()494 int 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 
DoHandshakeLoop(int last_io_result)509 int 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 
DoReadLoop(int result)540 int 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 
DoWriteLoop(int result)564 int 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 
DoHandshake()588 int 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 
DoAcceptCallback(int rv)612 void 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 
DoReadCallback(int rv)620 void 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 
DoWriteCallback(int rv)633 void 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.
OwnAuthCertHandler(void * arg,PRFileDesc * socket,PRBool checksig,PRBool is_server)652 SECStatus 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.
HandshakeCallback(PRFileDesc * socket,void * arg)664 void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket,
665                                            void* arg) {
666   // TODO(hclam): Implement.
667 }
668 
Init()669 int 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