mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-09 01:08:39 +09:00
Update NSS to 3.32.1-RTM
This commit is contained in:
parent
f29876f120
commit
c91ef9012b
512 changed files with 83203 additions and 16839 deletions
122
security/nss/fuzz/asn1_mutators.cc
Normal file
122
security/nss/fuzz/asn1_mutators.cc
Normal 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;
|
||||
}
|
||||
16
security/nss/fuzz/asn1_mutators.h
Normal file
16
security/nss/fuzz/asn1_mutators.h
Normal 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__
|
||||
45
security/nss/fuzz/certDN_target.cc
Normal file
45
security/nss/fuzz/certDN_target.cc
Normal 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;
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
d=$(dirname $0)
|
||||
exec $d/git-copy.sh https://github.com/mozilla/nss-fuzzing-corpus master $d/corpus
|
||||
|
|
@ -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
|
||||
4
security/nss/fuzz/config/clone_corpus.sh
Normal file
4
security/nss/fuzz/config/clone_corpus.sh
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
d=$(dirname $0)
|
||||
$d/git-copy.sh https://github.com/mozilla/nss-fuzzing-corpus master $d/../corpus
|
||||
6
security/nss/fuzz/config/clone_libfuzzer.sh
Normal file
6
security/nss/fuzz/config/clone_libfuzzer.sh
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
@ -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',
|
||||
}
|
||||
}
|
||||
|
|
|
|||
42
security/nss/fuzz/mpi_add_target.cc
Normal file
42
security/nss/fuzz/mpi_add_target.cc
Normal 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
|
||||
}
|
||||
27
security/nss/fuzz/mpi_addmod_target.cc
Normal file
27
security/nss/fuzz/mpi_addmod_target.cc
Normal 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
|
||||
}
|
||||
36
security/nss/fuzz/mpi_div_target.cc
Normal file
36
security/nss/fuzz/mpi_div_target.cc
Normal 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
|
||||
}
|
||||
27
security/nss/fuzz/mpi_expmod_target.cc
Normal file
27
security/nss/fuzz/mpi_expmod_target.cc
Normal 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
|
||||
}
|
||||
100
security/nss/fuzz/mpi_helper.cc
Normal file
100
security/nss/fuzz/mpi_helper.cc
Normal 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);
|
||||
}
|
||||
86
security/nss/fuzz/mpi_helper.h
Normal file
86
security/nss/fuzz/mpi_helper.h
Normal 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__
|
||||
69
security/nss/fuzz/mpi_invmod_target.cc
Normal file
69
security/nss/fuzz/mpi_invmod_target.cc
Normal 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
|
||||
}
|
||||
36
security/nss/fuzz/mpi_mod_target.cc
Normal file
36
security/nss/fuzz/mpi_mod_target.cc
Normal 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
|
||||
}
|
||||
27
security/nss/fuzz/mpi_mulmod_target.cc
Normal file
27
security/nss/fuzz/mpi_mulmod_target.cc
Normal 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
|
||||
}
|
||||
40
security/nss/fuzz/mpi_sqr_target.cc
Normal file
40
security/nss/fuzz/mpi_sqr_target.cc
Normal 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
|
||||
}
|
||||
36
security/nss/fuzz/mpi_sqrmod_target.cc
Normal file
36
security/nss/fuzz/mpi_sqrmod_target.cc
Normal 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
|
||||
}
|
||||
42
security/nss/fuzz/mpi_sub_target.cc
Normal file
42
security/nss/fuzz/mpi_sub_target.cc
Normal 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
|
||||
}
|
||||
27
security/nss/fuzz/mpi_submod_target.cc
Normal file
27
security/nss/fuzz/mpi_submod_target.cc
Normal 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
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
3
security/nss/fuzz/options/certDN.options
Normal file
3
security/nss/fuzz/options/certDN.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 4096
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 20000
|
||||
|
||||
3
security/nss/fuzz/options/dtls-client.options
Normal file
3
security/nss/fuzz/options/dtls-client.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 20000
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 20000
|
||||
|
||||
3
security/nss/fuzz/options/dtls-server.options
Normal file
3
security/nss/fuzz/options/dtls-server.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 20000
|
||||
|
||||
3
security/nss/fuzz/options/mpi-add.options
Normal file
3
security/nss/fuzz/options/mpi-add.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 2048
|
||||
|
||||
3
security/nss/fuzz/options/mpi-addmod.options
Normal file
3
security/nss/fuzz/options/mpi-addmod.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 2048
|
||||
|
||||
3
security/nss/fuzz/options/mpi-div.options
Normal file
3
security/nss/fuzz/options/mpi-div.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 2048
|
||||
|
||||
3
security/nss/fuzz/options/mpi-expmod.options
Normal file
3
security/nss/fuzz/options/mpi-expmod.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 1024
|
||||
|
||||
2
security/nss/fuzz/options/mpi-invmod.options
Normal file
2
security/nss/fuzz/options/mpi-invmod.options
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
[libfuzzer]
|
||||
max_len = 256
|
||||
3
security/nss/fuzz/options/mpi-mod.options
Normal file
3
security/nss/fuzz/options/mpi-mod.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 2048
|
||||
|
||||
3
security/nss/fuzz/options/mpi-mulmod.options
Normal file
3
security/nss/fuzz/options/mpi-mulmod.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 2048
|
||||
|
||||
3
security/nss/fuzz/options/mpi-sqr.options
Normal file
3
security/nss/fuzz/options/mpi-sqr.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 2048
|
||||
|
||||
3
security/nss/fuzz/options/mpi-sqrmod.options
Normal file
3
security/nss/fuzz/options/mpi-sqrmod.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 2048
|
||||
|
||||
3
security/nss/fuzz/options/mpi-sub.options
Normal file
3
security/nss/fuzz/options/mpi-sub.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 2048
|
||||
|
||||
3
security/nss/fuzz/options/mpi-submod.options
Normal file
3
security/nss/fuzz/options/mpi-submod.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 2048
|
||||
|
||||
3
security/nss/fuzz/options/quickder.options
Normal file
3
security/nss/fuzz/options/quickder.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 10000
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 20000
|
||||
|
||||
3
security/nss/fuzz/options/tls-client.options
Normal file
3
security/nss/fuzz/options/tls-client.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 20000
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 20000
|
||||
|
||||
3
security/nss/fuzz/options/tls-server.options
Normal file
3
security/nss/fuzz/options/tls-server.options
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[libfuzzer]
|
||||
max_len = 20000
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
85
security/nss/fuzz/quickder_target.cc
Normal file
85
security/nss/fuzz/quickder_target.cc
Normal 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);
|
||||
}
|
||||
|
|
@ -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")
|
||||
|
|
@ -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__
|
||||
18
security/nss/fuzz/shared.cc
Normal file
18
security/nss/fuzz/shared.cc
Normal 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);
|
||||
}
|
||||
|
|
@ -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__
|
||||
|
|
|
|||
51
security/nss/fuzz/tls_client_config.cc
Normal file
51
security/nss/fuzz/tls_client_config.cc
Normal 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; }
|
||||
28
security/nss/fuzz/tls_client_config.h
Normal file
28
security/nss/fuzz/tls_client_config.h
Normal 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__
|
||||
134
security/nss/fuzz/tls_client_target.cc
Normal file
134
security/nss/fuzz/tls_client_target.cc
Normal 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);
|
||||
}
|
||||
48
security/nss/fuzz/tls_common.cc
Normal file
48
security/nss/fuzz/tls_common.cc
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
14
security/nss/fuzz/tls_common.h
Normal file
14
security/nss/fuzz/tls_common.h
Normal 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__
|
||||
289
security/nss/fuzz/tls_mutators.cc
Normal file
289
security/nss/fuzz/tls_mutators.cc
Normal 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
|
||||
29
security/nss/fuzz/tls_mutators.h
Normal file
29
security/nss/fuzz/tls_mutators.h
Normal 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__
|
||||
295
security/nss/fuzz/tls_server_certs.cc
Normal file
295
security/nss/fuzz/tls_server_certs.cc
Normal 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));
|
||||
}
|
||||
12
security/nss/fuzz/tls_server_certs.h
Normal file
12
security/nss/fuzz/tls_server_certs.h
Normal 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__
|
||||
46
security/nss/fuzz/tls_server_config.cc
Normal file
46
security/nss/fuzz/tls_server_config.cc
Normal 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; }
|
||||
27
security/nss/fuzz/tls_server_config.h
Normal file
27
security/nss/fuzz/tls_server_config.h
Normal 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__
|
||||
141
security/nss/fuzz/tls_server_target.cc
Normal file
141
security/nss/fuzz/tls_server_target.cc
Normal 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);
|
||||
}
|
||||
34
security/nss/fuzz/tls_socket.cc
Normal file
34
security/nss/fuzz/tls_socket.cc
Normal 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);
|
||||
}
|
||||
24
security/nss/fuzz/tls_socket.h
Normal file
24
security/nss/fuzz/tls_socket.h
Normal 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__
|
||||
|
|
@ -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! ##
|
||||
## ##
|
||||
##################################################
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue