Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/socket/ssl_server_socket_nss.h" | 5 #include "net/socket/ssl_server_socket_nss.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <winsock2.h> | 8 #include <winsock2.h> |
| 9 #endif | 9 #endif |
| 10 | 10 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 39 #include "net/socket/nss_ssl_util.h" | 39 #include "net/socket/nss_ssl_util.h" |
| 40 #include "net/socket/ssl_error_params.h" | 40 #include "net/socket/ssl_error_params.h" |
| 41 | 41 |
| 42 static const int kRecvBufferSize = 4096; | 42 static const int kRecvBufferSize = 4096; |
| 43 | 43 |
| 44 #define GotoState(s) next_handshake_state_ = s | 44 #define GotoState(s) next_handshake_state_ = s |
| 45 | 45 |
| 46 namespace net { | 46 namespace net { |
| 47 | 47 |
| 48 SSLServerSocket* CreateSSLServerSocket( | 48 SSLServerSocket* CreateSSLServerSocket( |
| 49 Socket* socket, X509Certificate* cert, crypto::RSAPrivateKey* key, | 49 StreamSocket* socket, |
| 50 X509Certificate* cert, | |
| 51 crypto::RSAPrivateKey* key, | |
| 50 const SSLConfig& ssl_config) { | 52 const SSLConfig& ssl_config) { |
| 51 return new SSLServerSocketNSS(socket, cert, key, ssl_config); | 53 return new SSLServerSocketNSS(socket, cert, key, ssl_config); |
| 52 } | 54 } |
| 53 | 55 |
| 54 SSLServerSocketNSS::SSLServerSocketNSS( | 56 SSLServerSocketNSS::SSLServerSocketNSS( |
| 55 Socket* transport_socket, | 57 StreamSocket* transport_socket, |
| 56 scoped_refptr<X509Certificate> cert, | 58 scoped_refptr<X509Certificate> cert, |
| 57 crypto::RSAPrivateKey* key, | 59 crypto::RSAPrivateKey* key, |
| 58 const SSLConfig& ssl_config) | 60 const SSLConfig& ssl_config) |
| 59 : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_( | 61 : ALLOW_THIS_IN_INITIALIZER_LIST(buffer_send_callback_( |
| 60 this, &SSLServerSocketNSS::BufferSendComplete)), | 62 this, &SSLServerSocketNSS::BufferSendComplete)), |
| 61 ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_( | 63 ALLOW_THIS_IN_INITIALIZER_LIST(buffer_recv_callback_( |
| 62 this, &SSLServerSocketNSS::BufferRecvComplete)), | 64 this, &SSLServerSocketNSS::BufferRecvComplete)), |
| 63 transport_send_busy_(false), | 65 transport_send_busy_(false), |
| 64 transport_recv_busy_(false), | 66 transport_recv_busy_(false), |
| 65 user_accept_callback_(NULL), | 67 user_handshake_callback_(NULL), |
| 66 user_read_callback_(NULL), | 68 user_read_callback_(NULL), |
| 67 user_write_callback_(NULL), | 69 user_write_callback_(NULL), |
| 68 nss_fd_(NULL), | 70 nss_fd_(NULL), |
| 69 nss_bufs_(NULL), | 71 nss_bufs_(NULL), |
| 70 transport_socket_(transport_socket), | 72 transport_socket_(transport_socket), |
| 71 ssl_config_(ssl_config), | 73 ssl_config_(ssl_config), |
| 72 cert_(cert), | 74 cert_(cert), |
| 73 next_handshake_state_(STATE_NONE), | 75 next_handshake_state_(STATE_NONE), |
| 74 completed_handshake_(false) { | 76 completed_handshake_(false) { |
| 75 ssl_config_.false_start_enabled = false; | 77 ssl_config_.false_start_enabled = false; |
| 76 ssl_config_.ssl3_enabled = true; | 78 ssl_config_.ssl3_enabled = true; |
| 77 ssl_config_.tls1_enabled = true; | 79 ssl_config_.tls1_enabled = true; |
| 78 | 80 |
| 79 // TODO(hclam): Need a better way to clone a key. | 81 // TODO(hclam): Need a better way to clone a key. |
| 80 std::vector<uint8> key_bytes; | 82 std::vector<uint8> key_bytes; |
| 81 CHECK(key->ExportPrivateKey(&key_bytes)); | 83 CHECK(key->ExportPrivateKey(&key_bytes)); |
| 82 key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes)); | 84 key_.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_bytes)); |
| 83 CHECK(key_.get()); | 85 CHECK(key_.get()); |
| 84 } | 86 } |
| 85 | 87 |
| 86 SSLServerSocketNSS::~SSLServerSocketNSS() { | 88 SSLServerSocketNSS::~SSLServerSocketNSS() { |
| 87 if (nss_fd_ != NULL) { | 89 if (nss_fd_ != NULL) { |
| 88 PR_Close(nss_fd_); | 90 PR_Close(nss_fd_); |
| 89 nss_fd_ = NULL; | 91 nss_fd_ = NULL; |
| 90 } | 92 } |
| 91 } | 93 } |
| 92 | 94 |
| 93 int SSLServerSocketNSS::Accept(CompletionCallback* callback) { | 95 int SSLServerSocketNSS::Handshake(CompletionCallback* callback) { |
| 94 net_log_.BeginEvent(NetLog::TYPE_SSL_ACCEPT, NULL); | 96 net_log_.BeginEvent(NetLog::TYPE_SSL_ACCEPT, NULL); |
|
wtc
2011/06/16 21:35:07
NetLog::TYPE_SSL_ACCEPT probably should be renamed
Wez
2011/06/17 04:53:38
Done.
I've renamed to SSL_SERVER_HANDSHAKE, and u
| |
| 95 | 97 |
| 96 int rv = Init(); | 98 int rv = Init(); |
| 97 if (rv != OK) { | 99 if (rv != OK) { |
| 98 LOG(ERROR) << "Failed to initialize NSS"; | 100 LOG(ERROR) << "Failed to initialize NSS"; |
| 99 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv); | 101 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv); |
| 100 return rv; | 102 return rv; |
| 101 } | 103 } |
| 102 | 104 |
| 103 rv = InitializeSSLOptions(); | 105 rv = InitializeSSLOptions(); |
| 104 if (rv != OK) { | 106 if (rv != OK) { |
| 105 LOG(ERROR) << "Failed to initialize SSL options"; | 107 LOG(ERROR) << "Failed to initialize SSL options"; |
| 106 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv); | 108 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv); |
| 107 return rv; | 109 return rv; |
| 108 } | 110 } |
| 109 | 111 |
| 110 // Set peer address. TODO(hclam): This should be in a separate method. | 112 // Set peer address. TODO(hclam): This should be in a separate method. |
| 111 PRNetAddr peername; | 113 PRNetAddr peername; |
| 112 memset(&peername, 0, sizeof(peername)); | 114 memset(&peername, 0, sizeof(peername)); |
| 113 peername.raw.family = AF_INET; | 115 peername.raw.family = AF_INET; |
| 114 memio_SetPeerName(nss_fd_, &peername); | 116 memio_SetPeerName(nss_fd_, &peername); |
| 115 | 117 |
| 116 GotoState(STATE_HANDSHAKE); | 118 GotoState(STATE_HANDSHAKE); |
| 117 rv = DoHandshakeLoop(net::OK); | 119 rv = DoHandshakeLoop(net::OK); |
| 118 if (rv == ERR_IO_PENDING) { | 120 if (rv == ERR_IO_PENDING) { |
| 119 user_accept_callback_ = callback; | 121 user_handshake_callback_ = callback; |
| 120 } else { | 122 } else { |
| 121 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv); | 123 net_log_.EndEventWithNetErrorCode(NetLog::TYPE_SSL_ACCEPT, rv); |
| 122 } | 124 } |
| 123 | 125 |
| 124 return rv > OK ? OK : rv; | 126 return rv > OK ? OK : rv; |
| 125 } | 127 } |
| 126 | 128 |
| 129 int SSLServerSocketNSS::Connect(CompletionCallback* callback) { | |
| 130 NOTIMPLEMENTED(); | |
| 131 return ERR_NOT_IMPLEMENTED; | |
| 132 } | |
| 133 | |
| 127 int SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len, | 134 int SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len, |
| 128 CompletionCallback* callback) { | 135 CompletionCallback* callback) { |
| 129 DCHECK(!user_read_callback_); | 136 DCHECK(!user_read_callback_); |
| 130 DCHECK(!user_accept_callback_); | 137 DCHECK(!user_handshake_callback_); |
| 131 DCHECK(!user_read_buf_); | 138 DCHECK(!user_read_buf_); |
| 132 DCHECK(nss_bufs_); | 139 DCHECK(nss_bufs_); |
| 133 | 140 |
| 134 user_read_buf_ = buf; | 141 user_read_buf_ = buf; |
| 135 user_read_buf_len_ = buf_len; | 142 user_read_buf_len_ = buf_len; |
| 136 | 143 |
| 137 DCHECK(completed_handshake_); | 144 DCHECK(completed_handshake_); |
| 138 | 145 |
| 139 int rv = DoReadLoop(OK); | 146 int rv = DoReadLoop(OK); |
| 140 | 147 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 161 if (rv == ERR_IO_PENDING) { | 168 if (rv == ERR_IO_PENDING) { |
| 162 user_write_callback_ = callback; | 169 user_write_callback_ = callback; |
| 163 } else { | 170 } else { |
| 164 user_write_buf_ = NULL; | 171 user_write_buf_ = NULL; |
| 165 user_write_buf_len_ = 0; | 172 user_write_buf_len_ = 0; |
| 166 } | 173 } |
| 167 return rv; | 174 return rv; |
| 168 } | 175 } |
| 169 | 176 |
| 170 bool SSLServerSocketNSS::SetReceiveBufferSize(int32 size) { | 177 bool SSLServerSocketNSS::SetReceiveBufferSize(int32 size) { |
| 171 return false; | 178 return transport_socket_->SetReceiveBufferSize(size); |
| 172 } | 179 } |
| 173 | 180 |
| 174 bool SSLServerSocketNSS::SetSendBufferSize(int32 size) { | 181 bool SSLServerSocketNSS::SetSendBufferSize(int32 size) { |
| 175 return false; | 182 return transport_socket_->SetSendBufferSize(size); |
| 183 } | |
| 184 | |
| 185 bool SSLServerSocketNSS::IsConnected() const { | |
| 186 return completed_handshake_; | |
| 187 } | |
| 188 | |
| 189 void SSLServerSocketNSS::Disconnect() { | |
| 190 transport_socket_->Disconnect(); | |
| 191 } | |
| 192 | |
| 193 bool SSLServerSocketNSS::IsConnectedAndIdle() const { | |
| 194 return completed_handshake_ && transport_socket_->IsConnectedAndIdle(); | |
| 195 } | |
| 196 | |
| 197 int SSLServerSocketNSS::GetPeerAddress(AddressList* address) const { | |
| 198 if (!IsConnected()) | |
| 199 return ERR_SOCKET_NOT_CONNECTED; | |
| 200 return transport_socket_->GetPeerAddress(address); | |
| 201 } | |
| 202 | |
| 203 int SSLServerSocketNSS::GetLocalAddress(IPEndPoint* address) const { | |
| 204 if (!IsConnected()) | |
| 205 return ERR_SOCKET_NOT_CONNECTED; | |
| 206 return transport_socket_->GetLocalAddress(address); | |
| 207 } | |
| 208 | |
| 209 const BoundNetLog& SSLServerSocketNSS::NetLog() const { | |
| 210 return net_log_; | |
| 211 } | |
| 212 | |
| 213 void SSLServerSocketNSS::SetSubresourceSpeculation() { | |
| 214 transport_socket_->SetSubresourceSpeculation(); | |
| 215 } | |
| 216 | |
| 217 void SSLServerSocketNSS::SetOmniboxSpeculation() { | |
| 218 transport_socket_->SetOmniboxSpeculation(); | |
| 219 } | |
| 220 | |
| 221 bool SSLServerSocketNSS::WasEverUsed() const { | |
| 222 return transport_socket_->WasEverUsed(); | |
| 223 } | |
| 224 | |
| 225 bool SSLServerSocketNSS::UsingTCPFastOpen() const { | |
| 226 return transport_socket_->UsingTCPFastOpen(); | |
| 176 } | 227 } |
| 177 | 228 |
| 178 int SSLServerSocketNSS::InitializeSSLOptions() { | 229 int SSLServerSocketNSS::InitializeSSLOptions() { |
| 179 // Transport connected, now hook it up to nss | 230 // Transport connected, now hook it up to nss |
| 180 // TODO(port): specify rx and tx buffer sizes separately | 231 // TODO(port): specify rx and tx buffer sizes separately |
| 181 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize); | 232 nss_fd_ = memio_CreateIOLayer(kRecvBufferSize); |
| 182 if (nss_fd_ == NULL) { | 233 if (nss_fd_ == NULL) { |
| 183 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code. | 234 return ERR_OUT_OF_MEMORY; // TODO(port): map NSPR error code. |
| 184 } | 235 } |
| 185 | 236 |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 379 | 430 |
| 380 int rv = DoReadLoop(result); | 431 int rv = DoReadLoop(result); |
| 381 if (rv != ERR_IO_PENDING) | 432 if (rv != ERR_IO_PENDING) |
| 382 DoReadCallback(rv); | 433 DoReadCallback(rv); |
| 383 } | 434 } |
| 384 | 435 |
| 385 void SSLServerSocketNSS::OnHandshakeIOComplete(int result) { | 436 void SSLServerSocketNSS::OnHandshakeIOComplete(int result) { |
| 386 int rv = DoHandshakeLoop(result); | 437 int rv = DoHandshakeLoop(result); |
| 387 if (rv != ERR_IO_PENDING) { | 438 if (rv != ERR_IO_PENDING) { |
| 388 net_log_.EndEventWithNetErrorCode(net::NetLog::TYPE_SSL_ACCEPT, rv); | 439 net_log_.EndEventWithNetErrorCode(net::NetLog::TYPE_SSL_ACCEPT, rv); |
| 389 if (user_accept_callback_) | 440 if (user_handshake_callback_) |
| 390 DoAcceptCallback(rv); | 441 DoHandshakeCallback(rv); |
| 391 } | 442 } |
| 392 } | 443 } |
| 393 | 444 |
| 394 // Return 0 for EOF, | 445 // Return 0 for EOF, |
| 395 // > 0 for bytes transferred immediately, | 446 // > 0 for bytes transferred immediately, |
| 396 // < 0 for error (or the non-error ERR_IO_PENDING). | 447 // < 0 for error (or the non-error ERR_IO_PENDING). |
| 397 int SSLServerSocketNSS::BufferSend(void) { | 448 int SSLServerSocketNSS::BufferSend(void) { |
| 398 if (transport_send_busy_) | 449 if (transport_send_busy_) |
| 399 return ERR_IO_PENDING; | 450 return ERR_IO_PENDING; |
| 400 | 451 |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 602 LOG(ERROR) << "handshake failed; NSS error code " << prerr | 653 LOG(ERROR) << "handshake failed; NSS error code " << prerr |
| 603 << ", net_error " << net_error; | 654 << ", net_error " << net_error; |
| 604 net_log_.AddEvent( | 655 net_log_.AddEvent( |
| 605 NetLog::TYPE_SSL_HANDSHAKE_ERROR, | 656 NetLog::TYPE_SSL_HANDSHAKE_ERROR, |
| 606 make_scoped_refptr(new SSLErrorParams(net_error, prerr))); | 657 make_scoped_refptr(new SSLErrorParams(net_error, prerr))); |
| 607 } | 658 } |
| 608 } | 659 } |
| 609 return net_error; | 660 return net_error; |
| 610 } | 661 } |
| 611 | 662 |
| 612 void SSLServerSocketNSS::DoAcceptCallback(int rv) { | 663 void SSLServerSocketNSS::DoHandshakeCallback(int rv) { |
| 613 DCHECK_NE(rv, ERR_IO_PENDING); | 664 DCHECK_NE(rv, ERR_IO_PENDING); |
| 614 | 665 |
| 615 CompletionCallback* c = user_accept_callback_; | 666 CompletionCallback* c = user_handshake_callback_; |
| 616 user_accept_callback_ = NULL; | 667 user_handshake_callback_ = NULL; |
| 617 c->Run(rv > OK ? OK : rv); | 668 c->Run(rv > OK ? OK : rv); |
| 618 } | 669 } |
| 619 | 670 |
| 620 void SSLServerSocketNSS::DoReadCallback(int rv) { | 671 void SSLServerSocketNSS::DoReadCallback(int rv) { |
| 621 DCHECK(rv != ERR_IO_PENDING); | 672 DCHECK(rv != ERR_IO_PENDING); |
| 622 DCHECK(user_read_callback_); | 673 DCHECK(user_read_callback_); |
| 623 | 674 |
| 624 // Since Run may result in Read being called, clear |user_read_callback_| | 675 // Since Run may result in Read being called, clear |user_read_callback_| |
| 625 // up front. | 676 // up front. |
| 626 CompletionCallback* c = user_read_callback_; | 677 CompletionCallback* c = user_read_callback_; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop | 727 // We must call EnsureOCSPInit() here, on the IO thread, to get the IO loop |
| 677 // by MessageLoopForIO::current(). | 728 // by MessageLoopForIO::current(). |
| 678 // X509Certificate::Verify() runs on a worker thread of CertVerifier. | 729 // X509Certificate::Verify() runs on a worker thread of CertVerifier. |
| 679 EnsureOCSPInit(); | 730 EnsureOCSPInit(); |
| 680 #endif | 731 #endif |
| 681 | 732 |
| 682 return OK; | 733 return OK; |
| 683 } | 734 } |
| 684 | 735 |
| 685 } // namespace net | 736 } // namespace net |
| OLD | NEW |