Update NSS to 3.32.1-RTM

This commit is contained in:
wolfbeast 2018-02-06 11:46:26 +01:00 committed by Roy Tam
commit c91ef9012b
512 changed files with 83203 additions and 16839 deletions

View file

@ -0,0 +1,122 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <assert.h>
#include <string.h>
#include <random>
#include <tuple>
#include "asn1_mutators.h"
using namespace std;
static tuple<uint8_t *, size_t> ParseItem(uint8_t *Data, size_t MaxLength) {
// Short form. Bit 8 has value "0" and bits 7-1 give the length.
if ((Data[1] & 0x80) == 0) {
size_t length = min(static_cast<size_t>(Data[1]), MaxLength - 2);
return make_tuple(&Data[2], length);
}
// Constructed, indefinite length. Read until {0x00, 0x00}.
if (Data[1] == 0x80) {
void *offset = memmem(&Data[2], MaxLength - 2, "\0", 2);
size_t length = offset ? (static_cast<uint8_t *>(offset) - &Data[2]) + 2
: MaxLength - 2;
return make_tuple(&Data[2], length);
}
// Long form. Two to 127 octets. Bit 8 of first octet has value "1"
// and bits 7-1 give the number of additional length octets.
size_t octets = min(static_cast<size_t>(Data[1] & 0x7f), MaxLength - 2);
// Handle lengths bigger than 32 bits.
if (octets > 4) {
// Ignore any further children, assign remaining length.
return make_tuple(&Data[2] + octets, MaxLength - 2 - octets);
}
// Parse the length.
size_t length = 0;
for (size_t j = 0; j < octets; j++) {
length = (length << 8) | Data[2 + j];
}
length = min(length, MaxLength - 2 - octets);
return make_tuple(&Data[2] + octets, length);
}
static vector<uint8_t *> ParseItems(uint8_t *Data, size_t Size) {
vector<uint8_t *> items;
vector<size_t> lengths;
// The first item is always the whole corpus.
items.push_back(Data);
lengths.push_back(Size);
// Can't use iterators here because the `items` vector is modified inside the
// loop. That's safe as long as we always check `items.size()` before every
// iteration, and only call `.push_back()` to append new items we found.
// Items are accessed through `items.at()`, we hold no references.
for (size_t i = 0; i < items.size(); i++) {
uint8_t *item = items.at(i);
size_t remaining = lengths.at(i);
// Empty or primitive items have no children.
if (remaining == 0 || (0x20 & item[0]) == 0) {
continue;
}
while (remaining > 2) {
uint8_t *content;
size_t length;
tie(content, length) = ParseItem(item, remaining);
if (length > 0) {
// Record the item.
items.push_back(content);
// Record the length for further parsing.
lengths.push_back(length);
}
// Reduce number of bytes left in current item.
remaining -= length + (content - item);
// Skip the item we just parsed.
item = content + length;
}
}
return items;
}
size_t ASN1MutatorFlipConstructed(uint8_t *Data, size_t Size, size_t MaxSize,
unsigned int Seed) {
auto items = ParseItems(Data, Size);
std::mt19937 rng(Seed);
std::uniform_int_distribution<size_t> dist(0, items.size() - 1);
uint8_t *item = items.at(dist(rng));
// Flip "constructed" type bit.
item[0] ^= 0x20;
return Size;
}
size_t ASN1MutatorChangeType(uint8_t *Data, size_t Size, size_t MaxSize,
unsigned int Seed) {
auto items = ParseItems(Data, Size);
std::mt19937 rng(Seed);
std::uniform_int_distribution<size_t> dist(0, items.size() - 1);
uint8_t *item = items.at(dist(rng));
// Change type to a random int [0, 30].
static std::uniform_int_distribution<size_t> tdist(0, 30);
item[0] = tdist(rng);
return Size;
}

View file

@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef asn1_mutators_h__
#define asn1_mutators_h__
#include <stdint.h>
#include <cstddef>
size_t ASN1MutatorFlipConstructed(uint8_t *Data, size_t Size, size_t MaxSize,
unsigned int Seed);
size_t ASN1MutatorChangeType(uint8_t *Data, size_t Size, size_t MaxSize,
unsigned int Seed);
#endif // asn1_mutators_h__

View file

@ -0,0 +1,45 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <string>
#include "shared.h"
#define TEST_FUNCTION(f) \
out = f(certName); \
free(out);
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
std::string name(data, data + size);
assert(SECOID_Init() == SECSuccess);
CERTName* certName = CERT_AsciiToName(name.c_str());
if (certName) {
char* out;
TEST_FUNCTION(CERT_NameToAscii)
TEST_FUNCTION(CERT_GetCertEmailAddress)
// These functions call CERT_GetNameElement with different OIDs.
// Unfotunately CERT_GetNameElement is not accesible from here.
TEST_FUNCTION(CERT_GetCertUid)
TEST_FUNCTION(CERT_GetCommonName)
TEST_FUNCTION(CERT_GetCountryName)
TEST_FUNCTION(CERT_GetDomainComponentName)
TEST_FUNCTION(CERT_GetLocalityName)
TEST_FUNCTION(CERT_GetOrgName)
TEST_FUNCTION(CERT_GetOrgUnitName)
TEST_FUNCTION(CERT_GetStateName)
out = CERT_NameToAsciiInvertible(certName, CERT_N2A_READABLE);
free(out);
out = CERT_NameToAsciiInvertible(certName, CERT_N2A_STRICT);
free(out);
out = CERT_NameToAsciiInvertible(certName, CERT_N2A_INVERTIBLE);
free(out);
}
CERT_DestroyName(certName);
return 0;
}

View file

@ -1,4 +0,0 @@
#!/bin/sh
d=$(dirname $0)
exec $d/git-copy.sh https://github.com/mozilla/nss-fuzzing-corpus master $d/corpus

View file

@ -1,4 +0,0 @@
#!/bin/sh
d=$(dirname $0)
exec $d/git-copy.sh https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer 1b543d6e5073b56be214394890c9193979a3d7e1 $d/libFuzzer

View file

@ -0,0 +1,4 @@
#!/bin/sh
d=$(dirname $0)
$d/git-copy.sh https://github.com/mozilla/nss-fuzzing-corpus master $d/../corpus

View file

@ -0,0 +1,6 @@
#!/bin/sh
LIBFUZZER_REVISION=56bd1d43451cca4b6a11d3be316bb77ab159b09d
d=$(dirname $0)
$d/git-copy.sh https://chromium.googlesource.com/chromium/llvm-project/llvm/lib/Fuzzer $LIBFUZZER_REVISION $d/../libFuzzer

View file

@ -1,4 +1,4 @@
#!/bin/sh
#!/usr/bin/env bash
set -e
@ -15,18 +15,19 @@ echo "Copy '$COMMIT' from '$REPO' to '$DIR'"
if [ -f $DIR/.git-copy ]; then
CURRENT=$(cat $DIR/.git-copy)
if [ $(echo -n $COMMIT | wc -c) != "40" ]; then
# On the off chance that $COMMIT is a remote head.
ACTUAL=$(git ls-remote $REPO $COMMIT | cut -c 1-40 -)
else
ACTUAL=$COMMIT
fi
if [ CURRENT = ACTUAL ]; then
if [ "$CURRENT" = "$ACTUAL" ]; then
echo "Up to date."
exit
fi
fi
mkdir -p $DIR
git -C $DIR init -q
git init -q $DIR
git -C $DIR fetch -q --depth=1 $REPO $COMMIT:git-copy-tmp
git -C $DIR reset --hard git-copy-tmp
git -C $DIR show-ref HEAD | cut -c 1-40 - > $DIR/.git-copy
git -C $DIR rev-parse --verify HEAD > $DIR/.git-copy
rm -rf $DIR/.git

View file

@ -4,62 +4,373 @@
{
'includes': [
'../coreconf/config.gypi',
'../cmd/platlibs.gypi'
],
'target_defaults': {
'variables': {
'debug_optimization_level': '2',
},
'target_conditions': [
[ '_type=="executable"', {
'libraries!': [
'<@(nspr_libs)',
],
'libraries': [
'<(nss_dist_obj_dir)/lib/libplds4.a',
'<(nss_dist_obj_dir)/lib/libnspr4.a',
'<(nss_dist_obj_dir)/lib/libplc4.a',
],
}],
],
},
'targets': [
{
'target_name': 'libFuzzer',
'target_name': 'fuzz_base',
'type': 'static_library',
'sources': [
'libFuzzer/FuzzerCrossOver.cpp',
'libFuzzer/FuzzerDriver.cpp',
'libFuzzer/FuzzerExtFunctionsDlsym.cpp',
'libFuzzer/FuzzerExtFunctionsWeak.cpp',
'libFuzzer/FuzzerIO.cpp',
'libFuzzer/FuzzerLoop.cpp',
'libFuzzer/FuzzerMutate.cpp',
'libFuzzer/FuzzerSHA1.cpp',
'libFuzzer/FuzzerTracePC.cpp',
'libFuzzer/FuzzerTraceState.cpp',
'libFuzzer/FuzzerUtil.cpp',
'libFuzzer/FuzzerUtilDarwin.cpp',
'libFuzzer/FuzzerUtilLinux.cpp',
'shared.cc',
],
'cflags': [
'-O2',
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/lib/certdb/certdb.gyp:certdb',
'<(DEPTH)/lib/certhigh/certhigh.gyp:certhi',
'<(DEPTH)/lib/cryptohi/cryptohi.gyp:cryptohi',
'<(DEPTH)/lib/ssl/ssl.gyp:ssl',
'<(DEPTH)/lib/base/base.gyp:nssb',
'<(DEPTH)/lib/dev/dev.gyp:nssdev',
'<(DEPTH)/lib/pki/pki.gyp:nsspki',
'<(DEPTH)/lib/util/util.gyp:nssutil',
'<(DEPTH)/lib/nss/nss.gyp:nss_static',
'<(DEPTH)/lib/pkcs7/pkcs7.gyp:pkcs7',
# This is a static build of pk11wrap, softoken, and freebl.
'<(DEPTH)/lib/pk11wrap/pk11wrap.gyp:pk11wrap_static',
],
'cflags/': [
['exclude', '-fsanitize='],
['exclude', '-fsanitize-'],
'conditions': [
['fuzz_oss==0', {
'sources': [
'<!@(ls <(DEPTH)/fuzz/libFuzzer/*.cpp)',
],
'cflags/': [
['exclude', '-fsanitize-coverage'],
],
'xcode_settings': {
'OTHER_CFLAGS/': [
['exclude', '-fsanitize-coverage'],
],
},
}, {
'all_dependent_settings': {
'libraries': ['-lFuzzingEngine'],
}
}]
],
'xcode_settings': {
'GCC_OPTIMIZATION_LEVEL': '2', # -O2
'OTHER_CFLAGS/': [
['exclude', '-fsanitize='],
['exclude', '-fsanitize-'],
},
{
'target_name': 'nssfuzz-mpi-base',
'type': 'none',
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'fuzz_base',
],
'direct_dependent_settings': {
'include_dirs': [
'<(DEPTH)/lib/freebl/mpi',
],
'sources': [
'mpi_helper.cc',
],
'conditions': [
[ 'fuzz_oss==1', {
'libraries': [
'/usr/lib/x86_64-linux-gnu/libcrypto.a',
],
}, {
'libraries': [
'-lcrypto',
],
}],
# For test builds we have to set MPI defines.
[ 'target_arch=="ia32"', {
'defines': [
'MP_USE_UINT_DIGIT',
'MP_ASSEMBLY_MULTIPLY',
'MP_ASSEMBLY_SQUARE',
'MP_ASSEMBLY_DIV_2DX1D',
],
}],
],
},
},
{
'target_name': 'nssfuzz',
'target_name': 'nssfuzz-pkcs8',
'type': 'executable',
'sources': [
'nssfuzz.cc',
'asn1_mutators.cc',
'pkcs8_target.cc',
'quickder_targets.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'libFuzzer',
]
'fuzz_base',
],
},
{
'target_name': 'nssfuzz-quickder',
'type': 'executable',
'sources': [
'asn1_mutators.cc',
'quickder_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'fuzz_base',
],
},
{
'target_name': 'nssfuzz-certDN',
'type': 'executable',
'sources': [
'certDN_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'fuzz_base',
],
},
{
'target_name': 'nssfuzz-mpi-add',
'type': 'executable',
'sources': [
'mpi_add_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'nssfuzz-mpi-base',
],
},
{
'target_name': 'nssfuzz-mpi-sub',
'type': 'executable',
'sources': [
'mpi_sub_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'nssfuzz-mpi-base',
],
},
{
'target_name': 'nssfuzz-mpi-sqr',
'type': 'executable',
'sources': [
'mpi_sqr_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'nssfuzz-mpi-base',
],
},
{
'target_name': 'nssfuzz-mpi-div',
'type': 'executable',
'sources': [
'mpi_div_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'nssfuzz-mpi-base',
],
},
{
'target_name': 'nssfuzz-mpi-mod',
'type': 'executable',
'sources': [
'mpi_mod_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'nssfuzz-mpi-base',
],
},
{
'target_name': 'nssfuzz-mpi-sqrmod',
'type': 'executable',
'sources': [
'mpi_sqrmod_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'nssfuzz-mpi-base',
],
},
{
'target_name': 'nssfuzz-mpi-addmod',
'type': 'executable',
'sources': [
'mpi_addmod_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'nssfuzz-mpi-base',
],
},
{
'target_name': 'nssfuzz-mpi-submod',
'type': 'executable',
'sources': [
'mpi_submod_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'nssfuzz-mpi-base',
],
},
{
'target_name': 'nssfuzz-mpi-mulmod',
'type': 'executable',
'sources': [
'mpi_mulmod_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'nssfuzz-mpi-base',
],
},
{
'target_name': 'nssfuzz-mpi-expmod',
'type': 'executable',
'sources': [
'mpi_expmod_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'nssfuzz-mpi-base',
],
},
{
'target_name': 'nssfuzz-mpi-invmod',
'type': 'executable',
'sources': [
'mpi_invmod_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'nssfuzz-mpi-base',
],
'include_dirs': [
'<(DEPTH)/lib/freebl',
],
},
{
'target_name': 'nssfuzz-tls-base',
'type': 'static_library',
'sources': [
'tls_common.cc',
'tls_mutators.cc',
'tls_socket.cc',
],
'dependencies': [
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'<(DEPTH)/exports.gyp:nss_exports',
'fuzz_base',
],
'include_dirs': [
'<(DEPTH)/lib/ssl',
],
'direct_dependent_settings': {
'include_dirs': [
'<(DEPTH)/lib/freebl',
'<(DEPTH)/lib/ssl',
],
},
},
{
'target_name': 'nssfuzz-tls-client',
'type': 'executable',
'sources': [
'tls_client_config.cc',
'tls_client_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'nssfuzz-tls-base',
],
},
{
'target_name': 'nssfuzz-tls-server',
'type': 'executable',
'sources': [
'tls_server_certs.cc',
'tls_server_config.cc',
'tls_server_target.cc',
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'nssfuzz-tls-base',
],
},
{
'target_name': 'nssfuzz-dtls-client',
'type': 'executable',
'sources': [
'tls_client_config.cc',
'tls_client_target.cc',
],
'defines': [
'IS_DTLS'
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'nssfuzz-tls-base',
],
},
{
'target_name': 'nssfuzz-dtls-server',
'type': 'executable',
'sources': [
'tls_server_certs.cc',
'tls_server_config.cc',
'tls_server_target.cc',
],
'defines': [
'IS_DTLS'
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
'<(DEPTH)/cpputil/cpputil.gyp:cpputil',
'nssfuzz-tls-base',
],
},
{
'target_name': 'nssfuzz',
'type': 'none',
'dependencies': [
'nssfuzz-certDN',
'nssfuzz-dtls-client',
'nssfuzz-dtls-server',
'nssfuzz-pkcs8',
'nssfuzz-quickder',
'nssfuzz-tls-client',
'nssfuzz-tls-server',
],
'conditions': [
['OS=="linux"', {
'dependencies': [
'nssfuzz-mpi-add',
'nssfuzz-mpi-addmod',
'nssfuzz-mpi-div',
'nssfuzz-mpi-expmod',
'nssfuzz-mpi-invmod',
'nssfuzz-mpi-mod',
'nssfuzz-mpi-mulmod',
'nssfuzz-mpi-sqr',
'nssfuzz-mpi-sqrmod',
'nssfuzz-mpi-sub',
'nssfuzz-mpi-submod',
],
}],
],
}
],
'target_defaults': {
'include_dirs': [
'libFuzzer',
],
},
'variables': {
'module': 'nss',
}
}

View file

@ -0,0 +1,42 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* This target fuzzes NSS mpi against openssl bignum.
* It therefore requires openssl to be installed.
*/
#include "mpi_helper.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// We require at least size 3 to get two integers from Data.
if (size < 3) {
return 0;
}
INIT_FOUR_NUMBERS
// Compare with OpenSSL addition
assert(mp_add(&a, &b, &c) == MP_OKAY);
(void)BN_add(C, A, B);
check_equal(C, &c, max_size);
// Check a + b == a - -b
mp_neg(&b, &b);
assert(mp_sub(&a, &b, &r) == MP_OKAY);
bool eq = mp_cmp(&r, &c) == 0;
if (!eq) {
char rC[max_size], cC[max_size], aC[max_size], bC[max_size];
mp_tohex(&r, rC);
mp_tohex(&c, cC);
mp_tohex(&a, aC);
mp_tohex(&b, bC);
std::cout << "a = " << std::hex << aC << std::endl;
std::cout << "-b = " << std::hex << bC << std::endl;
std::cout << "a + b = " << std::hex << cC << std::endl;
std::cout << "a - -b = " << std::hex << rC << std::endl;
}
assert(eq);
CLEANUP_AND_RETURN
}

