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