summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--automation/taskcluster/graph/src/extend.js16
-rwxr-xr-xautomation/taskcluster/scripts/run_clang_format.sh1
-rw-r--r--cpputil/.clang-format4
-rw-r--r--cpputil/README11
-rw-r--r--cpputil/cpputil.gyp27
-rw-r--r--cpputil/dummy_io.cc221
-rw-r--r--cpputil/dummy_io.h62
-rw-r--r--cpputil/dummy_io_fwd.cc162
-rw-r--r--cpputil/scoped_ptrs.h (renamed from gtests/common/scoped_ptrs.h)6
-rw-r--r--fuzz/fuzz.gyp18
-rw-r--r--fuzz/tls-client.options3
-rw-r--r--fuzz/tls_client_socket.cc34
-rw-r--r--fuzz/tls_client_socket.h24
-rw-r--r--fuzz/tls_client_target.cc113
-rw-r--r--gtests/common/gtest.gypi5
-rw-r--r--gtests/common/manifest.mn3
-rw-r--r--gtests/der_gtest/der_gtest.gyp6
-rw-r--r--gtests/der_gtest/manifest.mn3
-rw-r--r--gtests/freebl_gtest/freebl_gtest.gyp2
-rw-r--r--gtests/google_test/google_test.gyp1
-rw-r--r--gtests/pk11_gtest/manifest.mn3
-rw-r--r--gtests/pk11_gtest/pk11_gtest.gyp6
-rw-r--r--gtests/ssl_gtest/manifest.mn5
-rw-r--r--gtests/ssl_gtest/ssl_gtest.gyp5
-rw-r--r--gtests/ssl_gtest/test_io.cc256
-rw-r--r--gtests/ssl_gtest/test_io.h10
-rw-r--r--gtests/util_gtest/manifest.mn1
-rw-r--r--gtests/util_gtest/util_gtest.gyp2
-rw-r--r--nss-tool/common/scoped_ptrs.h57
-rw-r--r--nss-tool/nss_tool.gyp3
30 files changed, 735 insertions, 335 deletions
diff --git a/automation/taskcluster/graph/src/extend.js b/automation/taskcluster/graph/src/extend.js
index c047d0586..be77e50e4 100644
--- a/automation/taskcluster/graph/src/extend.js
+++ b/automation/taskcluster/graph/src/extend.js
@@ -326,16 +326,22 @@ async function scheduleFuzzing() {
// Schedule fuzzing runs.
let run_base = merge(base, {parent: task_build, kind: "test"});
- let mpi_base = merge(run_base, {group: "MPI"});
scheduleFuzzingRun(run_base, "CertDN", "certDN", 4096);
scheduleFuzzingRun(run_base, "Hash", "hash", 4096);
scheduleFuzzingRun(run_base, "QuickDER", "quickder", 10000);
- for (let mpi_name of ["add", "addmod", "div", "expmod", "mod", "mulmod",
- "sqr", "sqrmod", "sub", "submod"]) {
- scheduleFuzzingRun(mpi_base, `MPI (${mpi_name})`, `mpi-${mpi_name}`,
- 4096, mpi_name);
+
+ // Schedule MPI fuzzing runs.
+ let mpi_base = merge(run_base, {group: "MPI"});
+ let mpi_names = ["add", "addmod", "div", "expmod", "mod", "mulmod", "sqr",
+ "sqrmod", "sub", "submod"];
+ for (let name of mpi_names) {
+ scheduleFuzzingRun(mpi_base, `MPI (${name})`, `mpi-${name}`, 4096, name);
}
+ // Schedule TLS fuzzing runs.
+ let tls_base = merge(run_base, {group: "TLS"});
+ scheduleFuzzingRun(tls_base, "TLS Client", "tls-client", 20000, "client");
+
return queue.submit();
}
diff --git a/automation/taskcluster/scripts/run_clang_format.sh b/automation/taskcluster/scripts/run_clang_format.sh
index c0e6a3071..3a3604207 100755
--- a/automation/taskcluster/scripts/run_clang_format.sh
+++ b/automation/taskcluster/scripts/run_clang_format.sh
@@ -42,6 +42,7 @@ else
"$top/gtests/ssl_gtest" \
"$top/gtests/util_gtest" \
"$top/nss-tool" \
+ "$top/cpputil" \
)
fi
diff --git a/cpputil/.clang-format b/cpputil/.clang-format
new file mode 100644
index 000000000..06e3c5115
--- /dev/null
+++ b/cpputil/.clang-format
@@ -0,0 +1,4 @@
+---
+Language: Cpp
+BasedOnStyle: Google
+...
diff --git a/cpputil/README b/cpputil/README
new file mode 100644
index 000000000..22297dd33
--- /dev/null
+++ b/cpputil/README
@@ -0,0 +1,11 @@
+######################################
+## PLEASE READ BEFORE USING CPPUTIL ##
+######################################
+
+This is a static library supposed to be mainly used by NSS internally. We use
+it for testing, fuzzing, and a few new tools written in C++ that we're
+experimenting with.
+
+You might find it handy to use for your own projects but please be aware that
+we will make no promises your application won't break in the future. We will
+provide no support if you decide to link against it.
diff --git a/cpputil/cpputil.gyp b/cpputil/cpputil.gyp
new file mode 100644
index 000000000..cf666fd3c
--- /dev/null
+++ b/cpputil/cpputil.gyp
@@ -0,0 +1,27 @@
+# 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/.
+{
+ 'includes': [
+ '../coreconf/config.gypi',
+ ],
+ 'targets': [
+ {
+ 'target_name': 'cpputil',
+ 'type': 'static_library',
+ 'sources': [
+ 'dummy_io.cc',
+ 'dummy_io_fwd.cc',
+ ],
+ 'dependencies': [
+ '<(DEPTH)/exports.gyp:nss_exports',
+ ],
+ 'direct_dependent_settings': {
+ 'include_dirs': [
+ '<(DEPTH)/cpputil',
+ ],
+ },
+ },
+ ],
+}
+
diff --git a/cpputil/dummy_io.cc b/cpputil/dummy_io.cc
new file mode 100644
index 000000000..a8dacedbe
--- /dev/null
+++ b/cpputil/dummy_io.cc
@@ -0,0 +1,221 @@
+/* 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 <assert.h>
+#include <iostream>
+
+#include "prerror.h"
+#include "prio.h"
+
+#include "dummy_io.h"
+
+#define UNIMPLEMENTED() \
+ std::cerr << "Unimplemented: " << __FUNCTION__ << std::endl; \
+ assert(false);
+
+extern const struct PRIOMethods DummyMethodsForward;
+
+ScopedPRFileDesc DummyIOLayerMethods::CreateFD(PRDescIdentity id,
+ DummyIOLayerMethods *methods) {
+ ScopedPRFileDesc fd(PR_CreateIOLayerStub(id, &DummyMethodsForward));
+ fd->secret = reinterpret_cast<PRFilePrivate *>(methods);
+ return fd;
+}
+
+PRStatus DummyIOLayerMethods::Close(PRFileDesc *f) {
+ f->secret = nullptr;
+ f->dtor(f);
+ return PR_SUCCESS;
+}
+
+int32_t DummyIOLayerMethods::Read(PRFileDesc *f, void *buf, int32_t length) {
+ UNIMPLEMENTED();
+ return -1;
+}
+
+int32_t DummyIOLayerMethods::Write(PRFileDesc *f, const void *buf,
+ int32_t length) {
+ UNIMPLEMENTED();
+ return -1;
+}
+
+int32_t DummyIOLayerMethods::Available(PRFileDesc *f) {
+ UNIMPLEMENTED();
+ return -1;
+}
+
+int64_t DummyIOLayerMethods::Available64(PRFileDesc *f) {
+ UNIMPLEMENTED();
+ return -1;
+}
+
+PRStatus DummyIOLayerMethods::Sync(PRFileDesc *f) {
+ UNIMPLEMENTED();
+ return PR_FAILURE;
+}
+
+int32_t DummyIOLayerMethods::Seek(PRFileDesc *f, int32_t offset,
+ PRSeekWhence how) {
+ UNIMPLEMENTED();
+ return -1;
+}
+
+int64_t DummyIOLayerMethods::Seek64(PRFileDesc *f, int64_t offset,
+ PRSeekWhence how) {
+ UNIMPLEMENTED();
+ return -1;
+}
+
+PRStatus DummyIOLayerMethods::FileInfo(PRFileDesc *f, PRFileInfo *info) {
+ UNIMPLEMENTED();
+ return PR_FAILURE;
+}
+
+PRStatus DummyIOLayerMethods::FileInfo64(PRFileDesc *f, PRFileInfo64 *info) {
+ UNIMPLEMENTED();
+ return PR_FAILURE;
+}
+
+int32_t DummyIOLayerMethods::Writev(PRFileDesc *f, const PRIOVec *iov,
+ int32_t iov_size, PRIntervalTime to) {
+ UNIMPLEMENTED();
+ return -1;
+}
+
+PRStatus DummyIOLayerMethods::Connect(PRFileDesc *f, const PRNetAddr *addr,
+ PRIntervalTime to) {
+ UNIMPLEMENTED();
+ return PR_FAILURE;
+}
+
+PRFileDesc *DummyIOLayerMethods::Accept(PRFileDesc *sd, PRNetAddr *addr,
+ PRIntervalTime to) {
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+PRStatus DummyIOLayerMethods::Bind(PRFileDesc *f, const PRNetAddr *addr) {
+ UNIMPLEMENTED();
+ return PR_FAILURE;
+}
+
+PRStatus DummyIOLayerMethods::Listen(PRFileDesc *f, int32_t depth) {
+ UNIMPLEMENTED();
+ return PR_FAILURE;
+}
+
+PRStatus DummyIOLayerMethods::Shutdown(PRFileDesc *f, int32_t how) {
+ return PR_SUCCESS;
+}
+
+int32_t DummyIOLayerMethods::Recv(PRFileDesc *f, void *buf, int32_t buflen,
+ int32_t flags, PRIntervalTime to) {
+ UNIMPLEMENTED();
+ return -1;
+}
+
+// Note: this is always nonblocking and assumes a zero timeout.
+int32_t DummyIOLayerMethods::Send(PRFileDesc *f, const void *buf,
+ int32_t amount, int32_t flags,
+ PRIntervalTime to) {
+ return Write(f, buf, amount);
+}
+
+int32_t DummyIOLayerMethods::Recvfrom(PRFileDesc *f, void *buf, int32_t amount,
+ int32_t flags, PRNetAddr *addr,
+ PRIntervalTime to) {
+ UNIMPLEMENTED();
+ return -1;
+}
+
+int32_t DummyIOLayerMethods::Sendto(PRFileDesc *f, const void *buf,
+ int32_t amount, int32_t flags,
+ const PRNetAddr *addr, PRIntervalTime to) {
+ UNIMPLEMENTED();
+ return -1;
+}
+
+int16_t DummyIOLayerMethods::Poll(PRFileDesc *f, int16_t in_flags,
+ int16_t *out_flags) {
+ UNIMPLEMENTED();
+ return -1;
+}
+
+int32_t DummyIOLayerMethods::AcceptRead(PRFileDesc *sd, PRFileDesc **nd,
+ PRNetAddr **raddr, void *buf,
+ int32_t amount, PRIntervalTime t) {
+ UNIMPLEMENTED();
+ return -1;
+}
+
+int32_t DummyIOLayerMethods::TransmitFile(PRFileDesc *sd, PRFileDesc *f,
+ const void *headers, int32_t hlen,
+ PRTransmitFileFlags flags,
+ PRIntervalTime t) {
+ UNIMPLEMENTED();
+ return -1;
+}
+
+// TODO: Modify to return unique names for each channel
+// somehow, as opposed to always the same static address. The current
+// implementation messes up the session cache, which is why it's off
+// elsewhere
+PRStatus DummyIOLayerMethods::Getpeername(PRFileDesc *f, PRNetAddr *addr) {
+ addr->inet.family = PR_AF_INET;
+ addr->inet.port = 0;
+ addr->inet.ip = 0;
+
+ return PR_SUCCESS;
+}
+
+PRStatus DummyIOLayerMethods::Getsockname(PRFileDesc *f, PRNetAddr *addr) {
+ UNIMPLEMENTED();
+ return PR_FAILURE;
+}
+
+PRStatus DummyIOLayerMethods::Getsockoption(PRFileDesc *f,
+ PRSocketOptionData *opt) {
+ switch (opt->option) {
+ case PR_SockOpt_Nonblocking:
+ opt->value.non_blocking = PR_TRUE;
+ return PR_SUCCESS;
+ default:
+ UNIMPLEMENTED();
+ break;
+ }
+
+ return PR_FAILURE;
+}
+
+PRStatus DummyIOLayerMethods::Setsockoption(PRFileDesc *f,
+ const PRSocketOptionData *opt) {
+ switch (opt->option) {
+ case PR_SockOpt_Nonblocking:
+ return PR_SUCCESS;
+ case PR_SockOpt_NoDelay:
+ return PR_SUCCESS;
+ default:
+ UNIMPLEMENTED();
+ break;
+ }
+
+ return PR_FAILURE;
+}
+
+int32_t DummyIOLayerMethods::Sendfile(PRFileDesc *out, PRSendFileData *in,
+ PRTransmitFileFlags flags,
+ PRIntervalTime to) {
+ UNIMPLEMENTED();
+ return -1;
+}
+
+PRStatus DummyIOLayerMethods::ConnectContinue(PRFileDesc *f, int16_t flags) {
+ UNIMPLEMENTED();
+ return PR_FAILURE;
+}
+
+int32_t DummyIOLayerMethods::Reserved(PRFileDesc *f) {
+ UNIMPLEMENTED();
+ return -1;
+}
diff --git a/cpputil/dummy_io.h b/cpputil/dummy_io.h
new file mode 100644
index 000000000..797ac6113
--- /dev/null
+++ b/cpputil/dummy_io.h
@@ -0,0 +1,62 @@
+/* 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 dummy_io_h__
+#define dummy_io_h__
+
+#include "prerror.h"
+#include "prio.h"
+
+#include "scoped_ptrs.h"
+
+class DummyIOLayerMethods {
+ public:
+ static ScopedPRFileDesc CreateFD(PRDescIdentity id,
+ DummyIOLayerMethods *methods);
+
+ virtual PRStatus Close(PRFileDesc *f);
+ virtual int32_t Read(PRFileDesc *f, void *buf, int32_t length);
+ virtual int32_t Write(PRFileDesc *f, const void *buf, int32_t length);
+ virtual int32_t Available(PRFileDesc *f);
+ virtual int64_t Available64(PRFileDesc *f);
+ virtual PRStatus Sync(PRFileDesc *f);
+ virtual int32_t Seek(PRFileDesc *f, int32_t offset, PRSeekWhence how);
+ virtual int64_t Seek64(PRFileDesc *f, int64_t offset, PRSeekWhence how);
+ virtual PRStatus FileInfo(PRFileDesc *f, PRFileInfo *info);
+ virtual PRStatus FileInfo64(PRFileDesc *f, PRFileInfo64 *info);
+ virtual int32_t Writev(PRFileDesc *f, const PRIOVec *iov, int32_t iov_size,
+ PRIntervalTime to);
+ virtual PRStatus Connect(PRFileDesc *f, const PRNetAddr *addr,
+ PRIntervalTime to);
+ virtual PRFileDesc *Accept(PRFileDesc *sd, PRNetAddr *addr,
+ PRIntervalTime to);
+ virtual PRStatus Bind(PRFileDesc *f, const PRNetAddr *addr);
+ virtual PRStatus Listen(PRFileDesc *f, int32_t depth);
+ virtual PRStatus Shutdown(PRFileDesc *f, int32_t how);
+ virtual int32_t Recv(PRFileDesc *f, void *buf, int32_t buflen, int32_t flags,
+ PRIntervalTime to);
+ virtual int32_t Send(PRFileDesc *f, const void *buf, int32_t amount,
+ int32_t flags, PRIntervalTime to);
+ virtual int32_t Recvfrom(PRFileDesc *f, void *buf, int32_t amount,
+ int32_t flags, PRNetAddr *addr, PRIntervalTime to);
+ virtual int32_t Sendto(PRFileDesc *f, const void *buf, int32_t amount,
+ int32_t flags, const PRNetAddr *addr,
+ PRIntervalTime to);
+ virtual int16_t Poll(PRFileDesc *f, int16_t in_flags, int16_t *out_flags);
+ virtual int32_t AcceptRead(PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr,
+ void *buf, int32_t amount, PRIntervalTime t);
+ virtual int32_t TransmitFile(PRFileDesc *sd, PRFileDesc *f,
+ const void *headers, int32_t hlen,
+ PRTransmitFileFlags flags, PRIntervalTime t);
+ virtual PRStatus Getpeername(PRFileDesc *f, PRNetAddr *addr);
+ virtual PRStatus Getsockname(PRFileDesc *f, PRNetAddr *addr);
+ virtual PRStatus Getsockoption(PRFileDesc *f, PRSocketOptionData *opt);
+ virtual PRStatus Setsockoption(PRFileDesc *f, const PRSocketOptionData *opt);
+ virtual int32_t Sendfile(PRFileDesc *out, PRSendFileData *in,
+ PRTransmitFileFlags flags, PRIntervalTime to);
+ virtual PRStatus ConnectContinue(PRFileDesc *f, int16_t flags);
+ virtual int32_t Reserved(PRFileDesc *f);
+};
+
+#endif // dummy_io_h__
diff --git a/cpputil/dummy_io_fwd.cc b/cpputil/dummy_io_fwd.cc
new file mode 100644
index 000000000..5e53d9e1b
--- /dev/null
+++ b/cpputil/dummy_io_fwd.cc
@@ -0,0 +1,162 @@
+/* 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 "prio.h"
+
+#include "dummy_io.h"
+
+static DummyIOLayerMethods *ToMethods(PRFileDesc *f) {
+ return reinterpret_cast<DummyIOLayerMethods *>(f->secret);
+}
+
+static PRStatus DummyClose(PRFileDesc *f) { return ToMethods(f)->Close(f); }
+
+static int32_t DummyRead(PRFileDesc *f, void *buf, int32_t length) {
+ return ToMethods(f)->Read(f, buf, length);
+}
+
+static int32_t DummyWrite(PRFileDesc *f, const void *buf, int32_t length) {
+ return ToMethods(f)->Write(f, buf, length);
+}
+
+static int32_t DummyAvailable(PRFileDesc *f) {
+ return ToMethods(f)->Available(f);
+}
+
+static int64_t DummyAvailable64(PRFileDesc *f) {
+ return ToMethods(f)->Available64(f);
+}
+
+static PRStatus DummySync(PRFileDesc *f) { return ToMethods(f)->Sync(f); }
+
+static int32_t DummySeek(PRFileDesc *f, int32_t offset, PRSeekWhence how) {
+ return ToMethods(f)->Seek(f, offset, how);
+}
+
+static int64_t DummySeek64(PRFileDesc *f, int64_t offset, PRSeekWhence how) {
+ return ToMethods(f)->Seek64(f, offset, how);
+}
+
+static PRStatus DummyFileInfo(PRFileDesc *f, PRFileInfo *info) {
+ return ToMethods(f)->FileInfo(f, info);
+}
+
+static PRStatus DummyFileInfo64(PRFileDesc *f, PRFileInfo64 *info) {
+ return ToMethods(f)->FileInfo64(f, info);
+}
+
+static int32_t DummyWritev(PRFileDesc *f, const PRIOVec *iov, int32_t iov_size,
+ PRIntervalTime to) {
+ return ToMethods(f)->Writev(f, iov, iov_size, to);
+}
+
+static PRStatus DummyConnect(PRFileDesc *f, const PRNetAddr *addr,
+ PRIntervalTime to) {
+ return ToMethods(f)->Connect(f, addr, to);
+}
+
+static PRFileDesc *DummyAccept(PRFileDesc *f, PRNetAddr *addr,
+ PRIntervalTime to) {
+ return ToMethods(f)->Accept(f, addr, to);
+}
+
+static PRStatus DummyBind(PRFileDesc *f, const PRNetAddr *addr) {
+ return ToMethods(f)->Bind(f, addr);
+}
+
+static PRStatus DummyListen(PRFileDesc *f, int32_t depth) {
+ return ToMethods(f)->Listen(f, depth);
+}
+
+static PRStatus DummyShutdown(PRFileDesc *f, int32_t how) {
+ return ToMethods(f)->Shutdown(f, how);
+}
+
+static int32_t DummyRecv(PRFileDesc *f, void *buf, int32_t buflen,
+ int32_t flags, PRIntervalTime to) {
+ return ToMethods(f)->Recv(f, buf, buflen, flags, to);
+}
+
+static int32_t DummySend(PRFileDesc *f, const void *buf, int32_t amount,
+ int32_t flags, PRIntervalTime to) {
+ return ToMethods(f)->Send(f, buf, amount, flags, to);
+}
+
+static int32_t DummyRecvfrom(PRFileDesc *f, void *buf, int32_t amount,
+ int32_t flags, PRNetAddr *addr,
+ PRIntervalTime to) {
+ return ToMethods(f)->Recvfrom(f, buf, amount, flags, addr, to);
+}
+
+static int32_t DummySendto(PRFileDesc *f, const void *buf, int32_t amount,
+ int32_t flags, const PRNetAddr *addr,
+ PRIntervalTime to) {
+ return ToMethods(f)->Sendto(f, buf, amount, flags, addr, to);
+}
+
+static int16_t DummyPoll(PRFileDesc *f, int16_t in_flags, int16_t *out_flags) {
+ return ToMethods(f)->Poll(f, in_flags, out_flags);
+}
+
+static int32_t DummyAcceptRead(PRFileDesc *f, PRFileDesc **nd,
+ PRNetAddr **raddr, void *buf, int32_t amount,
+ PRIntervalTime t) {
+ return ToMethods(f)->AcceptRead(f, nd, raddr, buf, amount, t);
+}
+
+static int32_t DummyTransmitFile(PRFileDesc *sd, PRFileDesc *f,
+ const void *headers, int32_t hlen,
+ PRTransmitFileFlags flags, PRIntervalTime t) {
+ return ToMethods(f)->TransmitFile(sd, f, headers, hlen, flags, t);
+}
+
+static PRStatus DummyGetpeername(PRFileDesc *f, PRNetAddr *addr) {
+ return ToMethods(f)->Getpeername(f, addr);
+}
+
+static PRStatus DummyGetsockname(PRFileDesc *f, PRNetAddr *addr) {
+ return ToMethods(f)->Getsockname(f, addr);
+}
+
+static PRStatus DummyGetsockoption(PRFileDesc *f, PRSocketOptionData *opt) {
+ return ToMethods(f)->Getsockoption(f, opt);
+}
+
+static PRStatus DummySetsockoption(PRFileDesc *f,
+ const PRSocketOptionData *opt) {
+ return ToMethods(f)->Setsockoption(f, opt);
+}
+
+static int32_t DummySendfile(PRFileDesc *f, PRSendFileData *in,
+ PRTransmitFileFlags flags, PRIntervalTime to) {
+ return ToMethods(f)->Sendfile(f, in, flags, to);
+}
+
+static PRStatus DummyConnectContinue(PRFileDesc *f, int16_t flags) {
+ return ToMethods(f)->ConnectContinue(f, flags);
+}
+
+static int32_t DummyReserved(PRFileDesc *f) {
+ return ToMethods(f)->Reserved(f);
+}
+
+extern const struct PRIOMethods DummyMethodsForward = {
+ PR_DESC_LAYERED, DummyClose,
+ DummyRead, DummyWrite,
+ DummyAvailable, DummyAvailable64,
+ DummySync, DummySeek,
+ DummySeek64, DummyFileInfo,
+ DummyFileInfo64, DummyWritev,
+ DummyConnect, DummyAccept,
+ DummyBind, DummyListen,
+ DummyShutdown, DummyRecv,
+ DummySend, DummyRecvfrom,
+ DummySendto, DummyPoll,
+ DummyAcceptRead, DummyTransmitFile,
+ DummyGetsockname, DummyGetpeername,
+ DummyReserved, DummyReserved,
+ DummyGetsockoption, DummySetsockoption,
+ DummySendfile, DummyConnectContinue,
+ DummyReserved, DummyReserved,
+ DummyReserved, DummyReserved};
diff --git a/gtests/common/scoped_ptrs.h b/cpputil/scoped_ptrs.h
index 4707393ad..a96ac1fa8 100644
--- a/gtests/common/scoped_ptrs.h
+++ b/cpputil/scoped_ptrs.h
@@ -12,8 +12,6 @@
#include "keyhi.h"
#include "pk11pub.h"
-namespace nss_test {
-
struct ScopedDelete {
void operator()(CERTCertificate* cert) { CERT_DestroyCertificate(cert); }
void operator()(CERTCertificateList* list) {
@@ -58,6 +56,4 @@ SCOPED(SECKEYPrivateKey);
#undef SCOPED
-} // namespace nss_test
-
-#endif
+#endif // scoped_ptrs_h__
diff --git a/fuzz/fuzz.gyp b/fuzz/fuzz.gyp
index 9272c9dbb..9e0444100 100644
--- a/fuzz/fuzz.gyp
+++ b/fuzz/fuzz.gyp
@@ -29,6 +29,7 @@
'<(DEPTH)/lib/certdb/certdb.gyp:certdb',
'<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
'<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
+ '<(DEPTH)/lib/ssl/ssl.gyp:ssl',
'<(DEPTH)/lib/base/base.gyp:nssb',
'<(DEPTH)/lib/dev/dev.gyp:nssdev',
'<(DEPTH)/lib/pki/pki.gyp:nsspki',
@@ -244,6 +245,22 @@
],
},
{
+ 'target_name': 'nssfuzz-tls-client',
+ 'type': 'executable',
+ 'sources': [
+ 'tls_client_socket.cc',
+ 'tls_client_target.cc',
+ ],
+ 'dependencies': [
+ '<(DEPTH)/cpputil/cpputil.gyp:cpputil',
+ '<(DEPTH)/exports.gyp:nss_exports',
+ 'fuzz_base',
+ ],
+ 'include_dirs': [
+ '<(DEPTH)/lib/freebl',
+ ],
+ },
+ {
'target_name': 'nssfuzz',
'type': 'none',
'dependencies': [
@@ -251,6 +268,7 @@
'nssfuzz-hash',
'nssfuzz-pkcs8',
'nssfuzz-quickder',
+ 'nssfuzz-tls-client',
],
'conditions': [
['OS=="linux"', {
diff --git a/fuzz/tls-client.options b/fuzz/tls-client.options
new file mode 100644
index 000000000..8b017d2ce
--- /dev/null
+++ b/fuzz/tls-client.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+max_len = 20000
+
diff --git a/fuzz/tls_client_socket.cc b/fuzz/tls_client_socket.cc
new file mode 100644
index 000000000..b5256a001
--- /dev/null
+++ b/fuzz/tls_client_socket.cc
@@ -0,0 +1,34 @@
+/* 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 <assert.h>
+#include <string.h>
+#include <algorithm>
+
+#include "prerror.h"
+#include "prio.h"
+
+#include "tls_client_socket.h"
+
+int32_t DummyPrSocket::Read(PRFileDesc *f, void *data, int32_t len) {
+ assert(data && len > 0);
+
+ int32_t amount = std::min(len, static_cast<int32_t>(len_));
+ memcpy(data, buf_, amount);
+
+ buf_ += amount;
+ len_ -= amount;
+
+ return amount;
+}
+
+int32_t DummyPrSocket::Write(PRFileDesc *f, const void *buf, int32_t length) {
+ return length;
+}
+
+int32_t DummyPrSocket::Recv(PRFileDesc *f, void *buf, int32_t buflen,
+ int32_t flags, PRIntervalTime to) {
+ assert(flags == 0);
+ return Read(f, buf, buflen);
+}
diff --git a/fuzz/tls_client_socket.h b/fuzz/tls_client_socket.h
new file mode 100644
index 000000000..c9dc9ba34
--- /dev/null
+++ b/fuzz/tls_client_socket.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_socket_h__
+#define tls_client_socket_h__
+
+#include "dummy_io.h"
+
+class DummyPrSocket : public DummyIOLayerMethods {
+ public:
+ DummyPrSocket(const uint8_t *buf, size_t len) : buf_(buf), len_(len) {}
+
+ int32_t Read(PRFileDesc *f, void *data, int32_t len) override;
+ int32_t Write(PRFileDesc *f, const void *buf, int32_t length) override;
+ int32_t Recv(PRFileDesc *f, void *buf, int32_t buflen, int32_t flags,
+ PRIntervalTime to) override;
+
+ private:
+ const uint8_t *buf_;
+ size_t len_;
+};
+
+#endif // tls_client_socket_h__
diff --git a/fuzz/tls_client_target.cc b/fuzz/tls_client_target.cc
new file mode 100644
index 000000000..4d8ed9ee9
--- /dev/null
+++ b/fuzz/tls_client_target.cc
@@ -0,0 +1,113 @@
+/* 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 <assert.h>
+#include <stdint.h>
+#include <memory>
+
+#include "blapi.h"
+#include "prinit.h"
+#include "ssl.h"
+
+#include "shared.h"
+#include "tls_client_socket.h"
+
+static PRStatus EnableAllProtocolVersions() {
+ SSLVersionRange supported;
+
+ SECStatus rv = SSL_VersionRangeGetSupported(ssl_variant_stream, &supported);
+ assert(rv == SECSuccess);
+
+ rv = SSL_VersionRangeSetDefault(ssl_variant_stream, &supported);
+ assert(rv == SECSuccess);
+
+ return PR_SUCCESS;
+}
+
+static SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checksig,
+ PRBool isServer) {
+ return SECSuccess;
+}
+
+static void SetSocketOptions(PRFileDesc* fd) {
+ // 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);
+ assert(rv == SECSuccess);
+
+ rv = SSL_OptionSet(fd, SSL_ENABLE_FALLBACK_SCSV, true);
+ assert(rv == SECSuccess);
+
+ rv = SSL_OptionSet(fd, SSL_ENABLE_ALPN, true);
+ assert(rv == SECSuccess);
+
+ rv =
+ SSL_OptionSet(fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED);
+ assert(rv == SECSuccess);
+}
+
+static void EnableAllCipherSuites(PRFileDesc* fd) {
+ for (uint16_t i = 0; i < SSL_NumImplementedCiphers; ++i) {
+ SECStatus rv = SSL_CipherPrefSet(fd, SSL_ImplementedCiphers[i], true);
+ assert(rv == SECSuccess);
+ }
+}
+
+static void SetupAuthCertificateHook(PRFileDesc* fd) {
+ SECStatus rv = SSL_AuthCertificateHook(fd, AuthCertificateHook, nullptr);
+ assert(rv == SECSuccess);
+}
+
+static void DoHandshake(PRFileDesc* fd) {
+ SECStatus rv = SSL_ResetHandshake(fd, false /* asServer */);
+ assert(rv == SECSuccess);
+
+ do {
+ rv = SSL_ForceHandshake(fd);
+ } while (rv != SECSuccess && PR_GetError() == PR_WOULD_BLOCK_ERROR);
+
+ // If the handshake succeeds, let's read some data from the server, if any.
+ if (rv == SECSuccess) {
+ uint8_t block[1024];
+ int32_t nb;
+
+ // Read application data and echo it back.
+ while ((nb = PR_Read(fd, block, sizeof(block))) > 0) {
+ PR_Write(fd, block, nb);
+ }
+ }
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
+ static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
+ assert(db != nullptr);
+
+ EnableAllProtocolVersions();
+
+ // Reset the RNG state.
+ SECStatus rv = RNG_ResetForFuzzing();
+ assert(rv == SECSuccess);
+
+ // Create and import dummy socket.
+ std::unique_ptr<DummyPrSocket> socket(new DummyPrSocket(data, len));
+ static PRDescIdentity id = PR_GetUniqueIdentity("fuzz-client");
+ ScopedPRFileDesc fd(DummyIOLayerMethods::CreateFD(id, socket.get()));
+ PRFileDesc* ssl_fd = SSL_ImportFD(nullptr, fd.get());
+ assert(ssl_fd == fd.get());
+
+ // Probably not too important for clients.
+ SSL_SetURL(ssl_fd, "server");
+
+ SetSocketOptions(ssl_fd);
+ EnableAllCipherSuites(ssl_fd);
+ SetupAuthCertificateHook(ssl_fd);
+ DoHandshake(ssl_fd);
+
+ return 0;
+}
diff --git a/gtests/common/gtest.gypi b/gtests/common/gtest.gypi
index 2a3163426..e0ffc86e2 100644
--- a/gtests/common/gtest.gypi
+++ b/gtests/common/gtest.gypi
@@ -3,6 +3,11 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
{
'target_defaults': {
+ 'include_dirs': [
+ '<(DEPTH)/gtests/google_test/gtest/include',
+ '<(DEPTH)/gtests/common',
+ '<(DEPTH)/cpputil',
+ ],
'cflags': [
'-Wsign-compare',
],
diff --git a/gtests/common/manifest.mn b/gtests/common/manifest.mn
index 9834e42a0..a40989bf7 100644
--- a/gtests/common/manifest.mn
+++ b/gtests/common/manifest.mn
@@ -11,7 +11,8 @@ CPPSRCS = \
$(NULL)
INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
- -I$(CORE_DEPTH)/gtests/common
+ -I$(CORE_DEPTH)/gtests/common \
+ -I$(CORE_DEPTH)/cpputil
REQUIRES = gtest
diff --git a/gtests/der_gtest/der_gtest.gyp b/gtests/der_gtest/der_gtest.gyp
index 39801aeb5..5c6ad86c3 100644
--- a/gtests/der_gtest/der_gtest.gyp
+++ b/gtests/der_gtest/der_gtest.gyp
@@ -24,12 +24,6 @@
]
}
],
- 'target_defaults': {
- 'include_dirs': [
- '../../gtests/google_test/gtest/include',
- '../../gtests/common'
- ]
- },
'variables': {
'module': 'nss'
}
diff --git a/gtests/der_gtest/manifest.mn b/gtests/der_gtest/manifest.mn
index 862692f56..93df2ef4d 100644
--- a/gtests/der_gtest/manifest.mn
+++ b/gtests/der_gtest/manifest.mn
@@ -12,7 +12,8 @@ CPPSRCS = \
$(NULL)
INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
- -I$(CORE_DEPTH)/gtests/common
+ -I$(CORE_DEPTH)/gtests/common \
+ -I$(CORE_DEPTH)/cpputil
REQUIRES = nspr nss libdbm gtest
diff --git a/gtests/freebl_gtest/freebl_gtest.gyp b/gtests/freebl_gtest/freebl_gtest.gyp
index a697ea410..b858c93d0 100644
--- a/gtests/freebl_gtest/freebl_gtest.gyp
+++ b/gtests/freebl_gtest/freebl_gtest.gyp
@@ -39,8 +39,6 @@
],
'target_defaults': {
'include_dirs': [
- '<(DEPTH)/gtests/google_test/gtest/include',
- '<(DEPTH)/gtests/common',
'<(DEPTH)/lib/freebl/mpi',
]
},
diff --git a/gtests/google_test/google_test.gyp b/gtests/google_test/google_test.gyp
index d23de2ab6..b3a11b7af 100644
--- a/gtests/google_test/google_test.gyp
+++ b/gtests/google_test/google_test.gyp
@@ -17,7 +17,6 @@
],
'target_defaults': {
'include_dirs': [
- 'gtest/include/',
'gtest'
],
},
diff --git a/gtests/pk11_gtest/manifest.mn b/gtests/pk11_gtest/manifest.mn
index 78f9529b7..cb78c8b3a 100644
--- a/gtests/pk11_gtest/manifest.mn
+++ b/gtests/pk11_gtest/manifest.mn
@@ -18,7 +18,8 @@ CPPSRCS = \
$(NULL)
INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
- -I$(CORE_DEPTH)/gtests/common
+ -I$(CORE_DEPTH)/gtests/common \
+ -I$(CORE_DEPTH)/cpputil
REQUIRES = nspr nss libdbm gtest
diff --git a/gtests/pk11_gtest/pk11_gtest.gyp b/gtests/pk11_gtest/pk11_gtest.gyp
index a67f61a69..e01afff91 100644
--- a/gtests/pk11_gtest/pk11_gtest.gyp
+++ b/gtests/pk11_gtest/pk11_gtest.gyp
@@ -47,12 +47,6 @@
],
}
],
- 'target_defaults': {
- 'include_dirs': [
- '../../gtests/google_test/gtest/include',
- '../../gtests/common'
- ]
- },
'variables': {
'module': 'nss'
}
diff --git a/gtests/ssl_gtest/manifest.mn b/gtests/ssl_gtest/manifest.mn
index 39db7f753..9f1b7f300 100644
--- a/gtests/ssl_gtest/manifest.mn
+++ b/gtests/ssl_gtest/manifest.mn
@@ -12,6 +12,8 @@ CSRCS = \
$(NULL)
CPPSRCS = \
+ $(CORE_DEPTH)/cpputil/dummy_io.cc \
+ $(CORE_DEPTH)/cpputil/dummy_io_fwd.cc \
ssl_0rtt_unittest.cc \
ssl_agent_unittest.cc \
ssl_auth_unittest.cc \
@@ -46,7 +48,8 @@ CPPSRCS = \
$(NULL)
INCLUDES += -I$(CORE_DEPTH)/gtests/google_test/gtest/include \
- -I$(CORE_DEPTH)/gtests/common
+ -I$(CORE_DEPTH)/gtests/common \
+ -I$(CORE_DEPTH)/cpputil
REQUIRES = nspr nss libdbm gtest
diff --git a/gtests/ssl_gtest/ssl_gtest.gyp b/gtests/ssl_gtest/ssl_gtest.gyp
index 818faf66e..c49d0d6d1 100644
--- a/gtests/ssl_gtest/ssl_gtest.gyp
+++ b/gtests/ssl_gtest/ssl_gtest.gyp
@@ -59,7 +59,8 @@
'<(DEPTH)/lib/pki/pki.gyp:nsspki',
'<(DEPTH)/lib/dev/dev.gyp:nssdev',
'<(DEPTH)/lib/base/base.gyp:nssb',
- '<(DEPTH)/lib/zlib/zlib.gyp:nss_zlib'
+ '<(DEPTH)/lib/zlib/zlib.gyp:nss_zlib',
+ '<(DEPTH)/cpputil/cpputil.gyp:cpputil',
],
'conditions': [
[ 'test_build==1', {
@@ -99,8 +100,6 @@
],
'target_defaults': {
'include_dirs': [
- '../../gtests/google_test/gtest/include',
- '../../gtests/common',
'../../lib/ssl'
],
'defines': [
diff --git a/gtests/ssl_gtest/test_io.cc b/gtests/ssl_gtest/test_io.cc
index 9f158bf77..42470a1a8 100644
--- a/gtests/ssl_gtest/test_io.cc
+++ b/gtests/ssl_gtest/test_io.cc
@@ -19,260 +19,27 @@ extern bool g_ssl_gtest_verbose;
namespace nss_test {
-static PRDescIdentity test_fd_identity = PR_INVALID_IO_LAYER;
-
-#define UNIMPLEMENTED() \
- std::cerr << "Call to unimplemented function " << __FUNCTION__ << std::endl; \
- PR_ASSERT(PR_FALSE); \
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0)
-
#define LOG(a) std::cerr << name_ << ": " << a << std::endl
#define LOGV(a) \
do { \
if (g_ssl_gtest_verbose) LOG(a); \
} while (false)
-// Implementation of NSPR methods
-static PRStatus DummyClose(PRFileDesc *f) {
- f->secret = nullptr;
- f->dtor(f);
- return PR_SUCCESS;
-}
-
-static int32_t DummyRead(PRFileDesc *f, void *buf, int32_t length) {
- DummyPrSocket *io = reinterpret_cast<DummyPrSocket *>(f->secret);
- return io->Read(buf, length);
-}
-
-static int32_t DummyWrite(PRFileDesc *f, const void *buf, int32_t length) {
- DummyPrSocket *io = reinterpret_cast<DummyPrSocket *>(f->secret);
- return io->Write(buf, length);
-}
-
-static int32_t DummyAvailable(PRFileDesc *f) {
- UNIMPLEMENTED();
- return -1;
-}
-
-static int64_t DummyAvailable64(PRFileDesc *f) {
- UNIMPLEMENTED();
- return -1;
-}
-
-static PRStatus DummySync(PRFileDesc *f) {
- UNIMPLEMENTED();
- return PR_FAILURE;
-}
-
-static int32_t DummySeek(PRFileDesc *f, int32_t offset, PRSeekWhence how) {
- UNIMPLEMENTED();
- return -1;
-}
-
-static int64_t DummySeek64(PRFileDesc *f, int64_t offset, PRSeekWhence how) {
- UNIMPLEMENTED();
- return -1;
-}
-
-static PRStatus DummyFileInfo(PRFileDesc *f, PRFileInfo *info) {
- UNIMPLEMENTED();
- return PR_FAILURE;
-}
-
-static PRStatus DummyFileInfo64(PRFileDesc *f, PRFileInfo64 *info) {
- UNIMPLEMENTED();
- return PR_FAILURE;
-}
-
-static int32_t DummyWritev(PRFileDesc *f, const PRIOVec *iov, int32_t iov_size,
- PRIntervalTime to) {
- UNIMPLEMENTED();
- return -1;
-}
-
-static PRStatus DummyConnect(PRFileDesc *f, const PRNetAddr *addr,
- PRIntervalTime to) {
- UNIMPLEMENTED();
- return PR_FAILURE;
-}
-
-static PRFileDesc *DummyAccept(PRFileDesc *sd, PRNetAddr *addr,
- PRIntervalTime to) {
- UNIMPLEMENTED();
- return nullptr;
-}
-
-static PRStatus DummyBind(PRFileDesc *f, const PRNetAddr *addr) {
- UNIMPLEMENTED();
- return PR_FAILURE;
-}
-
-static PRStatus DummyListen(PRFileDesc *f, int32_t depth) {
- UNIMPLEMENTED();
- return PR_FAILURE;
-}
-
-static PRStatus DummyShutdown(PRFileDesc *f, int32_t how) { return PR_SUCCESS; }
-
-// This function does not support peek.
-static int32_t DummyRecv(PRFileDesc *f, void *buf, int32_t buflen,
- int32_t flags, PRIntervalTime to) {
- PR_ASSERT(flags == 0);
- if (flags != 0) {
- PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
- return -1;
- }
-
- DummyPrSocket *io = reinterpret_cast<DummyPrSocket *>(f->secret);
-
- if (io->mode() == DGRAM) {
- return io->Recv(buf, buflen);
- } else {
- return io->Read(buf, buflen);
- }
-}
-
-// Note: this is always nonblocking and assumes a zero timeout.
-static int32_t DummySend(PRFileDesc *f, const void *buf, int32_t amount,
- int32_t flags, PRIntervalTime to) {
- int32_t written = DummyWrite(f, buf, amount);
- return written;
-}
-
-static int32_t DummyRecvfrom(PRFileDesc *f, void *buf, int32_t amount,
- int32_t flags, PRNetAddr *addr,
- PRIntervalTime to) {
- UNIMPLEMENTED();
- return -1;
-}
-
-static int32_t DummySendto(PRFileDesc *f, const void *buf, int32_t amount,
- int32_t flags, const PRNetAddr *addr,
- PRIntervalTime to) {
- UNIMPLEMENTED();
- return -1;
-}
-
-static int16_t DummyPoll(PRFileDesc *f, int16_t in_flags, int16_t *out_flags) {
- UNIMPLEMENTED();
- return -1;
-}
-
-static int32_t DummyAcceptRead(PRFileDesc *sd, PRFileDesc **nd,
- PRNetAddr **raddr, void *buf, int32_t amount,
- PRIntervalTime t) {
- UNIMPLEMENTED();
- return -1;
-}
-
-static int32_t DummyTransmitFile(PRFileDesc *sd, PRFileDesc *f,
- const void *headers, int32_t hlen,
- PRTransmitFileFlags flags, PRIntervalTime t) {
- UNIMPLEMENTED();
- return -1;
-}
-
-static PRStatus DummyGetpeername(PRFileDesc *f, PRNetAddr *addr) {
- // TODO: Modify to return unique names for each channel
- // somehow, as opposed to always the same static address. The current
- // implementation messes up the session cache, which is why it's off
- // elsewhere
- addr->inet.family = PR_AF_INET;
- addr->inet.port = 0;
- addr->inet.ip = 0;
-
- return PR_SUCCESS;
-}
-
-static PRStatus DummyGetsockname(PRFileDesc *f, PRNetAddr *addr) {
- UNIMPLEMENTED();
- return PR_FAILURE;
-}
-
-static PRStatus DummyGetsockoption(PRFileDesc *f, PRSocketOptionData *opt) {
- switch (opt->option) {
- case PR_SockOpt_Nonblocking:
- opt->value.non_blocking = PR_TRUE;
- return PR_SUCCESS;
- default:
- UNIMPLEMENTED();
- break;
- }
-
- return PR_FAILURE;
-}
-
-// Imitate setting socket options. These are mostly noops.
-static PRStatus DummySetsockoption(PRFileDesc *f,
- const PRSocketOptionData *opt) {
- switch (opt->option) {
- case PR_SockOpt_Nonblocking:
- return PR_SUCCESS;
- case PR_SockOpt_NoDelay:
- return PR_SUCCESS;
- default:
- UNIMPLEMENTED();
- break;
- }
-
- return PR_FAILURE;
-}
-
-static int32_t DummySendfile(PRFileDesc *out, PRSendFileData *in,
- PRTransmitFileFlags flags, PRIntervalTime to) {
- UNIMPLEMENTED();
- return -1;
-}
-
-static PRStatus DummyConnectContinue(PRFileDesc *f, int16_t flags) {
- UNIMPLEMENTED();
- return PR_FAILURE;
-}
-
-static int32_t DummyReserved(PRFileDesc *f) {
- UNIMPLEMENTED();
- return -1;
-}
-
void DummyPrSocket::SetPacketFilter(std::shared_ptr<PacketFilter> filter) {
filter_ = filter;
}
-static const struct PRIOMethods DummyMethods = {
- PR_DESC_LAYERED, DummyClose,
- DummyRead, DummyWrite,
- DummyAvailable, DummyAvailable64,
- DummySync, DummySeek,
- DummySeek64, DummyFileInfo,
- DummyFileInfo64, DummyWritev,
- DummyConnect, DummyAccept,
- DummyBind, DummyListen,
- DummyShutdown, DummyRecv,
- DummySend, DummyRecvfrom,
- DummySendto, DummyPoll,
- DummyAcceptRead, DummyTransmitFile,
- DummyGetsockname, DummyGetpeername,
- DummyReserved, DummyReserved,
- DummyGetsockoption, DummySetsockoption,
- DummySendfile, DummyConnectContinue,
- DummyReserved, DummyReserved,
- DummyReserved, DummyReserved};
-
ScopedPRFileDesc DummyPrSocket::CreateFD() {
- if (test_fd_identity == PR_INVALID_IO_LAYER) {
- test_fd_identity = PR_GetUniqueIdentity("testtransportadapter");
- }
-
- ScopedPRFileDesc fd(PR_CreateIOLayerStub(test_fd_identity, &DummyMethods));
- fd->secret = reinterpret_cast<PRFilePrivate *>(this);
- return fd;
+ static PRDescIdentity test_fd_identity =
+ PR_GetUniqueIdentity("testtransportadapter");
+ return DummyIOLayerMethods::CreateFD(test_fd_identity, this);
}
void DummyPrSocket::PacketReceived(const DataBuffer &packet) {
input_.push(Packet(packet));
}
-int32_t DummyPrSocket::Read(void *data, int32_t len) {
+int32_t DummyPrSocket::Read(PRFileDesc *f, void *data, int32_t len) {
PR_ASSERT(mode_ == STREAM);
if (mode_ != STREAM) {
@@ -300,7 +67,18 @@ int32_t DummyPrSocket::Read(void *data, int32_t len) {
return static_cast<int32_t>(to_read);
}
-int32_t DummyPrSocket::Recv(void *buf, int32_t buflen) {
+int32_t DummyPrSocket::Recv(PRFileDesc *f, void *buf, int32_t buflen,
+ int32_t flags, PRIntervalTime to) {
+ PR_ASSERT(flags == 0);
+ if (flags != 0) {
+ PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+ return -1;
+ }
+
+ if (mode() != DGRAM) {
+ return Read(f, buf, buflen);
+ }
+
if (input_.empty()) {
PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
return -1;
@@ -320,7 +98,7 @@ int32_t DummyPrSocket::Recv(void *buf, int32_t buflen) {
return static_cast<int32_t>(count);
}
-int32_t DummyPrSocket::Write(const void *buf, int32_t length) {
+int32_t DummyPrSocket::Write(PRFileDesc *f, const void *buf, int32_t length) {
auto peer = peer_.lock();
if (!peer || !writeable_) {
PR_SetError(PR_IO_ERROR, 0);
diff --git a/gtests/ssl_gtest/test_io.h b/gtests/ssl_gtest/test_io.h
index b111df20c..a7e0555e3 100644
--- a/gtests/ssl_gtest/test_io.h
+++ b/gtests/ssl_gtest/test_io.h
@@ -15,6 +15,7 @@
#include <string>
#include "databuffer.h"
+#include "dummy_io.h"
#include "prio.h"
#include "scoped_ptrs.h"
@@ -49,7 +50,7 @@ inline std::ostream& operator<<(std::ostream& os, Mode m) {
return os << ((m == STREAM) ? "TLS" : "DTLS");
}
-class DummyPrSocket {
+class DummyPrSocket : public DummyIOLayerMethods {
public:
DummyPrSocket(const std::string& name, Mode mode)
: name_(name),
@@ -71,9 +72,10 @@ class DummyPrSocket {
void Reset();
void PacketReceived(const DataBuffer& data);
- int32_t Read(void* data, int32_t len);
- int32_t Recv(void* buf, int32_t buflen);
- int32_t Write(const void* buf, int32_t length);
+ int32_t Read(PRFileDesc* f, void* data, int32_t len) override;
+ int32_t Recv(PRFileDesc* f, void* buf, int32_t buflen, int32_t flags,
+ PRIntervalTime to) override;
+ int32_t Write(PRFileDesc* f, const void* buf, int32_t length) override;
void CloseWrites() { writeable_ = false; }
Mode mode() const { return mode_; }
diff --git a/gtests/util_gtest/manifest.mn b/gtests/util_gtest/manifest.mn
index fd4925142..b97f92447 100644
--- a/gtests/util_gtest/manifest.mn
+++ b/gtests/util_gtest/manifest.mn
@@ -13,6 +13,7 @@ CPPSRCS = \
INCLUDES += \
-I$(CORE_DEPTH)/gtests/google_test/gtest/include \
-I$(CORE_DEPTH)/gtests/common \
+ -I$(CORE_DEPTH)/cpputil \
$(NULL)
REQUIRES = nspr gtest
diff --git a/gtests/util_gtest/util_gtest.gyp b/gtests/util_gtest/util_gtest.gyp
index ee08bd67d..e4b7be7ed 100644
--- a/gtests/util_gtest/util_gtest.gyp
+++ b/gtests/util_gtest/util_gtest.gyp
@@ -32,8 +32,6 @@
],
'target_defaults': {
'include_dirs': [
- '../../gtests/google_test/gtest/include',
- '../../gtests/common',
'../../lib/util'
]
},
diff --git a/nss-tool/common/scoped_ptrs.h b/nss-tool/common/scoped_ptrs.h
deleted file mode 100644
index 6752a32b4..000000000
--- a/nss-tool/common/scoped_ptrs.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* 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 scoped_ptrs_h__
-#define scoped_ptrs_h__
-
-#include <memory>
-#include "cert.h"
-#include "keyhi.h"
-#include "pk11pub.h"
-
-struct ScopedDelete {
- void operator()(CERTCertificate* cert) { CERT_DestroyCertificate(cert); }
- void operator()(CERTCertificateList* list) {
- CERT_DestroyCertificateList(list);
- }
- void operator()(CERTSubjectPublicKeyInfo* spki) {
- SECKEY_DestroySubjectPublicKeyInfo(spki);
- }
- void operator()(PK11SlotInfo* slot) { PK11_FreeSlot(slot); }
- void operator()(PK11SymKey* key) { PK11_FreeSymKey(key); }
- void operator()(SECAlgorithmID* id) { SECOID_DestroyAlgorithmID(id, true); }
- void operator()(SECItem* item) { SECITEM_FreeItem(item, true); }
- void operator()(SECKEYPublicKey* key) { SECKEY_DestroyPublicKey(key); }
- void operator()(SECKEYPrivateKey* key) { SECKEY_DestroyPrivateKey(key); }
-
- void operator()(CERTCertList* list) { CERT_DestroyCertList(list); }
-};
-
-template <class T>
-struct ScopedMaybeDelete {
- void operator()(T* ptr) {
- if (ptr) {
- ScopedDelete del;
- del(ptr);
- }
- }
-};
-
-#define SCOPED(x) typedef std::unique_ptr<x, ScopedMaybeDelete<x> > Scoped##x
-
-SCOPED(CERTCertificate);
-SCOPED(CERTCertificateList);
-SCOPED(CERTSubjectPublicKeyInfo);
-SCOPED(PK11SlotInfo);
-SCOPED(PK11SymKey);
-SCOPED(SECAlgorithmID);
-SCOPED(SECItem);
-SCOPED(SECKEYPublicKey);
-SCOPED(SECKEYPrivateKey);
-
-SCOPED(CERTCertList);
-
-#undef SCOPED
-
-#endif
diff --git a/nss-tool/nss_tool.gyp b/nss-tool/nss_tool.gyp
index 2882b70be..26eecfe0c 100644
--- a/nss-tool/nss_tool.gyp
+++ b/nss-tool/nss_tool.gyp
@@ -19,8 +19,9 @@
'common',
],
'dependencies' : [
+ '<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'<(DEPTH)/exports.gyp:dbm_exports',
- '<(DEPTH)/exports.gyp:nss_exports'
+ '<(DEPTH)/exports.gyp:nss_exports',
],
}
],