View file

@ -0,0 +1,27 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* This target fuzzes NSS mpi against openssl bignum.
* It therefore requires openssl to be installed.
*/
#include "mpi_helper.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// We require at least size 3 to get two integers from Data.
if (size < 3) {
return 0;
}
INIT_FOUR_NUMBERS
auto modulus = get_modulus(data, size, ctx);
// Compare with OpenSSL add mod
m1 = &std::get<1>(modulus);
assert(mp_addmod(&a, &b, m1, &c) == MP_OKAY);
(void)BN_mod_add(C, A, B, std::get<0>(modulus), ctx);
check_equal(C, &c, max_size);
CLEANUP_AND_RETURN
}

View file

@ -0,0 +1,36 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* This target fuzzes NSS mpi against openssl bignum.
* It therefore requires openssl to be installed.
*/
#include "mpi_helper.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// We require at least size 3 to get two integers from Data.
if (size < 3) {
return 0;
}
INIT_FOUR_NUMBERS
// We can't divide by 0.
if (mp_cmp_z(&b) == 0) {
CLEANUP_AND_RETURN
}
// Compare with OpenSSL division
assert(mp_div(&a, &b, &c, &r) == MP_OKAY);
BN_div(C, R, A, B, ctx);
check_equal(C, &c, max_size);
check_equal(R, &r, max_size);
// Check c * b + r == a
assert(mp_mul(&c, &b, &c) == MP_OKAY);
assert(mp_add(&c, &r, &c) == MP_OKAY);
assert(mp_cmp(&c, &a) == 0);
CLEANUP_AND_RETURN
}

View file

@ -0,0 +1,27 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* This target fuzzes NSS mpi against openssl bignum.
* It therefore requires openssl to be installed.
*/
#include "mpi_helper.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// We require at least size 3 to get two integers from Data.
if (size < 3) {
return 0;
}
INIT_FOUR_NUMBERS
auto modulus = get_modulus(data, size, ctx);
// Compare with OpenSSL exp mod
m1 = &std::get<1>(modulus);
assert(mp_exptmod(&a, &b, m1, &c) == MP_OKAY);
(void)BN_mod_exp(C, A, B, std::get<0>(modulus), ctx);
check_equal(C, &c, 2 * max_size);
CLEANUP_AND_RETURN
}

View file

@ -0,0 +1,100 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Helper functions for MPI fuzzing targets. */
#include "mpi_helper.h"
#include <cstdlib>
#include <random>
char *to_char(const uint8_t *x) {
return reinterpret_cast<char *>(const_cast<unsigned char *>(x));
}
// Check that the two numbers are equal.
void check_equal(BIGNUM *b, mp_int *m, size_t max_size) {
char *bnBc = BN_bn2hex(b);
char mpiMc[max_size];
mp_tohex(m, mpiMc);
std::string bnA(bnBc);
std::string mpiA(mpiMc);
OPENSSL_free(bnBc);
// We have to strip leading zeros from bignums, ignoring the sign.
if (bnA.at(0) != '-') {
bnA.erase(0, std::min(bnA.find_first_not_of('0'), bnA.size() - 1));
} else if (bnA.at(1) == '0') {
bnA.erase(1, std::min(bnA.find_first_not_of('0', 1) - 1, bnA.size() - 1));
}
if (mpiA != bnA) {
std::cout << "openssl: " << std::hex << bnA << std::endl;
std::cout << "nss: " << std::hex << mpiA << std::endl;
}
assert(mpiA == bnA);
}
// Parse data into two numbers for MPI and OpenSSL Bignum.
void parse_input(const uint8_t *data, size_t size, BIGNUM *A, BIGNUM *B,
mp_int *a, mp_int *b) {
// Note that b might overlap a.
size_t len = (size_t)size / 2;
assert(mp_read_raw(a, to_char(data), len) == MP_OKAY);
assert(mp_read_raw(b, to_char(data) + len, len) == MP_OKAY);
// Force a positive sign.
// TODO: add tests for negatives.
MP_SIGN(a) = MP_ZPOS;
MP_SIGN(b) = MP_ZPOS;
// Skip the first byte as it's interpreted as sign by NSS.
assert(BN_bin2bn(data + 1, len - 1, A) != nullptr);
assert(BN_bin2bn(data + len + 1, len - 1, B) != nullptr);
check_equal(A, a, 2 * size + 1);
check_equal(B, b, 2 * size + 1);
}
// Parse data into a number for MPI and OpenSSL Bignum.
void parse_input(const uint8_t *data, size_t size, BIGNUM *A, mp_int *a) {
assert(mp_read_raw(a, to_char(data), size) == MP_OKAY);
// Force a positive sign.
// TODO: add tests for negatives.
MP_SIGN(a) = MP_ZPOS;
// Skip the first byte as it's interpreted as sign by NSS.
assert(BN_bin2bn(data + 1, size - 1, A) != nullptr);
check_equal(A, a, 4 * size + 1);
}
// Take a chunk in the middle of data and use it as modulus.
std::tuple<BIGNUM *, mp_int> get_modulus(const uint8_t *data, size_t size,
BN_CTX *ctx) {
BIGNUM *r1 = BN_CTX_get(ctx);
mp_int r2;
assert(mp_init(&r2) == MP_OKAY);
size_t len = static_cast<size_t>(size / 4);
if (len != 0) {
assert(mp_read_raw(&r2, to_char(data + len), len) == MP_OKAY);
MP_SIGN(&r2) = MP_ZPOS;
assert(BN_bin2bn(data + len + 1, len - 1, r1) != nullptr);
check_equal(r1, &r2, 2 * len + 1);
}
// If we happen to get 0 for the modulus, take a random number.
if (mp_cmp_z(&r2) == 0 || len == 0) {
mp_zero(&r2);
BN_zero(r1);
std::mt19937 rng(data[0]);
std::uniform_int_distribution<mp_digit> dist(1, MP_DIGIT_MAX);
mp_digit x = dist(rng);
mp_add_d(&r2, x, &r2);
BN_add_word(r1, x);
}
return std::make_tuple(r1, r2);
}

View file

@ -0,0 +1,86 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* Helper functions for MPI fuzzing targets. */
#ifndef mpi_helper_h__
#define mpi_helper_h__
#include <iostream>
#include <string>
#include <tuple>
#include <vector>
#include "hasht.h"
#include "mpi.h"
#include <openssl/bn.h>
void check_equal(BIGNUM *b, mp_int *m, size_t max_size);
void parse_input(const uint8_t *data, size_t size, BIGNUM *A, BIGNUM *B,
mp_int *a, mp_int *b);
void parse_input(const uint8_t *data, size_t size, BIGNUM *A, mp_int *a);
std::tuple<BIGNUM *, mp_int> get_modulus(const uint8_t *data, size_t size,
BN_CTX *ctx);
// Initialise MPI and BN variables
// XXX: Also silence unused variable warnings for R.
#define INIT_FOUR_NUMBERS \
mp_int a, b, c, r; \
mp_int *m1 = nullptr; \
BN_CTX *ctx = BN_CTX_new(); \
BN_CTX_start(ctx); \
BIGNUM *A = BN_CTX_get(ctx); \
BIGNUM *B = BN_CTX_get(ctx); \
BIGNUM *C = BN_CTX_get(ctx); \
BIGNUM *R = BN_CTX_get(ctx); \
assert(mp_init(&a) == MP_OKAY); \
assert(mp_init(&b) == MP_OKAY); \
assert(mp_init(&c) == MP_OKAY); \
assert(mp_init(&r) == MP_OKAY); \
size_t max_size = 2 * size + 1; \
parse_input(data, size, A, B, &a, &b); \
do { \
(void)(R); \
} while (0);
// Initialise MPI and BN variables
// XXX: Also silence unused variable warnings for B.
#define INIT_THREE_NUMBERS \
mp_int a, b, c; \
BN_CTX *ctx = BN_CTX_new(); \
BN_CTX_start(ctx); \
BIGNUM *A = BN_CTX_get(ctx); \
BIGNUM *B = BN_CTX_get(ctx); \
BIGNUM *C = BN_CTX_get(ctx); \
assert(mp_init(&a) == MP_OKAY); \
assert(mp_init(&b) == MP_OKAY); \
assert(mp_init(&c) == MP_OKAY); \
size_t max_size = 4 * size + 1; \
parse_input(data, size, A, &a); \
do { \
(void)(B); \
} while (0);
#define CLEANUP_AND_RETURN \
mp_clear(&a); \
mp_clear(&b); \
mp_clear(&c); \
mp_clear(&r); \
if (m1) { \
mp_clear(m1); \
} \
BN_CTX_end(ctx); \
BN_CTX_free(ctx); \
return 0;
#define CLEANUP_AND_RETURN_THREE \
mp_clear(&a); \
mp_clear(&b); \
mp_clear(&c); \
BN_CTX_end(ctx); \
BN_CTX_free(ctx); \
return 0;
#endif // mpi_helper_h__

