1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick// Use of this source code is governed by a BSD-style license that can be 3c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick// found in the LICENSE file. 400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#ifndef NET_SOCKET_SSL_CLIENT_SOCKET_OPENSSL_H_ 600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#define NET_SOCKET_SSL_CLIENT_SOCKET_OPENSSL_H_ 7c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick#pragma once 800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <string> 1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 12731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/base/cert_verify_result.h" 13c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick#include "net/base/completion_callback.h" 1400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#include "net/base/io_buffer.h" 1500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#include "net/base/ssl_config_service.h" 1600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#include "net/socket/ssl_client_socket.h" 1700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#include "net/socket/client_socket_handle.h" 1800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 19c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merricktypedef struct bio_st BIO; 2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsentypedef struct evp_pkey_st EVP_PKEY; 21c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merricktypedef struct ssl_st SSL; 2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsentypedef struct x509_st X509; 2300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 2400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochnamespace net { 2500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickclass CertVerifier; 2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass SingleRequestCertVerifier; 2800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochclass SSLCertRequestInfo; 2900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochclass SSLConfig; 3000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochclass SSLInfo; 3100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 3200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch// An SSL client socket implemented with OpenSSL. 3300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdochclass SSLClientSocketOpenSSL : public SSLClientSocket { 3400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch public: 3500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // Takes ownership of the transport_socket, which may already be connected. 3600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // The given hostname will be compared with the name(s) in the server's 3700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // certificate during the SSL handshake. ssl_config specifies the SSL 3800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // settings. 3900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch SSLClientSocketOpenSSL(ClientSocketHandle* transport_socket, 404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const HostPortPair& host_and_port, 4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const SSLConfig& ssl_config, 4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CertVerifier* cert_verifier); 4300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch ~SSLClientSocketOpenSSL(); 4400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 45201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const HostPortPair& host_and_port() const { return host_and_port_; } 46201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Callback from the SSL layer that indicates the remote server is requesting 4821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // a certificate for this client. 4921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int ClientCertRequestCallback(SSL* ssl, X509** x509, EVP_PKEY** pkey); 5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // Callback from the SSL layer to check which NPN protocol we are supporting 5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int SelectNextProtoCallback(unsigned char** out, unsigned char* outlen, 5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen const unsigned char* in, unsigned int inlen); 540dfd56d4192bd442742c9a0205590d7ef7b7f414Kristian Monsen 5500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // SSLClientSocket methods: 5600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch virtual void GetSSLInfo(SSLInfo* ssl_info); 5700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info); 5800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch virtual NextProtoStatus GetNextProto(std::string* proto); 5900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 6000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // ClientSocket methods: 617b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen virtual int Connect(CompletionCallback* callback 627b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#ifdef ANDROID 637b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen , bool wait_for_connect 64e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma , bool valid_uid 65e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma , uid_t calling_uid 667b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#endif 677b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen ); 6800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch virtual void Disconnect(); 6900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch virtual bool IsConnected() const; 7000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch virtual bool IsConnectedAndIdle() const; 7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen virtual int GetPeerAddress(AddressList* address) const; 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual int GetLocalAddress(IPEndPoint* address) const; 7300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch virtual const BoundNetLog& NetLog() const; 74c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick virtual void SetSubresourceSpeculation(); 75c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick virtual void SetOmniboxSpeculation(); 76c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick virtual bool WasEverUsed() const; 77513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch virtual bool UsingTCPFastOpen() const; 7800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 7900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // Socket methods: 8000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback); 8100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback); 8200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch virtual bool SetReceiveBufferSize(int32 size); 8300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch virtual bool SetSendBufferSize(int32 size); 8400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 8500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch private: 8600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch bool Init(); 8700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch void DoReadCallback(int result); 8800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch void DoWriteCallback(int result); 8900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 9000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch bool DoTransportIO(); 9100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int DoHandshake(); 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int DoVerifyCert(int result); 93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int DoVerifyCertComplete(int result); 9400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch void DoConnectCallback(int result); 95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick X509Certificate* UpdateServerCert(); 9600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 9700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch void OnHandshakeIOComplete(int result); 9800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch void OnSendComplete(int result); 9900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch void OnRecvComplete(int result); 10000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 10100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int DoHandshakeLoop(int last_io_result); 10200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int DoReadLoop(int result); 10300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int DoWriteLoop(int result); 10400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int DoPayloadRead(); 10500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int DoPayloadWrite(); 10600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 107c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int BufferSend(); 108c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick int BufferRecv(); 10900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch void BufferSendComplete(int result); 11000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch void BufferRecvComplete(int result); 111c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick void TransportWriteComplete(int result); 112c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick void TransportReadComplete(int result); 11300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 114c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick CompletionCallbackImpl<SSLClientSocketOpenSSL> buffer_send_callback_; 115c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick CompletionCallbackImpl<SSLClientSocketOpenSSL> buffer_recv_callback_; 11600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch bool transport_send_busy_; 117c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick scoped_refptr<DrainableIOBuffer> send_buffer_; 11800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch bool transport_recv_busy_; 11900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch scoped_refptr<IOBuffer> recv_buffer_; 12000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 12100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch CompletionCallback* user_connect_callback_; 12200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch CompletionCallback* user_read_callback_; 12300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch CompletionCallback* user_write_callback_; 12400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 12500d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // Used by Read function. 12600d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch scoped_refptr<IOBuffer> user_read_buf_; 12700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int user_read_buf_len_; 12800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 12900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // Used by Write function. 13000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch scoped_refptr<IOBuffer> user_write_buf_; 13100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch int user_write_buf_len_; 13200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick // Set when handshake finishes. 134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick scoped_refptr<X509Certificate> server_cert_; 135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CertVerifyResult server_cert_verify_result_; 136201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch bool completed_handshake_; 137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 13800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // Stores client authentication information between ClientAuthHandler and 13900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // GetSSLCertRequestInfo calls. 14000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch std::vector<scoped_refptr<X509Certificate> > client_certs_; 14100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch bool client_auth_cert_needed_; 142c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick 14321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen CertVerifier* const cert_verifier_; 14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen scoped_ptr<SingleRequestCertVerifier> verifier_; 145731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CompletionCallbackImpl<SSLClientSocketOpenSSL> handshake_io_callback_; 146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 14700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch // OpenSSL stuff 148c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick SSL* ssl_; 149c6df357b0380597cd1c1b6d28fa7d8ecb98fbbd8Iain Merrick BIO* transport_bio_; 15000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 15100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch scoped_ptr<ClientSocketHandle> transport_; 1524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const HostPortPair host_and_port_; 15300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch SSLConfig ssl_config_; 15400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 155201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Used for session cache diagnostics. 156201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch bool trying_cached_session_; 15700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 15800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch enum State { 15900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch STATE_NONE, 16000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch STATE_HANDSHAKE, 16100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch STATE_VERIFY_CERT, 16200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch STATE_VERIFY_CERT_COMPLETE, 16300d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch }; 16400d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch State next_handshake_state_; 16521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen NextProtoStatus npn_status_; 16621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string npn_proto_; 16700d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch BoundNetLog net_log_; 16800d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch}; 16900d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 17000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch} // namespace net 17100d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch 17221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#endif // NET_SOCKET_SSL_CLIENT_SOCKET_OPENSSL_H_ 173