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.
This commit is contained in:
Damien Miller 2017-09-08 12:44:13 +10:00
parent de35c38289
commit ec9d22cc25
5 changed files with 92 additions and 0 deletions

1
.gitignore vendored
View File

@ -25,3 +25,4 @@ ssh-keyscan
ssh-keysign
ssh-pkcs11-helper
sshd
!regress/misc/fuzz-harness/Makefile

View File

@ -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

View File

@ -0,0 +1 @@
This directory contains fuzzing harnesses for use with clang's libfuzzer.

View File

@ -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

View File

@ -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 dont 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