View file

@ -0,0 +1,69 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* This target fuzzes NSS mpi against openssl bignum.
* It therefore requires openssl to be installed.
*/
#include "mpi_helper.h"
#include "mpprime.h"
#include <algorithm>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// We require at least size 4 to get everything we need from data.
if (size < 4) {
return 0;
}
INIT_THREE_NUMBERS
// Make a prime of length size.
int count = 0;
mp_err res = MP_NO;
// mpp_make_prime is so slow :( use something smaller than size.
int primeLen = std::max(static_cast<int>(size / 4), 3);
uint8_t bp[primeLen];
memcpy(bp, data, primeLen);
do {
bp[0] |= 0x80; /* set high-order bit */
bp[primeLen - 1] |= 0x01; /* set low-order bit */
++count;
assert(mp_read_unsigned_octets(&b, bp, primeLen) == MP_OKAY);
} while ((res = mpp_make_prime(&b, primeLen * 8, PR_FALSE)) != MP_YES &&
count < 10);
if (res != MP_YES) {
return 0;
}
// Use the same prime in OpenSSL B
char tmp[max_size];
mp_toradix(&b, tmp, 16);
int tmpLen;
assert((tmpLen = BN_hex2bn(&B, tmp)) != 0);
// Compare with OpenSSL invmod
res = mp_invmod(&a, &b, &c);
BIGNUM *X = BN_mod_inverse(C, A, B, ctx);
if (res != MP_OKAY) {
// In case we couldn't compute the inverse, OpenSSL shouldn't be able to
// either.
assert(X == nullptr);
} else {
check_equal(C, &c, max_size);
// Check a * c mod b == 1
assert(mp_mulmod(&a, &c, &b, &c) == MP_OKAY);
bool eq = mp_cmp_d(&c, 1) == 0;
if (!eq) {
char cC[max_size];
mp_tohex(&c, cC);
std::cout << "c = " << std::hex << cC << std::endl;
}
assert(eq);
}
CLEANUP_AND_RETURN_THREE
}

View file

@ -0,0 +1,36 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* This target fuzzes NSS mpi against openssl bignum.
* It therefore requires openssl to be installed.
*/
#include "mpi_helper.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// We require at least size 3 to get two integers from Data.
if (size < 3) {
return 0;
}
INIT_FOUR_NUMBERS
// We can't divide by 0.
if (mp_cmp_z(&b) == 0) {
CLEANUP_AND_RETURN
}
// Compare with OpenSSL mod
assert(mp_mod(&a, &b, &c) == MP_OKAY);
(void)BN_mod(C, A, B, ctx);
check_equal(C, &c, max_size);
// Check a mod b = a - floor(a / b) * b
assert(mp_div(&a, &b, &r, nullptr) == MP_OKAY);
assert(mp_mul(&r, &b, &r) == MP_OKAY);
assert(mp_sub(&a, &r, &r) == MP_OKAY);
assert(mp_cmp(&c, &r) == 0);
CLEANUP_AND_RETURN
}

View file

@ -0,0 +1,27 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* This target fuzzes NSS mpi against openssl bignum.
* It therefore requires openssl to be installed.
*/
#include "mpi_helper.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// We require at least size 3 to get two integers from Data.
if (size < 3) {
return 0;
}
INIT_FOUR_NUMBERS
auto modulus = get_modulus(data, size, ctx);
// Compare with OpenSSL mul mod
m1 = &std::get<1>(modulus);
assert(mp_mulmod(&a, &b, m1, &c) == MP_OKAY);
(void)BN_mod_mul(C, A, B, std::get<0>(modulus), ctx);
check_equal(C, &c, max_size);
CLEANUP_AND_RETURN
}

View file

@ -0,0 +1,40 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* This target fuzzes NSS mpi against openssl bignum.
* It therefore requires openssl to be installed.
*/
#include "mpi_helper.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// We require at least size 2 to get an integers from Data.
if (size < 2) {
return 0;
}
INIT_THREE_NUMBERS
// Compare with OpenSSL sqr
assert(mp_sqr(&a, &c) == MP_OKAY);
(void)BN_sqr(C, A, ctx);
check_equal(C, &c, max_size);
// Check a * a == a**2
assert(mp_mul(&a, &a, &b) == MP_OKAY);
bool eq = mp_cmp(&b, &c) == 0;
if (!eq) {
char rC[max_size], cC[max_size], aC[max_size];
mp_tohex(&b, rC);
mp_tohex(&c, cC);
mp_tohex(&a, aC);
std::cout << "a = " << std::hex << aC << std::endl;
std::cout << "a * a = " << std::hex << cC << std::endl;
std::cout << "a ** 2 = " << std::hex << rC << std::endl;
}
assert(eq);
CLEANUP_AND_RETURN_THREE
}

View file

@ -0,0 +1,36 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* This target fuzzes NSS mpi against openssl bignum.
* It therefore requires openssl to be installed.
*/
#include "mpi_helper.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// We require at least size 3 to get two integers from Data.
if (size < 3) {
return 0;
}
INIT_THREE_NUMBERS
// We can't divide by 0.
if (mp_cmp_z(&b) == 0) {
mp_clear(&a);
mp_clear(&b);
mp_clear(&c);
BN_CTX_end(ctx);
BN_CTX_free(ctx);
return 0;
}
// Compare with OpenSSL square mod
assert(mp_sqrmod(&a, &b, &c) == MP_OKAY);
(void)BN_mod_sqr(C, A, B, ctx);
check_equal(C, &c, max_size);
CLEANUP_AND_RETURN_THREE
}

View file

@ -0,0 +1,42 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* This target fuzzes NSS mpi against openssl bignum.
* It therefore requires openssl to be installed.
*/
#include "mpi_helper.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// We require at least size 3 to get two integers from Data.
if (size < 3) {
return 0;
}
INIT_FOUR_NUMBERS
// Compare with OpenSSL subtraction
assert(mp_sub(&a, &b, &c) == MP_OKAY);
(void)BN_sub(C, A, B);
check_equal(C, &c, max_size);
// Check a - b == a + -b
mp_neg(&b, &b);
assert(mp_add(&a, &b, &r) == MP_OKAY);
bool eq = mp_cmp(&r, &c) == 0;
if (!eq) {
char rC[max_size], cC[max_size], aC[max_size], bC[max_size];
mp_tohex(&r, rC);
mp_tohex(&c, cC);
mp_tohex(&a, aC);
mp_tohex(&b, bC);
std::cout << "a = " << std::hex << aC << std::endl;
std::cout << "-b = " << std::hex << bC << std::endl;
std::cout << "a - b = " << std::hex << cC << std::endl;
std::cout << "a + -b = " << std::hex << rC << std::endl;
}
assert(eq);
CLEANUP_AND_RETURN
}

View file

@ -0,0 +1,27 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* This target fuzzes NSS mpi against openssl bignum.
* It therefore requires openssl to be installed.
*/
#include "mpi_helper.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// We require at least size 3 to get two integers from Data.
if (size < 3) {
return 0;
}
INIT_FOUR_NUMBERS
auto modulus = get_modulus(data, size, ctx);
// Compare with OpenSSL sub mod
m1 = &std::get<1>(modulus);
assert(mp_submod(&a, &b, m1, &c) == MP_OKAY);
(void)BN_mod_sub(C, A, B, std::get<0>(modulus), ctx);
check_equal(C, &c, 2 * max_size);
CLEANUP_AND_RETURN
}

View file

@ -1,148 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <iomanip>
#include <iostream>
#include <memory>
#include "keyhi.h"
#include "pk11pub.h"
#include "FuzzerInternal.h"
#include "registry.h"
#include "shared.h"
using namespace std;
class Args {
public:
Args(int argc, char **argv) : args_(argv, argv + argc) {}
string &operator[](const int idx) { return args_[idx]; }
bool Has(const string &arg) {
return any_of(args_.begin(), args_.end(),
[&arg](string &a) { return a.find(arg) == 0; });
}
void Append(const string &arg) { args_.push_back(arg); }
void Remove(const int index) {
assert(index < count());
args_.erase(args_.begin() + index);
}
vector<char *> argv() {
vector<char *> out;
out.resize(count());
transform(args_.begin(), args_.end(), out.begin(),
[](string &a) { return const_cast<char *>(a.c_str()); });
return out;
}
size_t count() { return args_.size(); }
private:
vector<string> args_;
};
void printUsage(Args &args) {
size_t sep = args[0].rfind("/") + 1;
string progName = args[0].substr(sep);
cerr << progName << " - Various libFuzzer targets for NSS" << endl << endl;
cerr << "Usage: " << progName << " <target> <libFuzzer options>" << endl
<< endl;
cerr << "Valid targets:" << endl;
vector<string> names = Registry::Names();
// Find length of the longest name.
size_t name_w =
max_element(names.begin(), names.end(), [](string &a, string &b) {
return a.size() < b.size();
})->size();
// Find length of the longest description.
auto max = max_element(names.begin(), names.end(), [](string &a, string &b) {
return Registry::Desc(a).size() < Registry::Desc(b).size();
});
size_t desc_w = Registry::Desc(*max).size();
// Print list of targets.
for (string name : names) {
cerr << " " << left << setw(name_w) << name << " - " << setw(desc_w)
<< Registry::Desc(name)
<< " [default max_len=" << Registry::MaxLen(name) << "]" << endl;
}
// Some usage examples.
cerr << endl << "Run fuzzer with a given corpus directory:" << endl;
cerr << " " << progName << " <target> /path/to/corpus" << endl;
cerr << endl << "Run fuzzer with a single test input:" << endl;
cerr << " " << progName
<< " <target> ./crash-14d4355b971092e39572bc306a135ddf9f923e19" << endl;
cerr << endl
<< "Specify the number of cores you wish to dedicate to fuzzing:"
<< endl;
cerr << " " << progName << " <target> -jobs=8 -workers=8 /path/to/corpus"
<< endl;
cerr << endl << "Override the maximum length of a test input:" << endl;
cerr << " " << progName << " <target> -max_len=2048 /path/to/corpus" << endl;
cerr << endl
<< "Minimize a given corpus and put the result into 'new_corpus':"
<< endl;
cerr << " " << progName
<< " <target> -merge=1 -max_len=50000 ./new_corpus /path/to/corpus"
<< endl;
cerr << endl << "Merge new test inputs into a corpus:" << endl;
cerr
<< " " << progName
<< " <target> -merge=1 -max_len=50000 /path/to/corpus ./inputs1 ./inputs2"
<< endl;
cerr << endl << "Print libFuzzer usage information:" << endl;
cerr << " " << progName << " <target> -help=1" << endl << endl;
cerr << "Check out the docs at http://llvm.org/docs/LibFuzzer.html" << endl;
}
int main(int argc, char **argv) {
Args args(argc, argv);
if (args.count() < 2 || !Registry::Has(args[1])) {
printUsage(args);
return 1;
}
string targetName(args[1]);
// Remove the target argument when -workers=x or -jobs=y is NOT given.
// If both are given, libFuzzer will spawn multiple processes for the target.
if (!args.Has("-workers=") || !args.Has("-jobs=")) {
args.Remove(1);
}
// Set default max_len arg, if none given and we're not merging.
if (!args.Has("-max_len=") && !args.Has("-merge=1")) {
uint16_t maxLen = Registry::MaxLen(targetName);
args.Append("-max_len=" + to_string(maxLen));
}
// Hand control to the libFuzzer driver.
vector<char *> args_new(args.argv());
argc = args_new.size();
argv = args_new.data();
return fuzzer::FuzzerDriver(&argc, &argv, Registry::Func(targetName));
}

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 4096

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 20000

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 20000

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 20000

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 20000

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 2048

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 2048

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 2048

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 1024

View file

@ -0,0 +1,2 @@
[libfuzzer]
max_len = 256

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 2048

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 2048

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 2048

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 2048

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 2048

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 2048

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 10000

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 20000

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 20000

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 20000

View file

@ -0,0 +1,3 @@
[libfuzzer]
max_len = 20000

View file

