Add DTLS fuzzers.
Bug: 124 Change-Id: Iff02be9df2806572e6d3f860b448f598f85778c3 Reviewed-on: https://boringssl-review.googlesource.com/20107 Reviewed-by: David Benjamin <davidben@google.com> Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
parent
a196ea15af
commit
2ff44b183a
@ -58,6 +58,26 @@ target_link_libraries(client Fuzzer)
|
||||
target_link_libraries(client crypto)
|
||||
target_link_libraries(client ssl)
|
||||
|
||||
add_executable(
|
||||
dtls_server
|
||||
|
||||
dtls_server.cc
|
||||
)
|
||||
|
||||
target_link_libraries(dtls_server Fuzzer)
|
||||
target_link_libraries(dtls_server crypto)
|
||||
target_link_libraries(dtls_server ssl)
|
||||
|
||||
add_executable(
|
||||
dtls_client
|
||||
|
||||
dtls_client.cc
|
||||
)
|
||||
|
||||
target_link_libraries(dtls_client Fuzzer)
|
||||
target_link_libraries(dtls_client crypto)
|
||||
target_link_libraries(dtls_client ssl)
|
||||
|
||||
add_executable(
|
||||
read_pem
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "../ssl/test/fuzzer.h"
|
||||
|
||||
|
||||
static TLSFuzzer g_fuzzer(TLSFuzzer::kClient);
|
||||
static TLSFuzzer g_fuzzer(TLSFuzzer::kTLS, TLSFuzzer::kClient);
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
|
||||
return g_fuzzer.TestOneInput(buf, len);
|
||||
|
22
fuzz/dtls_client.cc
Normal file
22
fuzz/dtls_client.cc
Normal file
@ -0,0 +1,22 @@
|
||||
/* Copyright (c) 2017, Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#include "../ssl/test/fuzzer.h"
|
||||
|
||||
|
||||
static TLSFuzzer g_fuzzer(TLSFuzzer::kDTLS, TLSFuzzer::kClient);
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
|
||||
return g_fuzzer.TestOneInput(buf, len);
|
||||
}
|
22
fuzz/dtls_server.cc
Normal file
22
fuzz/dtls_server.cc
Normal file
@ -0,0 +1,22 @@
|
||||
/* Copyright (c) 2017, Google Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
|
||||
|
||||
#include "../ssl/test/fuzzer.h"
|
||||
|
||||
|
||||
static TLSFuzzer g_fuzzer(TLSFuzzer::kDTLS, TLSFuzzer::kServer);
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
|
||||
return g_fuzzer.TestOneInput(buf, len);
|
||||
}
|
@ -60,6 +60,8 @@ assert_directory client_corpus
|
||||
assert_directory client_corpus_no_fuzzer_mode
|
||||
assert_directory server_corpus
|
||||
assert_directory server_corpus_no_fuzzer_mode
|
||||
assert_directory dtls_client_corpus
|
||||
assert_directory dtls_server_corpus
|
||||
|
||||
|
||||
# Gather new transcripts. Ignore errors in running the tests.
|
||||
@ -102,6 +104,8 @@ minimize_corpus "$fuzzer_mode_build_dir/fuzz/client" client_corpus
|
||||
minimize_corpus "$fuzzer_mode_build_dir/fuzz/server" server_corpus
|
||||
minimize_corpus "$no_fuzzer_mode_build_dir/fuzz/client" client_corpus_no_fuzzer_mode
|
||||
minimize_corpus "$no_fuzzer_mode_build_dir/fuzz/server" server_corpus_no_fuzzer_mode
|
||||
minimize_corpus "$fuzzer_mode_build_dir/fuzz/dtls_client" dtls_client_corpus
|
||||
minimize_corpus "$fuzzer_mode_build_dir/fuzz/dtls_server" dtls_server_corpus
|
||||
|
||||
|
||||
# Incorporate the new transcripts.
|
||||
@ -110,3 +114,5 @@ minimize_corpus "$no_fuzzer_mode_build_dir/fuzz/server" server_corpus_no_fuzzer_
|
||||
"$fuzzer_mode_build_dir/fuzz/server" -max_len=50000 -merge=1 server_corpus "${fuzzer_mode_transcripts}/tls/server"
|
||||
"$no_fuzzer_mode_build_dir/fuzz/client" -max_len=50000 -merge=1 client_corpus_no_fuzzer_mode "${no_fuzzer_mode_transcripts}/tls/client"
|
||||
"$no_fuzzer_mode_build_dir/fuzz/server" -max_len=50000 -merge=1 server_corpus_no_fuzzer_mode "${no_fuzzer_mode_transcripts}/tls/server"
|
||||
"$fuzzer_mode_build_dir/fuzz/dtls_client" -max_len=50000 -merge=1 dtls_client_corpus "${fuzzer_mode_transcripts}/dtls/client"
|
||||
"$fuzzer_mode_build_dir/fuzz/dtls_server" -max_len=50000 -merge=1 dtls_server_corpus "${fuzzer_mode_transcripts}/dtls/server"
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "../ssl/test/fuzzer.h"
|
||||
|
||||
|
||||
static TLSFuzzer g_fuzzer(TLSFuzzer::kServer);
|
||||
static TLSFuzzer g_fuzzer(TLSFuzzer::kTLS, TLSFuzzer::kServer);
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
|
||||
return g_fuzzer.TestOneInput(buf, len);
|
||||
|
@ -15,7 +15,11 @@
|
||||
#ifndef HEADER_SSL_TEST_FUZZER
|
||||
#define HEADER_SSL_TEST_FUZZER
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bytestring.h>
|
||||
@ -253,13 +257,19 @@ int NPNAdvertiseCallback(SSL *ssl, const uint8_t **out, unsigned *out_len,
|
||||
|
||||
class TLSFuzzer {
|
||||
public:
|
||||
enum Protocol {
|
||||
kTLS,
|
||||
kDTLS,
|
||||
};
|
||||
|
||||
enum Role {
|
||||
kClient,
|
||||
kServer,
|
||||
};
|
||||
|
||||
explicit TLSFuzzer(Role role)
|
||||
TLSFuzzer(Protocol protocol, Role role)
|
||||
: debug_(getenv("BORINGSSL_FUZZER_DEBUG") != nullptr),
|
||||
protocol_(protocol),
|
||||
role_(role) {
|
||||
if (!Init()) {
|
||||
abort();
|
||||
@ -284,11 +294,9 @@ class TLSFuzzer {
|
||||
SSL_set_tlsext_host_name(ssl.get(), "hostname");
|
||||
}
|
||||
|
||||
BIO *in = BIO_new(BIO_s_mem());
|
||||
BIO *out = BIO_new(BIO_s_mem());
|
||||
SSL_set_bio(ssl.get(), in, out); // Takes ownership of |in| and |out|.
|
||||
SSL_set0_rbio(ssl.get(), MakeBIO(CBS_data(&cbs), CBS_len(&cbs)).release());
|
||||
SSL_set0_wbio(ssl.get(), BIO_new(BIO_s_mem()));
|
||||
|
||||
BIO_write(in, CBS_data(&cbs), CBS_len(&cbs));
|
||||
if (SSL_do_handshake(ssl.get()) == 1) {
|
||||
// Keep reading application data until error or EOF.
|
||||
uint8_t tmp[1024];
|
||||
@ -311,7 +319,7 @@ class TLSFuzzer {
|
||||
private:
|
||||
// Init initializes |ctx_| with settings common to all inputs.
|
||||
bool Init() {
|
||||
ctx_.reset(SSL_CTX_new(TLS_method()));
|
||||
ctx_.reset(SSL_CTX_new(protocol_ == kDTLS ? DTLS_method() : TLS_method()));
|
||||
bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
|
||||
bssl::UniquePtr<RSA> privkey(RSA_private_key_from_bytes(
|
||||
kRSAPrivateKeyDER, sizeof(kRSAPrivateKeyDER)));
|
||||
@ -341,11 +349,15 @@ class TLSFuzzer {
|
||||
SSL_CTX_enable_ocsp_stapling(ctx_.get());
|
||||
|
||||
// Enable versions and ciphers that are off by default.
|
||||
if (!SSL_CTX_set_strict_cipher_list(ctx_.get(), "ALL:NULL-SHA") ||
|
||||
!SSL_CTX_set_max_proto_version(ctx_.get(), TLS1_3_VERSION) ||
|
||||
!SSL_CTX_set_min_proto_version(ctx_.get(), SSL3_VERSION)) {
|
||||
if (!SSL_CTX_set_strict_cipher_list(ctx_.get(), "ALL:NULL-SHA")) {
|
||||
return false;
|
||||
}
|
||||
if (protocol_ == kTLS) {
|
||||
if (!SSL_CTX_set_max_proto_version(ctx_.get(), TLS1_3_VERSION) ||
|
||||
!SSL_CTX_set_min_proto_version(ctx_.get(), SSL3_VERSION)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SSL_CTX_set_early_data_enabled(ctx_.get(), 1);
|
||||
|
||||
@ -436,11 +448,70 @@ class TLSFuzzer {
|
||||
}
|
||||
}
|
||||
|
||||
struct BIOData {
|
||||
Protocol protocol;
|
||||
CBS cbs;
|
||||
};
|
||||
|
||||
bssl::UniquePtr<BIO> MakeBIO(const uint8_t *in, size_t len) {
|
||||
BIOData *b = new BIOData;
|
||||
b->protocol = protocol_;
|
||||
CBS_init(&b->cbs, in, len);
|
||||
|
||||
bssl::UniquePtr<BIO> bio(BIO_new(&kBIOMethod));
|
||||
bio->init = 1;
|
||||
bio->ptr = b;
|
||||
return bio;
|
||||
}
|
||||
|
||||
static int BIORead(BIO *bio, char *out, int len) {
|
||||
assert(bio->method == &kBIOMethod);
|
||||
BIOData *b = reinterpret_cast<BIOData *>(bio->ptr);
|
||||
if (b->protocol == kTLS) {
|
||||
len = std::min(static_cast<size_t>(len), CBS_len(&b->cbs));
|
||||
memcpy(out, CBS_data(&b->cbs), len);
|
||||
CBS_skip(&b->cbs, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
// Preserve packet boundaries for DTLS.
|
||||
CBS packet;
|
||||
if (!CBS_get_u24_length_prefixed(&b->cbs, &packet)) {
|
||||
return -1;
|
||||
}
|
||||
len = std::min(static_cast<size_t>(len), CBS_len(&packet));
|
||||
memcpy(out, CBS_data(&packet), len);
|
||||
return len;
|
||||
}
|
||||
|
||||
static int BIODestroy(BIO *bio) {
|
||||
assert(bio->method == &kBIOMethod);
|
||||
BIOData *b = reinterpret_cast<BIOData *>(bio->ptr);
|
||||
delete b;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const BIO_METHOD kBIOMethod;
|
||||
|
||||
bool debug_;
|
||||
Protocol protocol_;
|
||||
Role role_;
|
||||
bssl::UniquePtr<SSL_CTX> ctx_;
|
||||
};
|
||||
|
||||
const BIO_METHOD TLSFuzzer::kBIOMethod = {
|
||||
0, // type
|
||||
nullptr, // name
|
||||
nullptr, // bwrite
|
||||
TLSFuzzer::BIORead,
|
||||
nullptr, // bputs
|
||||
nullptr, // bgets
|
||||
nullptr, // ctrl
|
||||
nullptr, // create
|
||||
TLSFuzzer::BIODestroy,
|
||||
nullptr, // callback_ctrl
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
|
@ -112,6 +112,10 @@ func (r *recordingConn) Transcript() []byte {
|
||||
if flow.flowType != writeFlow {
|
||||
continue
|
||||
}
|
||||
if r.isDatagram {
|
||||
// Prepend a length prefix to preserve packet boundaries.
|
||||
ret = append(ret, byte(len(flow.data)>>16), byte(len(flow.data)>>8), byte(len(flow.data)))
|
||||
}
|
||||
ret = append(ret, flow.data...)
|
||||
}
|
||||
return ret
|
||||
|
Loading…
Reference in New Issue
Block a user