From f7bc3cb6e992d24836e16455788655fa2949bccc Mon Sep 17 00:00:00 2001 From: Tim Taubert Date: Fri, 10 Feb 2017 16:23:22 +0100 Subject: [PATCH] Bug 1330557 - Add basic TLS client fuzzer r=mt,franziskus Differential Revision: https://nss-review.dev.mozaws.net/D145 --HG-- rename : gtests/common/scoped_ptrs.h => cpputil/scoped_ptrs.h --- automation/taskcluster/graph/src/extend.js | 16 +- .../taskcluster/scripts/run_clang_format.sh | 1 + cpputil/.clang-format | 4 + cpputil/README | 11 + cpputil/cpputil.gyp | 27 ++ cpputil/dummy_io.cc | 221 +++++++++++++++ cpputil/dummy_io.h | 62 +++++ cpputil/dummy_io_fwd.cc | 162 +++++++++++ {gtests/common => cpputil}/scoped_ptrs.h | 6 +- fuzz/fuzz.gyp | 18 ++ fuzz/tls-client.options | 3 + fuzz/tls_client_socket.cc | 34 +++ fuzz/tls_client_socket.h | 24 ++ fuzz/tls_client_target.cc | 113 ++++++++ gtests/common/gtest.gypi | 5 + gtests/common/manifest.mn | 3 +- gtests/der_gtest/der_gtest.gyp | 6 - gtests/der_gtest/manifest.mn | 3 +- gtests/freebl_gtest/freebl_gtest.gyp | 2 - gtests/google_test/google_test.gyp | 1 - gtests/pk11_gtest/manifest.mn | 3 +- gtests/pk11_gtest/pk11_gtest.gyp | 6 - gtests/ssl_gtest/manifest.mn | 5 +- gtests/ssl_gtest/ssl_gtest.gyp | 5 +- gtests/ssl_gtest/test_io.cc | 256 ++---------------- gtests/ssl_gtest/test_io.h | 10 +- gtests/util_gtest/manifest.mn | 1 + gtests/util_gtest/util_gtest.gyp | 2 - nss-tool/common/scoped_ptrs.h | 57 ---- nss-tool/nss_tool.gyp | 3 +- 30 files changed, 735 insertions(+), 335 deletions(-) create mode 100644 cpputil/.clang-format create mode 100644 cpputil/README create mode 100644 cpputil/cpputil.gyp create mode 100644 cpputil/dummy_io.cc create mode 100644 cpputil/dummy_io.h create mode 100644 cpputil/dummy_io_fwd.cc rename {gtests/common => cpputil}/scoped_ptrs.h (97%) create mode 100644 fuzz/tls-client.options create mode 100644 fuzz/tls_client_socket.cc create mode 100644 fuzz/tls_client_socket.h create mode 100644 fuzz/tls_client_target.cc delete mode 100644 nss-tool/common/scoped_ptrs.h diff --git a/automation/taskcluster/graph/src/extend.js b/automation/taskcluster/graph/src/extend.js index c047d0586d..be77e50e4b 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 c0e6a3071f..3a3604207c 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 0000000000..06e3c5115f --- /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 0000000000..22297dd33f --- /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 0000000000..cf666fd3c1 --- /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 0000000000..a8dacedbe0 --- /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 +#include + +#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(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 0000000000..797ac61133 --- /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 0000000000..5e53d9e1bc --- /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(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 similarity index 97% rename from gtests/common/scoped_ptrs.h rename to cpputil/scoped_ptrs.h index 4707393ad1..a96ac1fa8a 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 9272c9dbbc..9e0444100c 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', @@ -243,6 +244,22 @@ 'nssfuzz-mpi-base', ], }, + { + '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', @@ -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 0000000000..8b017d2ce6 --- /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 0000000000..b5256a0018 --- /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 +#include +#include + +#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(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 0000000000..c9dc9ba347 --- /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 0000000000..4d8ed9ee95 --- /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 +#include +#include + +#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 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 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 2a31634261..e0ffc86e28 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 9834e42a05..a40989bf75 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 39801aeb58..5c6ad86c32 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 862692f56b..93df2ef4db 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 a697ea410a..b858c93d08 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 d23de2ab6e..b3a11b7af1 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 78f9529b76..cb78c8b3ae 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 a67f61a69a..e01afff91c 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 39db7f7539..9f1b7f3009 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 818faf66ee..c49d0d6d17 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 9f158bf77a..42470a1a8e 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(f->secret); - return io->Read(buf, length); -} - -static int32_t DummyWrite(PRFileDesc *f, const void *buf, int32_t length) { - DummyPrSocket *io = reinterpret_cast(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(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 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(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(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(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 b111df20c0..a7e0555e3c 100644 --- a/gtests/ssl_gtest/test_io.h +++ b/gtests/ssl_gtest/test_io.h @@ -15,6 +15,7 @@ #include #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 fd4925142f..b97f92447a 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 ee08bd67d7..e4b7be7edb 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 6752a32b49..0000000000 --- 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 -#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 -struct ScopedMaybeDelete { - void operator()(T* ptr) { - if (ptr) { - ScopedDelete del; - del(ptr); - } - } -}; - -#define SCOPED(x) typedef std::unique_ptr > 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 2882b70bea..26eecfe0ce 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', ], } ],