summaryrefslogtreecommitdiff
path: root/fuzz
diff options
context:
space:
mode:
authorMartin Thomson <mt@lowentropy.net>2019-05-20 09:45:56 +0100
committerMartin Thomson <mt@lowentropy.net>2019-05-20 09:45:56 +0100
commit2fb285c533cb19a01eeae798c76affea460f30ec (patch)
tree1cc155148ee7d1c7563561da10de1be4932f4ef9 /fuzz
parent390d9cfd74daaa3542ba11456ec36f0db74fd4df (diff)
downloadnss-hg-2fb285c533cb19a01eeae798c76affea460f30ec.tar.gz
Bug 1543874 - Use an external clock for SSL functions, r=ekr,kevinjacobs
Summary: This adds a new (experimental) API that allows users of libssl to provide their own clock function. This is primarily of use in testing, but it also enables our QUIC implementation, which also runs off an external clock. SSL Sockets (and session IDs, when they are in memory) now have a "now()" function and void* arg attached to them. By default, this is a function that calls PR_Now(). These values are copied from the socket to any session ID that is created from the socket, and to any session ID that is restored from the session cache. The ssl_Time() and ssl_TimeUsec() functions have been removed. As part of this, the experimental SSL_SetupAntiReplay() function had to be modified to take an external clock (PR_Now() suffices generally). That function relies on knowing the time, and it doesn't have a socket to work from. To avoid problems arising from the change in the signature, SSL_SetupAntiReplay is now removed. There are now three uses of time in the library: * The primary source of time runs of these newly added functions. This governs session expiry, 0-RTT checks, and related functions. * The session cache uses a separate time to manage its locking. This is of type PRUint32 in seconds (rather than PRTime in microseconds). In investigating this, I found several places where this time in seconds was leaking across to the main functions via the lastAccessTime property. That was fixed. The cache functions that use time now all call ssl_CacheNow() to get time. * DTLS timers run using PRIntervalTime. This is a little annoying and these could be made to use the main time source, but that would result in conversions between PRTime and PRIntervalTime at the DTLS API. PRIntervalTime has a different epoch to PRTime, so this would be a little awkward. Only the first of these can be controlled using the new API. Bugs found: * Expiration time of resumption tokens was based on the sid->expirationTime, which didn't account for the lifetime provided by the server. These are now capped by the minimum of ssl_ticket_lifetime and the value the server indicates. I removed ssl3_sid_timeout, the old limit, because inconsistent lifetimes between client and server messed with tests. The client would have a lower cap than the server, which prevented testing of the enforcement of server limits without jumping through hoops. * There was a missing time conversion in tls13_InWindow which made the window checks too lenient. * lastAccessTime was being set to seconds-since-epoch instead of microseconds-since-epoch in a few places. Reviewers: ekr, KevinJacobs Reviewed By: KevinJacobs Subscribers: cjpatton Bug #: 1543874 Differential Revision: https://phabricator.services.mozilla.com/D27238
Diffstat (limited to 'fuzz')
-rw-r--r--fuzz/tls_client_target.cc1
-rw-r--r--fuzz/tls_common.cc9
-rw-r--r--fuzz/tls_common.h1
-rw-r--r--fuzz/tls_server_target.cc1
4 files changed, 12 insertions, 0 deletions
diff --git a/fuzz/tls_client_target.cc b/fuzz/tls_client_target.cc
index a5b2a2c5f..461962c5d 100644
--- a/fuzz/tls_client_target.cc
+++ b/fuzz/tls_client_target.cc
@@ -106,6 +106,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
// Probably not too important for clients.
SSL_SetURL(ssl_fd, "server");
+ FixTime(ssl_fd);
SetSocketOptions(ssl_fd, config);
EnableAllCipherSuites(ssl_fd);
SetupCallbacks(ssl_fd, config.get());
diff --git a/fuzz/tls_common.cc b/fuzz/tls_common.cc
index 1e66684dc..b00ab26bf 100644
--- a/fuzz/tls_common.cc
+++ b/fuzz/tls_common.cc
@@ -5,9 +5,18 @@
#include <assert.h>
#include "ssl.h"
+#include "sslexp.h"
#include "tls_common.h"
+static PRTime FixedTime(void*) { return 1234; }
+
+// Fix the time input, to avoid any time-based variation.
+void FixTime(PRFileDesc* fd) {
+ SECStatus rv = SSL_SetTimeFunc(fd, FixedTime, nullptr);
+ assert(rv == SECSuccess);
+}
+
PRStatus EnableAllProtocolVersions() {
SSLVersionRange supported;
diff --git a/fuzz/tls_common.h b/fuzz/tls_common.h
index 8843347fa..e53accead 100644
--- a/fuzz/tls_common.h
+++ b/fuzz/tls_common.h
@@ -7,6 +7,7 @@
#include "prinit.h"
+void FixTime(PRFileDesc* fd);
PRStatus EnableAllProtocolVersions();
void EnableAllCipherSuites(PRFileDesc* fd);
void DoHandshake(PRFileDesc* fd, bool isServer);
diff --git a/fuzz/tls_server_target.cc b/fuzz/tls_server_target.cc
index 0c0902077..41a55541c 100644
--- a/fuzz/tls_server_target.cc
+++ b/fuzz/tls_server_target.cc
@@ -118,6 +118,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
PRFileDesc* ssl_fd = ImportFD(model.get(), fd.get());
assert(ssl_fd == fd.get());
+ FixTime(ssl_fd);
SetSocketOptions(ssl_fd, config);
DoHandshake(ssl_fd, true);