1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_
6#define NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_
7#pragma once
8
9#include <certt.h>
10#include <keyt.h>
11#include <nspr.h>
12#include <nss.h>
13
14#include <string>
15#include <vector>
16
17#include "base/memory/scoped_ptr.h"
18#include "base/synchronization/lock.h"
19#include "base/threading/platform_thread.h"
20#include "base/time.h"
21#include "base/timer.h"
22#include "net/base/cert_verify_result.h"
23#include "net/base/completion_callback.h"
24#include "net/base/host_port_pair.h"
25#include "net/base/net_log.h"
26#include "net/base/nss_memio.h"
27#include "net/base/ssl_config_service.h"
28#include "net/base/x509_certificate.h"
29#include "net/socket/ssl_client_socket.h"
30
31namespace net {
32
33class BoundNetLog;
34class CertVerifier;
35class ClientSocketHandle;
36class DnsCertProvenanceChecker;
37class SingleRequestCertVerifier;
38class SSLHostInfo;
39class X509Certificate;
40
41// An SSL client socket implemented with Mozilla NSS.
42class SSLClientSocketNSS : public SSLClientSocket {
43 public:
44  // Takes ownership of the |transport_socket|, which must already be connected.
45  // The hostname specified in |host_and_port| will be compared with the name(s)
46  // in the server's certificate during the SSL handshake.  If SSL client
47  // authentication is requested, the host_and_port field of SSLCertRequestInfo
48  // will be populated with |host_and_port|.  |ssl_config| specifies
49  // the SSL settings.
50  SSLClientSocketNSS(ClientSocketHandle* transport_socket,
51                     const HostPortPair& host_and_port,
52                     const SSLConfig& ssl_config,
53                     SSLHostInfo* ssl_host_info,
54                     CertVerifier* cert_verifier,
55                     DnsCertProvenanceChecker* dnsrr_resolver);
56  ~SSLClientSocketNSS();
57
58  // For tests
59  static void ClearSessionCache();
60
61  // SSLClientSocket methods:
62  virtual void GetSSLInfo(SSLInfo* ssl_info);
63  virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
64  virtual NextProtoStatus GetNextProto(std::string* proto);
65  virtual void UseDNSSEC(DNSSECProvider* provider);
66
67  // ClientSocket methods:
68  virtual int Connect(CompletionCallback* callback
69#ifdef ANDROID
70                      , bool wait_for_connect
71#endif
72                     );
73  virtual void Disconnect();
74  virtual bool IsConnected() const;
75  virtual bool IsConnectedAndIdle() const;
76  virtual int GetPeerAddress(AddressList* address) const;
77  virtual int GetLocalAddress(IPEndPoint* address) const;
78  virtual const BoundNetLog& NetLog() const;
79  virtual void SetSubresourceSpeculation();
80  virtual void SetOmniboxSpeculation();
81  virtual bool WasEverUsed() const;
82  virtual bool UsingTCPFastOpen() const;
83
84  // Socket methods:
85  virtual int Read(IOBuffer* buf, int buf_len, CompletionCallback* callback);
86  virtual int Write(IOBuffer* buf, int buf_len, CompletionCallback* callback);
87  virtual bool SetReceiveBufferSize(int32 size);
88  virtual bool SetSendBufferSize(int32 size);
89
90 private:
91  enum State {
92    STATE_NONE,
93    STATE_HANDSHAKE,
94    STATE_VERIFY_DNSSEC,
95    STATE_VERIFY_DNSSEC_COMPLETE,
96    STATE_VERIFY_CERT,
97    STATE_VERIFY_CERT_COMPLETE,
98  };
99
100  int Init();
101
102  // Initializes NSS SSL options.  Returns a net error code.
103  int InitializeSSLOptions();
104
105  // Initializes the socket peer name in SSL.  Returns a net error code.
106  int InitializeSSLPeerName();
107
108#if defined(OS_MACOSX) || defined(OS_WIN)
109  // Creates an OS certificate from a DER-encoded certificate.
110  static X509Certificate::OSCertHandle CreateOSCert(const SECItem& der_cert);
111#endif
112  X509Certificate* UpdateServerCert();
113  void UpdateConnectionStatus();
114  void DoReadCallback(int result);
115  void DoWriteCallback(int result);
116  void DoConnectCallback(int result);
117  void OnHandshakeIOComplete(int result);
118  void OnSendComplete(int result);
119  void OnRecvComplete(int result);
120
121  int DoHandshakeLoop(int last_io_result);
122  int DoReadLoop(int result);
123  int DoWriteLoop(int result);
124
125  int DoHandshake();
126
127  int DoVerifyDNSSEC(int result);
128  int DoVerifyDNSSECComplete(int result);
129  int DoVerifyCert(int result);
130  int DoVerifyCertComplete(int result);
131  int DoPayloadRead();
132  int DoPayloadWrite();
133  void LogConnectionTypeMetrics() const;
134  void SaveSSLHostInfo();
135  void UncorkAfterTimeout();
136
137  bool DoTransportIO();
138  int BufferSend(void);
139  void BufferSendComplete(int result);
140  int BufferRecv(void);
141  void BufferRecvComplete(int result);
142
143  // Handles an NSS error generated while handshaking or performing IO.
144  // Returns a network error code mapped from the original NSS error.
145  int HandleNSSError(PRErrorCode error, bool handshake_error);
146
147  // NSS calls this when checking certificates. We pass 'this' as the first
148  // argument.
149  static SECStatus OwnAuthCertHandler(void* arg, PRFileDesc* socket,
150                                      PRBool checksig, PRBool is_server);
151  // NSS calls this when client authentication is requested.
152#if defined(NSS_PLATFORM_CLIENT_AUTH)
153  static SECStatus PlatformClientAuthHandler(void* arg,
154                                             PRFileDesc* socket,
155                                             CERTDistNames* ca_names,
156                                             CERTCertList** result_certs,
157                                             void** result_private_key);
158#else
159  static SECStatus ClientAuthHandler(void* arg,
160                                     PRFileDesc* socket,
161                                     CERTDistNames* ca_names,
162                                     CERTCertificate** result_certificate,
163                                     SECKEYPrivateKey** result_private_key);
164#endif
165  // NSS calls this when handshake is completed.  We pass 'this' as the second
166  // argument.
167  static void HandshakeCallback(PRFileDesc* socket, void* arg);
168
169  // The following methods are for debugging bug 65948. Will remove this code
170  // after fixing bug 65948.
171  void EnsureThreadIdAssigned() const;
172  bool CalledOnValidThread() const;
173
174  CompletionCallbackImpl<SSLClientSocketNSS> buffer_send_callback_;
175  CompletionCallbackImpl<SSLClientSocketNSS> buffer_recv_callback_;
176  bool transport_send_busy_;
177  bool transport_recv_busy_;
178  // corked_ is true if we are currently suspending writes to the network. This
179  // is named after the similar kernel flag, TCP_CORK.
180  bool corked_;
181  // uncork_timer_ is used to limit the amount of time that we'll delay the
182  // Finished message while waiting for a Write.
183  base::OneShotTimer<SSLClientSocketNSS> uncork_timer_;
184  scoped_refptr<IOBuffer> recv_buffer_;
185
186  CompletionCallbackImpl<SSLClientSocketNSS> handshake_io_callback_;
187  scoped_ptr<ClientSocketHandle> transport_;
188  HostPortPair host_and_port_;
189  SSLConfig ssl_config_;
190
191  CompletionCallback* user_connect_callback_;
192  CompletionCallback* user_read_callback_;
193  CompletionCallback* user_write_callback_;
194
195  // Used by Read function.
196  scoped_refptr<IOBuffer> user_read_buf_;
197  int user_read_buf_len_;
198
199  // Used by Write function.
200  scoped_refptr<IOBuffer> user_write_buf_;
201  int user_write_buf_len_;
202
203  // Set when handshake finishes.  The server certificate is first received
204  // from NSS as an NSS certificate handle (server_cert_nss_), and then
205  // converted into an X509Certificate object (server_cert_).
206  scoped_refptr<X509Certificate> server_cert_;
207  CERTCertificate* server_cert_nss_;
208  // |server_cert_verify_result_| points at the verification result, which may,
209  // or may not be, |&local_server_cert_verify_result_|, depending on whether
210  // we used an SSLHostInfo's verification.
211  const CertVerifyResult* server_cert_verify_result_;
212  CertVerifyResult local_server_cert_verify_result_;
213  int ssl_connection_status_;
214
215  // Stores client authentication information between ClientAuthHandler and
216  // GetSSLCertRequestInfo calls.
217  std::vector<scoped_refptr<X509Certificate> > client_certs_;
218  bool client_auth_cert_needed_;
219
220  CertVerifier* const cert_verifier_;
221  scoped_ptr<SingleRequestCertVerifier> verifier_;
222
223  // True if NSS has called HandshakeCallback.
224  bool handshake_callback_called_;
225
226  // True if the SSL handshake has been completed.
227  bool completed_handshake_;
228
229  // True iff we believe that the user has an ESET product intercepting our
230  // HTTPS connections.
231  bool eset_mitm_detected_;
232
233  // True iff |ssl_host_info_| contained a predicted certificate chain and
234  // that we found the prediction to be correct.
235  bool predicted_cert_chain_correct_;
236
237  // True if the peer name has been initialized.
238  bool peername_initialized_;
239
240  // This pointer is owned by the caller of UseDNSSEC.
241  DNSSECProvider* dnssec_provider_;
242  // The time when we started waiting for DNSSEC records.
243  base::Time dnssec_wait_start_time_;
244
245  State next_handshake_state_;
246
247  // The NSS SSL state machine
248  PRFileDesc* nss_fd_;
249
250  // Buffers for the network end of the SSL state machine
251  memio_Private* nss_bufs_;
252
253  BoundNetLog net_log_;
254
255  base::TimeTicks start_cert_verification_time_;
256
257  scoped_ptr<SSLHostInfo> ssl_host_info_;
258  DnsCertProvenanceChecker* const dns_cert_checker_;
259
260  // The following two variables are added for debugging bug 65948. Will
261  // remove this code after fixing bug 65948.
262  // Added the following code Debugging in release mode.
263  mutable base::Lock lock_;
264  // This is mutable so that CalledOnValidThread can set it.
265  // It's guarded by |lock_|.
266  mutable base::PlatformThreadId valid_thread_id_;
267};
268
269}  // namespace net
270
271#endif  // NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_
272