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
33namespace base {
34class SequencedTaskRunner;
35}
36
37namespace net {
38
39class BoundNetLog;
40class CertVerifier;
41class ChannelIDService;
42class CTVerifier;
43class ClientSocketHandle;
44class SingleRequestCertVerifier;
45class TransportSecurityState;
46class X509Certificate;
47
48// An SSL client socket implemented with Mozilla NSS.
49class 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