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.
5 #include "net/socket/ssl_server_socket_nss.h"
11 #if defined(USE_SYSTEM_SSL)
14 #if defined(OS_MACOSX)
15 #include <Security/Security.h>
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"
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
46 static const int kRecvBufferSize
= 17 * 1024;
47 static const int kSendBufferSize
= 17 * 1024;
49 #define GotoState(s) next_handshake_state_ = s
55 bool g_nss_server_sockets_init
= false;
57 class NSSSSLServerInitSingleton
{
59 NSSSSLServerInitSingleton() {
62 SSL_ConfigServerSessionIDCache(1024, 5, 5, NULL
);
63 g_nss_server_sockets_init
= true;
66 ~NSSSSLServerInitSingleton() {
67 SSL_ShutdownServerSessionIDCache();
68 g_nss_server_sockets_init
= false;
72 static base::LazyInstance
<NSSSSLServerInitSingleton
>
73 g_nss_ssl_server_init_singleton
= LAZY_INSTANCE_INITIALIZER
;
77 void EnableSSLServerSockets() {
78 g_nss_ssl_server_init_singleton
.Get();
81 SSLServerSocket
* CreateSSLServerSocket(
83 X509Certificate
* cert
,
84 crypto::RSAPrivateKey
* key
,
85 const SSLConfig
& ssl_config
) {
86 DCHECK(g_nss_server_sockets_init
) << "EnableSSLServerSockets() has not been"
89 return new SSLServerSocketNSS(socket
, cert
, key
, ssl_config
);
92 SSLServerSocketNSS::SSLServerSocketNSS(
93 StreamSocket
* transport_socket
,
94 scoped_refptr
<X509Certificate
> cert
,
95 crypto::RSAPrivateKey
* key
,
96 const SSLConfig
& ssl_config
)
97 : transport_send_busy_(false),
98 transport_recv_busy_(false),
99 user_read_buf_len_(0),
100 user_write_buf_len_(0),
103 transport_socket_(transport_socket
),
104 ssl_config_(ssl_config
),
106 next_handshake_state_(STATE_NONE
),
107 completed_handshake_(false) {
108 ssl_config_
.false_start_enabled
= false;
109 ssl_config_
.version_min
= SSL_PROTOCOL_VERSION_SSL3
;
110 ssl_config_
.version_max
= SSL_PROTOCOL_VERSION_TLS1_1
;
112 // TODO(hclam): Need a better way to clone a key.
113 std::vector
<uint8
> key_bytes
;
114 CHECK(key
->ExportPrivateKey(&key_bytes
));
115 key_
.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes
));
119 SSLServerSocketNSS::~SSLServerSocketNSS() {
120 if (nss_fd_
!= NULL
) {
126 int SSLServerSocketNSS::Handshake(const CompletionCallback
& callback
) {
127 net_log_
.BeginEvent(NetLog::TYPE_SSL_SERVER_HANDSHAKE
);
131 LOG(ERROR
) << "Failed to initialize NSS";
132 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE
, rv
);
136 rv
= InitializeSSLOptions();
138 LOG(ERROR
) << "Failed to initialize SSL options";
139 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE
, rv
);
143 // Set peer address. TODO(hclam): This should be in a separate method.
145 memset(&peername
, 0, sizeof(peername
));
146 peername
.raw
.family
= AF_INET
;
147 memio_SetPeerName(nss_fd_
, &peername
);
149 GotoState(STATE_HANDSHAKE
);
150 rv
= DoHandshakeLoop(OK
);
151 if (rv
== ERR_IO_PENDING
) {
152 user_handshake_callback_
= callback
;
154 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE
, rv
);
157 return rv
> OK
? OK
: rv
;
160 int SSLServerSocketNSS::ExportKeyingMaterial(const base::StringPiece
& label
,
162 const base::StringPiece
& context
,
164 unsigned int outlen
) {
166 return ERR_SOCKET_NOT_CONNECTED
;
167 SECStatus result
= SSL_ExportKeyingMaterial(
168 nss_fd_
, label
.data(), label
.size(), has_context
,
169 reinterpret_cast<const unsigned char*>(context
.data()),
170 context
.length(), out
, outlen
);
171 if (result
!= SECSuccess
) {
172 LogFailedNSSFunction(net_log_
, "SSL_ExportKeyingMaterial", "");
173 return MapNSSError(PORT_GetError());
178 int SSLServerSocketNSS::GetTLSUniqueChannelBinding(std::string
* out
) {
180 return ERR_SOCKET_NOT_CONNECTED
;
181 unsigned char buf
[64];
183 SECStatus result
= SSL_GetChannelBinding(nss_fd_
,
184 SSL_CHANNEL_BINDING_TLS_UNIQUE
,
185 buf
, &len
, arraysize(buf
));
186 if (result
!= SECSuccess
) {
187 LogFailedNSSFunction(net_log_
, "SSL_GetChannelBinding", "");
188 return MapNSSError(PORT_GetError());
190 out
->assign(reinterpret_cast<char*>(buf
), len
);
194 int SSLServerSocketNSS::Connect(const CompletionCallback
& callback
) {
196 return ERR_NOT_IMPLEMENTED
;
199 int SSLServerSocketNSS::Read(IOBuffer
* buf
, int buf_len
,
200 const CompletionCallback
& callback
) {
201 DCHECK(user_read_callback_
.is_null());
202 DCHECK(user_handshake_callback_
.is_null());
203 DCHECK(!user_read_buf_
.get());
205 DCHECK(!callback
.is_null());
207 user_read_buf_
= buf
;
208 user_read_buf_len_
= buf_len
;
210 DCHECK(completed_handshake_
);
212 int rv
= DoReadLoop(OK
);
214 if (rv
== ERR_IO_PENDING
) {
215 user_read_callback_
= callback
;
217 user_read_buf_
= NULL
;
218 user_read_buf_len_
= 0;
223 int SSLServerSocketNSS::Write(IOBuffer
* buf
, int buf_len
,
224 const CompletionCallback
& callback
) {
225 DCHECK(user_write_callback_
.is_null());
226 DCHECK(!user_write_buf_
.get());
228 DCHECK(!callback
.is_null());
230 user_write_buf_
= buf
;
231 user_write_buf_len_
= buf_len
;
233 int rv
= DoWriteLoop(OK
);
235 if (rv
== ERR_IO_PENDING
) {
236 user_write_callback_
= callback
;
238 user_write_buf_
= NULL
;
239 user_write_buf_len_
= 0;
244 bool SSLServerSocketNSS::SetReceiveBufferSize(int32 size
) {
245 return transport_socket_
->SetReceiveBufferSize(size
);
248 bool SSLServerSocketNSS::SetSendBufferSize(int32 size
) {
249 return transport_socket_
->SetSendBufferSize(size
);
252 bool SSLServerSocketNSS::IsConnected() const {
253 return completed_handshake_
;
256 void SSLServerSocketNSS::Disconnect() {
257 transport_socket_
->Disconnect();
260 bool SSLServerSocketNSS::IsConnectedAndIdle() const {
261 return completed_handshake_
&& transport_socket_
->IsConnectedAndIdle();
264 int SSLServerSocketNSS::GetPeerAddress(IPEndPoint
* address
) const {
266 return ERR_SOCKET_NOT_CONNECTED
;
267 return transport_socket_
->GetPeerAddress(address
);
270 int SSLServerSocketNSS::GetLocalAddress(IPEndPoint
* address
) const {
272 return ERR_SOCKET_NOT_CONNECTED
;
273 return transport_socket_
->GetLocalAddress(address
);
276 const BoundNetLog
& SSLServerSocketNSS::NetLog() const {
280 void SSLServerSocketNSS::SetSubresourceSpeculation() {
281 transport_socket_
->SetSubresourceSpeculation();
284 void SSLServerSocketNSS::SetOmniboxSpeculation() {
285 transport_socket_
->SetOmniboxSpeculation();
288 bool SSLServerSocketNSS::WasEverUsed() const {
289 return transport_socket_
->WasEverUsed();
292 bool SSLServerSocketNSS::UsingTCPFastOpen() const {
293 return transport_socket_
->UsingTCPFastOpen();
296 bool SSLServerSocketNSS::WasNpnNegotiated() const {
300 NextProto
SSLServerSocketNSS::GetNegotiatedProtocol() const {
301 // NPN is not supported by this class.
302 return kProtoUnknown
;
305 bool SSLServerSocketNSS::GetSSLInfo(SSLInfo
* ssl_info
) {
310 int SSLServerSocketNSS::InitializeSSLOptions() {
311 // Transport connected, now hook it up to nss
312 nss_fd_
= memio_CreateIOLayer(kRecvBufferSize
, kSendBufferSize
);
313 if (nss_fd_
== NULL
) {
314 return ERR_OUT_OF_MEMORY
; // TODO(port): map NSPR error code.
317 // Grab pointer to buffers
318 nss_bufs_
= memio_GetSecret(nss_fd_
);
320 /* Create SSL state machine */
321 /* Push SSL onto our fake I/O socket */
322 nss_fd_
= SSL_ImportFD(NULL
, nss_fd_
);
323 if (nss_fd_
== NULL
) {
324 LogFailedNSSFunction(net_log_
, "SSL_ImportFD", "");
325 return ERR_OUT_OF_MEMORY
; // TODO(port): map NSPR/NSS error code.
327 // TODO(port): set more ssl options! Check errors!
331 rv
= SSL_OptionSet(nss_fd_
, SSL_SECURITY
, PR_TRUE
);
332 if (rv
!= SECSuccess
) {
333 LogFailedNSSFunction(net_log_
, "SSL_OptionSet", "SSL_SECURITY");
334 return ERR_UNEXPECTED
;
337 rv
= SSL_OptionSet(nss_fd_
, SSL_ENABLE_SSL2
, PR_FALSE
);
338 if (rv
!= SECSuccess
) {
339 LogFailedNSSFunction(net_log_
, "SSL_OptionSet", "SSL_ENABLE_SSL2");
340 return ERR_UNEXPECTED
;
343 SSLVersionRange version_range
;
344 version_range
.min
= ssl_config_
.version_min
;
345 version_range
.max
= ssl_config_
.version_max
;
346 rv
= SSL_VersionRangeSet(nss_fd_
, &version_range
);
347 if (rv
!= SECSuccess
) {
348 LogFailedNSSFunction(net_log_
, "SSL_VersionRangeSet", "");
349 return ERR_NO_SSL_VERSIONS_ENABLED
;
352 for (std::vector
<uint16
>::const_iterator it
=
353 ssl_config_
.disabled_cipher_suites
.begin();
354 it
!= ssl_config_
.disabled_cipher_suites
.end(); ++it
) {
355 // This will fail if the specified cipher is not implemented by NSS, but
356 // the failure is harmless.
357 SSL_CipherPrefSet(nss_fd_
, *it
, PR_FALSE
);
360 // Server socket doesn't need session tickets.
361 rv
= SSL_OptionSet(nss_fd_
, SSL_ENABLE_SESSION_TICKETS
, PR_FALSE
);
362 if (rv
!= SECSuccess
) {
363 LogFailedNSSFunction(
364 net_log_
, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS");
367 // Doing this will force PR_Accept perform handshake as server.
368 rv
= SSL_OptionSet(nss_fd_
, SSL_HANDSHAKE_AS_CLIENT
, PR_FALSE
);
369 if (rv
!= SECSuccess
) {
370 LogFailedNSSFunction(net_log_
, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT");
371 return ERR_UNEXPECTED
;
374 rv
= SSL_OptionSet(nss_fd_
, SSL_HANDSHAKE_AS_SERVER
, PR_TRUE
);
375 if (rv
!= SECSuccess
) {
376 LogFailedNSSFunction(net_log_
, "SSL_OptionSet", "SSL_HANDSHAKE_AS_SERVER");
377 return ERR_UNEXPECTED
;
380 rv
= SSL_OptionSet(nss_fd_
, SSL_REQUEST_CERTIFICATE
, PR_FALSE
);
381 if (rv
!= SECSuccess
) {
382 LogFailedNSSFunction(net_log_
, "SSL_OptionSet", "SSL_REQUEST_CERTIFICATE");
383 return ERR_UNEXPECTED
;
386 rv
= SSL_OptionSet(nss_fd_
, SSL_REQUIRE_CERTIFICATE
, PR_FALSE
);
387 if (rv
!= SECSuccess
) {
388 LogFailedNSSFunction(net_log_
, "SSL_OptionSet", "SSL_REQUIRE_CERTIFICATE");
389 return ERR_UNEXPECTED
;
392 rv
= SSL_AuthCertificateHook(nss_fd_
, OwnAuthCertHandler
, this);
393 if (rv
!= SECSuccess
) {
394 LogFailedNSSFunction(net_log_
, "SSL_AuthCertificateHook", "");
395 return ERR_UNEXPECTED
;
398 rv
= SSL_HandshakeCallback(nss_fd_
, HandshakeCallback
, this);
399 if (rv
!= SECSuccess
) {
400 LogFailedNSSFunction(net_log_
, "SSL_HandshakeCallback", "");
401 return ERR_UNEXPECTED
;
404 // Get a certificate of CERTCertificate structure.
405 std::string der_string
;
406 if (!X509Certificate::GetDEREncoded(cert_
->os_cert_handle(), &der_string
))
407 return ERR_UNEXPECTED
;
410 der_cert
.data
= reinterpret_cast<unsigned char*>(const_cast<char*>(
412 der_cert
.len
= der_string
.length();
413 der_cert
.type
= siDERCertBuffer
;
415 // Parse into a CERTCertificate structure.
416 CERTCertificate
* cert
= CERT_NewTempCertificate(
417 CERT_GetDefaultCertDB(), &der_cert
, NULL
, PR_FALSE
, PR_TRUE
);
419 LogFailedNSSFunction(net_log_
, "CERT_NewTempCertificate", "");
420 return MapNSSError(PORT_GetError());
423 // Get a key of SECKEYPrivateKey* structure.
424 std::vector
<uint8
> key_vector
;
425 if (!key_
->ExportPrivateKey(&key_vector
)) {
426 CERT_DestroyCertificate(cert
);
427 return ERR_UNEXPECTED
;
430 SECKEYPrivateKeyStr
* private_key
= NULL
;
431 PK11SlotInfo
* slot
= crypto::GetPrivateNSSKeySlot();
433 CERT_DestroyCertificate(cert
);
434 return ERR_UNEXPECTED
;
437 SECItem der_private_key_info
;
438 der_private_key_info
.data
=
439 const_cast<unsigned char*>(&key_vector
.front());
440 der_private_key_info
.len
= key_vector
.size();
441 // The server's RSA private key must be imported into NSS with the
442 // following key usage bits:
443 // - KU_KEY_ENCIPHERMENT, required for the RSA key exchange algorithm.
444 // - KU_DIGITAL_SIGNATURE, required for the DHE_RSA and ECDHE_RSA key
445 // exchange algorithms.
446 const unsigned int key_usage
= KU_KEY_ENCIPHERMENT
| KU_DIGITAL_SIGNATURE
;
447 rv
= PK11_ImportDERPrivateKeyInfoAndReturnKey(
448 slot
, &der_private_key_info
, NULL
, NULL
, PR_FALSE
, PR_FALSE
,
449 key_usage
, &private_key
, NULL
);
451 if (rv
!= SECSuccess
) {
452 CERT_DestroyCertificate(cert
);
453 return ERR_UNEXPECTED
;
456 // Assign server certificate and private key.
457 SSLKEAType cert_kea
= NSS_FindCertKEAType(cert
);
458 rv
= SSL_ConfigSecureServer(nss_fd_
, cert
, private_key
, cert_kea
);
459 CERT_DestroyCertificate(cert
);
460 SECKEY_DestroyPrivateKey(private_key
);
462 if (rv
!= SECSuccess
) {
463 PRErrorCode prerr
= PR_GetError();
464 LOG(ERROR
) << "Failed to config SSL server: " << prerr
;
465 LogFailedNSSFunction(net_log_
, "SSL_ConfigureSecureServer", "");
466 return ERR_UNEXPECTED
;
469 // Tell SSL we're a server; needed if not letting NSPR do socket I/O
470 rv
= SSL_ResetHandshake(nss_fd_
, PR_TRUE
);
471 if (rv
!= SECSuccess
) {
472 LogFailedNSSFunction(net_log_
, "SSL_ResetHandshake", "");
473 return ERR_UNEXPECTED
;
479 void SSLServerSocketNSS::OnSendComplete(int result
) {
480 if (next_handshake_state_
== STATE_HANDSHAKE
) {
481 // In handshake phase.
482 OnHandshakeIOComplete(result
);
486 if (!completed_handshake_
)
489 if (user_write_buf_
.get()) {
490 int rv
= DoWriteLoop(result
);
491 if (rv
!= ERR_IO_PENDING
)
494 // Ensure that any queued ciphertext is flushed.
499 void SSLServerSocketNSS::OnRecvComplete(int result
) {
500 if (next_handshake_state_
== STATE_HANDSHAKE
) {
501 // In handshake phase.
502 OnHandshakeIOComplete(result
);
506 // Network layer received some data, check if client requested to read
508 if (!user_read_buf_
.get() || !completed_handshake_
)
511 int rv
= DoReadLoop(result
);
512 if (rv
!= ERR_IO_PENDING
)
516 void SSLServerSocketNSS::OnHandshakeIOComplete(int result
) {
517 int rv
= DoHandshakeLoop(result
);
518 if (rv
!= ERR_IO_PENDING
) {
519 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE
, rv
);
520 if (!user_handshake_callback_
.is_null())
521 DoHandshakeCallback(rv
);
526 // > 0 for bytes transferred immediately,
527 // < 0 for error (or the non-error ERR_IO_PENDING).
528 int SSLServerSocketNSS::BufferSend(void) {
529 if (transport_send_busy_
)
530 return ERR_IO_PENDING
;
534 unsigned int len1
, len2
;
535 memio_GetWriteParams(nss_bufs_
, &buf1
, &len1
, &buf2
, &len2
);
536 const unsigned int len
= len1
+ len2
;
540 scoped_refptr
<IOBuffer
> send_buffer(new IOBuffer(len
));
541 memcpy(send_buffer
->data(), buf1
, len1
);
542 memcpy(send_buffer
->data() + len1
, buf2
, len2
);
543 rv
= transport_socket_
->Write(
546 base::Bind(&SSLServerSocketNSS::BufferSendComplete
,
547 base::Unretained(this)));
548 if (rv
== ERR_IO_PENDING
) {
549 transport_send_busy_
= true;
551 memio_PutWriteResult(nss_bufs_
, MapErrorToNSS(rv
));
558 void SSLServerSocketNSS::BufferSendComplete(int result
) {
559 memio_PutWriteResult(nss_bufs_
, MapErrorToNSS(result
));
560 transport_send_busy_
= false;
561 OnSendComplete(result
);
564 int SSLServerSocketNSS::BufferRecv(void) {
565 if (transport_recv_busy_
) return ERR_IO_PENDING
;
568 int nb
= memio_GetReadParams(nss_bufs_
, &buf
);
571 // buffer too full to read into, so no I/O possible at moment
574 recv_buffer_
= new IOBuffer(nb
);
575 rv
= transport_socket_
->Read(
578 base::Bind(&SSLServerSocketNSS::BufferRecvComplete
,
579 base::Unretained(this)));
580 if (rv
== ERR_IO_PENDING
) {
581 transport_recv_busy_
= true;
584 memcpy(buf
, recv_buffer_
->data(), rv
);
585 memio_PutReadResult(nss_bufs_
, MapErrorToNSS(rv
));
592 void SSLServerSocketNSS::BufferRecvComplete(int result
) {
595 memio_GetReadParams(nss_bufs_
, &buf
);
596 memcpy(buf
, recv_buffer_
->data(), result
);
599 memio_PutReadResult(nss_bufs_
, MapErrorToNSS(result
));
600 transport_recv_busy_
= false;
601 OnRecvComplete(result
);
604 // Do as much network I/O as possible between the buffer and the
605 // transport socket. Return true if some I/O performed, false
606 // otherwise (error or ERR_IO_PENDING).
607 bool SSLServerSocketNSS::DoTransportIO() {
608 bool network_moved
= false;
609 if (nss_bufs_
!= NULL
) {
611 // Read and write as much data as we can. The loop is neccessary
612 // because Write() may return synchronously.
616 network_moved
= true;
618 if (BufferRecv() >= 0)
619 network_moved
= true;
621 return network_moved
;
624 int SSLServerSocketNSS::DoPayloadRead() {
625 DCHECK(user_read_buf_
.get());
626 DCHECK_GT(user_read_buf_len_
, 0);
627 int rv
= PR_Read(nss_fd_
, user_read_buf_
->data(), user_read_buf_len_
);
630 PRErrorCode prerr
= PR_GetError();
631 if (prerr
== PR_WOULD_BLOCK_ERROR
) {
632 return ERR_IO_PENDING
;
634 rv
= MapNSSError(prerr
);
635 net_log_
.AddEvent(NetLog::TYPE_SSL_READ_ERROR
,
636 CreateNetLogSSLErrorCallback(rv
, prerr
));
640 int SSLServerSocketNSS::DoPayloadWrite() {
641 DCHECK(user_write_buf_
.get());
642 int rv
= PR_Write(nss_fd_
, user_write_buf_
->data(), user_write_buf_len_
);
645 PRErrorCode prerr
= PR_GetError();
646 if (prerr
== PR_WOULD_BLOCK_ERROR
) {
647 return ERR_IO_PENDING
;
649 rv
= MapNSSError(prerr
);
650 net_log_
.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR
,
651 CreateNetLogSSLErrorCallback(rv
, prerr
));
655 int SSLServerSocketNSS::DoHandshakeLoop(int last_io_result
) {
656 int rv
= last_io_result
;
658 // Default to STATE_NONE for next state.
659 // (This is a quirk carried over from the windows
660 // implementation. It makes reading the logs a bit harder.)
661 // State handlers can and often do call GotoState just
662 // to stay in the current state.
663 State state
= next_handshake_state_
;
664 GotoState(STATE_NONE
);
666 case STATE_HANDSHAKE
:
672 LOG(DFATAL
) << "unexpected state " << state
;
676 // Do the actual network I/O
677 bool network_moved
= DoTransportIO();
678 if (network_moved
&& next_handshake_state_
== STATE_HANDSHAKE
) {
679 // In general we exit the loop if rv is ERR_IO_PENDING. In this
680 // special case we keep looping even if rv is ERR_IO_PENDING because
681 // the transport IO may allow DoHandshake to make progress.
682 rv
= OK
; // This causes us to stay in the loop.
684 } while (rv
!= ERR_IO_PENDING
&& next_handshake_state_
!= STATE_NONE
);
688 int SSLServerSocketNSS::DoReadLoop(int result
) {
689 DCHECK(completed_handshake_
);
690 DCHECK(next_handshake_state_
== STATE_NONE
);
696 LOG(DFATAL
) << "!nss_bufs_";
697 int rv
= ERR_UNEXPECTED
;
698 net_log_
.AddEvent(NetLog::TYPE_SSL_READ_ERROR
,
699 CreateNetLogSSLErrorCallback(rv
, 0));
706 rv
= DoPayloadRead();
707 network_moved
= DoTransportIO();
708 } while (rv
== ERR_IO_PENDING
&& network_moved
);
712 int SSLServerSocketNSS::DoWriteLoop(int result
) {
713 DCHECK(completed_handshake_
);
714 DCHECK(next_handshake_state_
== STATE_NONE
);
720 LOG(DFATAL
) << "!nss_bufs_";
721 int rv
= ERR_UNEXPECTED
;
722 net_log_
.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR
,
723 CreateNetLogSSLErrorCallback(rv
, 0));
730 rv
= DoPayloadWrite();
731 network_moved
= DoTransportIO();
732 } while (rv
== ERR_IO_PENDING
&& network_moved
);
736 int SSLServerSocketNSS::DoHandshake() {
738 SECStatus rv
= SSL_ForceHandshake(nss_fd_
);
740 if (rv
== SECSuccess
) {
741 completed_handshake_
= true;
743 PRErrorCode prerr
= PR_GetError();
744 net_error
= MapNSSError(prerr
);
746 // If not done, stay in this state
747 if (net_error
== ERR_IO_PENDING
) {
748 GotoState(STATE_HANDSHAKE
);
750 LOG(ERROR
) << "handshake failed; NSS error code " << prerr
751 << ", net_error " << net_error
;
752 net_log_
.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR
,
753 CreateNetLogSSLErrorCallback(net_error
, prerr
));
759 void SSLServerSocketNSS::DoHandshakeCallback(int rv
) {
760 DCHECK_NE(rv
, ERR_IO_PENDING
);
762 CompletionCallback c
= user_handshake_callback_
;
763 user_handshake_callback_
.Reset();
764 c
.Run(rv
> OK
? OK
: rv
);
767 void SSLServerSocketNSS::DoReadCallback(int rv
) {
768 DCHECK(rv
!= ERR_IO_PENDING
);
769 DCHECK(!user_read_callback_
.is_null());
771 // Since Run may result in Read being called, clear |user_read_callback_|
773 CompletionCallback c
= user_read_callback_
;
774 user_read_callback_
.Reset();
775 user_read_buf_
= NULL
;
776 user_read_buf_len_
= 0;
780 void SSLServerSocketNSS::DoWriteCallback(int rv
) {
781 DCHECK(rv
!= ERR_IO_PENDING
);
782 DCHECK(!user_write_callback_
.is_null());
784 // Since Run may result in Write being called, clear |user_write_callback_|
786 CompletionCallback c
= user_write_callback_
;
787 user_write_callback_
.Reset();
788 user_write_buf_
= NULL
;
789 user_write_buf_len_
= 0;
794 // NSS calls this if an incoming certificate needs to be verified.
795 // Do nothing but return SECSuccess.
796 // This is called only in full handshake mode.
797 // Peer certificate is retrieved in HandshakeCallback() later, which is called
798 // in full handshake mode or in resumption handshake mode.
799 SECStatus
SSLServerSocketNSS::OwnAuthCertHandler(void* arg
,
803 // TODO(hclam): Implement.
804 // Tell NSS to not verify the certificate.
809 // NSS calls this when handshake is completed.
810 // After the SSL handshake is finished we need to verify the certificate.
811 void SSLServerSocketNSS::HandshakeCallback(PRFileDesc
* socket
,
813 // TODO(hclam): Implement.
816 int SSLServerSocketNSS::Init() {
817 // Initialize the NSS SSL library in a threadsafe way. This also
818 // initializes the NSS base library.
820 if (!NSS_IsInitialized())
821 return ERR_UNEXPECTED
;
823 EnableSSLServerSockets();