• 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/server_bound_cert_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 CTVerifier;
42 class ClientSocketHandle;
43 class ServerBoundCertService;
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 void GetSSLCertRequestInfo(
72       SSLCertRequestInfo* cert_request_info) OVERRIDE;
73   virtual NextProtoStatus GetNextProto(std::string* proto,
74                                        std::string* server_protos) OVERRIDE;
75 
76   // SSLSocket implementation.
77   virtual int ExportKeyingMaterial(const base::StringPiece& label,
78                                    bool has_context,
79                                    const base::StringPiece& context,
80                                    unsigned char* out,
81                                    unsigned int outlen) OVERRIDE;
82   virtual int GetTLSUniqueChannelBinding(std::string* out) OVERRIDE;
83 
84   // StreamSocket implementation.
85   virtual int Connect(const CompletionCallback& callback) OVERRIDE;
86   virtual void Disconnect() OVERRIDE;
87   virtual bool IsConnected() const OVERRIDE;
88   virtual bool IsConnectedAndIdle() const OVERRIDE;
89   virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE;
90   virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE;
91   virtual const BoundNetLog& NetLog() const OVERRIDE;
92   virtual void SetSubresourceSpeculation() OVERRIDE;
93   virtual void SetOmniboxSpeculation() OVERRIDE;
94   virtual bool WasEverUsed() const OVERRIDE;
95   virtual bool UsingTCPFastOpen() const OVERRIDE;
96   virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE;
97 
98   // Socket implementation.
99   virtual int Read(IOBuffer* buf,
100                    int buf_len,
101                    const CompletionCallback& callback) OVERRIDE;
102   virtual int Write(IOBuffer* buf,
103                     int buf_len,
104                     const CompletionCallback& callback) OVERRIDE;
105   virtual int SetReceiveBufferSize(int32 size) OVERRIDE;
106   virtual int SetSendBufferSize(int32 size) OVERRIDE;
107   virtual ServerBoundCertService* GetServerBoundCertService() const OVERRIDE;
108 
109  protected:
110   // SSLClientSocket implementation.
111   virtual scoped_refptr<X509Certificate> GetUnverifiedServerCertificateChain()
112       const OVERRIDE;
113 
114  private:
115   // Helper class to handle marshalling any NSS interaction to and from the
116   // NSS and network task runners. Not every call needs to happen on the Core
117   class Core;
118 
119   enum State {
120     STATE_NONE,
121     STATE_HANDSHAKE,
122     STATE_HANDSHAKE_COMPLETE,
123     STATE_VERIFY_CERT,
124     STATE_VERIFY_CERT_COMPLETE,
125   };
126 
127   int Init();
128   void InitCore();
129 
130   // Initializes NSS SSL options.  Returns a net error code.
131   int InitializeSSLOptions();
132 
133   // Initializes the socket peer name in SSL.  Returns a net error code.
134   int InitializeSSLPeerName();
135 
136   void DoConnectCallback(int result);
137   void OnHandshakeIOComplete(int result);
138 
139   int DoHandshakeLoop(int last_io_result);
140   int DoHandshake();
141   int DoHandshakeComplete(int result);
142   int DoVerifyCert(int result);
143   int DoVerifyCertComplete(int result);
144 
145   void VerifyCT();
146 
147   void LogConnectionTypeMetrics() const;
148 
149   // The following methods are for debugging bug 65948. Will remove this code
150   // after fixing bug 65948.
151   void EnsureThreadIdAssigned() const;
152   bool CalledOnValidThread() const;
153 
154   // Adds the SignedCertificateTimestamps from ct_verify_result_ to |ssl_info|.
155   // SCTs are held in three separate vectors in ct_verify_result, each
156   // vetor representing a particular verification state, this method associates
157   // each of the SCTs with the corresponding SCTVerifyStatus as it adds it to
158   // the |ssl_info|.signed_certificate_timestamps list.
159   void AddSCTInfoToSSLInfo(SSLInfo* ssl_info) const;
160 
161   // The task runner used to perform NSS operations.
162   scoped_refptr<base::SequencedTaskRunner> nss_task_runner_;
163   scoped_ptr<ClientSocketHandle> transport_;
164   HostPortPair host_and_port_;
165   SSLConfig ssl_config_;
166 
167   scoped_refptr<Core> core_;
168 
169   CompletionCallback user_connect_callback_;
170 
171   CertVerifyResult server_cert_verify_result_;
172 
173   CertVerifier* const cert_verifier_;
174   scoped_ptr<SingleRequestCertVerifier> verifier_;
175 
176   // Certificate Transparency: Verifier and result holder.
177   ct::CTVerifyResult ct_verify_result_;
178   CTVerifier* cert_transparency_verifier_;
179 
180   // The service for retrieving Channel ID keys.  May be NULL.
181   ServerBoundCertService* server_bound_cert_service_;
182 
183   // ssl_session_cache_shard_ is an opaque string that partitions the SSL
184   // session cache. i.e. sessions created with one value will not attempt to
185   // resume on the socket with a different value.
186   const std::string ssl_session_cache_shard_;
187 
188   // True if the SSL handshake has been completed.
189   bool completed_handshake_;
190 
191   State next_handshake_state_;
192 
193   // The NSS SSL state machine. This is owned by |core_|.
194   // TODO(rsleevi): http://crbug.com/130616 - Remove this member once
195   // ExportKeyingMaterial is updated to be asynchronous.
196   PRFileDesc* nss_fd_;
197 
198   BoundNetLog net_log_;
199 
200   base::TimeTicks start_cert_verification_time_;
201 
202   TransportSecurityState* transport_security_state_;
203 
204   // pinning_failure_log contains a message produced by
205   // TransportSecurityState::DomainState::CheckPublicKeyPins in the event of a
206   // pinning failure. It is a (somewhat) human-readable string.
207   std::string pinning_failure_log_;
208 
209   // The following two variables are added for debugging bug 65948. Will
210   // remove this code after fixing bug 65948.
211   // Added the following code Debugging in release mode.
212   mutable base::Lock lock_;
213   // This is mutable so that CalledOnValidThread can set it.
214   // It's guarded by |lock_|.
215   mutable base::PlatformThreadId valid_thread_id_;
216 };
217 
218 }  // namespace net
219 
220 #endif  // NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_
221