Index: net/socket/ssl_server_socket_nss.cc |
diff --git a/net/socket/ssl_server_socket_nss.cc b/net/socket/ssl_server_socket_nss.cc |
index 6258c87cb4b57abd7d6d7cf55c28d35d5e0a901d..9d29a46ee74e4c18c44df3b51654167879930a09 100644 |
--- a/net/socket/ssl_server_socket_nss.cc |
+++ b/net/socket/ssl_server_socket_nss.cc |
@@ -75,27 +75,140 @@ class NSSSSLServerInitSingleton { |
static base::LazyInstance<NSSSSLServerInitSingleton>::Leaky |
g_nss_ssl_server_init_singleton = LAZY_INSTANCE_INITIALIZER; |
-} // namespace |
- |
-void EnableSSLServerSockets() { |
- g_nss_ssl_server_init_singleton.Get(); |
-} |
- |
-scoped_ptr<SSLServerSocket> CreateSSLServerSocket( |
- scoped_ptr<StreamSocket> socket, |
- X509Certificate* certificate, |
- const crypto::RSAPrivateKey& key, |
- const SSLServerConfig& ssl_server_config) { |
- DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been" |
- << " called yet!"; |
- |
- return scoped_ptr<SSLServerSocket>(new SSLServerSocketNSS( |
- std::move(socket), certificate, key, ssl_server_config)); |
-} |
+class SSLServerSocketNSS : public SSLServerSocket { |
+ public: |
+ // See comments on CreateSSLServerSocket for details of how these |
+ // parameters are used. |
+ SSLServerSocketNSS(scoped_ptr<StreamSocket> socket, |
+ X509Certificate* certificate, |
+ const crypto::RSAPrivateKey& key, |
+ const SSLServerConfig& ssl_server_config); |
+ ~SSLServerSocketNSS() override; |
+ |
+ // SSLServerSocket interface. |
+ int Handshake(const CompletionCallback& callback) override; |
+ |
+ // SSLSocket interface. |
+ int ExportKeyingMaterial(const base::StringPiece& label, |
+ bool has_context, |
+ const base::StringPiece& context, |
+ unsigned char* out, |
+ unsigned int outlen) override; |
+ int GetTLSUniqueChannelBinding(std::string* out) override; |
+ |
+ // Socket interface (via StreamSocket). |
+ int Read(IOBuffer* buf, |
+ int buf_len, |
+ const CompletionCallback& callback) override; |
+ int Write(IOBuffer* buf, |
+ int buf_len, |
+ const CompletionCallback& callback) override; |
+ int SetReceiveBufferSize(int32_t size) override; |
+ int SetSendBufferSize(int32_t size) override; |
+ |
+ // StreamSocket implementation. |
+ int Connect(const CompletionCallback& callback) override; |
+ void Disconnect() override; |
+ bool IsConnected() const override; |
+ bool IsConnectedAndIdle() const override; |
+ int GetPeerAddress(IPEndPoint* address) const override; |
+ int GetLocalAddress(IPEndPoint* address) const override; |
+ const BoundNetLog& NetLog() const override; |
+ void SetSubresourceSpeculation() override; |
+ void SetOmniboxSpeculation() override; |
+ bool WasEverUsed() const override; |
+ bool UsingTCPFastOpen() const override; |
+ bool WasNpnNegotiated() const override; |
+ NextProto GetNegotiatedProtocol() const override; |
+ bool GetSSLInfo(SSLInfo* ssl_info) override; |
+ void GetConnectionAttempts(ConnectionAttempts* out) const override; |
+ void ClearConnectionAttempts() override {} |
+ void AddConnectionAttempts(const ConnectionAttempts& attempts) override {} |
+ int64_t GetTotalReceivedBytes() const override; |
+ |
+ private: |
+ enum State { |
+ STATE_NONE, |
+ STATE_HANDSHAKE, |
+ }; |
+ |
+ int InitializeSSLOptions(); |
+ |
+ void OnSendComplete(int result); |
+ void OnRecvComplete(int result); |
+ void OnHandshakeIOComplete(int result); |
+ |
+ int BufferSend(); |
+ void BufferSendComplete(int result); |
+ int BufferRecv(); |
+ void BufferRecvComplete(int result); |
+ bool DoTransportIO(); |
+ int DoPayloadRead(); |
+ int DoPayloadWrite(); |
+ |
+ int DoHandshakeLoop(int last_io_result); |
+ int DoReadLoop(int result); |
+ int DoWriteLoop(int result); |
+ int DoHandshake(); |
+ void DoHandshakeCallback(int result); |
+ void DoReadCallback(int result); |
+ void DoWriteCallback(int result); |
+ |
+ static SECStatus OwnAuthCertHandler(void* arg, |
+ PRFileDesc* socket, |
+ PRBool checksig, |
+ PRBool is_server); |
+ static void HandshakeCallback(PRFileDesc* socket, void* arg); |
+ |
+ int Init(); |
+ |
+ // Members used to send and receive buffer. |
+ bool transport_send_busy_; |
+ bool transport_recv_busy_; |
+ |
+ scoped_refptr<IOBuffer> recv_buffer_; |
+ |
+ BoundNetLog net_log_; |
+ |
+ CompletionCallback user_handshake_callback_; |
+ CompletionCallback user_read_callback_; |
+ CompletionCallback user_write_callback_; |
+ |
+ // Used by Read function. |
+ scoped_refptr<IOBuffer> user_read_buf_; |
+ int user_read_buf_len_; |
+ |
+ // Used by Write function. |
+ scoped_refptr<IOBuffer> user_write_buf_; |
+ int user_write_buf_len_; |
+ |
+ // The NSS SSL state machine |
+ PRFileDesc* nss_fd_; |
+ |
+ // Buffers for the network end of the SSL state machine |
+ memio_Private* nss_bufs_; |
+ |
+ // StreamSocket for sending and receiving data. |
+ scoped_ptr<StreamSocket> transport_socket_; |
+ |
+ // Options for the SSL socket. |
+ SSLServerConfig ssl_server_config_; |
+ |
+ // Certificate for the server. |
+ scoped_refptr<X509Certificate> cert_; |
+ |
+ // Private key used by the server. |
+ scoped_ptr<crypto::RSAPrivateKey> key_; |
+ |
+ State next_handshake_state_; |
+ bool completed_handshake_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(SSLServerSocketNSS); |
+}; |
SSLServerSocketNSS::SSLServerSocketNSS( |
scoped_ptr<StreamSocket> transport_socket, |
- scoped_refptr<X509Certificate> cert, |
+ X509Certificate* cert, |
const crypto::RSAPrivateKey& key, |
const SSLServerConfig& ssl_server_config) |
: transport_send_busy_(false), |
@@ -193,7 +306,8 @@ int SSLServerSocketNSS::Connect(const CompletionCallback& callback) { |
return ERR_NOT_IMPLEMENTED; |
} |
-int SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len, |
+int SSLServerSocketNSS::Read(IOBuffer* buf, |
+ int buf_len, |
const CompletionCallback& callback) { |
DCHECK(user_read_callback_.is_null()); |
DCHECK(user_handshake_callback_.is_null()); |
@@ -217,7 +331,8 @@ int SSLServerSocketNSS::Read(IOBuffer* buf, int buf_len, |
return rv; |
} |
-int SSLServerSocketNSS::Write(IOBuffer* buf, int buf_len, |
+int SSLServerSocketNSS::Write(IOBuffer* buf, |
+ int buf_len, |
const CompletionCallback& callback) { |
DCHECK(user_write_callback_.is_null()); |
DCHECK(!user_write_buf_); |
@@ -582,8 +697,7 @@ int SSLServerSocketNSS::BufferSend(void) { |
memcpy(send_buffer->data(), buf1, len1); |
memcpy(send_buffer->data() + len1, buf2, len2); |
rv = transport_socket_->Write( |
- send_buffer.get(), |
- len, |
+ send_buffer.get(), len, |
base::Bind(&SSLServerSocketNSS::BufferSendComplete, |
base::Unretained(this))); |
if (rv == ERR_IO_PENDING) { |
@@ -614,8 +728,7 @@ int SSLServerSocketNSS::BufferRecv(void) { |
} else { |
recv_buffer_ = new IOBuffer(nb); |
rv = transport_socket_->Read( |
- recv_buffer_.get(), |
- nb, |
+ recv_buffer_.get(), nb, |
base::Bind(&SSLServerSocketNSS::BufferRecvComplete, |
base::Unretained(this))); |
if (rv == ERR_IO_PENDING) { |
@@ -838,8 +951,7 @@ SECStatus SSLServerSocketNSS::OwnAuthCertHandler(void* arg, |
// static |
// NSS calls this when handshake is completed. |
// After the SSL handshake is finished we need to verify the certificate. |
-void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, |
- void* arg) { |
+void SSLServerSocketNSS::HandshakeCallback(PRFileDesc* socket, void* arg) { |
// TODO(hclam): Implement. |
} |
@@ -854,4 +966,39 @@ int SSLServerSocketNSS::Init() { |
return OK; |
} |
+} // namespace |
+ |
+scoped_ptr<SSLServerContext> CreateSSLServerContext( |
+ X509Certificate* certificate, |
+ const crypto::RSAPrivateKey& key, |
+ const SSLServerConfig& ssl_server_config) { |
+ return scoped_ptr<SSLServerContext>( |
+ new SSLServerContextNSS(certificate, key, ssl_server_config)); |
+} |
+ |
+SSLServerContextNSS::SSLServerContextNSS( |
+ X509Certificate* certificate, |
+ const crypto::RSAPrivateKey& key, |
+ const SSLServerConfig& ssl_server_config) |
+ : ssl_server_config_(ssl_server_config), |
+ cert_(certificate), |
+ key_(key.Copy()) { |
+ CHECK(key_); |
+} |
+ |
+SSLServerContextNSS::~SSLServerContextNSS() {} |
+ |
+scoped_ptr<SSLServerSocket> SSLServerContextNSS::CreateSSLServerSocket( |
+ scoped_ptr<StreamSocket> socket) { |
+ DCHECK(g_nss_server_sockets_init) << "EnableSSLServerSockets() has not been" |
+ << " called yet!"; |
+ |
+ return scoped_ptr<SSLServerSocket>(new SSLServerSocketNSS( |
+ std::move(socket), cert_.get(), *key_, ssl_server_config_)); |
+} |
+ |
+void EnableSSLServerSockets() { |
+ g_nss_ssl_server_init_singleton.Get(); |
+} |
+ |
} // namespace net |