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