@ -1,20 +1,17 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <assert.h>
#include <stdint.h>
#include <memory>
#include <vector>
#include "keyhi.h"
#include "pk11pub.h"
#include "registry.h"
#include "asn1_mutators.h"
#include "shared.h"
extern "C" int pkcs8_fuzzing_target(const uint8_t *Data, size_t Size) {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
SECItem data = {siBuffer, (unsigned char *)Data, (unsigned int)Size};
static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
@ -34,4 +31,9 @@ extern "C" int pkcs8_fuzzing_target(const uint8_t *Data, size_t Size) {
return 0;
}
REGISTER_FUZZING_TARGET("pkcs8", pkcs8_fuzzing_target, 2048, "PKCS#8 Import")
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *data, size_t size,
size_t max_size, unsigned int seed) {
return CustomMutate(
Mutators({ASN1MutatorFlipConstructed, ASN1MutatorChangeType}), data, size,
max_size, seed);
}

View file

@ -0,0 +1,85 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "asn1_mutators.h"
#include "shared.h"
const std::vector<const SEC_ASN1Template *> templates = {
CERT_AttributeTemplate,
CERT_CertExtensionTemplate,
CERT_CertificateRequestTemplate,
CERT_CertificateTemplate,
CERT_CrlTemplate,
CERT_IssuerAndSNTemplate,
CERT_NameTemplate,
CERT_PublicKeyAndChallengeTemplate,
CERT_RDNTemplate,
CERT_SequenceOfCertExtensionTemplate,
CERT_SetOfAttributeTemplate,
CERT_SetOfSignedCrlTemplate,
CERT_SignedCrlTemplate,
CERT_SignedDataTemplate,
CERT_SubjectPublicKeyInfoTemplate,
CERT_TimeChoiceTemplate,
CERT_ValidityTemplate,
SEC_AnyTemplate,
SEC_BitStringTemplate,
SEC_BMPStringTemplate,
SEC_BooleanTemplate,
SEC_CertSequenceTemplate,
SEC_EnumeratedTemplate,
SEC_GeneralizedTimeTemplate,
SEC_IA5StringTemplate,
SEC_IntegerTemplate,
SEC_NullTemplate,
SEC_ObjectIDTemplate,
SEC_OctetStringTemplate,
SEC_PointerToAnyTemplate,
SEC_PointerToEnumeratedTemplate,
SEC_PointerToGeneralizedTimeTemplate,
SEC_PointerToOctetStringTemplate,
SEC_PrintableStringTemplate,
SEC_SetOfAnyTemplate,
SEC_SetOfEnumeratedTemplate,
SEC_SequenceOfAnyTemplate,
SEC_SequenceOfObjectIDTemplate,
SEC_SignedCertificateTemplate,
SEC_SkipTemplate,
SEC_T61StringTemplate,
SEC_UniversalStringTemplate,
SEC_UTCTimeTemplate,
SEC_UTF8StringTemplate,
SEC_VisibleStringTemplate,
SECKEY_DHParamKeyTemplate,
SECKEY_DHPublicKeyTemplate,
SECKEY_DSAPrivateKeyExportTemplate,
SECKEY_DSAPublicKeyTemplate,
SECKEY_PQGParamsTemplate,
SECKEY_PrivateKeyInfoTemplate,
SECKEY_RSAPSSParamsTemplate,
SECKEY_RSAPublicKeyTemplate,
SECOID_AlgorithmIDTemplate};
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
char *dest[2048];
for (auto tpl : templates) {
PORTCheapArenaPool pool;
SECItem buf = {siBuffer, const_cast<unsigned char *>(Data),
static_cast<unsigned int>(Size)};
PORT_InitCheapArena(&pool, DER_DEFAULT_CHUNKSIZE);
(void)SEC_QuickDERDecodeItem(&pool.arena, dest, tpl, &buf);
PORT_DestroyCheapArena(&pool);
}
return 0;
}
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *data, size_t size,
size_t max_size, unsigned int seed) {
return CustomMutate(
Mutators({ASN1MutatorFlipConstructed, ASN1MutatorChangeType}), data, size,
max_size, seed);
}

View file

@ -1,36 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdint.h>
#include "cert.h"
#include "registry.h"
void QuickDERDecode(void *dst, const SEC_ASN1Template *tpl, const uint8_t *buf,
size_t len) {
PORTCheapArenaPool pool;
SECItem data = {siBuffer, const_cast<unsigned char *>(buf),
static_cast<unsigned int>(len)};
PORT_InitCheapArena(&pool, DER_DEFAULT_CHUNKSIZE);
(void)SEC_QuickDERDecodeItem(&pool.arena, dst, tpl, &data);
PORT_DestroyCheapArena(&pool);
}
extern "C" int cert_fuzzing_target(const uint8_t *Data, size_t Size) {
CERTCertificate cert;
QuickDERDecode(&cert, SEC_SignedCertificateTemplate, Data, Size);
return 0;
}
REGISTER_FUZZING_TARGET("cert", cert_fuzzing_target, 3072, "Certificate Import")
extern "C" int spki_fuzzing_target(const uint8_t *Data, size_t Size) {
CERTSubjectPublicKeyInfo spki;
QuickDERDecode(&spki, CERT_SubjectPublicKeyInfoTemplate, Data, Size);
return 0;
}
REGISTER_FUZZING_TARGET("spki", spki_fuzzing_target, 1024, "SPKI Import")

View file

@ -1,71 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef registry_h__
#define registry_h__
#include <map>
#include "FuzzerInternal.h"
#include "nss.h"
class Registry {
public:
static void Add(std::string name, fuzzer::UserCallback func, uint16_t max_len,
std::string desc) {
assert(!Has(name));
GetInstance().targets_[name] = TargetData(func, max_len, desc);
}
static bool Has(std::string name) {
return GetInstance().targets_.count(name) > 0;
}
static fuzzer::UserCallback Func(std::string name) {
assert(Has(name));
return std::get<0>(Get(name));
}
static uint16_t MaxLen(std::string name) {
assert(Has(name));
return std::get<1>(Get(name));
}
static std::string& Desc(std::string name) {
assert(Has(name));
return std::get<2>(Get(name));
}
static std::vector<std::string> Names() {
std::vector<std::string> names;
for (auto& it : GetInstance().targets_) {
names.push_back(it.first);
}
return names;
}
private:
typedef std::tuple<fuzzer::UserCallback, uint16_t, std::string> TargetData;
static Registry& GetInstance() {
static Registry registry;
return registry;
}
static TargetData& Get(std::string name) {
return GetInstance().targets_[name];
}
Registry() {}
std::map<std::string, TargetData> targets_;
};
#define REGISTER_FUZZING_TARGET(name, func, max_len, desc) \
static void __attribute__((constructor)) Register_##func() { \
Registry::Add(name, func, max_len, desc); \
}
#endif // registry_h__

View file

@ -0,0 +1,18 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "shared.h"
size_t CustomMutate(Mutators mutators, uint8_t *data, size_t size,
size_t max_size, unsigned int seed) {
std::mt19937 rng(seed);
static std::bernoulli_distribution bdist;
if (bdist(rng)) {
std::uniform_int_distribution<size_t> idist(0, mutators.size() - 1);
return mutators.at(idist(rng))(data, size, max_size, seed);
}
return LLVMFuzzerMutate(data, size, max_size);
}

View file

@ -7,12 +7,24 @@
#ifndef shared_h__
#define shared_h__
#include <assert.h>
#include <random>
#include "cert.h"
#include "nss.h"
extern "C" size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size,
size_t MaxSize, unsigned int Seed);
class NSSDatabase {
public:
NSSDatabase() { NSS_NoDB_Init(nullptr); }
~NSSDatabase() { NSS_Shutdown(); }
NSSDatabase() { assert(NSS_NoDB_Init(nullptr) == SECSuccess); }
~NSSDatabase() { assert(NSS_Shutdown() == SECSuccess); }
};
typedef std::vector<decltype(LLVMFuzzerCustomMutator) *> Mutators;
size_t CustomMutate(Mutators mutators, uint8_t *data, size_t size,
size_t max_size, unsigned int seed);
#endif // shared_h__

View file

@ -0,0 +1,51 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "tls_client_config.h"
const uint64_t CONFIG_FAIL_CERT_AUTH = 0x01;
const uint64_t CONFIG_ENABLE_EXTENDED_MS = 0x02;
const uint64_t CONFIG_REQUIRE_DH_NAMED_GROUPS = 0x04;
const uint64_t CONFIG_ENABLE_FALSE_START = 0x08;
const uint64_t CONFIG_ENABLE_DEFLATE = 0x10;
const uint64_t CONFIG_ENABLE_CBC_RANDOM_IV = 0x20;
const uint64_t CONFIG_REQUIRE_SAFE_NEGOTIATION = 0x40;
const uint64_t CONFIG_ENABLE_CACHE = 0x80;
// XOR 64-bit chunks of data to build a bitmap of config options derived from
// the fuzzing input. This seems the only way to fuzz various options while
// still maintaining compatibility with BoringSSL or OpenSSL fuzzers.
ClientConfig::ClientConfig(const uint8_t* data, size_t len) {
for (size_t i = 0; i < len; i++) {
config_ ^= static_cast<uint64_t>(data[i]) << (8 * (i % 8));
}
}
bool ClientConfig::FailCertificateAuthentication() {
return config_ & CONFIG_FAIL_CERT_AUTH;
}
bool ClientConfig::EnableExtendedMasterSecret() {
return config_ & CONFIG_ENABLE_EXTENDED_MS;
}
bool ClientConfig::RequireDhNamedGroups() {
return config_ & CONFIG_REQUIRE_DH_NAMED_GROUPS;
}
bool ClientConfig::EnableFalseStart() {
return config_ & CONFIG_ENABLE_FALSE_START;
}
bool ClientConfig::EnableDeflate() { return config_ & CONFIG_ENABLE_DEFLATE; }
bool ClientConfig::EnableCbcRandomIv() {
return config_ & CONFIG_ENABLE_CBC_RANDOM_IV;
}
bool ClientConfig::RequireSafeNegotiation() {
return config_ & CONFIG_REQUIRE_SAFE_NEGOTIATION;
}
bool ClientConfig::EnableCache() { return config_ & CONFIG_ENABLE_CACHE; }

View file

@ -0,0 +1,28 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef tls_client_config_h__
#define tls_client_config_h__
#include <stdint.h>
#include <cstddef>
class ClientConfig {
public:
ClientConfig(const uint8_t* data, size_t len);
bool FailCertificateAuthentication();
bool EnableExtendedMasterSecret();
bool RequireDhNamedGroups();
bool EnableFalseStart();
bool EnableDeflate();
bool EnableCbcRandomIv();
bool RequireSafeNegotiation();
bool EnableCache();
private:
uint64_t config_;
};
#endif // tls_client_config_h__

View file

@ -0,0 +1,134 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <assert.h>
#include <stdint.h>
#include <memory>
#include "blapi.h"
#include "prinit.h"
#include "ssl.h"
#include "shared.h"
#include "tls_client_config.h"
#include "tls_common.h"
#include "tls_mutators.h"
#include "tls_socket.h"
#ifdef IS_DTLS
__attribute__((constructor)) static void set_is_dtls() {
TlsMutators::SetIsDTLS();
}
#endif
PRFileDesc* ImportFD(PRFileDesc* model, PRFileDesc* fd) {
#ifdef IS_DTLS
return DTLS_ImportFD(model, fd);
#else
return SSL_ImportFD(model, fd);
#endif
}
static SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checksig,
PRBool isServer) {
assert(!isServer);
auto config = reinterpret_cast<ClientConfig*>(arg);
return config->FailCertificateAuthentication() ? SECFailure : SECSuccess;
}
static void SetSocketOptions(PRFileDesc* fd,
std::unique_ptr<ClientConfig>& config) {
SECStatus rv = SSL_OptionSet(fd, SSL_NO_CACHE, config->EnableCache());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_ENABLE_EXTENDED_MASTER_SECRET,
config->EnableExtendedMasterSecret());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_REQUIRE_DH_NAMED_GROUPS,
config->RequireDhNamedGroups());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_ENABLE_FALSE_START, config->EnableFalseStart());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_ENABLE_DEFLATE, config->EnableDeflate());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_CBC_RANDOM_IV, config->EnableCbcRandomIv());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_REQUIRE_SAFE_NEGOTIATION,
config->RequireSafeNegotiation());
assert(rv == SECSuccess);
#ifndef IS_DTLS
rv =
SSL_OptionSet(fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED);
assert(rv == SECSuccess);
#endif
}
// This is only called when we set SSL_ENABLE_FALSE_START=1,
// so we can always just set *canFalseStart=true.
static SECStatus CanFalseStartCallback(PRFileDesc* fd, void* arg,
PRBool* canFalseStart) {
*canFalseStart = true;
return SECSuccess;
}
static void SetupCallbacks(PRFileDesc* fd, ClientConfig* config) {
SECStatus rv = SSL_AuthCertificateHook(fd, AuthCertificateHook, config);
assert(rv == SECSuccess);
rv = SSL_SetCanFalseStartCallback(fd, CanFalseStartCallback, nullptr);
assert(rv == SECSuccess);
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
assert(db != nullptr);
EnableAllProtocolVersions();
std::unique_ptr<ClientConfig> config(new ClientConfig(data, len));
// Clear the cache. We never want to resume as we couldn't reproduce that.
SSL_ClearSessionCache();
// Reset the RNG state.
assert(RNG_RandomUpdate(NULL, 0) == SECSuccess);
// Create and import dummy socket.
std::unique_ptr<DummyPrSocket> socket(new DummyPrSocket(data, len));
static PRDescIdentity id = PR_GetUniqueIdentity("fuzz-client");
ScopedPRFileDesc fd(DummyIOLayerMethods::CreateFD(id, socket.get()));
PRFileDesc* ssl_fd = ImportFD(nullptr, fd.get());
assert(ssl_fd == fd.get());
// Probably not too important for clients.
SSL_SetURL(ssl_fd, "server");
SetSocketOptions(ssl_fd, config);
EnableAllCipherSuites(ssl_fd);
SetupCallbacks(ssl_fd, config.get());
DoHandshake(ssl_fd, false);
return 0;
}
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
size_t max_size, unsigned int seed) {
using namespace TlsMutators;
return CustomMutate({DropRecord, ShuffleRecords, DuplicateRecord,
TruncateRecord, FragmentRecord},
data, size, max_size, seed);
}
extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t* data1, size_t size1,
const uint8_t* data2, size_t size2,
uint8_t* out, size_t max_out_size,
unsigned int seed) {
return TlsMutators::CrossOver(data1, size1, data2, size2, out, max_out_size,
seed);
}

