| 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
|
|
|