summaryrefslogtreecommitdiff
path: root/fuzz
diff options
context:
space:
mode:
authorTim Taubert <ttaubert@mozilla.com>2017-02-13 20:31:22 +0100
committerTim Taubert <ttaubert@mozilla.com>2017-02-13 20:31:22 +0100
commitd6f390bd6435ad8d602c6ba9f4d7d1221fd892e8 (patch)
treebedff4479dd5536375595832ba984369768fdc1f /fuzz
parent36e1d7970d4dfef665245896736d8d75b9b4135c (diff)
downloadnss-hg-d6f390bd6435ad8d602c6ba9f4d7d1221fd892e8.tar.gz
Bug 1338620 - Derive tls-client fuzzer configuration from input data r=franziskus
Differential Revision: https://nss-review.dev.mozaws.net/D205
Diffstat (limited to 'fuzz')
-rw-r--r--fuzz/fuzz.gyp1
-rw-r--r--fuzz/tls_client_config.cc35
-rw-r--r--fuzz/tls_client_config.h24
-rw-r--r--fuzz/tls_client_target.cc39
4 files changed, 87 insertions, 12 deletions
diff --git a/fuzz/fuzz.gyp b/fuzz/fuzz.gyp
index 9e0444100..a51be799a 100644
--- a/fuzz/fuzz.gyp
+++ b/fuzz/fuzz.gyp
@@ -248,6 +248,7 @@
'target_name': 'nssfuzz-tls-client',
'type': 'executable',
'sources': [
+ 'tls_client_config.cc',
'tls_client_socket.cc',
'tls_client_target.cc',
],
diff --git a/fuzz/tls_client_config.cc b/fuzz/tls_client_config.cc
new file mode 100644
index 000000000..78ab591e3
--- /dev/null
+++ b/fuzz/tls_client_config.cc
@@ -0,0 +1,35 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "tls_client_config.h"
+
+const uint64_t CONFIG_FAIL_CERT_AUTH = 1;
+const uint64_t CONFIG_ENABLE_EXTENDED_MS = 2;
+const uint64_t CONFIG_REQUIRE_DH_NAMED_GROUPS = 4;
+const uint64_t CONFIG_ENABLE_FALSE_START = 8;
+
+// XOR 64-bit chunks of data to build a bitmap of config options derived from
+// the fuzzing input. This seems the only way to fuzz various options while
+// still maintaining compatibility with BoringSSL or OpenSSL fuzzers.
+ClientConfig::ClientConfig(const uint8_t* data, size_t len) {
+ for (size_t i = 0; i < len; i++) {
+ config_ ^= static_cast<uint64_t>(data[i]) << (8 * (i % 8));
+ }
+}
+
+bool ClientConfig::FailCertificateAuthentication() {
+ return config_ & CONFIG_FAIL_CERT_AUTH;
+}
+
+bool ClientConfig::EnableExtendedMasterSecret() {
+ return config_ & CONFIG_ENABLE_EXTENDED_MS;
+}
+
+bool ClientConfig::RequireDhNamedGroups() {
+ return config_ & CONFIG_REQUIRE_DH_NAMED_GROUPS;
+}
+
+bool ClientConfig::EnableFalseStart() {
+ return config_ & CONFIG_ENABLE_FALSE_START;
+}
diff --git a/fuzz/tls_client_config.h b/fuzz/tls_client_config.h
new file mode 100644
index 000000000..9cf3cf208
--- /dev/null
+++ b/fuzz/tls_client_config.h
@@ -0,0 +1,24 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef tls_client_config_h__
+#define tls_client_config_h__
+
+#include <stdint.h>
+#include <cstddef>
+
+class ClientConfig {
+ public:
+ ClientConfig(const uint8_t* data, size_t len);
+
+ bool FailCertificateAuthentication();
+ bool EnableExtendedMasterSecret();
+ bool RequireDhNamedGroups();
+ bool EnableFalseStart();
+
+ private:
+ uint64_t config_;
+};
+
+#endif // tls_client_config_h__
diff --git a/fuzz/tls_client_target.cc b/fuzz/tls_client_target.cc
index 4d8ed9ee9..fdc447916 100644
--- a/fuzz/tls_client_target.cc
+++ b/fuzz/tls_client_target.cc
@@ -11,6 +11,7 @@
#include "ssl.h"
#include "shared.h"
+#include "tls_client_config.h"
#include "tls_client_socket.h"
static PRStatus EnableAllProtocolVersions() {
@@ -27,24 +28,26 @@ static PRStatus EnableAllProtocolVersions() {
static SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checksig,
PRBool isServer) {
- return SECSuccess;
+ assert(!isServer);
+ auto config = reinterpret_cast<ClientConfig*>(arg);
+ return config->FailCertificateAuthentication() ? SECFailure : SECSuccess;
}
-static void SetSocketOptions(PRFileDesc* fd) {
+static void SetSocketOptions(PRFileDesc* fd,
+ std::unique_ptr<ClientConfig>& config) {
// Disable session cache for now.
SECStatus rv = SSL_OptionSet(fd, SSL_NO_CACHE, true);
assert(rv == SECSuccess);
- rv = SSL_OptionSet(fd, SSL_ENABLE_EXTENDED_MASTER_SECRET, true);
- assert(rv == SECSuccess);
-
- rv = SSL_OptionSet(fd, SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, true);
+ rv = SSL_OptionSet(fd, SSL_ENABLE_EXTENDED_MASTER_SECRET,
+ config->EnableExtendedMasterSecret());
assert(rv == SECSuccess);
- rv = SSL_OptionSet(fd, SSL_ENABLE_FALLBACK_SCSV, true);
+ rv = SSL_OptionSet(fd, SSL_REQUIRE_DH_NAMED_GROUPS,
+ config->RequireDhNamedGroups());
assert(rv == SECSuccess);
- rv = SSL_OptionSet(fd, SSL_ENABLE_ALPN, true);
+ rv = SSL_OptionSet(fd, SSL_ENABLE_FALSE_START, config->EnableFalseStart());
assert(rv == SECSuccess);
rv =
@@ -59,8 +62,19 @@ static void EnableAllCipherSuites(PRFileDesc* fd) {
}
}
-static void SetupAuthCertificateHook(PRFileDesc* fd) {
- SECStatus rv = SSL_AuthCertificateHook(fd, AuthCertificateHook, nullptr);
+// This is only called when we set SSL_ENABLE_FALSE_START=1,
+// so we can always just set *canFalseStart=true.
+static SECStatus CanFalseStartCallback(PRFileDesc* fd, void* arg,
+ PRBool* canFalseStart) {
+ *canFalseStart = true;
+ return SECSuccess;
+}
+
+static void SetupCallbacks(PRFileDesc* fd, ClientConfig* config) {
+ SECStatus rv = SSL_AuthCertificateHook(fd, AuthCertificateHook, config);
+ assert(rv == SECSuccess);
+
+ rv = SSL_SetCanFalseStartCallback(fd, CanFalseStartCallback, nullptr);
assert(rv == SECSuccess);
}
@@ -89,6 +103,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
assert(db != nullptr);
EnableAllProtocolVersions();
+ std::unique_ptr<ClientConfig> config(new ClientConfig(data, len));
// Reset the RNG state.
SECStatus rv = RNG_ResetForFuzzing();
@@ -104,9 +119,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
// Probably not too important for clients.
SSL_SetURL(ssl_fd, "server");
- SetSocketOptions(ssl_fd);
+ SetSocketOptions(ssl_fd, config);
EnableAllCipherSuites(ssl_fd);
- SetupAuthCertificateHook(ssl_fd);
+ SetupCallbacks(ssl_fd, config.get());
DoHandshake(ssl_fd);
return 0;