View file

@ -0,0 +1,48 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <assert.h>
#include "ssl.h"
#include "tls_common.h"
PRStatus EnableAllProtocolVersions() {
SSLVersionRange supported;
SECStatus rv = SSL_VersionRangeGetSupported(ssl_variant_stream, &supported);
assert(rv == SECSuccess);
rv = SSL_VersionRangeSetDefault(ssl_variant_stream, &supported);
assert(rv == SECSuccess);
return PR_SUCCESS;
}
void EnableAllCipherSuites(PRFileDesc* fd) {
for (uint16_t i = 0; i < SSL_NumImplementedCiphers; ++i) {
SECStatus rv = SSL_CipherPrefSet(fd, SSL_ImplementedCiphers[i], true);
assert(rv == SECSuccess);
}
}
void DoHandshake(PRFileDesc* fd, bool isServer) {
SECStatus rv = SSL_ResetHandshake(fd, isServer);
assert(rv == SECSuccess);
do {
rv = SSL_ForceHandshake(fd);
} while (rv != SECSuccess && PR_GetError() == PR_WOULD_BLOCK_ERROR);
// If the handshake succeeds, let's read some data from the server, if any.
if (rv == SECSuccess) {
uint8_t block[1024];
int32_t nb;
// Read application data and echo it back.
while ((nb = PR_Read(fd, block, sizeof(block))) > 0) {
PR_Write(fd, block, nb);
}
}
}

View file

@ -0,0 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef tls_common_h__
#define tls_common_h__
#include "prinit.h"
PRStatus EnableAllProtocolVersions();
void EnableAllCipherSuites(PRFileDesc* fd);
void DoHandshake(PRFileDesc* fd, bool isServer);
#endif // tls_common_h__

View file

@ -0,0 +1,289 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "shared.h"
#include "tls_parser.h"
#include "ssl.h"
#include "sslimpl.h"
using namespace nss_test;
// Number of additional bytes in the TLS header.
// Used to properly skip DTLS seqnums.
static size_t gExtraHeaderBytes = 0;
// Helper class to simplify TLS record manipulation.
class Record {
public:
static std::unique_ptr<Record> Create(const uint8_t *data, size_t size,
size_t remaining) {
return std::unique_ptr<Record>(new Record(data, size, remaining));
}
void insert_before(const std::unique_ptr<Record> &other) {
assert(data_ && size_ > 0);
// Copy data in case other == this.
uint8_t buf[size_];
memcpy(buf, data_, size_);
uint8_t *dest = const_cast<uint8_t *>(other->data());
// Make room for the record we want to insert.
memmove(dest + size_, other->data(), other->size() + other->remaining());
// Insert the record.
memcpy(dest, buf, size_);
}
void truncate(size_t length) {
assert(length >= 5 + gExtraHeaderBytes);
uint8_t *dest = const_cast<uint8_t *>(data_);
(void)ssl_EncodeUintX(length - 5 - gExtraHeaderBytes, 2, &dest[3]);
memmove(dest + length, data_ + size_, remaining_);
}
void drop() {
uint8_t *dest = const_cast<uint8_t *>(data_);
memmove(dest, data_ + size_, remaining_);
}
const uint8_t *data() { return data_; }
size_t remaining() { return remaining_; }
size_t size() { return size_; }
private:
Record(const uint8_t *data, size_t size, size_t remaining)
: data_(data), remaining_(remaining), size_(size) {}
const uint8_t *data_;
size_t remaining_;
size_t size_;
};
// Parse records contained in a given TLS transcript.
std::vector<std::unique_ptr<Record>> ParseRecords(const uint8_t *data,
size_t size) {
std::vector<std::unique_ptr<Record>> records;
TlsParser parser(data, size);
while (parser.remaining()) {
size_t offset = parser.consumed();
// Skip type, version, and DTLS seqnums.
if (!parser.Skip(3 + gExtraHeaderBytes)) {
break;
}
DataBuffer fragment;
if (!parser.ReadVariable(&fragment, 2)) {
break;
}
records.push_back(Record::Create(data + offset,
fragment.len() + 5 + gExtraHeaderBytes,
parser.remaining()));
}
return records;
}
namespace TlsMutators {
// Handle seqnums in DTLS transcripts.
void SetIsDTLS() { gExtraHeaderBytes = 8; }
// Mutator that drops whole TLS records.
size_t DropRecord(uint8_t *data, size_t size, size_t max_size,
unsigned int seed) {
std::mt19937 rng(seed);
// Find TLS records in the corpus.
auto records = ParseRecords(data, size);
if (records.empty()) {
return 0;
}
// Pick a record to drop at random.
std::uniform_int_distribution<size_t> dist(0, records.size() - 1);
auto &rec = records.at(dist(rng));
// Drop the record.
rec->drop();
// Return the new final size.
return size - rec->size();
}
// Mutator that shuffles TLS records in a transcript.
size_t ShuffleRecords(uint8_t *data, size_t size, size_t max_size,
unsigned int seed) {
std::mt19937 rng(seed);
// Store the original corpus.
uint8_t buf[size];
memcpy(buf, data, size);
// Find TLS records in the corpus.
auto records = ParseRecords(buf, sizeof(buf));
if (records.empty()) {
return 0;
}
// Find offset of first record in target buffer.
uint8_t *dest = const_cast<uint8_t *>(ParseRecords(data, size).at(0)->data());
// Shuffle record order.
std::shuffle(records.begin(), records.end(), rng);
// Write records to their new positions.
for (auto &rec : records) {
memcpy(dest, rec->data(), rec->size());
dest += rec->size();
}
// Final size hasn't changed.
return size;
}
// Mutator that duplicates a single TLS record and randomly inserts it.
size_t DuplicateRecord(uint8_t *data, size_t size, size_t max_size,
unsigned int seed) {
std::mt19937 rng(seed);
// Find TLS records in the corpus.
const auto records = ParseRecords(data, size);
if (records.empty()) {
return 0;
}
// Pick a record to duplicate at random.
std::uniform_int_distribution<size_t> dist(0, records.size() - 1);
auto &rec = records.at(dist(rng));
if (size + rec->size() > max_size) {
return 0;
}
// Insert before random record.
rec->insert_before(records.at(dist(rng)));
// Return the new final size.
return size + rec->size();
}
// Mutator that truncates a TLS record.
size_t TruncateRecord(uint8_t *data, size_t size, size_t max_size,
unsigned int seed) {
std::mt19937 rng(seed);
// Find TLS records in the corpus.
const auto records = ParseRecords(data, size);
if (records.empty()) {
return 0;
}
// Pick a record to truncate at random.
std::uniform_int_distribution<size_t> dist(0, records.size() - 1);
auto &rec = records.at(dist(rng));
// Need a record with data.
if (rec->size() <= 5 + gExtraHeaderBytes) {
return 0;
}
// Truncate.
std::uniform_int_distribution<size_t> dist2(5 + gExtraHeaderBytes,
rec->size() - 1);
size_t new_length = dist2(rng);
rec->truncate(new_length);
// Return the new final size.
return size + new_length - rec->size();
}
// Mutator that splits a TLS record in two.
size_t FragmentRecord(uint8_t *data, size_t size, size_t max_size,
unsigned int seed) {
std::mt19937 rng(seed);
// We can't deal with DTLS yet.
if (gExtraHeaderBytes > 0) {
return 0;
}
if (size + 5 > max_size) {
return 0;
}
// Find TLS records in the corpus.
const auto records = ParseRecords(data, size);
if (records.empty()) {
return 0;
}
// Pick a record to fragment at random.
std::uniform_int_distribution<size_t> dist(0, records.size() - 1);
auto &rec = records.at(dist(rng));
uint8_t *rdata = const_cast<uint8_t *>(rec->data());
size_t length = rec->size();
size_t content_length = length - 5;
if (content_length < 2) {
return 0;
}
// Assign a new length to the first fragment.
size_t new_length = content_length / 2;
uint8_t *content = ssl_EncodeUintX(new_length, 2, &rdata[3]);
// Make room for one more header.
memmove(content + new_length + 5, content + new_length,
rec->remaining() + content_length - new_length);
// Write second header.
memcpy(content + new_length, rdata, 3);
(void)ssl_EncodeUintX(content_length - new_length, 2,
&content[new_length + 3]);
return size + 5;
}
// Cross-over function that merges and shuffles two transcripts.
size_t CrossOver(const uint8_t *data1, size_t size1, const uint8_t *data2,
size_t size2, uint8_t *out, size_t max_out_size,
unsigned int seed) {
std::mt19937 rng(seed);
// Find TLS records in the corpus.
auto records1 = ParseRecords(data1, size1);
if (records1.empty()) {
return 0;
}
{ // Merge the two vectors.
auto records2 = ParseRecords(data2, size2);
if (records2.empty()) {
return 0;
}
std::move(records2.begin(), records2.end(), std::back_inserter(records1));
}
// Shuffle record order.
std::shuffle(records1.begin(), records1.end(), rng);
size_t total = 0;
for (auto &rec : records1) {
size_t length = rec->size();
if (total + length > max_out_size) {
break;
}
// Write record to its new position.
memcpy(out + total, rec->data(), length);
total += length;
}
return total;
}
} // namespace TlsMutators

View file

@ -0,0 +1,29 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef tls_mutators_h__
#define tls_mutators_h__
namespace TlsMutators {
void SetIsDTLS();
size_t DropRecord(uint8_t *data, size_t size, size_t max_size,
unsigned int seed);
size_t ShuffleRecords(uint8_t *data, size_t size, size_t max_size,
unsigned int seed);
size_t DuplicateRecord(uint8_t *data, size_t size, size_t max_size,
unsigned int seed);
size_t TruncateRecord(uint8_t *data, size_t size, size_t max_size,
unsigned int seed);
size_t FragmentRecord(uint8_t *data, size_t size, size_t max_size,
unsigned int seed);
size_t CrossOver(const uint8_t *data1, size_t size1, const uint8_t *data2,
size_t size2, uint8_t *out, size_t max_out_size,
unsigned int seed);
} // namespace TlsMutators
#endif // tls_mutators_h__

View file

