server_config.cc (7207B)
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 "server_config.h" 6 7 #include <cassert> 8 #include <cstddef> 9 #include <cstdint> 10 11 #include "nss_scoped_ptrs.h" 12 #include "pk11pub.h" 13 #include "prio.h" 14 #include "seccomon.h" 15 #include "ssl.h" 16 #include "sslexp.h" 17 #include "sslt.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 26 static SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checksig, 27 PRBool isServer) { 28 assert(isServer); 29 auto config = reinterpret_cast<TlsServer::Config*>(arg); 30 if (config->FailCertificateAuthentication()) return SECFailure; 31 32 return SECSuccess; 33 } 34 35 static SECStatus CanFalseStartCallback(PRFileDesc* fd, void* arg, 36 PRBool* canFalseStart) { 37 *canFalseStart = true; 38 return SECSuccess; 39 } 40 41 namespace TlsServer { 42 43 // XOR 64-bit chunks of data to build a bitmap of config options derived from 44 // the fuzzing input. This seems the only way to fuzz various options while 45 // still maintaining compatibility with BoringSSL or OpenSSL fuzzers. 46 Config::Config(const uint8_t* data, size_t len) { 47 union { 48 uint64_t bitmap; 49 struct { 50 uint32_t config; 51 uint16_t ssl_version_range_min; 52 uint16_t ssl_version_range_max; 53 }; 54 }; 55 56 for (size_t i = 0; i < len; i++) { 57 bitmap ^= static_cast<uint64_t>(data[i]) << (8 * (i % 8)); 58 } 59 60 // Map SSL version values to a valid range. 61 ssl_version_range_min = 62 SSL_VERSION_RANGE_MIN_VALID + 63 (ssl_version_range_min % 64 (1 + SSL_VERSION_RANGE_MAX_VALID - SSL_VERSION_RANGE_MIN_VALID)); 65 ssl_version_range_max = 66 ssl_version_range_min + 67 (ssl_version_range_max % 68 (1 + SSL_VERSION_RANGE_MAX_VALID - ssl_version_range_min)); 69 70 config_ = config; 71 ssl_version_range_ = { 72 .min = ssl_version_range_min, 73 .max = ssl_version_range_max, 74 }; 75 } 76 77 void Config::SetCallbacks(PRFileDesc* fd) { 78 SECStatus rv = SSL_AuthCertificateHook(fd, AuthCertificateHook, this); 79 assert(rv == SECSuccess); 80 81 rv = SSL_SetCanFalseStartCallback(fd, CanFalseStartCallback, nullptr); 82 assert(rv == SECSuccess); 83 } 84 85 void Config::SetSocketOptions(PRFileDesc* fd) { 86 SECStatus rv = SSL_OptionSet(fd, SSL_ENABLE_EXTENDED_MASTER_SECRET, 87 this->EnableExtendedMasterSecret()); 88 assert(rv == SECSuccess); 89 90 rv = SSL_OptionSet(fd, SSL_REQUEST_CERTIFICATE, this->RequestCertificate()); 91 assert(rv == SECSuccess); 92 93 rv = SSL_OptionSet(fd, SSL_REQUIRE_CERTIFICATE, this->RequireCertificate()); 94 assert(rv == SECSuccess); 95 96 rv = SSL_OptionSet(fd, SSL_ENABLE_DEFLATE, this->EnableDeflate()); 97 assert(rv == SECSuccess); 98 99 rv = SSL_OptionSet(fd, SSL_CBC_RANDOM_IV, this->EnableCbcRandomIv()); 100 assert(rv == SECSuccess); 101 102 rv = SSL_OptionSet(fd, SSL_REQUIRE_SAFE_NEGOTIATION, 103 this->RequireSafeNegotiation()); 104 assert(rv == SECSuccess); 105 106 rv = SSL_OptionSet(fd, SSL_NO_CACHE, this->NoCache()); 107 assert(rv == SECSuccess); 108 109 rv = SSL_OptionSet(fd, SSL_ENABLE_GREASE, this->EnableGrease()); 110 assert(rv == SECSuccess); 111 112 if (this->SetCertificateCompressionAlgorithm()) { 113 rv = SSL_SetCertificateCompressionAlgorithm(fd, kCompressionAlg); 114 assert(rv == SECSuccess); 115 } 116 117 if (this->SetVersionRange()) { 118 rv = SSL_VersionRangeSet(fd, &ssl_version_range_); 119 assert(rv == SECSuccess); 120 } 121 122 if (this->AddExternalPsk()) { 123 ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); 124 assert(slot); 125 126 ScopedPK11SymKey key(PK11_KeyGen(slot.get(), CKM_NSS_CHACHA20_POLY1305, 127 nullptr, 32, nullptr)); 128 assert(key); 129 130 rv = SSL_AddExternalPsk(fd, key.get(), kPskIdentity, 131 sizeof(kPskIdentity) - 1, this->PskHashType()); 132 assert(rv == SECSuccess); 133 } 134 135 rv = SSL_OptionSet(fd, SSL_ENABLE_0RTT_DATA, this->EnableZeroRtt()); 136 assert(rv == SECSuccess); 137 138 rv = SSL_OptionSet(fd, SSL_ENABLE_ALPN, this->EnableAlpn()); 139 assert(rv == SECSuccess); 140 141 rv = SSL_OptionSet(fd, SSL_ENABLE_FALLBACK_SCSV, this->EnableFallbackScsv()); 142 assert(rv == SECSuccess); 143 144 rv = SSL_OptionSet(fd, SSL_ENABLE_SESSION_TICKETS, 145 this->EnableSessionTickets()); 146 assert(rv == SECSuccess); 147 148 rv = SSL_OptionSet(fd, SSL_NO_LOCKS, this->NoLocks()); 149 assert(rv == SECSuccess); 150 151 rv = SSL_EnableTls13BackendEch(fd, this->EnableTls13BackendEch()); 152 assert(rv == SECSuccess); 153 154 rv = SSL_OptionSet(fd, SSL_ENABLE_DELEGATED_CREDENTIALS, 155 this->EnableDelegatedCredentials()); 156 assert(rv == SECSuccess); 157 158 rv = SSL_OptionSet(fd, SSL_ENABLE_DTLS_SHORT_HEADER, 159 this->EnableDtlsShortHeader()); 160 assert(rv == SECSuccess); 161 162 #ifndef IS_DTLS_FUZZ 163 rv = 164 SSL_OptionSet(fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED); 165 assert(rv == SECSuccess); 166 #endif 167 } 168 169 std::ostream& operator<<(std::ostream& out, Config& config) { 170 out << "============= ServerConfig =============" 171 << "\n"; 172 out << "SSL_NO_CACHE: " << config.NoCache() << "\n"; 173 out << "SSL_ENABLE_EXTENDED_MASTER_SECRET: " 174 << config.EnableExtendedMasterSecret() << "\n"; 175 out << "SSL_REQUEST_CERTIFICATE: " 176 << config.RequestCertificate() << "\n"; 177 out << "SSL_REQUIRE_CERTIFICATE: " 178 << config.RequireCertificate() << "\n"; 179 out << "SSL_ENABLE_DEFLATE: " << config.EnableDeflate() 180 << "\n"; 181 out << "SSL_CBC_RANDOM_IV: " 182 << config.EnableCbcRandomIv() << "\n"; 183 out << "SSL_REQUIRE_SAFE_NEGOTIATION: " 184 << config.RequireSafeNegotiation() << "\n"; 185 out << "SSL_ENABLE_GREASE: " << config.EnableGrease() 186 << "\n"; 187 out << "SSL_SetCertificateCompressionAlgorithm: " 188 << config.SetCertificateCompressionAlgorithm() << "\n"; 189 out << "SSL_VersionRangeSet: " << config.SetVersionRange() 190 << "\n"; 191 out << " Min: " 192 << config.SslVersionRange().min << "\n"; 193 out << " Max: " 194 << config.SslVersionRange().max << "\n"; 195 out << "SSL_AddExternalPsk: " << config.AddExternalPsk() 196 << "\n"; 197 out << " Type: " << config.PskHashType() 198 << "\n"; 199 out << "SSL_ENABLE_0RTT_DATA: " << config.EnableZeroRtt() 200 << "\n"; 201 out << "SSL_ENABLE_ALPN: " << config.EnableAlpn() 202 << "\n"; 203 out << "SSL_ENABLE_FALLBACK_SCSV: " 204 << config.EnableFallbackScsv() << "\n"; 205 out << "SSL_ENABLE_SESSION_TICKETS: " 206 << config.EnableSessionTickets() << "\n"; 207 out << "SSL_NO_LOCKS: " << config.NoLocks() << "\n"; 208 out << "========================================"; 209 210 return out; 211 } 212 213 } // namespace TlsServer