OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #if defined(OS_WIN) | 9 #if defined(OS_WIN) |
10 #include <winsock2.h> | 10 #include <winsock2.h> |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 | 68 |
69 ~NSSSSLServerInitSingleton() { | 69 ~NSSSSLServerInitSingleton() { |
70 SSL_ShutdownServerSessionIDCache(); | 70 SSL_ShutdownServerSessionIDCache(); |
71 g_nss_server_sockets_init = false; | 71 g_nss_server_sockets_init = false; |
72 } | 72 } |
73 }; | 73 }; |
74 | 74 |
75 static base::LazyInstance<NSSSSLServerInitSingleton>::Leaky | 75 static base::LazyInstance<NSSSSLServerInitSingleton>::Leaky |
76 g_nss_ssl_server_init_singleton = LAZY_INSTANCE_INITIALIZER; | 76 g_nss_ssl_server_init_singleton = LAZY_INSTANCE_INITIALIZER; |
77 | 77 |
78 } // namespace | 78 class SSLServerSocketNSS : public SSLServerSocket { |
| 79 public: |
| 80 // See comments on CreateSSLServerSocket for details of how these |
| 81 // parameters are used. |
| 82 SSLServerSocketNSS(scoped_ptr<StreamSocket> socket, |
| 83 X509Certificate* certificate, |
| 84 const crypto::RSAPrivateKey& key, |
| 85 const SSLServerConfig& ssl_server_config); |
| 86 ~SSLServerSocketNSS() override; |
79 | 87 |
80 void EnableSSLServerSockets() { | 88 // SSLServerSocket interface. |
81 g_nss_ssl_server_init_singleton.Get(); | 89 int Handshake(const CompletionCallback& callback) override; |
82 } | |
83 | 90 |
84 scoped_ptr<SSLServerSocket> CreateSSLServerSocket( | 91 // SSLSocket interface. |
85 scoped_ptr<StreamSocket> socket, | 92 int ExportKeyingMaterial(const base::StringPiece& label, |
86 X509Certificate* certificate, | 93 bool has_context, |
87 const crypto::RSAPrivateKey& key, | 94 const base::StringPiece& context, |
88 const SSLServerConfig& ssl_server_config) { | 95 unsigned char* out, |
89 DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been" | 96 unsigned int outlen) override; |
90 << " called yet!"; | 97 int GetTLSUniqueChannelBinding(std::string* out) override; |
91 | 98 |
92 return scoped_ptr<SSLServerSocket>(new SSLServerSocketNSS( | 99 // Socket interface (via StreamSocket). |
93 std::move(socket), certificate, key, ssl_server_config)); | 100 int Read(IOBuffer* buf, |
94 } | 101 int buf_len, |
| 102 const CompletionCallback& callback) override; |
| 103 int Write(IOBuffer* buf, |
| 104 int buf_len, |
| 105 const CompletionCallback& callback) override; |
| 106 int SetReceiveBufferSize(int32_t size) override; |
| 107 int SetSendBufferSize(int32_t size) override; |
| 108 |
| 109 // StreamSocket implementation. |
| 110 int Connect(const CompletionCallback& callback) override; |
| 111 void Disconnect() override; |
| 112 bool IsConnected() const override; |
| 113 bool IsConnectedAndIdle() const override; |
| 114 int GetPeerAddress(IPEndPoint* address) const override; |
| 115 int GetLocalAddress(IPEndPoint* address) const override; |
| 116 const BoundNetLog& NetLog() const override; |
| 117 void SetSubresourceSpeculation() override; |
| 118 void SetOmniboxSpeculation() override; |
| 119 bool WasEverUsed() const override; |
| 120 bool UsingTCPFastOpen() const override; |
| 121 bool WasNpnNegotiated() const override; |
| 122 NextProto GetNegotiatedProtocol() const override; |
| 123 bool GetSSLInfo(SSLInfo* ssl_info) override; |
| 124 void GetConnectionAttempts(ConnectionAttempts* out) const override; |
| 125 void ClearConnectionAttempts() override {} |
| 126 void AddConnectionAttempts(const ConnectionAttempts& attempts) override {} |
| 127 int64_t GetTotalReceivedBytes() const override; |
| 128 |
| 129 private: |
| 130 enum State { |
| 131 STATE_NONE, |
| 132 STATE_HANDSHAKE, |
| 133 }; |
| 134 |
| 135 int InitializeSSLOptions(); |
| 136 |
| 137 void OnSendComplete(int result); |
| 138 void OnRecvComplete(int result); |
| 139 void OnHandshakeIOComplete(int result); |
| 140 |
| 141 int BufferSend(); |
| 142 void BufferSendComplete(int result); |
| 143 int BufferRecv(); |
| 144 void BufferRecvComplete(int result); |
| 145 bool DoTransportIO(); |
| 146 int DoPayloadRead(); |
| 147 int DoPayloadWrite(); |
| 148 |
| 149 int DoHandshakeLoop(int last_io_result); |
| 150 int DoReadLoop(int result); |
| 151 int DoWriteLoop(int result); |
| 152 int DoHandshake(); |
| 153 void DoHandshakeCallback(int result); |
| 154 void DoReadCallback(int result); |
| 155 void DoWriteCallback(int result); |
| 156 |
| 157 static SECStatus OwnAuthCertHandler(void* arg, |
| 158 PRFileDesc* socket, |
| 159 PRBool checksig, |
| 160 PRBool is_server); |
| 161 static void HandshakeCallback(PRFileDesc* socket, void* arg); |
| 162 |
| 163 int Init(); |
| 164 |
| 165 // Members used to send and receive buffer. |
| 166 bool transport_send_busy_; |
| 167 bool transport_recv_busy_; |
| 168 |
| 169 scoped_refptr<IOBuffer> recv_buffer_; |
| 170 |
| 171 BoundNetLog net_log_; |
| 172 |
| 173 CompletionCallback user_handshake_callback_; |
| 174 CompletionCallback user_read_callback_; |
| 175 CompletionCallback user_write_callback_; |
| 176 |
| 177 // Used by Read function. |
| 178 scoped_refptr<IOBuffer> user_read_buf_; |
| 179 int user_read_buf_len_; |
| 180 |
| 181 // Used by Write function. |
| 182 scoped_refptr<IOBuffer> user_write_buf_; |
| 183 int user_write_buf_len_; |
| 184 |
| 185 // The NSS SSL state machine |
| 186 PRFileDesc* nss_fd_; |
| 187 |
| 188 // Buffers for the network end of the SSL state machine |
| 189 memio_Private* nss_bufs_; |
| 190 |
| 191 // StreamSocket for sending and receiving data. |
| 192 scoped_ptr<StreamSocket> transport_socket_; |
| 193 |
| 194 // Options for the SSL socket. |
| 195 SSLServerConfig ssl_server_config_; |
| 196 |
| 197 // Certificate for the server. |
| 198 scoped_refptr<X509Certificate> cert_; |
| 199 |
| 200 // Private key used by the server. |
| 201 scoped_ptr<crypto::RSAPrivateKey> key_; |
| 202 |
| 203 State next_handshake_state_; |
| 204 bool completed_handshake_; |
| 205 |
| 206 DISALLOW_COPY_AND_ASSIGN(SSLServerSocketNSS); |
| 207 }; |
95 | 208 |
96 SSLServerSocketNSS::SSLServerSocketNSS( | 209 SSLServerSocketNSS::SSLServerSocketNSS( |
97 scoped_ptr<StreamSocket> transport_socket, | 210 scoped_ptr<StreamSocket> transport_socket, |
98 scoped_refptr<X509Certificate> cert, | 211 X509Certificate* cert, |
99 const crypto::RSAPrivateKey& key, | 212 const crypto::RSAPrivateKey& key, |
100 const SSLServerConfig& ssl_server_config) | 213 const SSLServerConfig& ssl_server_config) |
101 : transport_send_busy_(false), | 214 : transport_send_busy_(false), |
102 transport_recv_busy_(false), | 215 transport_recv_busy_(false), |
103 user_read_buf_len_(0), | 216 user_read_buf_len_(0), |
104 user_write_buf_len_(0), | 217 user_write_buf_len_(0), |
105 nss_fd_(NULL), | 218 nss_fd_(NULL), |
106 nss_bufs_(NULL), | 219 nss_bufs_(NULL), |
107 transport_socket_(std::move(transport_socket)), | 220 transport_socket_(std::move(transport_socket)), |
108 ssl_server_config_(ssl_server_config), | 221 ssl_server_config_(ssl_server_config), |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 } | 299 } |
187 out->assign(reinterpret_cast<char*>(buf), len); | 300 out->assign(reinterpret_cast<char*>(buf), len); |
188 return OK; | 301 return OK; |
189 } | 302 } |
190 | 303 |
191 int SSLServerSocketNSS::Connect(const CompletionCallback& callback) { | 304 int SSLServerSocketNSS::Connect(const CompletionCallback& callback) { |
192 NOTIMPLEMENTED(); | 305 NOTIMPLEMENTED(); |
193 return ERR_NOT_IMPLEMENTED; | 306 return ERR_NOT_IMPLEMENTED; |
194 } | 307 } |
195 | 308 |
196 int SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len, | 309 int SSLServerSocketNSS::Read(IOBuffer* buf, |
| 310 int buf_len, |
197 const CompletionCallback& callback) { | 311 const CompletionCallback& callback) { |
198 DCHECK(user_read_callback_.is_null()); | 312 DCHECK(user_read_callback_.is_null()); |
199 DCHECK(user_handshake_callback_.is_null()); | 313 DCHECK(user_handshake_callback_.is_null()); |
200 DCHECK(!user_read_buf_); | 314 DCHECK(!user_read_buf_); |
201 DCHECK(nss_bufs_); | 315 DCHECK(nss_bufs_); |
202 DCHECK(!callback.is_null()); | 316 DCHECK(!callback.is_null()); |
203 | 317 |
204 user_read_buf_ = buf; | 318 user_read_buf_ = buf; |
205 user_read_buf_len_ = buf_len; | 319 user_read_buf_len_ = buf_len; |
206 | 320 |
207 DCHECK(completed_handshake_); | 321 DCHECK(completed_handshake_); |
208 | 322 |
209 int rv = DoReadLoop(OK); | 323 int rv = DoReadLoop(OK); |
210 | 324 |
211 if (rv == ERR_IO_PENDING) { | 325 if (rv == ERR_IO_PENDING) { |
212 user_read_callback_ = callback; | 326 user_read_callback_ = callback; |
213 } else { | 327 } else { |
214 user_read_buf_ = NULL; | 328 user_read_buf_ = NULL; |
215 user_read_buf_len_ = 0; | 329 user_read_buf_len_ = 0; |
216 } | 330 } |
217 return rv; | 331 return rv; |
218 } | 332 } |
219 | 333 |
220 int SSLServerSocketNSS::Write(IOBuffer* buf, int buf_len, | 334 int SSLServerSocketNSS::Write(IOBuffer* buf, |
| 335 int buf_len, |
221 const CompletionCallback& callback) { | 336 const CompletionCallback& callback) { |
222 DCHECK(user_write_callback_.is_null()); | 337 DCHECK(user_write_callback_.is_null()); |
223 DCHECK(!user_write_buf_); | 338 DCHECK(!user_write_buf_); |
224 DCHECK(nss_bufs_); | 339 DCHECK(nss_bufs_); |
225 DCHECK(!callback.is_null()); | 340 DCHECK(!callback.is_null()); |
226 | 341 |
227 user_write_buf_ = buf; | 342 user_write_buf_ = buf; |
228 user_write_buf_len_ = buf_len; | 343 user_write_buf_len_ = buf_len; |
229 | 344 |
230 int rv = DoWriteLoop(OK); | 345 int rv = DoWriteLoop(OK); |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 return ERR_ABORTED; | 690 return ERR_ABORTED; |
576 } | 691 } |
577 const size_t len = len1 + len2; | 692 const size_t len = len1 + len2; |
578 | 693 |
579 int rv = 0; | 694 int rv = 0; |
580 if (len) { | 695 if (len) { |
581 scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len)); | 696 scoped_refptr<IOBuffer> send_buffer(new IOBuffer(len)); |
582 memcpy(send_buffer->data(), buf1, len1); | 697 memcpy(send_buffer->data(), buf1, len1); |
583 memcpy(send_buffer->data() + len1, buf2, len2); | 698 memcpy(send_buffer->data() + len1, buf2, len2); |
584 rv = transport_socket_->Write( | 699 rv = transport_socket_->Write( |
585 send_buffer.get(), | 700 send_buffer.get(), len, |
586 len, | |
587 base::Bind(&SSLServerSocketNSS::BufferSendComplete, | 701 base::Bind(&SSLServerSocketNSS::BufferSendComplete, |
588 base::Unretained(this))); | 702 base::Unretained(this))); |
589 if (rv == ERR_IO_PENDING) { | 703 if (rv == ERR_IO_PENDING) { |
590 transport_send_busy_ = true; | 704 transport_send_busy_ = true; |
591 } else { | 705 } else { |
592 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv)); | 706 memio_PutWriteResult(nss_bufs_, MapErrorToNSS(rv)); |
593 } | 707 } |
594 } | 708 } |
595 | 709 |
596 return rv; | 710 return rv; |
(...skipping 10 matching lines...) Expand all Loading... |
607 | 721 |
608 char* buf; | 722 char* buf; |
609 int nb = memio_GetReadParams(nss_bufs_, &buf); | 723 int nb = memio_GetReadParams(nss_bufs_, &buf); |
610 int rv; | 724 int rv; |
611 if (!nb) { | 725 if (!nb) { |
612 // buffer too full to read into, so no I/O possible at moment | 726 // buffer too full to read into, so no I/O possible at moment |
613 rv = ERR_IO_PENDING; | 727 rv = ERR_IO_PENDING; |
614 } else { | 728 } else { |
615 recv_buffer_ = new IOBuffer(nb); | 729 recv_buffer_ = new IOBuffer(nb); |
616 rv = transport_socket_->Read( | 730 rv = transport_socket_->Read( |
617 recv_buffer_.get(), | 731 recv_buffer_.get(), nb, |
618 nb, | |
619 base::Bind(&SSLServerSocketNSS::BufferRecvComplete, | 732 base::Bind(&SSLServerSocketNSS::BufferRecvComplete, |
620 base::Unretained(this))); | 733 base::Unretained(this))); |
621 if (rv == ERR_IO_PENDING) { | 734 if (rv == ERR_IO_PENDING) { |
622 transport_recv_busy_ = true; | 735 transport_recv_busy_ = true; |
623 } else { | 736 } else { |
624 if (rv > 0) | 737 if (rv > 0) |
625 memcpy(buf, recv_buffer_->data(), rv); | 738 memcpy(buf, recv_buffer_->data(), rv); |
626 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv)); | 739 memio_PutReadResult(nss_bufs_, MapErrorToNSS(rv)); |
627 recv_buffer_ = NULL; | 740 recv_buffer_ = NULL; |
628 } | 741 } |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
831 PRBool checksig, | 944 PRBool checksig, |
832 PRBool is_server) { | 945 PRBool is_server) { |
833 // TODO(hclam): Implement. | 946 // TODO(hclam): Implement. |
834 // Tell NSS to not verify the certificate. | 947 // Tell NSS to not verify the certificate. |
835 return SECSuccess; | 948 return SECSuccess; |
836 } | 949 } |
837 | 950 |
838 // static | 951 // static |
839 // NSS calls this when handshake is completed. | 952 // NSS calls this when handshake is completed. |
840 // After the SSL handshake is finished we need to verify the certificate. | 953 // After the SSL handshake is finished we need to verify the certificate. |
841 void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, | 954 void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, void* arg) { |
842 void* arg) { | |
843 // TODO(hclam): Implement. | 955 // TODO(hclam): Implement. |
844 } | 956 } |
845 | 957 |
846 int SSLServerSocketNSS::Init() { | 958 int SSLServerSocketNSS::Init() { |
847 // Initialize the NSS SSL library in a threadsafe way. This also | 959 // Initialize the NSS SSL library in a threadsafe way. This also |
848 // initializes the NSS base library. | 960 // initializes the NSS base library. |
849 EnsureNSSSSLInit(); | 961 EnsureNSSSSLInit(); |
850 if (!NSS_IsInitialized()) | 962 if (!NSS_IsInitialized()) |
851 return ERR_UNEXPECTED; | 963 return ERR_UNEXPECTED; |
852 | 964 |
853 EnableSSLServerSockets(); | 965 EnableSSLServerSockets(); |
854 return OK; | 966 return OK; |
855 } | 967 } |
856 | 968 |
| 969 } // namespace |
| 970 |
| 971 scoped_ptr<SSLServerContext> CreateSSLServerContext( |
| 972 X509Certificate* certificate, |
| 973 const crypto::RSAPrivateKey& key, |
| 974 const SSLServerConfig& ssl_server_config) { |
| 975 return scoped_ptr<SSLServerContext>( |
| 976 new SSLServerContextNSS(certificate, key, ssl_server_config)); |
| 977 } |
| 978 |
| 979 SSLServerContextNSS::SSLServerContextNSS( |
| 980 X509Certificate* certificate, |
| 981 const crypto::RSAPrivateKey& key, |
| 982 const SSLServerConfig& ssl_server_config) |
| 983 : ssl_server_config_(ssl_server_config), |
| 984 cert_(certificate), |
| 985 key_(key.Copy()) { |
| 986 CHECK(key_); |
| 987 } |
| 988 |
| 989 SSLServerContextNSS::~SSLServerContextNSS() {} |
| 990 |
| 991 scoped_ptr<SSLServerSocket> SSLServerContextNSS::CreateSSLServerSocket( |
| 992 scoped_ptr<StreamSocket> socket) { |
| 993 DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been" |
| 994 << " called yet!"; |
| 995 |
| 996 return scoped_ptr<SSLServerSocket>(new SSLServerSocketNSS( |
| 997 std::move(socket), cert_.get(), *key_, ssl_server_config_)); |
| 998 } |
| 999 |
| 1000 void EnableSSLServerSockets() { |
| 1001 g_nss_ssl_server_init_singleton.Get(); |
| 1002 } |
| 1003 |
857 } // namespace net | 1004 } // namespace net |
OLD | NEW |