tor-browser

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

tls_parser.h (5543B)


      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 #ifndef tls_parser_h_
      8 #define tls_parser_h_
      9 
     10 #include <cstdint>
     11 #include <cstring>
     12 #include <memory>
     13 #if defined(WIN32) || defined(WIN64)
     14 #include <winsock2.h>
     15 #else
     16 #include <arpa/inet.h>
     17 #endif
     18 #include "databuffer.h"
     19 #include "sslt.h"
     20 
     21 namespace nss_test {
     22 
     23 const uint8_t kTlsHandshakeClientHello = 1;
     24 const uint8_t kTlsHandshakeServerHello = 2;
     25 const uint8_t kTlsHandshakeNewSessionTicket = 4;
     26 const uint8_t kTlsHandshakeHelloRetryRequest = 6;
     27 const uint8_t kTlsHandshakeEncryptedExtensions = 8;
     28 const uint8_t kTlsHandshakeCertificate = 11;
     29 const uint8_t kTlsHandshakeServerKeyExchange = 12;
     30 const uint8_t kTlsHandshakeCertificateRequest = 13;
     31 const uint8_t kTlsHandshakeCertificateVerify = 15;
     32 const uint8_t kTlsHandshakeClientKeyExchange = 16;
     33 const uint8_t kTlsHandshakeFinished = 20;
     34 const uint8_t kTlsHandshakeKeyUpdate = 24;
     35 const uint8_t kTlsHandshakeCertificateCompression = 25;
     36 
     37 const uint8_t kTlsAlertWarning = 1;
     38 const uint8_t kTlsAlertFatal = 2;
     39 
     40 const uint8_t kTlsAlertCloseNotify = 0;
     41 const uint8_t kTlsAlertUnexpectedMessage = 10;
     42 const uint8_t kTlsAlertBadRecordMac = 20;
     43 const uint8_t kTlsAlertRecordOverflow = 22;
     44 const uint8_t kTlsAlertHandshakeFailure = 40;
     45 const uint8_t kTlsAlertBadCertificate = 42;
     46 const uint8_t kTlsAlertCertificateRevoked = 44;
     47 const uint8_t kTlsAlertCertificateExpired = 45;
     48 const uint8_t kTlsAlertIllegalParameter = 47;
     49 const uint8_t kTlsAlertDecodeError = 50;
     50 const uint8_t kTlsAlertDecryptError = 51;
     51 const uint8_t kTlsAlertProtocolVersion = 70;
     52 const uint8_t kTlsAlertInsufficientSecurity = 71;
     53 const uint8_t kTlsAlertInternalError = 80;
     54 const uint8_t kTlsAlertInappropriateFallback = 86;
     55 const uint8_t kTlsAlertMissingExtension = 109;
     56 const uint8_t kTlsAlertUnsupportedExtension = 110;
     57 const uint8_t kTlsAlertUnrecognizedName = 112;
     58 const uint8_t kTlsAlertCertificateRequired = 116;
     59 const uint8_t kTlsAlertNoApplicationProtocol = 120;
     60 const uint8_t kTlsAlertEchRequired = 121;
     61 
     62 const uint8_t kTlsFakeChangeCipherSpec[] = {
     63    ssl_ct_change_cipher_spec,  // Type
     64    0xfe,
     65    0xff,  // Version
     66    0x00,
     67    0x00,
     68    0x00,
     69    0x00,
     70    0x00,
     71    0x00,
     72    0x00,
     73    0x10,  // Fictitious sequence #
     74    0x00,
     75    0x01,  // Length
     76    0x01   // Value
     77 };
     78 
     79 const uint8_t kCtDtlsCiphertext = 0x20;
     80 const uint8_t kCtDtlsCiphertextMask = 0xE0;
     81 const uint8_t kCtDtlsCiphertext16bSeqno = 0x08;
     82 const uint8_t kCtDtlsCiphertextLengthPresent = 0x04;
     83 
     84 static const uint8_t kTls13PskKe = 0;
     85 static const uint8_t kTls13PskDhKe = 1;
     86 static const uint8_t kTls13PskAuth = 0;
     87 static const uint8_t kTls13PskSignAuth = 1;
     88 
     89 inline std::ostream& operator<<(std::ostream& os, SSLProtocolVariant v) {
     90  return os << ((v == ssl_variant_stream) ? "TLS" : "DTLS");
     91 }
     92 
     93 inline std::ostream& operator<<(std::ostream& os, SSLContentType v) {
     94  switch (v) {
     95    case ssl_ct_change_cipher_spec:
     96      return os << "CCS";
     97    case ssl_ct_alert:
     98      return os << "alert";
     99    case ssl_ct_handshake:
    100      return os << "handshake";
    101    case ssl_ct_application_data:
    102      return os << "application data";
    103    case ssl_ct_ack:
    104      return os << "ack";
    105  }
    106  return os << "UNKNOWN content type " << static_cast<int>(v);
    107 }
    108 
    109 inline std::ostream& operator<<(std::ostream& os, SSLSecretDirection v) {
    110  switch (v) {
    111    case ssl_secret_read:
    112      return os << "read";
    113    case ssl_secret_write:
    114      return os << "write";
    115  }
    116  return os << "UNKNOWN secret direction " << static_cast<int>(v);
    117 }
    118 
    119 inline bool IsDtls(uint16_t version) { return (version & 0x8000) == 0x8000; }
    120 
    121 inline uint16_t NormalizeTlsVersion(uint16_t version) {
    122  if (version == 0xfeff) {
    123    return 0x0302;  // special: DTLS 1.0 == TLS 1.1
    124  }
    125  if (IsDtls(version)) {
    126    return (version ^ 0xffff) + 0x0201;
    127  }
    128  return version;
    129 }
    130 
    131 inline uint16_t TlsVersionToDtlsVersion(uint16_t version) {
    132  if (version == 0x0302) {
    133    return 0xfeff;
    134  }
    135  if (version == 0x0304) {
    136    return version;
    137  }
    138  return 0xffff - version + 0x0201;
    139 }
    140 
    141 inline size_t WriteVariable(DataBuffer* target, size_t index,
    142                            const DataBuffer& buf, size_t len_size) {
    143  index = target->Write(index, static_cast<uint32_t>(buf.len()), len_size);
    144  return target->Write(index, buf.data(), buf.len());
    145 }
    146 
    147 class TlsParser {
    148 public:
    149  TlsParser(const uint8_t* data, size_t len) : buffer_(data, len), offset_(0) {}
    150  explicit TlsParser(const DataBuffer& buf) : buffer_(buf), offset_(0) {}
    151 
    152  bool Read(uint8_t* val);
    153  // Read an integral type of specified width.
    154  bool Read(uint32_t* val, size_t size);
    155  // Reads len bytes into dest buffer, overwriting it.
    156  bool Read(DataBuffer* dest, size_t len);
    157  bool ReadFromMark(DataBuffer* val, size_t len, size_t mark);
    158  // Reads bytes into dest buffer, overwriting it.  The number of bytes is
    159  // determined by reading from len_size bytes from the stream first.
    160  bool ReadVariable(DataBuffer* dest, size_t len_size);
    161 
    162  bool Skip(size_t len);
    163  bool SkipVariable(size_t len_size);
    164 
    165  size_t consumed() const { return offset_; }
    166  size_t remaining() const { return buffer_.len() - offset_; }
    167 
    168 private:
    169  void consume(size_t len) { offset_ += len; }
    170  const uint8_t* ptr() const { return buffer_.data() + offset_; }
    171 
    172  DataBuffer buffer_;
    173  size_t offset_;
    174 };
    175 
    176 }  // namespace nss_test
    177 
    178 #endif