@ -0,0 +1,295 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <assert.h>
#include <stdint.h>
#include "ssl.h"
#include "cpputil.h"
#include "scoped_ptrs.h"
#include "tls_server_certs.h"
const uint8_t kP256ServerCert[] = {
0x30, 0x82, 0x01, 0xcf, 0x30, 0x82, 0x01, 0x76, 0xa0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x09, 0x00, 0xd9, 0x4c, 0x04, 0xda, 0x49, 0x7d, 0xbf, 0xeb,
0x30, 0x09, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x30,
0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31,
0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49, 0x6e,
0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69,
0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x1e,
0x17, 0x0d, 0x31, 0x34, 0x30, 0x34, 0x32, 0x33, 0x32, 0x33, 0x32, 0x31,
0x35, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x35, 0x32, 0x33, 0x32,
0x33, 0x32, 0x31, 0x35, 0x37, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09,
0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30,
0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65,
0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74,
0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a,
0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xe6, 0x2b, 0x69, 0xe2,
0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f, 0x1e, 0x0d, 0x94, 0x8a, 0x4c, 0xd5,
0x97, 0x6b, 0xb7, 0xa9, 0x1e, 0x0d, 0x46, 0xfb, 0xdd, 0xa9, 0xa9, 0x1e,
0x9d, 0xdc, 0xba, 0x5a, 0x01, 0xe7, 0xd6, 0x97, 0xa8, 0x0a, 0x18, 0xf9,
0xc3, 0xc4, 0xa3, 0x1e, 0x56, 0xe2, 0x7c, 0x83, 0x48, 0xdb, 0x16, 0x1a,
0x1c, 0xf5, 0x1d, 0x7e, 0xf1, 0x94, 0x2d, 0x4b, 0xcf, 0x72, 0x22, 0xc1,
0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
0x16, 0x04, 0x14, 0xab, 0x84, 0xd2, 0xac, 0xab, 0x95, 0xf0, 0x82, 0x4e,
0x16, 0x78, 0x07, 0x55, 0x57, 0x5f, 0xe4, 0x26, 0x8d, 0x82, 0xd1, 0x30,
0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
0xab, 0x84, 0xd2, 0xac, 0xab, 0x95, 0xf0, 0x82, 0x4e, 0x16, 0x78, 0x07,
0x55, 0x57, 0x5f, 0xe4, 0x26, 0x8d, 0x82, 0xd1, 0x30, 0x0c, 0x06, 0x03,
0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x09,
0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, 0x03, 0x48, 0x00,
0x30, 0x45, 0x02, 0x21, 0x00, 0xf2, 0xa0, 0x35, 0x5e, 0x51, 0x3a, 0x36,
0xc3, 0x82, 0x79, 0x9b, 0xee, 0x27, 0x50, 0x85, 0x8e, 0x70, 0x06, 0x74,
0x95, 0x57, 0xd2, 0x29, 0x74, 0x00, 0xf4, 0xbe, 0x15, 0x87, 0x5d, 0xc4,
0x07, 0x02, 0x20, 0x7c, 0x1e, 0x79, 0x14, 0x6a, 0x21, 0x83, 0xf0, 0x7a,
0x74, 0x68, 0x79, 0x5f, 0x14, 0x99, 0x9a, 0x68, 0xb4, 0xf1, 0xcb, 0x9e,
0x15, 0x5e, 0xe6, 0x1f, 0x32, 0x52, 0x61, 0x5e, 0x75, 0xc9, 0x14};
const uint8_t kP256ServerKey[] = {
0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
0x03, 0x01, 0x07, 0x04, 0x6d, 0x30, 0x6b, 0x02, 0x01, 0x01, 0x04, 0x20,
0x07, 0x0f, 0x08, 0x72, 0x7a, 0xd4, 0xa0, 0x4a, 0x9c, 0xdd, 0x59, 0xc9,
0x4d, 0x89, 0x68, 0x77, 0x08, 0xb5, 0x6f, 0xc9, 0x5d, 0x30, 0x77, 0x0e,
0xe8, 0xd1, 0xc9, 0xce, 0x0a, 0x8b, 0xb4, 0x6a, 0xa1, 0x44, 0x03, 0x42,
0x00, 0x04, 0xe6, 0x2b, 0x69, 0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f,
0x1e, 0x0d, 0x94, 0x8a, 0x4c, 0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e, 0x0d,
0x46, 0xfb, 0xdd, 0xa9, 0xa9, 0x1e, 0x9d, 0xdc, 0xba, 0x5a, 0x01, 0xe7,
0xd6, 0x97, 0xa8, 0x0a, 0x18, 0xf9, 0xc3, 0xc4, 0xa3, 0x1e, 0x56, 0xe2,
0x7c, 0x83, 0x48, 0xdb, 0x16, 0x1a, 0x1c, 0xf5, 0x1d, 0x7e, 0xf1, 0x94,
0x2d, 0x4b, 0xcf, 0x72, 0x22, 0xc1};
const uint8_t kRsaServerCert[] = {
0x30, 0x82, 0x03, 0xb5, 0x30, 0x82, 0x02, 0x9d, 0xa0, 0x03, 0x02, 0x01,
0x02, 0x02, 0x09, 0x00, 0xb5, 0xb6, 0x22, 0xb9, 0x5a, 0x04, 0xa5, 0x21,
0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
0x0b, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74,
0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a,
0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57,
0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c,
0x74, 0x64, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x37, 0x30, 0x39,
0x30, 0x34, 0x33, 0x38, 0x30, 0x39, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x30,
0x38, 0x30, 0x38, 0x30, 0x34, 0x33, 0x38, 0x30, 0x39, 0x5a, 0x30, 0x45,
0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41,
0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a,
0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21,
0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74,
0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74,
0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x30, 0x82, 0x01,
0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xba, 0x0b, 0xda, 0x84, 0x19, 0x12,
0x01, 0x41, 0x75, 0x7c, 0x2e, 0x3d, 0xbd, 0xbd, 0x5b, 0xbe, 0x53, 0xeb,
0x72, 0x5f, 0x34, 0x92, 0x8a, 0x75, 0x88, 0xba, 0x62, 0xb9, 0x8a, 0x33,
0xe1, 0x0a, 0x6d, 0xc3, 0x2e, 0x7b, 0xf8, 0x45, 0xac, 0xb1, 0x90, 0x5c,
0x1e, 0x9a, 0xd9, 0xe4, 0x19, 0x16, 0x7f, 0xa3, 0xde, 0x19, 0x9e, 0xc5,
0xe4, 0x05, 0xf5, 0x3f, 0x22, 0x5b, 0x18, 0x76, 0x4b, 0xaa, 0xf3, 0x02,
0xbd, 0x58, 0x8f, 0xea, 0x97, 0x78, 0x30, 0x5a, 0x31, 0xfe, 0x28, 0x04,
0x48, 0x84, 0x84, 0x1c, 0x48, 0xb1, 0xa2, 0x25, 0xc2, 0xcd, 0xea, 0x41,
0xae, 0x1b, 0x69, 0xe5, 0x44, 0x12, 0x8c, 0x70, 0xf8, 0x0f, 0x88, 0x4a,
0xb6, 0x07, 0x4c, 0x81, 0x5c, 0x57, 0xf8, 0xb4, 0x6d, 0xc2, 0x05, 0xb7,
0x9a, 0x7b, 0xbf, 0xbc, 0x1b, 0xbb, 0xaf, 0x3a, 0x6b, 0xfc, 0x34, 0xbc,
0x8a, 0x8f, 0x7d, 0xa7, 0x79, 0x6a, 0x67, 0x50, 0x24, 0xcb, 0xe6, 0x8d,
0x95, 0xc3, 0x23, 0xe8, 0xc6, 0x32, 0xf1, 0x4f, 0x98, 0x14, 0x47, 0xaf,
0x6f, 0xf5, 0x74, 0x95, 0x16, 0x3d, 0xa2, 0xac, 0x26, 0x5b, 0xb0, 0x47,
0x9d, 0x78, 0xa4, 0x9b, 0xfb, 0xe2, 0xea, 0xc8, 0xc8, 0x4b, 0x7e, 0x74,
0x53, 0xcc, 0xdb, 0xfe, 0x64, 0x73, 0x61, 0xe2, 0x2c, 0xd9, 0x1e, 0xb9,
0x2d, 0x47, 0x6e, 0x4c, 0xbe, 0x74, 0xf9, 0x43, 0x20, 0x6a, 0xdf, 0x68,
0x71, 0xec, 0x08, 0xd9, 0xdb, 0xfc, 0x68, 0xef, 0x43, 0xa6, 0x1f, 0xbc,
0x35, 0xd1, 0xad, 0x83, 0xc2, 0xc5, 0x63, 0x24, 0xd3, 0x1d, 0xc5, 0x31,
0x26, 0x83, 0x2b, 0xd4, 0xf4, 0xce, 0x82, 0x79, 0x84, 0x4f, 0x5f, 0x56,
0x24, 0x7e, 0x0f, 0xac, 0x5c, 0x24, 0xed, 0x91, 0x35, 0x40, 0x94, 0x10,
0xd4, 0xbe, 0x22, 0x2a, 0x63, 0xde, 0x42, 0x2b, 0x2d, 0xb9, 0x02, 0x03,
0x01, 0x00, 0x01, 0xa3, 0x81, 0xa7, 0x30, 0x81, 0xa4, 0x30, 0x1d, 0x06,
0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf9, 0x9b, 0xa5, 0x6f,
0xcd, 0x88, 0xd5, 0x60, 0x71, 0xb7, 0xd2, 0x20, 0x44, 0xfa, 0x3d, 0x97,
0x0e, 0x15, 0x04, 0xf2, 0x30, 0x75, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04,
0x6e, 0x30, 0x6c, 0x80, 0x14, 0xf9, 0x9b, 0xa5, 0x6f, 0xcd, 0x88, 0xd5,
0x60, 0x71, 0xb7, 0xd2, 0x20, 0x44, 0xfa, 0x3d, 0x97, 0x0e, 0x15, 0x04,
0xf2, 0xa1, 0x49, 0xa4, 0x47, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06,
0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11,
0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d,
0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55,
0x04, 0x0a, 0x13, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74,
0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79,
0x20, 0x4c, 0x74, 0x64, 0x82, 0x09, 0x00, 0xb5, 0xb6, 0x22, 0xb9, 0x5a,
0x04, 0xa5, 0x21, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05,
0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01,
0x00, 0x3e, 0xc9, 0x83, 0xaf, 0x12, 0x02, 0xb6, 0x16, 0x95, 0xca, 0x07,
0x7d, 0x90, 0x01, 0xf7, 0x43, 0xe6, 0xca, 0xbb, 0x79, 0x1f, 0xa0, 0xfc,
0x2d, 0x18, 0xbe, 0x5b, 0x64, 0x62, 0xd5, 0xf0, 0x4d, 0xc5, 0x11, 0x04,
0x2e, 0x77, 0xb3, 0x58, 0x9d, 0xac, 0x72, 0x39, 0x78, 0x50, 0xc7, 0x2c,
0x29, 0x8a, 0x78, 0x3e, 0x2f, 0x79, 0xd2, 0x05, 0x4d, 0xfb, 0xad, 0x88,
0x82, 0xb2, 0x26, 0x70, 0x23, 0x6f, 0xb5, 0xbe, 0x48, 0xd4, 0x27, 0xf2,
0xfc, 0xc3, 0x4d, 0xba, 0xbf, 0x5f, 0x7d, 0xab, 0x3a, 0x5f, 0x7d, 0xf8,
0x0f, 0x48, 0x58, 0x54, 0x84, 0x13, 0x78, 0xfc, 0x85, 0x93, 0x7b, 0xa6,
0x23, 0xed, 0xa6, 0x25, 0x0a, 0xed, 0x65, 0x9c, 0x8c, 0x3c, 0x82, 0x92,
0x63, 0xfb, 0x18, 0x19, 0x01, 0xe1, 0x18, 0x65, 0xfa, 0xc0, 0x62, 0xbe,
0x18, 0xef, 0xe8, 0x83, 0x43, 0xd0, 0x93, 0xf5, 0x6e, 0xe8, 0x3f, 0x86,
0x53, 0x65, 0xd1, 0x9c, 0x35, 0x74, 0x61, 0x98, 0x35, 0x96, 0xc0, 0x2c,
0x1d, 0xdd, 0xb5, 0x5e, 0xbc, 0x8a, 0xe9, 0xf0, 0xe6, 0x36, 0x41, 0x0c,
0xc1, 0xb2, 0x16, 0xae, 0xdb, 0x38, 0xc5, 0xce, 0xec, 0x71, 0x1a, 0xc6,
0x1d, 0x6c, 0xbe, 0x88, 0xc7, 0xfa, 0xff, 0xba, 0x7f, 0x02, 0x4f, 0xd2,
0x22, 0x27, 0x0c, 0xe1, 0x74, 0xb0, 0x9a, 0x54, 0x3c, 0xa4, 0xfc, 0x40,
0x64, 0xfa, 0xfe, 0x13, 0x62, 0xe8, 0x55, 0xdf, 0x69, 0x32, 0x95, 0x94,
0xc2, 0x95, 0xb6, 0x51, 0xbb, 0x4e, 0xe7, 0x0b, 0x06, 0x4e, 0xb6, 0x39,
0xb0, 0xee, 0x39, 0xb4, 0x53, 0x4d, 0xff, 0x2f, 0xa3, 0xb5, 0x48, 0x5e,
0x07, 0x50, 0xb6, 0x8a, 0x33, 0x9b, 0x1b, 0xfb, 0x57, 0x10, 0xb6, 0xa2,
0xc8, 0x27, 0x4c, 0xf9, 0x2f, 0xf0, 0x69, 0xeb, 0xaf, 0xd0, 0xc5, 0xed,
0x23, 0x8c, 0x67, 0x9f, 0x50};
const uint8_t kRsaServerKey[] = {
0x30, 0x82, 0x04, 0xbc, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
0x04, 0xa6, 0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
0x01, 0x00, 0xba, 0x0b, 0xda, 0x84, 0x19, 0x12, 0x01, 0x41, 0x75, 0x7c,
0x2e, 0x3d, 0xbd, 0xbd, 0x5b, 0xbe, 0x53, 0xeb, 0x72, 0x5f, 0x34, 0x92,
0x8a, 0x75, 0x88, 0xba, 0x62, 0xb9, 0x8a, 0x33, 0xe1, 0x0a, 0x6d, 0xc3,
0x2e, 0x7b, 0xf8, 0x45, 0xac, 0xb1, 0x90, 0x5c, 0x1e, 0x9a, 0xd9, 0xe4,
0x19, 0x16, 0x7f, 0xa3, 0xde, 0x19, 0x9e, 0xc5, 0xe4, 0x05, 0xf5, 0x3f,
0x22, 0x5b, 0x18, 0x76, 0x4b, 0xaa, 0xf3, 0x02, 0xbd, 0x58, 0x8f, 0xea,
0x97, 0x78, 0x30, 0x5a, 0x31, 0xfe, 0x28, 0x04, 0x48, 0x84, 0x84, 0x1c,
0x48, 0xb1, 0xa2, 0x25, 0xc2, 0xcd, 0xea, 0x41, 0xae, 0x1b, 0x69, 0xe5,
0x44, 0x12, 0x8c, 0x70, 0xf8, 0x0f, 0x88, 0x4a, 0xb6, 0x07, 0x4c, 0x81,
0x5c, 0x57, 0xf8, 0xb4, 0x6d, 0xc2, 0x05, 0xb7, 0x9a, 0x7b, 0xbf, 0xbc,
0x1b, 0xbb, 0xaf, 0x3a, 0x6b, 0xfc, 0x34, 0xbc, 0x8a, 0x8f, 0x7d, 0xa7,
0x79, 0x6a, 0x67, 0x50, 0x24, 0xcb, 0xe6, 0x8d, 0x95, 0xc3, 0x23, 0xe8,
0xc6, 0x32, 0xf1, 0x4f, 0x98, 0x14, 0x47, 0xaf, 0x6f, 0xf5, 0x74, 0x95,
0x16, 0x3d, 0xa2, 0xac, 0x26, 0x5b, 0xb0, 0x47, 0x9d, 0x78, 0xa4, 0x9b,
0xfb, 0xe2, 0xea, 0xc8, 0xc8, 0x4b, 0x7e, 0x74, 0x53, 0xcc, 0xdb, 0xfe,
0x64, 0x73, 0x61, 0xe2, 0x2c, 0xd9, 0x1e, 0xb9, 0x2d, 0x47, 0x6e, 0x4c,
0xbe, 0x74, 0xf9, 0x43, 0x20, 0x6a, 0xdf, 0x68, 0x71, 0xec, 0x08, 0xd9,
0xdb, 0xfc, 0x68, 0xef, 0x43, 0xa6, 0x1f, 0xbc, 0x35, 0xd1, 0xad, 0x83,
0xc2, 0xc5, 0x63, 0x24, 0xd3, 0x1d, 0xc5, 0x31, 0x26, 0x83, 0x2b, 0xd4,
0xf4, 0xce, 0x82, 0x79, 0x84, 0x4f, 0x5f, 0x56, 0x24, 0x7e, 0x0f, 0xac,
0x5c, 0x24, 0xed, 0x91, 0x35, 0x40, 0x94, 0x10, 0xd4, 0xbe, 0x22, 0x2a,
0x63, 0xde, 0x42, 0x2b, 0x2d, 0xb9, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
0x82, 0x01, 0x00, 0x1c, 0xfb, 0xef, 0xc5, 0x18, 0xaa, 0xc7, 0x6b, 0x4d,
0x44, 0x55, 0x67, 0xe5, 0x01, 0x75, 0x23, 0x87, 0xab, 0x6c, 0x9c, 0x0c,
0x72, 0xb0, 0x03, 0x73, 0x93, 0xa6, 0x01, 0xc5, 0xd8, 0x23, 0x3d, 0x1e,
0xb0, 0x83, 0xb3, 0x68, 0x90, 0x62, 0x41, 0x1f, 0x7e, 0x5a, 0x7e, 0x41,
0x67, 0xd9, 0xc8, 0xb9, 0x85, 0xeb, 0xfa, 0x0d, 0xd4, 0x42, 0x9b, 0xf3,
0x03, 0x2c, 0xf5, 0x08, 0x30, 0x95, 0xc5, 0x42, 0x2a, 0xb1, 0x18, 0xf5,
0x02, 0xd5, 0x2a, 0x32, 0x4e, 0x3a, 0xef, 0x9f, 0x88, 0x5b, 0x4b, 0xd9,
0xd1, 0x16, 0x3a, 0x26, 0x4a, 0xbf, 0xb8, 0x98, 0xc0, 0x36, 0xc1, 0xaa,
0x93, 0xbf, 0x31, 0x2c, 0x94, 0x04, 0xf1, 0x56, 0x88, 0x5d, 0x27, 0x71,
0xf1, 0xcd, 0x53, 0x1f, 0x39, 0xec, 0xc7, 0x87, 0x60, 0x7d, 0x3e, 0xbe,
0x36, 0x2e, 0x13, 0xe5, 0x4e, 0xb2, 0xb8, 0x0d, 0xf7, 0x39, 0x96, 0xb0,
0xe0, 0xd7, 0x58, 0x65, 0x8b, 0x44, 0x92, 0xa3, 0x62, 0xa8, 0xae, 0x95,
0x61, 0xee, 0x26, 0x03, 0x1c, 0x55, 0x87, 0x9a, 0xac, 0x72, 0x28, 0x55,
0x54, 0xc1, 0xa4, 0x05, 0x5a, 0x89, 0x36, 0x28, 0x84, 0xa2, 0xd7, 0x2d,
0x9b, 0x59, 0x69, 0x87, 0xca, 0x30, 0xfb, 0xba, 0x3c, 0x82, 0x05, 0xce,
0x5b, 0xdc, 0x66, 0xf9, 0x11, 0xc7, 0x3d, 0xc1, 0xfb, 0x12, 0x9c, 0x7b,
0x86, 0x39, 0x1b, 0xfe, 0x17, 0xa5, 0x00, 0xd7, 0x18, 0x38, 0xaf, 0x79,
0xd1, 0x6e, 0x7f, 0x47, 0xed, 0xb3, 0x59, 0x5f, 0x51, 0xea, 0x4c, 0x68,
0xe9, 0x1f, 0xbf, 0x85, 0xf1, 0x85, 0x16, 0x60, 0xaf, 0x97, 0x89, 0x39,
0xfa, 0x2f, 0x18, 0xd0, 0x89, 0x44, 0xbf, 0x77, 0xf3, 0x7b, 0x51, 0x34,
0x2f, 0x0c, 0x9f, 0xdf, 0xbf, 0x62, 0xdc, 0x2f, 0xdc, 0x29, 0xcb, 0x9a,
0x13, 0x98, 0x30, 0x47, 0x9e, 0x01, 0x01, 0x02, 0x81, 0x81, 0x00, 0xf1,
0x96, 0xc3, 0x72, 0xf4, 0xcd, 0xfb, 0x1e, 0x08, 0x2e, 0x82, 0x51, 0xed,
0xf1, 0x6f, 0x9c, 0xb8, 0xf3, 0x6d, 0xc4, 0xd8, 0xc5, 0x09, 0x62, 0x23,
0x35, 0x1f, 0x5d, 0x4a, 0xf7, 0x6b, 0xd4, 0xe8, 0xb6, 0xf1, 0x9d, 0x40,
0x63, 0xe0, 0x41, 0x3d, 0x2b, 0xfa, 0x50, 0x12, 0xa7, 0x4f, 0x93, 0xe9,
0x38, 0x58, 0xea, 0xc5, 0xf3, 0x18, 0xfe, 0x3f, 0xf3, 0xa0, 0xa7, 0x48,
0x69, 0x85, 0xf5, 0xa6, 0x18, 0x1e, 0x40, 0x75, 0xdc, 0x1e, 0xb0, 0x75,
0xa5, 0x2f, 0x32, 0xa1, 0xa1, 0x7f, 0xa5, 0x32, 0x52, 0x37, 0x66, 0x1b,
0xf2, 0xff, 0x64, 0x97, 0xf0, 0xa1, 0xd7, 0x27, 0x98, 0x5d, 0xa3, 0x55,
0x1a, 0x67, 0x81, 0x2e, 0x41, 0xfd, 0x1f, 0xac, 0x08, 0x71, 0x4c, 0x43,
0x31, 0xab, 0x35, 0x8b, 0xc5, 0x54, 0xce, 0xc8, 0x73, 0x85, 0xc9, 0x6e,
0x08, 0xd1, 0xa8, 0x26, 0x3f, 0x70, 0x51, 0x02, 0x81, 0x81, 0x00, 0xc5,
0x24, 0xea, 0x16, 0x9d, 0xcb, 0x2c, 0x7d, 0x60, 0xab, 0xb2, 0xe0, 0xd6,
0x12, 0x87, 0x94, 0xef, 0x56, 0x61, 0xdf, 0xe6, 0xc3, 0xf7, 0xa1, 0x85,
0xb3, 0x6f, 0x42, 0x74, 0x86, 0xc7, 0xa5, 0xc6, 0xf1, 0x85, 0x66, 0x23,
0x03, 0xd4, 0x4c, 0xf3, 0x2c, 0x5b, 0x18, 0xfa, 0x29, 0x7b, 0x1c, 0xe8,
0x19, 0xc5, 0x75, 0x1d, 0x7e, 0xa3, 0xf0, 0x4d, 0x6c, 0xd3, 0x17, 0xd8,
0x64, 0x95, 0x76, 0xde, 0xbc, 0x68, 0x33, 0xd6, 0x63, 0xf6, 0x5e, 0x43,
0x99, 0x90, 0x09, 0x40, 0xfc, 0x58, 0x5c, 0x87, 0x6e, 0xde, 0x1e, 0x0f,
0xb2, 0x58, 0x59, 0x2d, 0xdd, 0xe9, 0xf8, 0x31, 0x07, 0x8d, 0xbb, 0x0b,
0x0b, 0xf6, 0xaf, 0x93, 0x73, 0x38, 0x89, 0x98, 0xa6, 0xd4, 0x53, 0x0f,
0x04, 0x93, 0x2c, 0xc0, 0xa4, 0x8b, 0xdb, 0x7c, 0xac, 0xa9, 0x7a, 0x18,
0xff, 0x29, 0xe8, 0xaf, 0xe5, 0xb4, 0xe9, 0x02, 0x81, 0x80, 0x76, 0x1e,
0xbb, 0xa3, 0x3a, 0x34, 0x78, 0x02, 0x60, 0x07, 0xb5, 0x6a, 0x2f, 0x87,
0xab, 0x85, 0x9a, 0x1c, 0x53, 0x60, 0x3a, 0x88, 0x64, 0x25, 0x1a, 0x87,
0xbf, 0xb5, 0x12, 0x91, 0x54, 0xa4, 0xbd, 0xbf, 0xac, 0xf4, 0xb0, 0xe5,
0xe4, 0x60, 0xa1, 0x73, 0x1e, 0x29, 0x06, 0x65, 0xcd, 0x8f, 0xc9, 0x28,
0xe6, 0xb8, 0xab, 0x5e, 0x47, 0xab, 0x10, 0x43, 0xa3, 0x1a, 0x07, 0x5a,
0xa8, 0xc7, 0xc9, 0x94, 0xe3, 0x3d, 0xab, 0x22, 0x9b, 0xd2, 0xb5, 0x42,
0xb5, 0x87, 0xf0, 0xe5, 0x10, 0x8f, 0x09, 0xc2, 0x8f, 0x19, 0x9a, 0xb2,
0xbd, 0xd2, 0x46, 0x43, 0xbe, 0x2d, 0x7f, 0x4b, 0x8d, 0x04, 0xed, 0xf8,
0x42, 0x01, 0x34, 0x47, 0xc9, 0x66, 0x31, 0xeb, 0xd2, 0xd1, 0x71, 0xcd,
0x18, 0x23, 0xcf, 0x1a, 0x05, 0x74, 0x31, 0x27, 0xe2, 0x92, 0xf0, 0xfc,
0xd8, 0xdd, 0x79, 0x0d, 0xed, 0x71, 0x02, 0x81, 0x80, 0x6e, 0xc6, 0x4c,
0x46, 0xc3, 0x09, 0x7c, 0x09, 0x43, 0x3d, 0x97, 0x38, 0xa0, 0xf1, 0x2e,
0x7f, 0xf0, 0x70, 0x30, 0x74, 0xd8, 0x3d, 0x3b, 0x32, 0xe6, 0x66, 0xa9,
0xd8, 0xc4, 0x93, 0x4b, 0x31, 0x8a, 0x75, 0x01, 0xc9, 0x1f, 0x59, 0xb2,
0x7c, 0x3e, 0x93, 0xa8, 0xe8, 0x83, 0x00, 0xb5, 0xed, 0xcb, 0x39, 0x57,
0xeb, 0x73, 0xd4, 0x4a, 0x17, 0xe7, 0xd9, 0x83, 0x4f, 0xbd, 0xc6, 0xde,
0xf9, 0x39, 0x34, 0xd2, 0xb4, 0x75, 0xfe, 0x1b, 0x5c, 0x62, 0x4d, 0xb2,
0x52, 0x90, 0xd2, 0x7a, 0x70, 0x1b, 0xa5, 0x9f, 0x67, 0x72, 0xd8, 0x7a,
0xae, 0x39, 0x88, 0x9d, 0x44, 0x59, 0x80, 0x6e, 0x12, 0x30, 0xa5, 0xdb,
0x4a, 0x52, 0xe7, 0x06, 0x58, 0xc2, 0x8e, 0xd3, 0x75, 0x8c, 0x55, 0xbc,
0xc1, 0x03, 0xca, 0x31, 0xcf, 0xf5, 0xe1, 0x2b, 0x25, 0xb1, 0x50, 0x07,
0x63, 0x79, 0x1a, 0xf0, 0xa9, 0x02, 0x81, 0x80, 0x79, 0xf1, 0x03, 0x53,
0xd5, 0x87, 0xc7, 0xde, 0x34, 0xba, 0xdb, 0xe9, 0x93, 0xda, 0x95, 0xea,
0xa8, 0xb8, 0xcb, 0xaa, 0xfb, 0x03, 0xef, 0x8d, 0x95, 0x62, 0x71, 0x68,
0x1d, 0x1f, 0x87, 0x04, 0xe9, 0xcd, 0xf2, 0xbc, 0xb4, 0x75, 0xd6, 0xb8,
0x96, 0x0c, 0x0c, 0xd7, 0x4e, 0x8b, 0xe4, 0x58, 0x12, 0x83, 0xd0, 0xce,
0x66, 0xf0, 0x12, 0x67, 0xe4, 0x06, 0x16, 0x4f, 0x90, 0x55, 0x0b, 0xfe,
0x73, 0xbe, 0xc0, 0x49, 0x6a, 0x6e, 0x86, 0x60, 0x66, 0x6a, 0x66, 0x42,
0xaf, 0x06, 0x57, 0xae, 0xaf, 0x57, 0x73, 0xdd, 0x91, 0x0c, 0xf9, 0x0a,
0x16, 0xa9, 0xcf, 0xf4, 0xc5, 0x6f, 0xd3, 0xa8, 0x58, 0x28, 0xda, 0x74,
0x9a, 0x84, 0x9d, 0x33, 0xc7, 0x48, 0x68, 0xce, 0xae, 0x4a, 0x8c, 0x2c,
0xfe, 0xbf, 0xda, 0x0e, 0xce, 0x28, 0xb9, 0xdb, 0x9b, 0xcf, 0x6e, 0xa8,
0xe4, 0x60, 0xca, 0x98};
void InstallServerCertificate(PRFileDesc* fd, const uint8_t* cert_data,
size_t cert_len, const uint8_t* key_data,
size_t key_len) {
ScopedPK11SlotInfo slot(PK11_GetInternalSlot());
assert(slot);
SECItem certItem = {siBuffer, toUcharPtr(cert_data),
static_cast<unsigned int>(cert_len)};
SECItem pkcs8Item = {siBuffer, toUcharPtr(key_data),
static_cast<unsigned int>(key_len)};
// Import the certificate.
static CERTCertDBHandle* certDB = CERT_GetDefaultCertDB();
ScopedCERTCertificate cert(
CERT_NewTempCertificate(certDB, &certItem, nullptr, false, true));
assert(cert);
// Import the private key.
SECKEYPrivateKey* key = nullptr;
SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey(
slot.get(), &pkcs8Item, nullptr, nullptr, false, false, KU_ALL, &key,
nullptr);
assert(rv == SECSuccess);
// Adopt the private key to ensure it's freed.
ScopedSECKEYPrivateKey privKey(key);
// Configure server with the imported key and certificate.
rv = SSL_ConfigServerCert(fd, cert.get(), privKey.get(), nullptr, 0);
assert(rv == SECSuccess);
}
void InstallServerCertificates(PRFileDesc* fd) {
// ECDSA P-256 certificate.
InstallServerCertificate(fd, kP256ServerCert, sizeof(kP256ServerCert),
kP256ServerKey, sizeof(kP256ServerKey));
// RSA-2048 certificate.
InstallServerCertificate(fd, kRsaServerCert, sizeof(kRsaServerCert),
kRsaServerKey, sizeof(kRsaServerKey));
}

