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/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