[boringssl] Structure Aware ASN.1 Fuzzing in BoringSSL (#4179)

* using asn.1 structure aware fuzzer to fuzz boringssl

* incorporating feedback

* changing fuzzer output name

* updating build script

* formatted files

* pulling from google/fuzzing

* uncommenting build

* removing certs
This commit is contained in:
Danny Halawi 2020-08-04 16:52:53 -07:00 committed by GitHub
parent 466b6eb6fe
commit e15b72d833
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 169 additions and 4 deletions

View File

@ -15,7 +15,12 @@
################################################################################
FROM gcr.io/oss-fuzz-base/base-builder
RUN apt-get update && apt-get install -y cmake ninja-build golang
RUN apt-get update && apt-get install -y wget \
golang binutils cmake ninja-build liblzma-dev libz-dev \
pkg-config autoconf libtool
RUN git clone --depth 1 https://boringssl.googlesource.com/boringssl
COPY build.sh $SRC/
# Use ASN.1 pdu protobuf and converter from the google/fuzzing repo.
RUN git clone --depth 1 https://github.com/google/fuzzing.git
RUN git clone --depth 1 https://github.com/google/libprotobuf-mutator.git
RUN (mkdir LPM && cd LPM && cmake ../libprotobuf-mutator -GNinja -DLIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=ON -DLIB_PROTO_MUTATOR_TESTING=OFF -DCMAKE_BUILD_TYPE=Release && ninja)
COPY *.cc build.sh $SRC/

View File

@ -32,7 +32,6 @@ cmake -GNinja -DCMAKE_C_COMPILER=$CC -DCMAKE_CXX_COMPILER=$CXX \
$CMAKE_DEFINES $SRC/boringssl/
ninja
fuzzerFiles=$(find $SRC/boringssl/fuzz/ -name "*.cc")
find . -name "*.a"
@ -48,3 +47,26 @@ for F in $fuzzerFiles; do
zip -j $OUT/${fuzzerName}_seed_corpus.zip $SRC/boringssl/fuzz/${fuzzerName}_corpus/*
fi
done
if [[ $CFLAGS != *sanitize=memory* ]]; then
fuzzerLPMFiles=$(find $SRC/ -maxdepth 1 -name "*.cc")
cp $SRC/fuzzing/proto/asn1-pdu/* $SRC/
rm -rf genfiles && mkdir genfiles && $SRC/LPM/external.protobuf/bin/protoc asn1_pdu.proto --cpp_out=genfiles --proto_path=$SRC/
for F in $fuzzerLPMFiles
do
fuzzerName=$(echo ${F#*_})
fuzzerName=$(basename $fuzzerName .cc)
echo "Building fuzzer $fuzzerName"
$CXX $CXXFLAGS -I genfiles -I . -I $SRC/libprotobuf-mutator/ -I $SRC/LPM/external.protobuf/include -I include $LIB_FUZZING_ENGINE \
-I $SRC/boringssl/include \
$F genfiles/asn1_pdu.pb.cc $SRC/asn1_pdu_to_der.cc \
./ssl/libssl.a ./crypto/libcrypto.a \
$SRC/LPM/src/libfuzzer/libprotobuf-mutator-libfuzzer.a \
$SRC/LPM/src/libprotobuf-mutator.a \
$SRC/LPM/external.protobuf/lib/libprotobuf.a \
-o $OUT/"${fuzzerName}_lpm"
done
fi

View File

@ -0,0 +1,46 @@
// Copyright 2020 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
// This fuzz target fuzzes the same API as
// https://github.com/google/boringssl/blob/master/fuzz/cert.cc, but it employs
// libprotobuf-mutator for structure-aware fuzzing.
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/x509.h>
#include "asn1_pdu.pb.h"
#include "asn1_pdu_to_der.h"
#include "libprotobuf-mutator/src/libfuzzer/libfuzzer_macro.h"
DEFINE_PROTO_FUZZER(const asn1_pdu::PDU& asn1) {
asn1_pdu::ASN1PDUToDER converter;
std::vector<uint8_t> encoded = converter.PDUToDER(asn1);
const uint8_t* buf = encoded.data();
size_t len = encoded.size();
X509* x509 = d2i_X509(NULL, &buf, len);
if (x509 != NULL) {
// Extract the public key.
EVP_PKEY_free(X509_get_pubkey(x509));
// Reserialize the structure.
uint8_t* der = NULL;
i2d_X509(x509, &der);
OPENSSL_free(der);
}
X509_free(x509);
ERR_clear_error();
}

View File

@ -0,0 +1,41 @@
// Copyright 2020 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
// This fuzz target fuzzes the same API as
// https://github.com/google/boringssl/blob/master/fuzz/pkcs12.cc, but it
// employs libprotobuf-mutator for structure-aware fuzzing.
#include <openssl/bytestring.h>
#include <openssl/evp.h>
#include <openssl/pkcs8.h>
#include <openssl/x509.h>
#include "asn1_pdu.pb.h"
#include "asn1_pdu_to_der.h"
#include "libprotobuf-mutator/src/libfuzzer/libfuzzer_macro.h"
DEFINE_PROTO_FUZZER(const asn1_pdu::PDU& asn1) {
asn1_pdu::ASN1PDUToDER converter;
std::vector<uint8_t> encoded = converter.PDUToDER(asn1);
const uint8_t* buf = encoded.data();
size_t len = encoded.size();
bssl::UniquePtr<STACK_OF(X509)> certs(sk_X509_new_null());
EVP_PKEY* key = nullptr;
CBS cbs;
CBS_init(&cbs, buf, len);
PKCS12_get_key_and_certs(&key, certs.get(), &cbs, "foo");
EVP_PKEY_free(key);
}

View File

@ -0,0 +1,51 @@
// Copyright 2020 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
// This fuzz target fuzzes the same API as
// https://github.com/google/boringssl/blob/master/fuzz/pkcs8.cc, but it employs
// libprotobuf-mutator for structure-aware fuzzing.
#include <openssl/bytestring.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
#include "asn1_pdu.pb.h"
#include "asn1_pdu_to_der.h"
#include "libprotobuf-mutator/src/libfuzzer/libfuzzer_macro.h"
DEFINE_PROTO_FUZZER(const asn1_pdu::PDU& asn1) {
asn1_pdu::ASN1PDUToDER converter;
std::vector<uint8_t> encoded = converter.PDUToDER(asn1);
const uint8_t* buf = encoded.data();
size_t len = encoded.size();
CBS cbs;
CBS_init(&cbs, buf, len);
bssl::UniquePtr<EVP_PKEY> pkey(EVP_parse_private_key(&cbs));
if (pkey == NULL) {
return;
}
uint8_t* der;
size_t der_len;
bssl::ScopedCBB cbb;
if (CBB_init(cbb.get(), 0) &&
EVP_marshal_private_key(cbb.get(), pkey.get()) &&
CBB_finish(cbb.get(), &der, &der_len)) {
OPENSSL_free(der);
}
ERR_clear_error();
}