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