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/callback_helpers.h"
33 #include "base/lazy_instance.h"
34 #include "base/memory/ref_counted.h"
35 #include "crypto/nss_util_internal.h"
36 #include "crypto/rsa_private_key.h"
37 #include "net/base/io_buffer.h"
38 #include "net/base/net_errors.h"
39 #include "net/log/net_log.h"
40 #include "net/socket/nss_ssl_util.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(64, 28800, 28800, 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 scoped_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"
89 return scoped_ptr
<SSLServerSocket
>(
90 new SSLServerSocketNSS(socket
.Pass(), cert
, key
, ssl_config
));
93 SSLServerSocketNSS::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),
104 transport_socket_(transport_socket
.Pass()),
105 ssl_config_(ssl_config
),
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
));
116 SSLServerSocketNSS::~SSLServerSocketNSS() {
117 if (nss_fd_
!= NULL
) {
123 int SSLServerSocketNSS::Handshake(const CompletionCallback
& callback
) {
124 net_log_
.BeginEvent(NetLog::TYPE_SSL_SERVER_HANDSHAKE
);
128 LOG(ERROR
) << "Failed to initialize NSS";
129 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE
, rv
);
133 rv
= InitializeSSLOptions();
135 LOG(ERROR
) << "Failed to initialize SSL options";
136 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE
, rv
);
140 // Set peer address. TODO(hclam): This should be in a separate method.
142 memset(&peername
, 0, sizeof(peername
));
143 peername
.raw
.family
= AF_INET
;
144 memio_SetPeerName(nss_fd_
, &peername
);
146 GotoState(STATE_HANDSHAKE
);
147 rv
= DoHandshakeLoop(OK
);
148 if (rv
== ERR_IO_PENDING
) {
149 user_handshake_callback_
= callback
;
151 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE
, rv
);
154 return rv
> OK
? OK
: rv
;
157 int SSLServerSocketNSS::ExportKeyingMaterial(const base::StringPiece
& label
,
159 const base::StringPiece
& context
,
161 unsigned int outlen
) {
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());
175 int SSLServerSocketNSS::GetTLSUniqueChannelBinding(std::string
* out
) {
177 return ERR_SOCKET_NOT_CONNECTED
;
178 unsigned char buf
[64];
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());
187 out
->assign(reinterpret_cast<char*>(buf
), len
);
191 int SSLServerSocketNSS::Connect(const CompletionCallback
& callback
) {
193 return ERR_NOT_IMPLEMENTED
;
196 int 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());
202 DCHECK(!callback
.is_null());
204 user_read_buf_
= buf
;
205 user_read_buf_len_
= buf_len
;
207 DCHECK(completed_handshake_
);
209 int rv
= DoReadLoop(OK
);
211 if (rv
== ERR_IO_PENDING
) {
212 user_read_callback_
= callback
;
214 user_read_buf_
= NULL
;
215 user_read_buf_len_
= 0;
220 int SSLServerSocketNSS::Write(IOBuffer
* buf
, int buf_len
,
221 const CompletionCallback
& callback
) {
222 DCHECK(user_write_callback_
.is_null());
223 DCHECK(!user_write_buf_
.get());
225 DCHECK(!callback
.is_null());
227 user_write_buf_
= buf
;
228 user_write_buf_len_
= buf_len
;
230 int rv
= DoWriteLoop(OK
);
232 if (rv
== ERR_IO_PENDING
) {
233 user_write_callback_
= callback
;
235 user_write_buf_
= NULL
;
236 user_write_buf_len_
= 0;
241 int SSLServerSocketNSS::SetReceiveBufferSize(int32 size
) {
242 return transport_socket_
->SetReceiveBufferSize(size
);
245 int SSLServerSocketNSS::SetSendBufferSize(int32 size
) {
246 return transport_socket_
->SetSendBufferSize(size
);
249 bool SSLServerSocketNSS::IsConnected() const {
250 // TODO(wtc): Find out if we should check transport_socket_->IsConnected()
252 return completed_handshake_
;
255 void SSLServerSocketNSS::Disconnect() {
256 transport_socket_
->Disconnect();
259 bool SSLServerSocketNSS::IsConnectedAndIdle() const {
260 return completed_handshake_
&& transport_socket_
->IsConnectedAndIdle();
263 int SSLServerSocketNSS::GetPeerAddress(IPEndPoint
* address
) const {
265 return ERR_SOCKET_NOT_CONNECTED
;
266 return transport_socket_
->GetPeerAddress(address
);
269 int SSLServerSocketNSS::GetLocalAddress(IPEndPoint
* address
) const {
271 return ERR_SOCKET_NOT_CONNECTED
;
272 return transport_socket_
->GetLocalAddress(address
);
275 const BoundNetLog
& SSLServerSocketNSS::NetLog() const {
279 void SSLServerSocketNSS::SetSubresourceSpeculation() {
280 transport_socket_
->SetSubresourceSpeculation();
283 void SSLServerSocketNSS::SetOmniboxSpeculation() {
284 transport_socket_
->SetOmniboxSpeculation();
287 bool SSLServerSocketNSS::WasEverUsed() const {
288 return transport_socket_
->WasEverUsed();
291 bool SSLServerSocketNSS::UsingTCPFastOpen() const {
292 return transport_socket_
->UsingTCPFastOpen();
295 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 void SSLServerSocketNSS::GetConnectionAttempts(ConnectionAttempts
* out
) const {
314 int SSLServerSocketNSS::InitializeSSLOptions() {
315 // Transport connected, now hook it up to nss
316 nss_fd_
= memio_CreateIOLayer(kRecvBufferSize
, kSendBufferSize
);
317 if (nss_fd_
== NULL
) {
318 return ERR_OUT_OF_MEMORY
; // TODO(port): map NSPR error code.
321 // Grab pointer to buffers
322 nss_bufs_
= memio_GetSecret(nss_fd_
);
324 /* Create SSL state machine */
325 /* Push SSL onto our fake I/O socket */
326 nss_fd_
= SSL_ImportFD(NULL
, nss_fd_
);
327 if (nss_fd_
== NULL
) {
328 LogFailedNSSFunction(net_log_
, "SSL_ImportFD", "");
329 return ERR_OUT_OF_MEMORY
; // TODO(port): map NSPR/NSS error code.
331 // TODO(port): set more ssl options! Check errors!
335 rv
= SSL_OptionSet(nss_fd_
, SSL_SECURITY
, PR_TRUE
);
336 if (rv
!= SECSuccess
) {
337 LogFailedNSSFunction(net_log_
, "SSL_OptionSet", "SSL_SECURITY");
338 return ERR_UNEXPECTED
;
341 rv
= SSL_OptionSet(nss_fd_
, SSL_ENABLE_SSL2
, PR_FALSE
);
342 if (rv
!= SECSuccess
) {
343 LogFailedNSSFunction(net_log_
, "SSL_OptionSet", "SSL_ENABLE_SSL2");
344 return ERR_UNEXPECTED
;
347 SSLVersionRange version_range
;
348 version_range
.min
= ssl_config_
.version_min
;
349 version_range
.max
= ssl_config_
.version_max
;
350 rv
= SSL_VersionRangeSet(nss_fd_
, &version_range
);
351 if (rv
!= SECSuccess
) {
352 LogFailedNSSFunction(net_log_
, "SSL_VersionRangeSet", "");
353 return ERR_NO_SSL_VERSIONS_ENABLED
;
356 if (ssl_config_
.require_ecdhe
) {
357 const PRUint16
* const ssl_ciphers
= SSL_GetImplementedCiphers();
358 const PRUint16 num_ciphers
= SSL_GetNumImplementedCiphers();
360 // Require forward security by iterating over the cipher suites and
361 // disabling all those that don't use ECDHE.
362 for (unsigned i
= 0; i
< num_ciphers
; i
++) {
363 SSLCipherSuiteInfo info
;
364 if (SSL_GetCipherSuiteInfo(ssl_ciphers
[i
], &info
, sizeof(info
)) ==
366 if (strcmp(info
.keaTypeName
, "ECDHE") != 0) {
367 SSL_CipherPrefSet(nss_fd_
, ssl_ciphers
[i
], PR_FALSE
);
373 for (std::vector
<uint16
>::const_iterator it
=
374 ssl_config_
.disabled_cipher_suites
.begin();
375 it
!= ssl_config_
.disabled_cipher_suites
.end(); ++it
) {
376 // This will fail if the specified cipher is not implemented by NSS, but
377 // the failure is harmless.
378 SSL_CipherPrefSet(nss_fd_
, *it
, PR_FALSE
);
381 // Server socket doesn't need session tickets.
382 rv
= SSL_OptionSet(nss_fd_
, SSL_ENABLE_SESSION_TICKETS
, PR_FALSE
);
383 if (rv
!= SECSuccess
) {
384 LogFailedNSSFunction(
385 net_log_
, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS");
388 // Doing this will force PR_Accept perform handshake as server.
389 rv
= SSL_OptionSet(nss_fd_
, SSL_HANDSHAKE_AS_CLIENT
, PR_FALSE
);
390 if (rv
!= SECSuccess
) {
391 LogFailedNSSFunction(net_log_
, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT");
392 return ERR_UNEXPECTED
;
395 rv
= SSL_OptionSet(nss_fd_
, SSL_HANDSHAKE_AS_SERVER
, PR_TRUE
);
396 if (rv
!= SECSuccess
) {
397 LogFailedNSSFunction(net_log_
, "SSL_OptionSet", "SSL_HANDSHAKE_AS_SERVER");
398 return ERR_UNEXPECTED
;
401 rv
= SSL_OptionSet(nss_fd_
, SSL_REQUEST_CERTIFICATE
, PR_FALSE
);
402 if (rv
!= SECSuccess
) {
403 LogFailedNSSFunction(net_log_
, "SSL_OptionSet", "SSL_REQUEST_CERTIFICATE");
404 return ERR_UNEXPECTED
;
407 rv
= SSL_OptionSet(nss_fd_
, SSL_REQUIRE_CERTIFICATE
, PR_FALSE
);
408 if (rv
!= SECSuccess
) {
409 LogFailedNSSFunction(net_log_
, "SSL_OptionSet", "SSL_REQUIRE_CERTIFICATE");
410 return ERR_UNEXPECTED
;
413 rv
= SSL_AuthCertificateHook(nss_fd_
, OwnAuthCertHandler
, this);
414 if (rv
!= SECSuccess
) {
415 LogFailedNSSFunction(net_log_
, "SSL_AuthCertificateHook", "");
416 return ERR_UNEXPECTED
;
419 rv
= SSL_HandshakeCallback(nss_fd_
, HandshakeCallback
, this);
420 if (rv
!= SECSuccess
) {
421 LogFailedNSSFunction(net_log_
, "SSL_HandshakeCallback", "");
422 return ERR_UNEXPECTED
;
425 // Get a certificate of CERTCertificate structure.
426 std::string der_string
;
427 if (!X509Certificate::GetDEREncoded(cert_
->os_cert_handle(), &der_string
))
428 return ERR_UNEXPECTED
;
431 der_cert
.data
= reinterpret_cast<unsigned char*>(const_cast<char*>(
433 der_cert
.len
= der_string
.length();
434 der_cert
.type
= siDERCertBuffer
;
436 // Parse into a CERTCertificate structure.
437 CERTCertificate
* cert
= CERT_NewTempCertificate(
438 CERT_GetDefaultCertDB(), &der_cert
, NULL
, PR_FALSE
, PR_TRUE
);
440 LogFailedNSSFunction(net_log_
, "CERT_NewTempCertificate", "");
441 return MapNSSError(PORT_GetError());
444 // Get a key of SECKEYPrivateKey* structure.
445 std::vector
<uint8
> key_vector
;
446 if (!key_
->ExportPrivateKey(&key_vector
)) {
447 CERT_DestroyCertificate(cert
);
448 return ERR_UNEXPECTED
;
451 SECKEYPrivateKeyStr
* private_key
= NULL
;
452 PK11SlotInfo
* slot
= PK11_GetInternalSlot();
454 CERT_DestroyCertificate(cert
);
455 return ERR_UNEXPECTED
;
458 SECItem der_private_key_info
;
459 der_private_key_info
.data
=
460 const_cast<unsigned char*>(&key_vector
.front());
461 der_private_key_info
.len
= key_vector
.size();
462 // The server's RSA private key must be imported into NSS with the
463 // following key usage bits:
464 // - KU_KEY_ENCIPHERMENT, required for the RSA key exchange algorithm.
465 // - KU_DIGITAL_SIGNATURE, required for the DHE_RSA and ECDHE_RSA key
466 // exchange algorithms.
467 const unsigned int key_usage
= KU_KEY_ENCIPHERMENT
| KU_DIGITAL_SIGNATURE
;
468 rv
= PK11_ImportDERPrivateKeyInfoAndReturnKey(
469 slot
, &der_private_key_info
, NULL
, NULL
, PR_FALSE
, PR_FALSE
,
470 key_usage
, &private_key
, NULL
);
472 if (rv
!= SECSuccess
) {
473 CERT_DestroyCertificate(cert
);
474 return ERR_UNEXPECTED
;
477 // Assign server certificate and private key.
478 SSLKEAType cert_kea
= NSS_FindCertKEAType(cert
);
479 rv
= SSL_ConfigSecureServer(nss_fd_
, cert
, private_key
, cert_kea
);
480 CERT_DestroyCertificate(cert
);
481 SECKEY_DestroyPrivateKey(private_key
);
483 if (rv
!= SECSuccess
) {
484 PRErrorCode prerr
= PR_GetError();
485 LOG(ERROR
) << "Failed to config SSL server: " << prerr
;
486 LogFailedNSSFunction(net_log_
, "SSL_ConfigureSecureServer", "");
487 return ERR_UNEXPECTED
;
490 // Tell SSL we're a server; needed if not letting NSPR do socket I/O
491 rv
= SSL_ResetHandshake(nss_fd_
, PR_TRUE
);
492 if (rv
!= SECSuccess
) {
493 LogFailedNSSFunction(net_log_
, "SSL_ResetHandshake", "");
494 return ERR_UNEXPECTED
;
500 void SSLServerSocketNSS::OnSendComplete(int result
) {
501 if (next_handshake_state_
== STATE_HANDSHAKE
) {
502 // In handshake phase.
503 OnHandshakeIOComplete(result
);
507 // TODO(byungchul): This state machine is not correct. Copy the state machine
508 // of SSLClientSocketNSS::OnSendComplete() which handles it better.
509 if (!completed_handshake_
)
512 if (user_write_buf_
.get()) {
513 int rv
= DoWriteLoop(result
);
514 if (rv
!= ERR_IO_PENDING
)
517 // Ensure that any queued ciphertext is flushed.
522 void SSLServerSocketNSS::OnRecvComplete(int result
) {
523 if (next_handshake_state_
== STATE_HANDSHAKE
) {
524 // In handshake phase.
525 OnHandshakeIOComplete(result
);
529 // Network layer received some data, check if client requested to read
531 if (!user_read_buf_
.get() || !completed_handshake_
)
534 int rv
= DoReadLoop(result
);
535 if (rv
!= ERR_IO_PENDING
)
539 void SSLServerSocketNSS::OnHandshakeIOComplete(int result
) {
540 int rv
= DoHandshakeLoop(result
);
541 if (rv
== ERR_IO_PENDING
)
544 net_log_
.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE
, rv
);
545 if (!user_handshake_callback_
.is_null())
546 DoHandshakeCallback(rv
);
550 // > 0 for bytes transferred immediately,
551 // < 0 for error (or the non-error ERR_IO_PENDING).
552 int SSLServerSocketNSS::BufferSend(void) {
553 if (transport_send_busy_
)
554 return ERR_IO_PENDING
;
558 unsigned int len1
, len2
;
559 if (memio_GetWriteParams(nss_bufs_
, &buf1
, &len1
, &buf2
, &len2
)) {
560 // The error code itself is ignored, so just return ERR_ABORTED.
563 const size_t len
= len1
+ len2
;
567 scoped_refptr
<IOBuffer
> send_buffer(new IOBuffer(len
));
568 memcpy(send_buffer
->data(), buf1
, len1
);
569 memcpy(send_buffer
->data() + len1
, buf2
, len2
);
570 rv
= transport_socket_
->Write(
573 base::Bind(&SSLServerSocketNSS::BufferSendComplete
,
574 base::Unretained(this)));
575 if (rv
== ERR_IO_PENDING
) {
576 transport_send_busy_
= true;
578 memio_PutWriteResult(nss_bufs_
, MapErrorToNSS(rv
));
585 void SSLServerSocketNSS::BufferSendComplete(int result
) {
586 memio_PutWriteResult(nss_bufs_
, MapErrorToNSS(result
));
587 transport_send_busy_
= false;
588 OnSendComplete(result
);
591 int SSLServerSocketNSS::BufferRecv(void) {
592 if (transport_recv_busy_
) return ERR_IO_PENDING
;
595 int nb
= memio_GetReadParams(nss_bufs_
, &buf
);
598 // buffer too full to read into, so no I/O possible at moment
601 recv_buffer_
= new IOBuffer(nb
);
602 rv
= transport_socket_
->Read(
605 base::Bind(&SSLServerSocketNSS::BufferRecvComplete
,
606 base::Unretained(this)));
607 if (rv
== ERR_IO_PENDING
) {
608 transport_recv_busy_
= true;
611 memcpy(buf
, recv_buffer_
->data(), rv
);
612 memio_PutReadResult(nss_bufs_
, MapErrorToNSS(rv
));
619 void SSLServerSocketNSS::BufferRecvComplete(int result
) {
622 memio_GetReadParams(nss_bufs_
, &buf
);
623 memcpy(buf
, recv_buffer_
->data(), result
);
626 memio_PutReadResult(nss_bufs_
, MapErrorToNSS(result
));
627 transport_recv_busy_
= false;
628 OnRecvComplete(result
);
631 // Do as much network I/O as possible between the buffer and the
632 // transport socket. Return true if some I/O performed, false
633 // otherwise (error or ERR_IO_PENDING).
634 bool SSLServerSocketNSS::DoTransportIO() {
635 bool network_moved
= false;
636 if (nss_bufs_
!= NULL
) {
638 // Read and write as much data as we can. The loop is neccessary
639 // because Write() may return synchronously.
643 network_moved
= true;
645 if (BufferRecv() >= 0)
646 network_moved
= true;
648 return network_moved
;
651 int SSLServerSocketNSS::DoPayloadRead() {
652 DCHECK(user_read_buf_
.get());
653 DCHECK_GT(user_read_buf_len_
, 0);
654 int rv
= PR_Read(nss_fd_
, user_read_buf_
->data(), user_read_buf_len_
);
657 PRErrorCode prerr
= PR_GetError();
658 if (prerr
== PR_WOULD_BLOCK_ERROR
) {
659 return ERR_IO_PENDING
;
661 rv
= MapNSSError(prerr
);
662 net_log_
.AddEvent(NetLog::TYPE_SSL_READ_ERROR
,
663 CreateNetLogSSLErrorCallback(rv
, prerr
));
667 int SSLServerSocketNSS::DoPayloadWrite() {
668 DCHECK(user_write_buf_
.get());
669 int rv
= PR_Write(nss_fd_
, user_write_buf_
->data(), user_write_buf_len_
);
672 PRErrorCode prerr
= PR_GetError();
673 if (prerr
== PR_WOULD_BLOCK_ERROR
) {
674 return ERR_IO_PENDING
;
676 rv
= MapNSSError(prerr
);
677 net_log_
.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR
,
678 CreateNetLogSSLErrorCallback(rv
, prerr
));
682 int SSLServerSocketNSS::DoHandshakeLoop(int last_io_result
) {
683 int rv
= last_io_result
;
685 // Default to STATE_NONE for next state.
686 // (This is a quirk carried over from the windows
687 // implementation. It makes reading the logs a bit harder.)
688 // State handlers can and often do call GotoState just
689 // to stay in the current state.
690 State state
= next_handshake_state_
;
691 GotoState(STATE_NONE
);
693 case STATE_HANDSHAKE
:
699 LOG(DFATAL
) << "unexpected state " << state
;
703 // Do the actual network I/O
704 bool network_moved
= DoTransportIO();
705 if (network_moved
&& next_handshake_state_
== STATE_HANDSHAKE
) {
706 // In general we exit the loop if rv is ERR_IO_PENDING. In this
707 // special case we keep looping even if rv is ERR_IO_PENDING because
708 // the transport IO may allow DoHandshake to make progress.
709 rv
= OK
; // This causes us to stay in the loop.
711 } while (rv
!= ERR_IO_PENDING
&& next_handshake_state_
!= STATE_NONE
);
715 int SSLServerSocketNSS::DoReadLoop(int result
) {
716 DCHECK(completed_handshake_
);
717 DCHECK(next_handshake_state_
== STATE_NONE
);
723 LOG(DFATAL
) << "!nss_bufs_";
724 int rv
= ERR_UNEXPECTED
;
725 net_log_
.AddEvent(NetLog::TYPE_SSL_READ_ERROR
,
726 CreateNetLogSSLErrorCallback(rv
, 0));
733 rv
= DoPayloadRead();
734 network_moved
= DoTransportIO();
735 } while (rv
== ERR_IO_PENDING
&& network_moved
);
739 int SSLServerSocketNSS::DoWriteLoop(int result
) {
740 DCHECK(completed_handshake_
);
741 DCHECK_EQ(next_handshake_state_
, STATE_NONE
);
747 LOG(DFATAL
) << "!nss_bufs_";
748 int rv
= ERR_UNEXPECTED
;
749 net_log_
.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR
,
750 CreateNetLogSSLErrorCallback(rv
, 0));
757 rv
= DoPayloadWrite();
758 network_moved
= DoTransportIO();
759 } while (rv
== ERR_IO_PENDING
&& network_moved
);
763 int SSLServerSocketNSS::DoHandshake() {
765 SECStatus rv
= SSL_ForceHandshake(nss_fd_
);
767 if (rv
== SECSuccess
) {
768 completed_handshake_
= true;
770 PRErrorCode prerr
= PR_GetError();
771 net_error
= MapNSSError(prerr
);
773 // If not done, stay in this state
774 if (net_error
== ERR_IO_PENDING
) {
775 GotoState(STATE_HANDSHAKE
);
777 LOG(ERROR
) << "handshake failed; NSS error code " << prerr
778 << ", net_error " << net_error
;
779 net_log_
.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR
,
780 CreateNetLogSSLErrorCallback(net_error
, prerr
));
786 void SSLServerSocketNSS::DoHandshakeCallback(int rv
) {
787 DCHECK_NE(rv
, ERR_IO_PENDING
);
788 ResetAndReturn(&user_handshake_callback_
).Run(rv
> OK
? OK
: rv
);
791 void SSLServerSocketNSS::DoReadCallback(int rv
) {
792 DCHECK(rv
!= ERR_IO_PENDING
);
793 DCHECK(!user_read_callback_
.is_null());
795 user_read_buf_
= NULL
;
796 user_read_buf_len_
= 0;
797 ResetAndReturn(&user_read_callback_
).Run(rv
);
800 void SSLServerSocketNSS::DoWriteCallback(int rv
) {
801 DCHECK(rv
!= ERR_IO_PENDING
);
802 DCHECK(!user_write_callback_
.is_null());
804 user_write_buf_
= NULL
;
805 user_write_buf_len_
= 0;
806 ResetAndReturn(&user_write_callback_
).Run(rv
);
810 // NSS calls this if an incoming certificate needs to be verified.
811 // Do nothing but return SECSuccess.
812 // This is called only in full handshake mode.
813 // Peer certificate is retrieved in HandshakeCallback() later, which is called
814 // in full handshake mode or in resumption handshake mode.
815 SECStatus
SSLServerSocketNSS::OwnAuthCertHandler(void* arg
,
819 // TODO(hclam): Implement.
820 // Tell NSS to not verify the certificate.
825 // NSS calls this when handshake is completed.
826 // After the SSL handshake is finished we need to verify the certificate.
827 void SSLServerSocketNSS::HandshakeCallback(PRFileDesc
* socket
,
829 // TODO(hclam): Implement.
832 int SSLServerSocketNSS::Init() {
833 // Initialize the NSS SSL library in a threadsafe way. This also
834 // initializes the NSS base library.
836 if (!NSS_IsInitialized())
837 return ERR_UNEXPECTED
;
839 EnableSSLServerSockets();