Home | History | Annotate | Download | only in socket
      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/x509_certificate.h"
     28 #include "net/socket/ssl_client_socket.h"
     29 #include "net/ssl/server_bound_cert_service.h"
     30 #include "net/ssl/ssl_config_service.h"
     31 
     32 namespace base {
     33 class SequencedTaskRunner;
     34 }
     35 
     36 namespace net {
     37 
     38 class BoundNetLog;
     39 class CertVerifier;
     40 class ClientSocketHandle;
     41 class ServerBoundCertService;
     42 class SingleRequestCertVerifier;
     43 class TransportSecurityState;
     44 class X509Certificate;
     45 
     46 // An SSL client socket implemented with Mozilla NSS.
     47 class SSLClientSocketNSS : public SSLClientSocket {
     48  public:
     49   // Takes ownership of the |transport_socket|, which must already be connected.
     50   // The hostname specified in |host_and_port| will be compared with the name(s)
     51   // in the server's certificate during the SSL handshake.  If SSL client
     52   // authentication is requested, the host_and_port field of SSLCertRequestInfo
     53   // will be populated with |host_and_port|.  |ssl_config| specifies
     54   // the SSL settings.
     55   //
     56   // Because calls to NSS may block, such as due to needing to access slow
     57   // hardware or needing to synchronously unlock protected tokens, calls to
     58   // NSS may optionally be run on a dedicated thread. If synchronous/blocking
     59   // behaviour is desired, for performance or compatibility, the current task
     60   // runner should be supplied instead.
     61   SSLClientSocketNSS(base::SequencedTaskRunner* nss_task_runner,
     62                      ClientSocketHandle* transport_socket,
     63                      const HostPortPair& host_and_port,
     64                      const SSLConfig& ssl_config,
     65                      const SSLClientSocketContext& context);
     66   virtual ~SSLClientSocketNSS();
     67 
     68   // SSLClientSocket implementation.
     69   virtual void GetSSLCertRequestInfo(
     70       SSLCertRequestInfo* cert_request_info) OVERRIDE;
     71   virtual NextProtoStatus GetNextProto(std::string* proto,
     72                                        std::string* server_protos) OVERRIDE;
     73 
     74   // SSLSocket implementation.
     75   virtual int ExportKeyingMaterial(const base::StringPiece& label,
     76                                    bool has_context,
     77                                    const base::StringPiece& context,
     78                                    unsigned char* out,
     79                                    unsigned int outlen) OVERRIDE;
     80   virtual int GetTLSUniqueChannelBinding(std::string* out) OVERRIDE;
     81 
     82   // StreamSocket implementation.
     83   virtual int Connect(const CompletionCallback& callback) OVERRIDE;
     84   virtual void Disconnect() OVERRIDE;
     85   virtual bool IsConnected() const OVERRIDE;
     86   virtual bool IsConnectedAndIdle() const OVERRIDE;
     87   virtual int GetPeerAddress(IPEndPoint* address) const OVERRIDE;
     88   virtual int GetLocalAddress(IPEndPoint* address) const OVERRIDE;
     89   virtual const BoundNetLog& NetLog() const OVERRIDE;
     90   virtual void SetSubresourceSpeculation() OVERRIDE;
     91   virtual void SetOmniboxSpeculation() OVERRIDE;
     92   virtual bool WasEverUsed() const OVERRIDE;
     93   virtual bool UsingTCPFastOpen() const OVERRIDE;
     94   virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE;
     95 
     96   // Socket implementation.
     97   virtual int Read(IOBuffer* buf,
     98                    int buf_len,
     99                    const CompletionCallback& callback) OVERRIDE;
    100   virtual int Write(IOBuffer* buf,
    101                     int buf_len,
    102                     const CompletionCallback& callback) OVERRIDE;
    103   virtual bool SetReceiveBufferSize(int32 size) OVERRIDE;
    104   virtual bool SetSendBufferSize(int32 size) OVERRIDE;
    105   virtual ServerBoundCertService* GetServerBoundCertService() const OVERRIDE;
    106 
    107  private:
    108   // Helper class to handle marshalling any NSS interaction to and from the
    109   // NSS and network task runners. Not every call needs to happen on the Core
    110   class Core;
    111 
    112   enum State {
    113     STATE_NONE,
    114     STATE_HANDSHAKE,
    115     STATE_HANDSHAKE_COMPLETE,
    116     STATE_VERIFY_CERT,
    117     STATE_VERIFY_CERT_COMPLETE,
    118   };
    119 
    120   int Init();
    121   void InitCore();
    122 
    123   // Initializes NSS SSL options.  Returns a net error code.
    124   int InitializeSSLOptions();
    125 
    126   // Initializes the socket peer name in SSL.  Returns a net error code.
    127   int InitializeSSLPeerName();
    128 
    129   void DoConnectCallback(int result);
    130   void OnHandshakeIOComplete(int result);
    131 
    132   int DoHandshakeLoop(int last_io_result);
    133   int DoHandshake();
    134   int DoHandshakeComplete(int result);
    135   int DoVerifyCert(int result);
    136   int DoVerifyCertComplete(int result);
    137 
    138   void LogConnectionTypeMetrics() const;
    139 
    140   // The following methods are for debugging bug 65948. Will remove this code
    141   // after fixing bug 65948.
    142   void EnsureThreadIdAssigned() const;
    143   bool CalledOnValidThread() const;
    144 
    145   // The task runner used to perform NSS operations.
    146   scoped_refptr<base::SequencedTaskRunner> nss_task_runner_;
    147   scoped_ptr<ClientSocketHandle> transport_;
    148   HostPortPair host_and_port_;
    149   SSLConfig ssl_config_;
    150 
    151   scoped_refptr<Core> core_;
    152 
    153   CompletionCallback user_connect_callback_;
    154 
    155   CertVerifyResult server_cert_verify_result_;
    156   HashValueVector side_pinned_public_keys_;
    157 
    158   CertVerifier* const cert_verifier_;
    159   scoped_ptr<SingleRequestCertVerifier> verifier_;
    160 
    161   // The service for retrieving Channel ID keys.  May be NULL.
    162   ServerBoundCertService* server_bound_cert_service_;
    163 
    164   // ssl_session_cache_shard_ is an opaque string that partitions the SSL
    165   // session cache. i.e. sessions created with one value will not attempt to
    166   // resume on the socket with a different value.
    167   const std::string ssl_session_cache_shard_;
    168 
    169   // True if the SSL handshake has been completed.
    170   bool completed_handshake_;
    171 
    172   State next_handshake_state_;
    173 
    174   // The NSS SSL state machine. This is owned by |core_|.
    175   // TODO(rsleevi): http://crbug.com/130616 - Remove this member once
    176   // ExportKeyingMaterial is updated to be asynchronous.
    177   PRFileDesc* nss_fd_;
    178 
    179   BoundNetLog net_log_;
    180 
    181   base::TimeTicks start_cert_verification_time_;
    182 
    183   TransportSecurityState* transport_security_state_;
    184 
    185   // The following two variables are added for debugging bug 65948. Will
    186   // remove this code after fixing bug 65948.
    187   // Added the following code Debugging in release mode.
    188   mutable base::Lock lock_;
    189   // This is mutable so that CalledOnValidThread can set it.
    190   // It's guarded by |lock_|.
    191   mutable base::PlatformThreadId valid_thread_id_;
    192 };
    193 
    194 }  // namespace net
    195 
    196 #endif  // NET_SOCKET_SSL_CLIENT_SOCKET_NSS_H_
    197