tor-browser

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

client_config.cc (9086B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #include "client_config.h"
      6 
      7 #include <cassert>
      8 #include <cstddef>
      9 #include <cstdint>
     10 
     11 #include "nss_scoped_ptrs.h"
     12 #include "nssb64.h"
     13 #include "prio.h"
     14 #include "prtypes.h"
     15 #include "seccomon.h"
     16 #include "ssl.h"
     17 #include "sslexp.h"
     18 
     19 #include "common.h"
     20 
     21 const SSLCertificateCompressionAlgorithm kCompressionAlg = {
     22    0x1337, "fuzz", TlsCommon::DummyCompressionEncode,
     23    TlsCommon::DummyCompressionDecode};
     24 const PRUint8 kPskIdentity[] = "fuzz-psk-identity";
     25 #ifndef IS_DTLS_FUZZ
     26 const char kEchConfigs[] =
     27    "AEX+"
     28    "DQBBcQAgACDh4IuiuhhInUcKZx5uYcehlG9PQ1ZlzhvVZyjJl7dscQAEAAEAAQASY2xvdWRmbG"
     29    "FyZS1lY2guY29tAAA=";
     30 #endif  // IS_DTLS_FUZZ
     31 
     32 static SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checksig,
     33                                     PRBool isServer) {
     34  assert(!isServer);
     35 
     36  auto config = reinterpret_cast<TlsClient::Config*>(arg);
     37  if (config->FailCertificateAuthentication()) return SECFailure;
     38 
     39  return SECSuccess;
     40 }
     41 
     42 static SECStatus CanFalseStartCallback(PRFileDesc* fd, void* arg,
     43                                       PRBool* canFalseStart) {
     44  *canFalseStart = true;
     45  return SECSuccess;
     46 }
     47 
     48 namespace TlsClient {
     49 
     50 // XOR 64-bit chunks of data to build a bitmap of config options derived from
     51 // the fuzzing input. This seems the only way to fuzz various options while
     52 // still maintaining compatibility with BoringSSL or OpenSSL fuzzers.
     53 Config::Config(const uint8_t* data, size_t len) {
     54  union {
     55    uint64_t bitmap;
     56    struct {
     57      uint32_t config;
     58      uint16_t ssl_version_range_min;
     59      uint16_t ssl_version_range_max;
     60    };
     61  };
     62 
     63  for (size_t i = 0; i < len; i++) {
     64    bitmap ^= static_cast<uint64_t>(data[i]) << (8 * (i % 8));
     65  }
     66 
     67  // Map SSL version values to a valid range.
     68  ssl_version_range_min =
     69      SSL_VERSION_RANGE_MIN_VALID +
     70      (ssl_version_range_min %
     71       (1 + SSL_VERSION_RANGE_MAX_VALID - SSL_VERSION_RANGE_MIN_VALID));
     72  ssl_version_range_max =
     73      ssl_version_range_min +
     74      (ssl_version_range_max %
     75       (1 + SSL_VERSION_RANGE_MAX_VALID - ssl_version_range_min));
     76 
     77  config_ = config;
     78  ssl_version_range_ = {
     79      .min = ssl_version_range_min,
     80      .max = ssl_version_range_max,
     81  };
     82 }
     83 
     84 void Config::SetCallbacks(PRFileDesc* fd) {
     85  SECStatus rv = SSL_AuthCertificateHook(fd, AuthCertificateHook, this);
     86  assert(rv == SECSuccess);
     87 
     88  rv = SSL_SetCanFalseStartCallback(fd, CanFalseStartCallback, nullptr);
     89  assert(rv == SECSuccess);
     90 }
     91 
     92 void Config::SetSocketOptions(PRFileDesc* fd) {
     93  SECStatus rv = SSL_OptionSet(fd, SSL_ENABLE_EXTENDED_MASTER_SECRET,
     94                               this->EnableExtendedMasterSecret());
     95  assert(rv == SECSuccess);
     96 
     97  rv = SSL_OptionSet(fd, SSL_REQUIRE_DH_NAMED_GROUPS,
     98                     this->RequireDhNamedGroups());
     99  assert(rv == SECSuccess);
    100 
    101  rv = SSL_OptionSet(fd, SSL_ENABLE_FALSE_START, this->EnableFalseStart());
    102  assert(rv == SECSuccess);
    103 
    104  rv = SSL_OptionSet(fd, SSL_ENABLE_DEFLATE, this->EnableDeflate());
    105  assert(rv == SECSuccess);
    106 
    107  rv = SSL_OptionSet(fd, SSL_CBC_RANDOM_IV, this->CbcRandomIv());
    108  assert(rv == SECSuccess);
    109 
    110  rv = SSL_OptionSet(fd, SSL_REQUIRE_SAFE_NEGOTIATION,
    111                     this->RequireSafeNegotiation());
    112  assert(rv == SECSuccess);
    113 
    114  rv = SSL_OptionSet(fd, SSL_NO_CACHE, this->NoCache());
    115  assert(rv == SECSuccess);
    116 
    117  rv = SSL_OptionSet(fd, SSL_ENABLE_GREASE, this->EnableGrease());
    118  assert(rv == SECSuccess);
    119 
    120  rv = SSL_OptionSet(fd, SSL_ENABLE_CH_EXTENSION_PERMUTATION,
    121                     this->EnableCHExtensionPermutation());
    122  assert(rv == SECSuccess);
    123 
    124  if (this->SetCertificateCompressionAlgorithm()) {
    125    rv = SSL_SetCertificateCompressionAlgorithm(fd, kCompressionAlg);
    126    assert(rv == SECSuccess);
    127  }
    128 
    129  if (this->SetVersionRange()) {
    130    rv = SSL_VersionRangeSet(fd, &ssl_version_range_);
    131    assert(rv == SECSuccess);
    132  }
    133 
    134  if (this->AddExternalPsk()) {
    135    ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
    136    assert(slot);
    137 
    138    ScopedPK11SymKey key(PK11_KeyGen(slot.get(), CKM_NSS_CHACHA20_POLY1305,
    139                                     nullptr, 32, nullptr));
    140    assert(key);
    141 
    142    rv = SSL_AddExternalPsk(fd, key.get(), kPskIdentity,
    143                            sizeof(kPskIdentity) - 1, this->PskHashType());
    144    assert(rv == SECSuccess);
    145  }
    146 
    147  rv = SSL_OptionSet(fd, SSL_ENABLE_POST_HANDSHAKE_AUTH,
    148                     this->EnablePostHandshakeAuth());
    149  assert(rv == SECSuccess);
    150 
    151  rv = SSL_OptionSet(fd, SSL_ENABLE_0RTT_DATA, this->EnableZeroRtt());
    152  assert(rv == SECSuccess);
    153 
    154  rv = SSL_OptionSet(fd, SSL_ENABLE_ALPN, this->EnableAlpn());
    155  assert(rv == SECSuccess);
    156 
    157  rv = SSL_OptionSet(fd, SSL_ENABLE_FALLBACK_SCSV, this->EnableFallbackScsv());
    158  assert(rv == SECSuccess);
    159 
    160  rv = SSL_OptionSet(fd, SSL_ENABLE_OCSP_STAPLING, this->EnableOcspStapling());
    161  assert(rv == SECSuccess);
    162 
    163  rv = SSL_OptionSet(fd, SSL_ENABLE_SESSION_TICKETS,
    164                     this->EnableSessionTickets());
    165  assert(rv == SECSuccess);
    166 
    167  rv = SSL_OptionSet(fd, SSL_ENABLE_TLS13_COMPAT_MODE,
    168                     this->EnableTls13CompatMode());
    169  assert(rv == SECSuccess);
    170 
    171  rv = SSL_OptionSet(fd, SSL_NO_LOCKS, this->NoLocks());
    172  assert(rv == SECSuccess);
    173 
    174  rv = SSL_EnableTls13GreaseEch(fd, this->EnableTls13GreaseEch());
    175  assert(rv == SECSuccess);
    176 
    177  rv = SSL_SetDtls13VersionWorkaround(fd, this->SetDtls13VersionWorkaround());
    178  assert(rv == SECSuccess);
    179 
    180  rv = SSL_OptionSet(fd, SSL_ENABLE_DELEGATED_CREDENTIALS,
    181                     this->EnableDelegatedCredentials());
    182  assert(rv == SECSuccess);
    183 
    184  rv = SSL_OptionSet(fd, SSL_ENABLE_DTLS_SHORT_HEADER,
    185                     this->EnableDtlsShortHeader());
    186  assert(rv == SECSuccess);
    187 
    188 #ifndef IS_DTLS_FUZZ
    189  rv =
    190      SSL_OptionSet(fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED);
    191  assert(rv == SECSuccess);
    192 
    193  if (this->SetClientEchConfigs()) {
    194    ScopedSECItem echConfigsBin(NSSBase64_DecodeBuffer(
    195        nullptr, nullptr, kEchConfigs, sizeof(kEchConfigs)));
    196    assert(echConfigsBin);
    197 
    198    rv = SSL_SetClientEchConfigs(fd, echConfigsBin->data, echConfigsBin->len);
    199    assert(rv == SECSuccess);
    200  }
    201 #endif  // IS_DTLS_FUZZ
    202 }
    203 
    204 std::ostream& operator<<(std::ostream& out, Config& config) {
    205  out << "============= ClientConfig ============="
    206      << "\n";
    207  out << "SSL_NO_CACHE:                           " << config.NoCache() << "\n";
    208  out << "SSL_ENABLE_EXTENDED_MASTER_SECRET:      "
    209      << config.EnableExtendedMasterSecret() << "\n";
    210  out << "SSL_REQUIRE_DH_NAMED_GROUPS:            "
    211      << config.RequireDhNamedGroups() << "\n";
    212  out << "SSL_ENABLE_FALSE_START:                 " << config.EnableFalseStart()
    213      << "\n";
    214  out << "SSL_ENABLE_DEFLATE:                     " << config.EnableDeflate()
    215      << "\n";
    216  out << "SSL_CBC_RANDOM_IV:                      " << config.CbcRandomIv()
    217      << "\n";
    218  out << "SSL_REQUIRE_SAFE_NEGOTIATION:           "
    219      << config.RequireSafeNegotiation() << "\n";
    220  out << "SSL_ENABLE_GREASE:                      " << config.EnableGrease()
    221      << "\n";
    222  out << "SSL_ENABLE_CH_EXTENSION_PERMUTATION:    "
    223      << config.EnableCHExtensionPermutation() << "\n";
    224  out << "SSL_SetCertificateCompressionAlgorithm: "
    225      << config.SetCertificateCompressionAlgorithm() << "\n";
    226  out << "SSL_VersionRangeSet:                    " << config.SetVersionRange()
    227      << "\n";
    228  out << "  Min:                                  "
    229      << config.SslVersionRange().min << "\n";
    230  out << "  Max:                                  "
    231      << config.SslVersionRange().max << "\n";
    232  out << "SSL_AddExternalPsk:                     " << config.AddExternalPsk()
    233      << "\n";
    234  out << "  Type:                                 " << config.PskHashType()
    235      << "\n";
    236  out << "SSL_ENABLE_POST_HANDSHAKE_AUTH:         "
    237      << config.EnablePostHandshakeAuth() << "\n";
    238  out << "SSL_ENABLE_0RTT_DATA:                   " << config.EnableZeroRtt()
    239      << "\n";
    240  out << "SSL_ENABLE_ALPN:                        " << config.EnableAlpn()
    241      << "\n";
    242  out << "SSL_ENABLE_FALLBACK_SCSV:               "
    243      << config.EnableFallbackScsv() << "\n";
    244  out << "SSL_ENABLE_OCSP_STAPLING:               "
    245      << config.EnableOcspStapling() << "\n";
    246  out << "SSL_ENABLE_SESSION_TICKETS:             "
    247      << config.EnableSessionTickets() << "\n";
    248  out << "SSL_ENABLE_TLS13_COMPAT_MODE:           "
    249      << config.EnableTls13CompatMode() << "\n";
    250  out << "SSL_NO_LOCKS:                           " << config.NoLocks() << "\n";
    251  out << "SSL_EnableTls13GreaseEch:               "
    252      << config.EnableTls13GreaseEch() << "\n";
    253  out << "SSL_SetDtls13VersionWorkaround:         "
    254      << config.SetDtls13VersionWorkaround() << "\n";
    255  out << "SSL_SetClientEchConfigs:                "
    256      << config.SetClientEchConfigs() << "\n";
    257  out << "========================================";
    258 
    259  return out;
    260 }
    261 
    262 }  // namespace TlsClient