tor-browser

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

tls_server.cc (3401B)


      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 <cassert>
      6 #include <cstdint>
      7 #include <iostream>
      8 
      9 #include "blapi.h"
     10 #include "seccomon.h"
     11 #include "ssl.h"
     12 #include "sslimpl.h"
     13 
     14 #include "base/database.h"
     15 #include "base/mutate.h"
     16 #include "tls/common.h"
     17 #include "tls/mutators.h"
     18 #include "tls/server_certs.h"
     19 #include "tls/server_config.h"
     20 #include "tls/socket.h"
     21 
     22 #ifdef IS_DTLS_FUZZ
     23 #define ImportFD DTLS_ImportFD
     24 #else
     25 #define ImportFD SSL_ImportFD
     26 #endif  // IS_DTLS_FUZZ
     27 
     28 class SSLServerSessionCache {
     29 public:
     30  SSLServerSessionCache() {
     31    assert(SSL_ConfigServerSessionIDCache(1024, 0, 0, ".") == SECSuccess);
     32  }
     33 
     34  ~SSLServerSessionCache() {
     35    assert(SSL_ShutdownServerSessionIDCache() == SECSuccess);
     36  }
     37 };
     38 
     39 static PRStatus InitModelSocket(void* arg) {
     40  PRFileDesc* fd = reinterpret_cast<PRFileDesc*>(arg);
     41 
     42  TlsCommon::EnableAllCipherSuites(fd);
     43  TlsServer::InstallServerCertificates(fd);
     44 
     45  return PR_SUCCESS;
     46 }
     47 
     48 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
     49  static NSSDatabase db = NSSDatabase();
     50  static SSLServerSessionCache cache = SSLServerSessionCache();
     51  static PRDescIdentity id = PR_GetUniqueIdentity("fuzz-server");
     52 
     53  // Create model socket.
     54  static ScopedPRFileDesc model(ImportFD(nullptr, PR_NewTCPSocket()));
     55  assert(model);
     56 
     57  // Initialize the model socket once.
     58  static PRCallOnceType initModelOnce;
     59  PR_CallOnceWithArg(&initModelOnce, InitModelSocket, model.get());
     60 
     61  // Create and import dummy socket.
     62  TlsSocket::DummyPrSocket socket = TlsSocket::DummyPrSocket(data, size);
     63  ScopedPRFileDesc prFd(DummyIOLayerMethods::CreateFD(id, &socket));
     64  PRFileDesc* sslFd = ImportFD(model.get(), prFd.get());
     65  assert(sslFd == prFd.get());
     66 
     67  // Derive server config from input data.
     68  TlsServer::Config config = TlsServer::Config(data, size);
     69 
     70  if (ssl_trace >= 90) {
     71    std::cerr << config << "\n";
     72  }
     73 
     74  // Keeping things determinstic.
     75  assert(RNG_RandomUpdate(NULL, 0) == SECSuccess);
     76  assert(SSL_SetURL(sslFd, "fuzz.server") == SECSuccess);
     77 
     78  TlsCommon::EnableAllProtocolVersions();
     79  TlsCommon::EnableAllCipherSuites(sslFd);
     80  TlsCommon::FixTime(sslFd);
     81 
     82  // Set socket options from server config.
     83  config.SetCallbacks(sslFd);
     84  config.SetSocketOptions(sslFd);
     85 
     86  // Perform the acutal handshake.
     87  TlsCommon::DoHandshake(sslFd, true);
     88 
     89  // Clear the cache. We never want to resume as we couldn't reproduce that.
     90  SSL_ClearSessionCache();
     91 
     92  return 0;
     93 }
     94 
     95 extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
     96                                          size_t maxSize, unsigned int seed) {
     97  return CustomMutate(
     98      {TlsMutators::DropRecord, TlsMutators::ShuffleRecords,
     99       TlsMutators::DuplicateRecord, TlsMutators::TruncateRecord,
    100       TlsMutators::FragmentRecord},
    101      data, size, maxSize, seed);
    102 }
    103 
    104 extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t* data1, size_t size1,
    105                                            const uint8_t* data2, size_t size2,
    106                                            uint8_t* out, size_t maxOutSize,
    107                                            unsigned int seed) {
    108  return TlsMutators::CrossOver(data1, size1, data2, size2, out, maxOutSize,
    109                                seed);
    110 }