• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
31 namespace net {
32 
33 class BoundNetLog;
34 class CertVerifier;
35 class ClientSocketHandle;
36 class DnsCertProvenanceChecker;
37 class SingleRequestCertVerifier;
38 class SSLHostInfo;
39 class X509Certificate;
40 
41 // An SSL client socket implemented with Mozilla NSS.
42 class 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