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. 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/callback_helpers.h" 33 #include "base/lazy_instance.h" 34 #include "base/memory/ref_counted.h" 35 #include "crypto/rsa_private_key.h" 36 #include "crypto/nss_util_internal.h" 37 #include "net/base/io_buffer.h" 38 #include "net/base/net_errors.h" 39 #include "net/base/net_log.h" 40 #include "net/socket/nss_ssl_util.h" 41 #include "net/socket/ssl_error_params.h" 42 43 // SSL plaintext fragments are shorter than 16KB. Although the record layer 44 // overhead is allowed to be 2K + 5 bytes, in practice the overhead is much 45 // smaller than 1KB. So a 17KB buffer should be large enough to hold an 46 // entire SSL record. 47 static const int kRecvBufferSize = 17 * 1024; 48 static const int kSendBufferSize = 17 * 1024; 49 50 #define GotoState(s) next_handshake_state_ = s 51 52 namespace net { 53 54 namespace { 55 56 bool g_nss_server_sockets_init = false; 57 58 class NSSSSLServerInitSingleton { 59 public: 60 NSSSSLServerInitSingleton() { 61 EnsureNSSSSLInit(); 62 63 SSL_ConfigServerSessionIDCache(1024, 5, 5, NULL); 64 g_nss_server_sockets_init = true; 65 } 66 67 ~NSSSSLServerInitSingleton() { 68 SSL_ShutdownServerSessionIDCache(); 69 g_nss_server_sockets_init = false; 70 } 71 }; 72 73 static base::LazyInstance<NSSSSLServerInitSingleton> 74 g_nss_ssl_server_init_singleton = LAZY_INSTANCE_INITIALIZER; 75 76 } // namespace 77 78 void EnableSSLServerSockets() { 79 g_nss_ssl_server_init_singleton.Get(); 80 } 81 82 scoped_ptr<SSLServerSocket> CreateSSLServerSocket( 83 scoped_ptr<StreamSocket> socket, 84 X509Certificate* cert, 85 crypto::RSAPrivateKey* key, 86 const SSLConfig& ssl_config) { 87 DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been" 88 << "called yet!"; 89 90 return scoped_ptr<SSLServerSocket>( 91 new SSLServerSocketNSS(socket.Pass(), cert, key, ssl_config)); 92 } 93 94 SSLServerSocketNSS::SSLServerSocketNSS( 95 scoped_ptr<StreamSocket> transport_socket, 96 scoped_refptr<X509Certificate> cert, 97 crypto::RSAPrivateKey* key, 98 const SSLConfig& ssl_config) 99 : transport_send_busy_(false), 100 transport_recv_busy_(false), 101 user_read_buf_len_(0), 102 user_write_buf_len_(0), 103 nss_fd_(NULL), 104 nss_bufs_(NULL), 105 transport_socket_(transport_socket.Pass()), 106 ssl_config_(ssl_config), 107 cert_(cert), 108 next_handshake_state_(STATE_NONE), 109 completed_handshake_(false) { 110 // TODO(hclam): Need a better way to clone a key. 111 std::vector<uint8> key_bytes; 112 CHECK(key->ExportPrivateKey(&key_bytes)); 113 key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes)); 114 CHECK(key_.get()); 115 } 116 117 SSLServerSocketNSS::~SSLServerSocketNSS() { 118 if (nss_fd_ != NULL) { 119 PR_Close(nss_fd_); 120 nss_fd_ = NULL; 121 } 122 } 123 124 int SSLServerSocketNSS::Handshake(const CompletionCallback& callback) { 125 net_log_.BeginEvent(NetLog::TYPE_SSL_SERVER_HANDSHAKE); 126 127 int rv = Init(); 128 if (rv != OK) { 129 LOG(ERROR) << "Failed to initialize NSS"; 130 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv); 131 return rv; 132 } 133 134 rv = InitializeSSLOptions(); 135 if (rv != OK) { 136 LOG(ERROR) << "Failed to initialize SSL options"; 137 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv); 138 return rv; 139 } 140 141 // Set peer address. TODO(hclam): This should be in a separate method. 142 PRNetAddr peername; 143 memset(&peername, 0, sizeof(peername)); 144 peername.raw.family = AF_INET; 145 memio_SetPeerName(nss_fd_, &peername); 146 147 GotoState(STATE_HANDSHAKE); 148 rv = DoHandshakeLoop(OK); 149 if (rv == ERR_IO_PENDING) { 150 user_handshake_callback_ = callback; 151 } else { 152 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv); 153 } 154 155 return rv > OK ? OK : rv; 156 } 157 158 int SSLServerSocketNSS::ExportKeyingMaterial(const base::StringPiece& label, 159 bool has_context, 160 const base::StringPiece& context, 161 unsigned char* out, 162 unsigned int outlen) { 163 if (!IsConnected()) 164 return ERR_SOCKET_NOT_CONNECTED; 165 SECStatus result = SSL_ExportKeyingMaterial( 166 nss_fd_, label.data(), label.size(), has_context, 167 reinterpret_cast<const unsigned char*>(context.data()), 168 context.length(), out, outlen); 169 if (result != SECSuccess) { 170 LogFailedNSSFunction(net_log_, "SSL_ExportKeyingMaterial", ""); 171 return MapNSSError(PORT_GetError()); 172 } 173 return OK; 174 } 175 176 int SSLServerSocketNSS::GetTLSUniqueChannelBinding(std::string* out) { 177 if (!IsConnected()) 178 return ERR_SOCKET_NOT_CONNECTED; 179 unsigned char buf[64]; 180 unsigned int len; 181 SECStatus result = SSL_GetChannelBinding(nss_fd_, 182 SSL_CHANNEL_BINDING_TLS_UNIQUE, 183 buf, &len, arraysize(buf)); 184 if (result != SECSuccess) { 185 LogFailedNSSFunction(net_log_, "SSL_GetChannelBinding", ""); 186 return MapNSSError(PORT_GetError()); 187 } 188 out->assign(reinterpret_cast<char*>(buf), len); 189 return OK; 190 } 191 192 int SSLServerSocketNSS::Connect(const CompletionCallback& callback) { 193 NOTIMPLEMENTED(); 194 return ERR_NOT_IMPLEMENTED; 195 } 196 197 int SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len, 198 const CompletionCallback& callback) { 199 DCHECK(user_read_callback_.is_null()); 200 DCHECK(user_handshake_callback_.is_null()); 201 DCHECK(!user_read_buf_.get()); 202 DCHECK(nss_bufs_); 203 DCHECK(!callback.is_null()); 204 205 user_read_buf_ = buf; 206 user_read_buf_len_ = buf_len; 207 208 DCHECK(completed_handshake_); 209 210 int rv = DoReadLoop(OK); 211 212 if (rv == ERR_IO_PENDING) { 213 user_read_callback_ = callback; 214 } else { 215 user_read_buf_ = NULL; 216 user_read_buf_len_ = 0; 217 } 218 return rv; 219 } 220 221 int SSLServerSocketNSS::Write(IOBuffer* buf, int buf_len, 222 const CompletionCallback& callback) { 223 DCHECK(user_write_callback_.is_null()); 224 DCHECK(!user_write_buf_.get()); 225 DCHECK(nss_bufs_); 226 DCHECK(!callback.is_null()); 227 228 user_write_buf_ = buf; 229 user_write_buf_len_ = buf_len; 230 231 int rv = DoWriteLoop(OK); 232 233 if (rv == ERR_IO_PENDING) { 234 user_write_callback_ = callback; 235 } else { 236 user_write_buf_ = NULL; 237 user_write_buf_len_ = 0; 238 } 239 return rv; 240 } 241 242 int SSLServerSocketNSS::SetReceiveBufferSize(int32 size) { 243 return transport_socket_->SetReceiveBufferSize(size); 244 } 245 246 int SSLServerSocketNSS::SetSendBufferSize(int32 size) { 247 return transport_socket_->SetSendBufferSize(size); 248 } 249 250 bool SSLServerSocketNSS::IsConnected() const { 251 // TODO(wtc): Find out if we should check transport_socket_->IsConnected() 252 // as well. 253 return completed_handshake_; 254 } 255 256 void SSLServerSocketNSS::Disconnect() { 257 transport_socket_->Disconnect(); 258 } 259 260 bool SSLServerSocketNSS::IsConnectedAndIdle() const { 261 return completed_handshake_ && transport_socket_->IsConnectedAndIdle(); 262 } 263 264 int SSLServerSocketNSS::GetPeerAddress(IPEndPoint* address) const { 265 if (!IsConnected()) 266 return ERR_SOCKET_NOT_CONNECTED; 267 return transport_socket_->GetPeerAddress(address); 268 } 269 270 int SSLServerSocketNSS::GetLocalAddress(IPEndPoint* address) const { 271 if (!IsConnected()) 272 return ERR_SOCKET_NOT_CONNECTED; 273 return transport_socket_->GetLocalAddress(address); 274 } 275 276 const BoundNetLog& SSLServerSocketNSS::NetLog() const { 277 return net_log_; 278 } 279 280 void SSLServerSocketNSS::SetSubresourceSpeculation() { 281 transport_socket_->SetSubresourceSpeculation(); 282 } 283 284 void SSLServerSocketNSS::SetOmniboxSpeculation() { 285 transport_socket_->SetOmniboxSpeculation(); 286 } 287 288 bool SSLServerSocketNSS::WasEverUsed() const { 289 return transport_socket_->WasEverUsed(); 290 } 291 292 bool SSLServerSocketNSS::UsingTCPFastOpen() const { 293 return transport_socket_->UsingTCPFastOpen(); 294 } 295 296 bool SSLServerSocketNSS::WasNpnNegotiated() const { 297 NOTIMPLEMENTED(); 298 return false; 299 } 300 301 NextProto SSLServerSocketNSS::GetNegotiatedProtocol() const { 302 // NPN is not supported by this class. 303 return kProtoUnknown; 304 } 305 306 bool SSLServerSocketNSS::GetSSLInfo(SSLInfo* ssl_info) { 307 NOTIMPLEMENTED(); 308 return false; 309 } 310 311 int SSLServerSocketNSS::InitializeSSLOptions() { 312 // Transport connected, now hook it up to nss 313 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize, kSendBufferSize); 314 if (nss_fd_ == NULL) { 315 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code. 316 } 317 318 // Grab pointer to buffers 319 nss_bufs_ = memio_GetSecret(nss_fd_); 320 321 /* Create SSL state machine */ 322 /* Push SSL onto our fake I/O socket */ 323 nss_fd_ = SSL_ImportFD(NULL, nss_fd_); 324 if (nss_fd_ == NULL) { 325 LogFailedNSSFunction(net_log_, "SSL_ImportFD", ""); 326 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR/NSS error code. 327 } 328 // TODO(port): set more ssl options! Check errors! 329 330 int rv; 331 332 rv = SSL_OptionSet(nss_fd_, SSL_SECURITY, PR_TRUE); 333 if (rv != SECSuccess) { 334 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_SECURITY"); 335 return ERR_UNEXPECTED; 336 } 337 338 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SSL2, PR_FALSE); 339 if (rv != SECSuccess) { 340 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_ENABLE_SSL2"); 341 return ERR_UNEXPECTED; 342 } 343 344 SSLVersionRange version_range; 345 version_range.min = ssl_config_.version_min; 346 version_range.max = ssl_config_.version_max; 347 rv = SSL_VersionRangeSet(nss_fd_, &version_range); 348 if (rv != SECSuccess) { 349 LogFailedNSSFunction(net_log_, "SSL_VersionRangeSet", ""); 350 return ERR_NO_SSL_VERSIONS_ENABLED; 351 } 352 353 if (ssl_config_.require_forward_secrecy) { 354 const PRUint16* const ssl_ciphers = SSL_GetImplementedCiphers(); 355 const PRUint16 num_ciphers = SSL_GetNumImplementedCiphers(); 356 357 // Require forward security by iterating over the cipher suites and 358 // disabling all those that don't use ECDHE. 359 for (unsigned i = 0; i < num_ciphers; i++) { 360 SSLCipherSuiteInfo info; 361 if (SSL_GetCipherSuiteInfo(ssl_ciphers[i], &info, sizeof(info)) == 362 SECSuccess) { 363 if (strcmp(info.keaTypeName, "ECDHE") != 0) { 364 SSL_CipherPrefSet(nss_fd_, ssl_ciphers[i], PR_FALSE); 365 } 366 } 367 } 368 } 369 370 for (std::vector<uint16>::const_iterator it = 371 ssl_config_.disabled_cipher_suites.begin(); 372 it != ssl_config_.disabled_cipher_suites.end(); ++it) { 373 // This will fail if the specified cipher is not implemented by NSS, but 374 // the failure is harmless. 375 SSL_CipherPrefSet(nss_fd_, *it, PR_FALSE); 376 } 377 378 // Server socket doesn't need session tickets. 379 rv = SSL_OptionSet(nss_fd_, SSL_ENABLE_SESSION_TICKETS, PR_FALSE); 380 if (rv != SECSuccess) { 381 LogFailedNSSFunction( 382 net_log_, "SSL_OptionSet", "SSL_ENABLE_SESSION_TICKETS"); 383 } 384 385 // Doing this will force PR_Accept perform handshake as server. 386 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_CLIENT, PR_FALSE); 387 if (rv != SECSuccess) { 388 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_CLIENT"); 389 return ERR_UNEXPECTED; 390 } 391 392 rv = SSL_OptionSet(nss_fd_, SSL_HANDSHAKE_AS_SERVER, PR_TRUE); 393 if (rv != SECSuccess) { 394 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_HANDSHAKE_AS_SERVER"); 395 return ERR_UNEXPECTED; 396 } 397 398 rv = SSL_OptionSet(nss_fd_, SSL_REQUEST_CERTIFICATE, PR_FALSE); 399 if (rv != SECSuccess) { 400 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUEST_CERTIFICATE"); 401 return ERR_UNEXPECTED; 402 } 403 404 rv = SSL_OptionSet(nss_fd_, SSL_REQUIRE_CERTIFICATE, PR_FALSE); 405 if (rv != SECSuccess) { 406 LogFailedNSSFunction(net_log_, "SSL_OptionSet", "SSL_REQUIRE_CERTIFICATE"); 407 return ERR_UNEXPECTED; 408 } 409 410 rv = SSL_AuthCertificateHook(nss_fd_, OwnAuthCertHandler, this); 411 if (rv != SECSuccess) { 412 LogFailedNSSFunction(net_log_, "SSL_AuthCertificateHook", ""); 413 return ERR_UNEXPECTED; 414 } 415 416 rv = SSL_HandshakeCallback(nss_fd_, HandshakeCallback, this); 417 if (rv != SECSuccess) { 418 LogFailedNSSFunction(net_log_, "SSL_HandshakeCallback", ""); 419 return ERR_UNEXPECTED; 420 } 421 422 // Get a certificate of CERTCertificate structure. 423 std::string der_string; 424 if (!X509Certificate::GetDEREncoded(cert_->os_cert_handle(), &der_string)) 425 return ERR_UNEXPECTED; 426 427 SECItem der_cert; 428 der_cert.data = reinterpret_cast<unsigned char*>(const_cast<char*>( 429 der_string.data())); 430 der_cert.len = der_string.length(); 431 der_cert.type = siDERCertBuffer; 432 433 // Parse into a CERTCertificate structure. 434 CERTCertificate* cert = CERT_NewTempCertificate( 435 CERT_GetDefaultCertDB(), &der_cert, NULL, PR_FALSE, PR_TRUE); 436 if (!cert) { 437 LogFailedNSSFunction(net_log_, "CERT_NewTempCertificate", ""); 438 return MapNSSError(PORT_GetError()); 439 } 440 441 // Get a key of SECKEYPrivateKey* structure. 442 std::vector<uint8> key_vector; 443 if (!key_->ExportPrivateKey(&key_vector)) { 444 CERT_DestroyCertificate(cert); 445 return ERR_UNEXPECTED; 446 } 447 448 SECKEYPrivateKeyStr* private_key = NULL; 449 PK11SlotInfo* slot = crypto::GetPrivateNSSKeySlot(); 450 if (!slot) { 451 CERT_DestroyCertificate(cert); 452 return ERR_UNEXPECTED; 453 } 454 455 SECItem der_private_key_info; 456 der_private_key_info.data = 457 const_cast<unsigned char*>(&key_vector.front()); 458 der_private_key_info.len = key_vector.size(); 459 // The server's RSA private key must be imported into NSS with the 460 // following key usage bits: 461 // - KU_KEY_ENCIPHERMENT, required for the RSA key exchange algorithm. 462 // - KU_DIGITAL_SIGNATURE, required for the DHE_RSA and ECDHE_RSA key 463 // exchange algorithms. 464 const unsigned int key_usage = KU_KEY_ENCIPHERMENT | KU_DIGITAL_SIGNATURE; 465 rv = PK11_ImportDERPrivateKeyInfoAndReturnKey( 466 slot, &der_private_key_info, NULL, NULL, PR_FALSE, PR_FALSE, 467 key_usage, &private_key, NULL); 468 PK11_FreeSlot(slot); 469 if (rv != SECSuccess) { 470 CERT_DestroyCertificate(cert); 471 return ERR_UNEXPECTED; 472 } 473 474 // Assign server certificate and private key. 475 SSLKEAType cert_kea = NSS_FindCertKEAType(cert); 476 rv = SSL_ConfigSecureServer(nss_fd_, cert, private_key, cert_kea); 477 CERT_DestroyCertificate(cert); 478 SECKEY_DestroyPrivateKey(private_key); 479 480 if (rv != SECSuccess) { 481 PRErrorCode prerr = PR_GetError(); 482 LOG(ERROR) << "Failed to config SSL server: " << prerr; 483 LogFailedNSSFunction(net_log_, "SSL_ConfigureSecureServer", ""); 484 return ERR_UNEXPECTED; 485 } 486 487 // Tell SSL we're a server; needed if not letting NSPR do socket I/O 488 rv = SSL_ResetHandshake(nss_fd_, PR_TRUE); 489 if (rv != SECSuccess) { 490 LogFailedNSSFunction(net_log_, "SSL_ResetHandshake", ""); 491 return ERR_UNEXPECTED; 492 } 493 494 return OK; 495 } 496 497 void SSLServerSocketNSS::OnSendComplete(int result) { 498 if (next_handshake_state_ == STATE_HANDSHAKE) { 499 // In handshake phase. 500 OnHandshakeIOComplete(result); 501 return; 502 } 503 504 // TODO(byungchul): This state machine is not correct. Copy the state machine 505 // of SSLClientSocketNSS::OnSendComplete() which handles it better. 506 if (!completed_handshake_) 507 return; 508 509 if (user_write_buf_.get()) { 510 int rv = DoWriteLoop(result); 511 if (rv != ERR_IO_PENDING) 512 DoWriteCallback(rv); 513 } else { 514 // Ensure that any queued ciphertext is flushed. 515 DoTransportIO(); 516 } 517 } 518 519 void SSLServerSocketNSS::OnRecvComplete(int result) { 520 if (next_handshake_state_ == STATE_HANDSHAKE) { 521 // In handshake phase. 522 OnHandshakeIOComplete(result); 523 return; 524 } 525 526 // Network layer received some data, check if client requested to read 527 // decrypted data. 528 if (!user_read_buf_.get() || !completed_handshake_) 529 return; 530 531 int rv = DoReadLoop(result); 532 if (rv != ERR_IO_PENDING) 533 DoReadCallback(rv); 534 } 535 536 void SSLServerSocketNSS::OnHandshakeIOComplete(int result) { 537 int rv = DoHandshakeLoop(result); 538 if (rv == ERR_IO_PENDING) 539 return; 540 541 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_SERVER_HANDSHAKE, rv); 542 if (!user_handshake_callback_.is_null()) 543 DoHandshakeCallback(rv); 544 } 545 546 // Return 0 for EOF, 547 // > 0 for bytes transferred immediately, 548 // < 0 for error (or the non-error ERR_IO_PENDING). 549 int SSLServerSocketNSS::BufferSend(void) { 550 if (transport_send_busy_) 551 return ERR_IO_PENDING; 552 553 const char* buf1; 554 const char* buf2; 555 unsigned int len1, len2; 556 if (memio_GetWriteParams(nss_bufs_, &buf1, &len1, &buf2, &len2)) { 557 // The error code itself is ignored, so just return ERR_ABORTED. 558 return ERR_ABORTED; 559 } 560 const unsigned int len = len1 + len2; 561 562 int rv = 0; 563 if (len) { 564 scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len)); 565 memcpy(send_buffer->data(), buf1, len1); 566 memcpy(send_buffer->data() + len1, buf2, len2); 567 rv = transport_socket_->Write( 568 send_buffer.get(), 569 len, 570 base::Bind(&SSLServerSocketNSS::BufferSendComplete, 571 base::Unretained(this))); 572 if (rv == ERR_IO_PENDING) { 573 transport_send_busy_ = true; 574 } else { 575 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv)); 576 } 577 } 578 579 return rv; 580 } 581 582 void SSLServerSocketNSS::BufferSendComplete(int result) { 583 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(result)); 584 transport_send_busy_ = false; 585 OnSendComplete(result); 586 } 587 588 int SSLServerSocketNSS::BufferRecv(void) { 589 if (transport_recv_busy_) return ERR_IO_PENDING; 590 591 char* buf; 592 int nb = memio_GetReadParams(nss_bufs_, &buf); 593 int rv; 594 if (!nb) { 595 // buffer too full to read into, so no I/O possible at moment 596 rv = ERR_IO_PENDING; 597 } else { 598 recv_buffer_ = new IOBuffer(nb); 599 rv = transport_socket_->Read( 600 recv_buffer_.get(), 601 nb, 602 base::Bind(&SSLServerSocketNSS::BufferRecvComplete, 603 base::Unretained(this))); 604 if (rv == ERR_IO_PENDING) { 605 transport_recv_busy_ = true; 606 } else { 607 if (rv > 0) 608 memcpy(buf, recv_buffer_->data(), rv); 609 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv)); 610 recv_buffer_ = NULL; 611 } 612 } 613 return rv; 614 } 615 616 void SSLServerSocketNSS::BufferRecvComplete(int result) { 617 if (result > 0) { 618 char* buf; 619 memio_GetReadParams(nss_bufs_, &buf); 620 memcpy(buf, recv_buffer_->data(), result); 621 } 622 recv_buffer_ = NULL; 623 memio_PutReadResult(nss_bufs_, MapErrorToNSS(result)); 624 transport_recv_busy_ = false; 625 OnRecvComplete(result); 626 } 627 628 // Do as much network I/O as possible between the buffer and the 629 // transport socket. Return true if some I/O performed, false 630 // otherwise (error or ERR_IO_PENDING). 631 bool SSLServerSocketNSS::DoTransportIO() { 632 bool network_moved = false; 633 if (nss_bufs_ != NULL) { 634 int rv; 635 // Read and write as much data as we can. The loop is neccessary 636 // because Write() may return synchronously. 637 do { 638 rv = BufferSend(); 639 if (rv > 0) 640 network_moved = true; 641 } while (rv > 0); 642 if (BufferRecv() >= 0) 643 network_moved = true; 644 } 645 return network_moved; 646 } 647 648 int SSLServerSocketNSS::DoPayloadRead() { 649 DCHECK(user_read_buf_.get()); 650 DCHECK_GT(user_read_buf_len_, 0); 651 int rv = PR_Read(nss_fd_, user_read_buf_->data(), user_read_buf_len_); 652 if (rv >= 0) 653 return rv; 654 PRErrorCode prerr = PR_GetError(); 655 if (prerr == PR_WOULD_BLOCK_ERROR) { 656 return ERR_IO_PENDING; 657 } 658 rv = MapNSSError(prerr); 659 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR, 660 CreateNetLogSSLErrorCallback(rv, prerr)); 661 return rv; 662 } 663 664 int SSLServerSocketNSS::DoPayloadWrite() { 665 DCHECK(user_write_buf_.get()); 666 int rv = PR_Write(nss_fd_, user_write_buf_->data(), user_write_buf_len_); 667 if (rv >= 0) 668 return rv; 669 PRErrorCode prerr = PR_GetError(); 670 if (prerr == PR_WOULD_BLOCK_ERROR) { 671 return ERR_IO_PENDING; 672 } 673 rv = MapNSSError(prerr); 674 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR, 675 CreateNetLogSSLErrorCallback(rv, prerr)); 676 return rv; 677 } 678 679 int SSLServerSocketNSS::DoHandshakeLoop(int last_io_result) { 680 int rv = last_io_result; 681 do { 682 // Default to STATE_NONE for next state. 683 // (This is a quirk carried over from the windows 684 // implementation. It makes reading the logs a bit harder.) 685 // State handlers can and often do call GotoState just 686 // to stay in the current state. 687 State state = next_handshake_state_; 688 GotoState(STATE_NONE); 689 switch (state) { 690 case STATE_HANDSHAKE: 691 rv = DoHandshake(); 692 break; 693 case STATE_NONE: 694 default: 695 rv = ERR_UNEXPECTED; 696 LOG(DFATAL) << "unexpected state " << state; 697 break; 698 } 699 700 // Do the actual network I/O 701 bool network_moved = DoTransportIO(); 702 if (network_moved && next_handshake_state_ == STATE_HANDSHAKE) { 703 // In general we exit the loop if rv is ERR_IO_PENDING. In this 704 // special case we keep looping even if rv is ERR_IO_PENDING because 705 // the transport IO may allow DoHandshake to make progress. 706 rv = OK; // This causes us to stay in the loop. 707 } 708 } while (rv != ERR_IO_PENDING && next_handshake_state_ != STATE_NONE); 709 return rv; 710 } 711 712 int SSLServerSocketNSS::DoReadLoop(int result) { 713 DCHECK(completed_handshake_); 714 DCHECK(next_handshake_state_ == STATE_NONE); 715 716 if (result < 0) 717 return result; 718 719 if (!nss_bufs_) { 720 LOG(DFATAL) << "!nss_bufs_"; 721 int rv = ERR_UNEXPECTED; 722 net_log_.AddEvent(NetLog::TYPE_SSL_READ_ERROR, 723 CreateNetLogSSLErrorCallback(rv, 0)); 724 return rv; 725 } 726 727 bool network_moved; 728 int rv; 729 do { 730 rv = DoPayloadRead(); 731 network_moved = DoTransportIO(); 732 } while (rv == ERR_IO_PENDING && network_moved); 733 return rv; 734 } 735 736 int SSLServerSocketNSS::DoWriteLoop(int result) { 737 DCHECK(completed_handshake_); 738 DCHECK_EQ(next_handshake_state_, STATE_NONE); 739 740 if (result < 0) 741 return result; 742 743 if (!nss_bufs_) { 744 LOG(DFATAL) << "!nss_bufs_"; 745 int rv = ERR_UNEXPECTED; 746 net_log_.AddEvent(NetLog::TYPE_SSL_WRITE_ERROR, 747 CreateNetLogSSLErrorCallback(rv, 0)); 748 return rv; 749 } 750 751 bool network_moved; 752 int rv; 753 do { 754 rv = DoPayloadWrite(); 755 network_moved = DoTransportIO(); 756 } while (rv == ERR_IO_PENDING && network_moved); 757 return rv; 758 } 759 760 int SSLServerSocketNSS::DoHandshake() { 761 int net_error = OK; 762 SECStatus rv = SSL_ForceHandshake(nss_fd_); 763 764 if (rv == SECSuccess) { 765 completed_handshake_ = true; 766 } else { 767 PRErrorCode prerr = PR_GetError(); 768 net_error = MapNSSError(prerr); 769 770 // If not done, stay in this state 771 if (net_error == ERR_IO_PENDING) { 772 GotoState(STATE_HANDSHAKE); 773 } else { 774 LOG(ERROR) << "handshake failed; NSS error code " << prerr 775 << ", net_error " << net_error; 776 net_log_.AddEvent(NetLog::TYPE_SSL_HANDSHAKE_ERROR, 777 CreateNetLogSSLErrorCallback(net_error, prerr)); 778 } 779 } 780 return net_error; 781 } 782 783 void SSLServerSocketNSS::DoHandshakeCallback(int rv) { 784 DCHECK_NE(rv, ERR_IO_PENDING); 785 ResetAndReturn(&user_handshake_callback_).Run(rv > OK ? OK : rv); 786 } 787 788 void SSLServerSocketNSS::DoReadCallback(int rv) { 789 DCHECK(rv != ERR_IO_PENDING); 790 DCHECK(!user_read_callback_.is_null()); 791 792 user_read_buf_ = NULL; 793 user_read_buf_len_ = 0; 794 ResetAndReturn(&user_read_callback_).Run(rv); 795 } 796 797 void SSLServerSocketNSS::DoWriteCallback(int rv) { 798 DCHECK(rv != ERR_IO_PENDING); 799 DCHECK(!user_write_callback_.is_null()); 800 801 user_write_buf_ = NULL; 802 user_write_buf_len_ = 0; 803 ResetAndReturn(&user_write_callback_).Run(rv); 804 } 805 806 // static 807 // NSS calls this if an incoming certificate needs to be verified. 808 // Do nothing but return SECSuccess. 809 // This is called only in full handshake mode. 810 // Peer certificate is retrieved in HandshakeCallback() later, which is called 811 // in full handshake mode or in resumption handshake mode. 812 SECStatus SSLServerSocketNSS::OwnAuthCertHandler(void* arg, 813 PRFileDesc* socket, 814 PRBool checksig, 815 PRBool is_server) { 816 // TODO(hclam): Implement. 817 // Tell NSS to not verify the certificate. 818 return SECSuccess; 819 } 820 821 // static 822 // NSS calls this when handshake is completed. 823 // After the SSL handshake is finished we need to verify the certificate. 824 void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, 825 void* arg) { 826 // TODO(hclam): Implement. 827 } 828 829 int SSLServerSocketNSS::Init() { 830 // Initialize the NSS SSL library in a threadsafe way. This also 831 // initializes the NSS base library. 832 EnsureNSSSSLInit(); 833 if (!NSS_IsInitialized()) 834 return ERR_UNEXPECTED; 835 836 EnableSSLServerSockets(); 837 return OK; 838 } 839 840 } // namespace net 841