tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

transportlayerdtls.h (6190B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 // Original author: ekr@rtfm.com
      8 
      9 #ifndef transportlayerdtls_h__
     10 #define transportlayerdtls_h__
     11 
     12 #include <queue>
     13 #include <set>
     14 
     15 #ifdef XP_MACOSX
     16 // ensure that Apple Security kit enum goes before "sslproto.h"
     17 #  include <CoreFoundation/CFAvailability.h>
     18 #  include <Security/CipherSuite.h>
     19 #endif
     20 
     21 #include "ScopedNSSTypes.h"
     22 #include "dtlsidentity.h"
     23 #include "m_cpp_utils.h"
     24 #include "mozilla/RefPtr.h"
     25 #include "mozilla/UniquePtr.h"
     26 #include "nsCOMPtr.h"
     27 #include "nsITimer.h"
     28 #include "ssl.h"
     29 #include "sslproto.h"
     30 #include "transportlayer.h"
     31 
     32 namespace mozilla {
     33 
     34 // RFC 5764 (we don't support the NULL cipher)
     35 static const uint16_t kDtlsSrtpAes128CmHmacSha1_80 = 0x0001;
     36 static const uint16_t kDtlsSrtpAes128CmHmacSha1_32 = 0x0002;
     37 // RFC 7714
     38 static const uint16_t kDtlsSrtpAeadAes128Gcm = 0x0007;
     39 static const uint16_t kDtlsSrtpAeadAes256Gcm = 0x0008;
     40 
     41 struct Packet;
     42 
     43 class TransportLayerNSPRAdapter {
     44 public:
     45  explicit TransportLayerNSPRAdapter(TransportLayer* output)
     46      : output_(output), enabled_(true) {}
     47 
     48  void PacketReceived(MediaPacket& packet);
     49  int32_t Recv(void* buf, int32_t buflen);
     50  int32_t Write(const void* buf, int32_t length);
     51  void SetEnabled(bool enabled) { enabled_ = enabled; }
     52 
     53 private:
     54  DISALLOW_COPY_ASSIGN(TransportLayerNSPRAdapter);
     55 
     56  TransportLayer* output_;
     57  std::queue<MediaPacket*> input_;
     58  bool enabled_;
     59 };
     60 
     61 class TransportLayerDtls final : public TransportLayer {
     62 public:
     63  TransportLayerDtls() = default;
     64 
     65  virtual ~TransportLayerDtls();
     66 
     67  enum Role { CLIENT, SERVER };
     68  enum Verification { VERIFY_UNSET, VERIFY_ALLOW_ALL, VERIFY_DIGEST };
     69 
     70  // DTLS-specific operations
     71  void SetRole(Role role) { role_ = role; }
     72  Role role() { return role_; }
     73 
     74  enum class Version : uint16_t {
     75    DTLS_1_0 = SSL_LIBRARY_VERSION_DTLS_1_0,
     76    DTLS_1_2 = SSL_LIBRARY_VERSION_DTLS_1_2,
     77    DTLS_1_3 = SSL_LIBRARY_VERSION_DTLS_1_3
     78  };
     79  void SetMinMaxVersion(Version min_version, Version max_version);
     80 
     81  void SetIdentity(const RefPtr<DtlsIdentity>& identity) {
     82    identity_ = identity;
     83  }
     84  nsresult SetAlpn(const std::set<std::string>& allowedAlpn,
     85                   const std::string& alpnDefault);
     86  const std::string& GetNegotiatedAlpn() const { return alpn_; }
     87 
     88  nsresult SetVerificationAllowAll();
     89 
     90  nsresult SetVerificationDigest(const DtlsDigest& digest);
     91 
     92  nsresult GetCipherSuite(uint16_t* cipherSuite) const;
     93 
     94  nsresult SetSrtpCiphers(const std::vector<uint16_t>& ciphers);
     95  nsresult GetSrtpCipher(uint16_t* cipher) const;
     96  static std::vector<uint16_t> GetDefaultSrtpCiphers();
     97 
     98  nsresult ExportKeyingMaterial(const std::string& label, bool use_context,
     99                                const std::string& context, unsigned char* out,
    100                                unsigned int outlen);
    101 
    102  // Transport layer overrides.
    103  nsresult InitInternal() override;
    104  void WasInserted() override;
    105  TransportResult SendPacket(MediaPacket& packet) override;
    106 
    107  // Signals
    108  void StateChange(TransportLayer* layer, State state);
    109  void PacketReceived(TransportLayer* layer, MediaPacket& packet);
    110 
    111  // For testing use only.  Returns the fd.
    112  PRFileDesc* internal_fd() {
    113    CheckThread();
    114    return ssl_fd_.get();
    115  }
    116 
    117  TRANSPORT_LAYER_ID("dtls")
    118 
    119 protected:
    120  void SetState(State state, const char* file, unsigned line) override;
    121 
    122 private:
    123  DISALLOW_COPY_ASSIGN(TransportLayerDtls);
    124 
    125  bool Setup();
    126  bool SetupCipherSuites(UniquePRFileDesc& ssl_fd);
    127  bool SetupAlpn(UniquePRFileDesc& ssl_fd) const;
    128  void GetDecryptedPackets();
    129  void Handshake();
    130 
    131  bool CheckAlpn();
    132 
    133  static SECStatus GetClientAuthDataHook(void* arg, PRFileDesc* fd,
    134                                         CERTDistNames* caNames,
    135                                         CERTCertificate** pRetCert,
    136                                         SECKEYPrivateKey** pRetKey);
    137  static SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd,
    138                                       PRBool checksig, PRBool isServer);
    139  SECStatus AuthCertificateHook(PRFileDesc* fd, PRBool checksig,
    140                                PRBool isServer);
    141 
    142  static void TimerCallback(nsITimer* timer, void* arg);
    143 
    144  SECStatus CheckDigest(const DtlsDigest& digest,
    145                        UniqueCERTCertificate& cert) const;
    146 
    147  void RecordHandshakeCompletionTelemetry(const char* aResult);
    148  void RecordStartedHandshakeTelemetry();
    149  void RecordTlsTelemetry();
    150 
    151  static PRBool WriteSrtpXtn(PRFileDesc* fd, SSLHandshakeType message,
    152                             uint8_t* data, unsigned int* len,
    153                             unsigned int max_len, void* arg);
    154 
    155  static SECStatus HandleSrtpXtn(PRFileDesc* fd, SSLHandshakeType message,
    156                                 const uint8_t* data, unsigned int len,
    157                                 SSLAlertDescription* alert, void* arg);
    158 
    159  RefPtr<DtlsIdentity> identity_;
    160  // What ALPN identifiers are permitted.
    161  std::set<std::string> alpn_allowed_;
    162  // What ALPN identifier is used if ALPN is not supported.
    163  // The empty string indicates that ALPN is required.
    164  std::string alpn_default_;
    165  // What ALPN string was negotiated.
    166  std::string alpn_;
    167  std::vector<uint16_t> enabled_srtp_ciphers_;
    168  uint16_t srtp_cipher_ = 0;
    169 
    170  Role role_ = CLIENT;
    171  Verification verification_mode_ = VERIFY_UNSET;
    172  std::vector<DtlsDigest> digests_;
    173 
    174  Version minVersion_ = Version::DTLS_1_0;
    175  Version maxVersion_ = Version::DTLS_1_2;
    176 
    177  // Must delete nspr_io_adapter after ssl_fd_ b/c ssl_fd_ causes an alert
    178  // (ssl_fd_ contains an un-owning pointer to nspr_io_adapter_)
    179  UniquePtr<TransportLayerNSPRAdapter> nspr_io_adapter_ = nullptr;
    180  UniquePRFileDesc ssl_fd_ = nullptr;
    181 
    182  nsCOMPtr<nsITimer> timer_ = nullptr;
    183  bool auth_hook_called_ = false;
    184  bool cert_ok_ = false;
    185 
    186  // We record once the fact that the handshake was started
    187  bool handshakeTelemetryRecorded = false;
    188 };
    189 
    190 }  // namespace mozilla
    191 #endif