View file

@ -0,0 +1,12 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef tls_server_certs_h__
#define tls_server_certs_h__
#include "prio.h"
void InstallServerCertificates(PRFileDesc* fd);
#endif // tls_server_certs_h__

View file

@ -0,0 +1,46 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "tls_server_config.h"
const uint64_t CONFIG_ENABLE_EXTENDED_MS = 0x01;
const uint64_t CONFIG_REQUEST_CERTIFICATE = 0x02;
const uint64_t CONFIG_REQUIRE_CERTIFICATE = 0x04;
const uint64_t CONFIG_ENABLE_DEFLATE = 0x08;
const uint64_t CONFIG_ENABLE_CBC_RANDOM_IV = 0x10;
const uint64_t CONFIG_REQUIRE_SAFE_NEGOTIATION = 0x20;
const uint64_t CONFIG_ENABLE_CACHE = 0x40;
// XOR 64-bit chunks of data to build a bitmap of config options derived from
// the fuzzing input. This seems the only way to fuzz various options while
// still maintaining compatibility with BoringSSL or OpenSSL fuzzers.
ServerConfig::ServerConfig(const uint8_t* data, size_t len) {
for (size_t i = 0; i < len; i++) {
config_ ^= static_cast<uint64_t>(data[i]) << (8 * (i % 8));
}
}
bool ServerConfig::EnableExtendedMasterSecret() {
return config_ & CONFIG_ENABLE_EXTENDED_MS;
}
bool ServerConfig::RequestCertificate() {
return config_ & CONFIG_REQUEST_CERTIFICATE;
}
bool ServerConfig::RequireCertificate() {
return config_ & CONFIG_REQUIRE_CERTIFICATE;
}
bool ServerConfig::EnableDeflate() { return config_ & CONFIG_ENABLE_DEFLATE; }
bool ServerConfig::EnableCbcRandomIv() {
return config_ & CONFIG_ENABLE_CBC_RANDOM_IV;
}
bool ServerConfig::RequireSafeNegotiation() {
return config_ & CONFIG_REQUIRE_SAFE_NEGOTIATION;
}
bool ServerConfig::EnableCache() { return config_ & CONFIG_ENABLE_CACHE; }

