diff options
author | Damien Miller <djm@mindrot.org> | 2017-09-08 12:44:13 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2017-09-08 12:44:13 +1000 |
commit | ec9d22cc251cc5acfe7b2bcef9cc7a1fe0e949d8 (patch) | |
tree | d6dd817fd7bf3a02bbcb14e3d536590c0fcefac1 /regress | |
parent | de35c382894964a896a63ecd5607d3a3b93af75d (diff) |
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.
Diffstat (limited to 'regress')
-rw-r--r-- | regress/misc/fuzz-harness/Makefile | 22 | ||||
-rw-r--r-- | regress/misc/fuzz-harness/README | 1 | ||||
-rw-r--r-- | regress/misc/fuzz-harness/pubkey_fuzz.cc | 18 | ||||
-rw-r--r-- | regress/misc/fuzz-harness/sig_fuzz.cc | 50 |
4 files changed, 91 insertions, 0 deletions
diff --git a/regress/misc/fuzz-harness/Makefile b/regress/misc/fuzz-harness/Makefile new file mode 100644 index 000000000..8fbfc20c6 --- /dev/null +++ b/regress/misc/fuzz-harness/Makefile | |||
@@ -0,0 +1,22 @@ | |||
1 | # NB. libssh and libopenbsd-compat should be built with the same sanitizer opts. | ||
2 | CXX=clang++-3.9 | ||
3 | FUZZ_FLAGS=-fsanitize=address,undefined -fsanitize-coverage=edge | ||
4 | FUZZ_LIBS=-lFuzzer | ||
5 | |||
6 | CXXFLAGS=-O2 -g -Wall -Wextra -I ../../.. $(FUZZ_FLAGS) | ||
7 | LDFLAGS=-L ../../.. -L ../../../openbsd-compat -g $(FUZZ_FLAGS) | ||
8 | LIBS=-lssh -lopenbsd-compat -lcrypto $(FUZZ_LIBS) | ||
9 | |||
10 | all: pubkey_fuzz sig_fuzz | ||
11 | |||
12 | .cc.o: | ||
13 | $(CXX) $(CXXFLAGS) -c $< -o $@ | ||
14 | |||
15 | pubkey_fuzz: pubkey_fuzz.o | ||
16 | $(CXX) -o $@ pubkey_fuzz.o $(LDFLAGS) $(LIBS) | ||
17 | |||
18 | sig_fuzz: sig_fuzz.o | ||
19 | $(CXX) -o $@ sig_fuzz.o $(LDFLAGS) $(LIBS) | ||
20 | |||
21 | clean: | ||
22 | -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 000000000..ae6fbe75d --- /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 000000000..8bbc11093 --- /dev/null +++ b/regress/misc/fuzz-harness/pubkey_fuzz.cc | |||
@@ -0,0 +1,18 @@ | |||
1 | #include <stddef.h> | ||
2 | #include <stdio.h> | ||
3 | #include <stdint.h> | ||
4 | |||
5 | extern "C" { | ||
6 | |||
7 | #include "sshkey.h" | ||
8 | |||
9 | int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) | ||
10 | { | ||
11 | struct sshkey *k = NULL; | ||
12 | int r = sshkey_from_blob(data, size, &k); | ||
13 | if (r == 0) sshkey_free(k); | ||
14 | return 0; | ||
15 | } | ||
16 | |||
17 | } // extern | ||
18 | |||
diff --git a/regress/misc/fuzz-harness/sig_fuzz.cc b/regress/misc/fuzz-harness/sig_fuzz.cc new file mode 100644 index 000000000..0e535b49a --- /dev/null +++ b/regress/misc/fuzz-harness/sig_fuzz.cc | |||
@@ -0,0 +1,50 @@ | |||
1 | // cc_fuzz_target test for public key parsing. | ||
2 | |||
3 | #include <stddef.h> | ||
4 | #include <stdio.h> | ||
5 | #include <stdint.h> | ||
6 | #include <stdlib.h> | ||
7 | #include <string.h> | ||
8 | |||
9 | extern "C" { | ||
10 | |||
11 | #include "includes.h" | ||
12 | #include "sshkey.h" | ||
13 | #include "ssherr.h" | ||
14 | |||
15 | static struct sshkey *generate_or_die(int type, unsigned bits) { | ||
16 | int r; | ||
17 | struct sshkey *ret; | ||
18 | if ((r = sshkey_generate(type, bits, &ret)) != 0) { | ||
19 | fprintf(stderr, "generate(%d, %u): %s", type, bits, ssh_err(r)); | ||
20 | abort(); | ||
21 | } | ||
22 | return ret; | ||
23 | } | ||
24 | |||
25 | int LLVMFuzzerTestOneInput(const uint8_t* sig, size_t slen) | ||
26 | { | ||
27 | #ifdef WITH_OPENSSL | ||
28 | static struct sshkey *rsa = generate_or_die(KEY_RSA, 2048); | ||
29 | static struct sshkey *dsa = generate_or_die(KEY_DSA, 1024); | ||
30 | static struct sshkey *ecdsa256 = generate_or_die(KEY_ECDSA, 256); | ||
31 | static struct sshkey *ecdsa384 = generate_or_die(KEY_ECDSA, 384); | ||
32 | static struct sshkey *ecdsa521 = generate_or_die(KEY_ECDSA, 521); | ||
33 | #endif | ||
34 | static struct sshkey *ed25519 = generate_or_die(KEY_ED25519, 0); | ||
35 | static const char *data = "If everyone started announcing his nose had " | ||
36 | "run away, I don’t know how it would all end"; | ||
37 | static const size_t dlen = strlen(data); | ||
38 | |||
39 | #ifdef WITH_OPENSSL | ||
40 | sshkey_verify(rsa, sig, slen, (const u_char *)data, dlen, 0); | ||
41 | sshkey_verify(dsa, sig, slen, (const u_char *)data, dlen, 0); | ||
42 | sshkey_verify(ecdsa256, sig, slen, (const u_char *)data, dlen, 0); | ||
43 | sshkey_verify(ecdsa384, sig, slen, (const u_char *)data, dlen, 0); | ||
44 | sshkey_verify(ecdsa521, sig, slen, (const u_char *)data, dlen, 0); | ||
45 | #endif | ||
46 | sshkey_verify(ed25519, sig, slen, (const u_char *)data, dlen, 0); | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | } // extern | ||