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 }