View file

@ -0,0 +1,27 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef tls_server_config_h__
#define tls_server_config_h__
#include <stdint.h>
#include <cstddef>
class ServerConfig {
public:
ServerConfig(const uint8_t* data, size_t len);
bool EnableExtendedMasterSecret();
bool RequestCertificate();
bool RequireCertificate();
bool EnableDeflate();
bool EnableCbcRandomIv();
bool RequireSafeNegotiation();
bool EnableCache();
private:
uint64_t config_;
};
#endif // tls_server_config_h__

View file

@ -0,0 +1,141 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <assert.h>
#include <stdint.h>
#include <memory>
#include "blapi.h"
#include "prinit.h"
#include "ssl.h"
#include "shared.h"
#include "tls_common.h"
#include "tls_mutators.h"
#include "tls_server_certs.h"
#include "tls_server_config.h"
#include "tls_socket.h"
#ifdef IS_DTLS
__attribute__((constructor)) static void set_is_dtls() {
TlsMutators::SetIsDTLS();
}
#endif
PRFileDesc* ImportFD(PRFileDesc* model, PRFileDesc* fd) {
#ifdef IS_DTLS
return DTLS_ImportFD(model, fd);
#else
return SSL_ImportFD(model, fd);
#endif
}
class SSLServerSessionCache {
public:
SSLServerSessionCache() {
assert(SSL_ConfigServerSessionIDCache(1024, 0, 0, ".") == SECSuccess);
}
~SSLServerSessionCache() {
assert(SSL_ShutdownServerSessionIDCache() == SECSuccess);
}
};
static void SetSocketOptions(PRFileDesc* fd,
std::unique_ptr<ServerConfig>& config) {
SECStatus rv = SSL_OptionSet(fd, SSL_NO_CACHE, config->EnableCache());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_REUSE_SERVER_ECDHE_KEY, false);
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_ENABLE_EXTENDED_MASTER_SECRET,
config->EnableExtendedMasterSecret());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_REQUEST_CERTIFICATE, config->RequestCertificate());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_REQUIRE_CERTIFICATE, config->RequireCertificate());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_ENABLE_DEFLATE, config->EnableDeflate());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_CBC_RANDOM_IV, config->EnableCbcRandomIv());
assert(rv == SECSuccess);
rv = SSL_OptionSet(fd, SSL_REQUIRE_SAFE_NEGOTIATION,
config->RequireSafeNegotiation());
assert(rv == SECSuccess);
#ifndef IS_DTLS
rv =
SSL_OptionSet(fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED);
assert(rv == SECSuccess);
#endif
}
static PRStatus InitModelSocket(void* arg) {
PRFileDesc* fd = reinterpret_cast<PRFileDesc*>(arg);
EnableAllProtocolVersions();
EnableAllCipherSuites(fd);
InstallServerCertificates(fd);
return PR_SUCCESS;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t len) {
static std::unique_ptr<NSSDatabase> db(new NSSDatabase());
assert(db != nullptr);
static std::unique_ptr<SSLServerSessionCache> cache(
new SSLServerSessionCache());
assert(cache != nullptr);
std::unique_ptr<ServerConfig> config(new ServerConfig(data, len));
// Clear the cache. We never want to resume as we couldn't reproduce that.
SSL_ClearSessionCache();
// Reset the RNG state.
assert(RNG_RandomUpdate(NULL, 0) == SECSuccess);
// Create model socket.
static ScopedPRFileDesc model(ImportFD(nullptr, PR_NewTCPSocket()));
assert(model);
// Initialize the model socket once.
static PRCallOnceType initModelOnce;
PR_CallOnceWithArg(&initModelOnce, InitModelSocket, model.get());
// Create and import dummy socket.
std::unique_ptr<DummyPrSocket> socket(new DummyPrSocket(data, len));
static PRDescIdentity id = PR_GetUniqueIdentity("fuzz-server");
ScopedPRFileDesc fd(DummyIOLayerMethods::CreateFD(id, socket.get()));
PRFileDesc* ssl_fd = ImportFD(model.get(), fd.get());
assert(ssl_fd == fd.get());
SetSocketOptions(ssl_fd, config);
DoHandshake(ssl_fd, true);
return 0;
}
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data, size_t size,
size_t max_size, unsigned int seed) {
using namespace TlsMutators;
return CustomMutate({DropRecord, ShuffleRecords, DuplicateRecord,
TruncateRecord, FragmentRecord},
data, size, max_size, seed);
}
extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t* data1, size_t size1,
const uint8_t* data2, size_t size2,
uint8_t* out, size_t max_out_size,
unsigned int seed) {
return TlsMutators::CrossOver(data1, size1, data2, size2, out, max_out_size,
seed);
}

View file

@ -0,0 +1,34 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <assert.h>
#include <string.h>
#include <algorithm>
#include "prerror.h"
#include "prio.h"
#include "tls_socket.h"
int32_t DummyPrSocket::Read(PRFileDesc *f, void *data, int32_t len) {
assert(data && len > 0);
int32_t amount = std::min(len, static_cast<int32_t>(len_));
memcpy(data, buf_, amount);
buf_ += amount;
len_ -= amount;
return amount;
}
int32_t DummyPrSocket::Write(PRFileDesc *f, const void *buf, int32_t length) {
return length;
}
int32_t DummyPrSocket::Recv(PRFileDesc *f, void *buf, int32_t buflen,
int32_t flags, PRIntervalTime to) {
assert(flags == 0);
return Read(f, buf, buflen);
}

View file

@ -0,0 +1,24 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef tls_socket_h__
#define tls_socket_h__
#include "dummy_io.h"
class DummyPrSocket : public DummyIOLayerMethods {
public:
DummyPrSocket(const uint8_t *buf, size_t len) : buf_(buf), len_(len) {}
int32_t Read(PRFileDesc *f, void *data, int32_t len) override;
int32_t Write(PRFileDesc *f, const void *buf, int32_t length) override;
int32_t Recv(PRFileDesc *f, void *buf, int32_t buflen, int32_t flags,
PRIntervalTime to) override;
private:
const uint8_t *buf_;
size_t len_;
};
#endif // tls_socket_h__

View file

@ -1,15 +1,16 @@
##############################################
## ##
## WARNING: You're building with -Dfuzz=1 ##
## ##
## This means: ##
## ##
## * Your PRNG is DETERMINISTIC. ##
## * TLS transcripts are PLAINTEXT. ##
## * TLS signature checks are DISABLED. ##
## ##
## Thank you for fuzzing! ##
## ##
##############################################
##################################################
## ##
## WARNING: You're building with -Dfuzz_tls=1 ##
## ##
## This means: ##
## ##
## * Your PRNG is DETERMINISTIC. ##
## * TLS transcripts are PLAINTEXT. ##
## * Session tickets are NOT encrypted. ##
## * TLS signature/MAC checks are DISABLED. ##
## ##
## Thank you for fuzzing! ##
## ##
##################################################