summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2017-09-08 12:44:13 +1000
committerDamien Miller <djm@mindrot.org>2017-09-08 12:44:13 +1000
commitec9d22cc251cc5acfe7b2bcef9cc7a1fe0e949d8 (patch)
treed6dd817fd7bf3a02bbcb14e3d536590c0fcefac1
parentde35c382894964a896a63ecd5607d3a3b93af75d (diff)
downloadopenssh-git-ec9d22cc251cc5acfe7b2bcef9cc7a1fe0e949d8.tar.gz
Fuzzer harnesses for sig verify and pubkey parsing
These are some basic clang libfuzzer harnesses for signature verification and public key parsing. Some assembly (metaphorical) required.
-rw-r--r--.gitignore1
-rw-r--r--regress/misc/fuzz-harness/Makefile22
-rw-r--r--regress/misc/fuzz-harness/README1
-rw-r--r--regress/misc/fuzz-harness/pubkey_fuzz.cc18
-rw-r--r--regress/misc/fuzz-harness/sig_fuzz.cc50
5 files changed, 92 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e25a8302..650eb3c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,4 @@ ssh-keyscan
ssh-keysign
ssh-pkcs11-helper
sshd
+!regress/misc/fuzz-harness/Makefile
diff --git a/regress/misc/fuzz-harness/Makefile b/regress/misc/fuzz-harness/Makefile
new file mode 100644
index 00000000..8fbfc20c
--- /dev/null
+++ b/regress/misc/fuzz-harness/Makefile
@@ -0,0 +1,22 @@
+# NB. libssh and libopenbsd-compat should be built with the same sanitizer opts.
+CXX=clang++-3.9
+FUZZ_FLAGS=-fsanitize=address,undefined -fsanitize-coverage=edge
+FUZZ_LIBS=-lFuzzer
+
+CXXFLAGS=-O2 -g -Wall -Wextra -I ../../.. $(FUZZ_FLAGS)
+LDFLAGS=-L ../../.. -L ../../../openbsd-compat -g $(FUZZ_FLAGS)
+LIBS=-lssh -lopenbsd-compat -lcrypto $(FUZZ_LIBS)
+
+all: pubkey_fuzz sig_fuzz
+
+.cc.o:
+ $(CXX) $(CXXFLAGS) -c $< -o $@
+
+pubkey_fuzz: pubkey_fuzz.o
+ $(CXX) -o $@ pubkey_fuzz.o $(LDFLAGS) $(LIBS)
+
+sig_fuzz: sig_fuzz.o
+ $(CXX) -o $@ sig_fuzz.o $(LDFLAGS) $(LIBS)
+
+clean:
+ -rm -f *.o pubkey_fuzz sig_fuzz
diff --git a/regress/misc/fuzz-harness/README b/regress/misc/fuzz-harness/README
new file mode 100644
index 00000000..ae6fbe75
--- /dev/null
+++ b/regress/misc/fuzz-harness/README
@@ -0,0 +1 @@
+This directory contains fuzzing harnesses for use with clang's libfuzzer.
diff --git a/regress/misc/fuzz-harness/pubkey_fuzz.cc b/regress/misc/fuzz-harness/pubkey_fuzz.cc
new file mode 100644
index 00000000..8bbc1109
--- /dev/null
+++ b/regress/misc/fuzz-harness/pubkey_fuzz.cc
@@ -0,0 +1,18 @@
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+
+extern "C" {
+
+#include "sshkey.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
+{
+ struct sshkey *k = NULL;
+ int r = sshkey_from_blob(data, size, &k);
+ if (r == 0) sshkey_free(k);
+ return 0;
+}
+
+} // extern
+
diff --git a/regress/misc/fuzz-harness/sig_fuzz.cc b/regress/misc/fuzz-harness/sig_fuzz.cc
new file mode 100644
index 00000000..0e535b49
--- /dev/null
+++ b/regress/misc/fuzz-harness/sig_fuzz.cc
@@ -0,0 +1,50 @@
+// cc_fuzz_target test for public key parsing.
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern "C" {
+
+#include "includes.h"
+#include "sshkey.h"
+#include "ssherr.h"
+
+static struct sshkey *generate_or_die(int type, unsigned bits) {
+ int r;
+ struct sshkey *ret;
+ if ((r = sshkey_generate(type, bits, &ret)) != 0) {
+ fprintf(stderr, "generate(%d, %u): %s", type, bits, ssh_err(r));
+ abort();
+ }
+ return ret;
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t* sig, size_t slen)
+{
+#ifdef WITH_OPENSSL
+ static struct sshkey *rsa = generate_or_die(KEY_RSA, 2048);
+ static struct sshkey *dsa = generate_or_die(KEY_DSA, 1024);
+ static struct sshkey *ecdsa256 = generate_or_die(KEY_ECDSA, 256);
+ static struct sshkey *ecdsa384 = generate_or_die(KEY_ECDSA, 384);
+ static struct sshkey *ecdsa521 = generate_or_die(KEY_ECDSA, 521);
+#endif
+ static struct sshkey *ed25519 = generate_or_die(KEY_ED25519, 0);
+ static const char *data = "If everyone started announcing his nose had "
+ "run away, I don’t know how it would all end";
+ static const size_t dlen = strlen(data);
+
+#ifdef WITH_OPENSSL
+ sshkey_verify(rsa, sig, slen, (const u_char *)data, dlen, 0);
+ sshkey_verify(dsa, sig, slen, (const u_char *)data, dlen, 0);
+ sshkey_verify(ecdsa256, sig, slen, (const u_char *)data, dlen, 0);
+ sshkey_verify(ecdsa384, sig, slen, (const u_char *)data, dlen, 0);
+ sshkey_verify(ecdsa521, sig, slen, (const u_char *)data, dlen, 0);
+#endif
+ sshkey_verify(ed25519, sig, slen, (const u_char *)data, dlen, 0);
+ return 0;
+}
+
+} // extern