• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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 
8 #include <certt.h>
9 #include <keyt.h>
10 #include <nspr.h>
11 #include <nss.h>
12 
13 #include <string>
14 #include <vector>
15 
16 #include "base/memory/scoped_ptr.h"
17 #include "base/synchronization/lock.h"
18 #include "base/threading/platform_thread.h"
19 #include "base/time/time.h"
20 #include "base/timer/timer.h"
21 #include "net/base/completion_callback.h"
22 #include "net/base/host_port_pair.h"
23 #include "net/base/net_export.h"
24 #include "net/base/net_log.h"
25 #include "net/base/nss_memio.h"
26 #include "net/cert/cert_verify_result.h"
27 #include "net/cert/ct_verify_result.h"
28 #include "net/cert/x509_certificate.h"
29 #include "net/socket/ssl_client_socket.h"
30 #include "net/ssl/channel_id_service.h"
31 #include "net/ssl/ssl_config_service.h"
32 
33 namespace base {
34 class SequencedTaskRunner;
35 }
36 
37 namespace net {
38 
39 class BoundNetLog;
40 class CertVerifier;
41 class ChannelIDService;
42 class CTVerifier;
43 class ClientSocketHandle;
44 class SingleRequestCertVerifier;
45 class TransportSecurityState;
46 class X509Certificate;
47 
48 // An SSL client socket implemented with Mozilla NSS.
49 class SSLClientSocketNSS : public SSLClientSocket {
50  public:
51   // Takes ownership of the |transport_socket|, which must already be connected.
52   // The hostname specified in |host_and_port| will be compared with the name(s)
53   // in the server's certificate during the SSL handshake.  If SSL client
54   // authentication is requested, the host_and_port field of SSLCertRequestInfo
55   // will be populated with |host_and_port|.  |ssl_config| specifies
56   // the SSL settings.
57   //
58   // Because calls to NSS may block, such as due to needing to access slow
59   // hardware or needing to synchronously unlock protected tokens, calls to
60   // NSS may optionally be run on a dedicated thread. If synchronous/blocking
61   // behaviour is desired, for performance or compatibility, the current task
62   // runner should be supplied instead.
63   SSLClientSocketNSS(base::SequencedTaskRunner* nss_task_runner,
64                      scoped_ptr<ClientSocketHandle> transport_socket,
65                      const HostPortPair& host_and_port,
66                      const SSLConfig& ssl_config,
67                      const SSLClientSocketContext& context);
68   virtual ~SSLClientSocketNSS();
69 
70   // SSLClientSocket implementation.
71   virtual std::string GetSessionCacheKey() const OVERRIDE;
72   virtual bool InSessionCache() const OVERRIDE;
73   virtual void SetHandshakeCompletionCallback(
74       const base::Closure& callback) OVERRIDE;
75   virtual void GetSSLCertRequestInfo(
76       SSLCertRequestInfo* cert_request_info) OVERRIDE;
77   virtual NextProtoStatus GetNextProto(std::string* proto) OVERRIDE;
78 
79   // SSLSocket implementation.
80   virtual int ExportKeyingMaterial(const base::StringPiece& label,
81                                    bool has_context,
82                                    const base::StringPiece& context,
83                                    unsigned char* out,
84                                    unsigned int outlen) OVERRIDE;
85   virtual int GetTLSUniqueChannelBinding(std::string* out) OVERRIDE;
86 
87   // StreamSocket implementation.
88   virtual int Connect(const CompletionCallback& callback) OVERRIDE;
89   virtual void Disconnect() OVERRIDE;
90   virtual bool IsConnected() const OVERRIDE;
91   virtual bool IsConnectedAndIdle() const OVERRIDE;
92   virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE;
93   virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE;
94   virtual const BoundNetLog& NetLog() const OVERRIDE;
95   virtual void SetSubresourceSpeculation() OVERRIDE;
96   virtual void SetOmniboxSpeculation() OVERRIDE;
97   virtual bool WasEverUsed() const OVERRIDE;
98   virtual bool UsingTCPFastOpen() const OVERRIDE;
99   virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE;
100 
101   // Socket implementation.
102   virtual int Read(IOBuffer* buf,
103                    int buf_len,
104                    const CompletionCallback& callback) OVERRIDE;
105   virtual int Write(IOBuffer* buf,
106                     int buf_len,
107                     const CompletionCallback& callback) OVERRIDE;
108   virtual int SetReceiveBufferSize(int32 size) OVERRIDE;
109   virtual int SetSendBufferSize(int32 size) OVERRIDE;
110   virtual ChannelIDService* GetChannelIDService() const OVERRIDE;
111 
112  protected:
113   // SSLClientSocket implementation.
114   virtual scoped_refptr<X509Certificate> GetUnverifiedServerCertificateChain()
115       const OVERRIDE;
116 
117  private:
118   // Helper class to handle marshalling any NSS interaction to and from the
119   // NSS and network task runners. Not every call needs to happen on the Core
120   class Core;
121 
122   enum State {
123     STATE_NONE,
124     STATE_HANDSHAKE,
125     STATE_HANDSHAKE_COMPLETE,
126     STATE_VERIFY_CERT,
127     STATE_VERIFY_CERT_COMPLETE,
128   };
129 
130   int Init();
131   void InitCore();
132 
133   // Initializes NSS SSL options.  Returns a net error code.
134   int InitializeSSLOptions();
135 
136   // Initializes the socket peer name in SSL.  Returns a net error code.
137   int InitializeSSLPeerName();
138 
139   void DoConnectCallback(int result);
140   void OnHandshakeIOComplete(int result);
141 
142   int DoHandshakeLoop(int last_io_result);
143   int DoHandshake();
144   int DoHandshakeComplete(int result);
145   int DoVerifyCert(int result);
146   int DoVerifyCertComplete(int result);
147 
148   void VerifyCT();
149 
150   void LogConnectionTypeMetrics() const;
151 
152   // The following methods are for debugging bug 65948. Will remove this code
153   // after fixing bug 65948.
154   void EnsureThreadIdAssigned() const;
155   bool CalledOnValidThread() const;
156 
157   // Adds the SignedCertificateTimestamps from ct_verify_result_ to |ssl_info|.
158   // SCTs are held in three separate vectors in ct_verify_result, each
159   // vetor representing a particular verification state, this method associates
160   // each of the SCTs with the corresponding SCTVerifyStatus as it adds it to
161   // the |ssl_info|.signed_certificate_timestamps list.
162   void AddSCTInfoToSSLInfo(SSLInfo* ssl_info) const;
163 
164   // The task runner used to perform NSS operations.
165   scoped_refptr<base::SequencedTaskRunner> nss_task_runner_;
166   scoped_ptr<ClientSocketHandle> transport_;
167   HostPortPair host_and_port_;
168   SSLConfig ssl_config_;
169 
170   scoped_refptr<Core> core_;
171 
172   CompletionCallback user_connect_callback_;
173 
174   CertVerifyResult server_cert_verify_result_;
175 
176   CertVerifier* const cert_verifier_;
177   scoped_ptr<SingleRequestCertVerifier> verifier_;
178 
179   // Certificate Transparency: Verifier and result holder.
180   ct::CTVerifyResult ct_verify_result_;
181   CTVerifier* cert_transparency_verifier_;
182 
183   // The service for retrieving Channel ID keys.  May be NULL.
184   ChannelIDService* channel_id_service_;
185 
186   // ssl_session_cache_shard_ is an opaque string that partitions the SSL
187   // session cache. i.e. sessions created with one value will not attempt to
188   // resume on the socket with a different value.
189   const std::string ssl_session_cache_shard_;
190 
191   // True if the SSL handshake has been completed.
192   bool completed_handshake_;
193 
194   State next_handshake_state_;
195 
196   // The NSS SSL state machine. This is owned by |core_|.
197   // TODO(rsleevi): http://crbug.com/130616 - Remove this member once
198   // ExportKeyingMaterial is updated to be asynchronous.
199   PRFileDesc* nss_fd_;
200 
201   BoundNetLog net_log_;
202 
203   base::TimeTicks start_cert_verification_time_;
204 
205   TransportSecurityState* transport_security_state_;
206 
207   // pinning_failure_log contains a message produced by
208   // TransportSecurityState::CheckPublicKeyPins in the event of a
209   // pinning failure. It is a (somewhat) human-readable string.
210   std::string pinning_failure_log_;
211 
212   // The following two variables are added for debugging bug 65948. Will
213   // remove this code after fixing bug 65948.
214   // Added the following code Debugging in release mode.
215   mutable base::Lock lock_;
216   // This is mutable so that CalledOnValidThread can set it.
217   // It's guarded by |lock_|.
218   mutable base::PlatformThreadId valid_thread_id_;
219 };
220 
221 }  // namespace net
222 
223 #endif  // NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_
224