Skip to content

Commit 5e47b19

Browse files
tests: Add harness which fuzzes EvalScript and VerifyScript using a fuzzed signature checker
1 parent 39497d1 commit 5e47b19

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

src/Makefile.test.include

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ FUZZ_TARGETS = \
9191
test/fuzz/script_ops \
9292
test/fuzz/scriptnum_ops \
9393
test/fuzz/service_deserialize \
94+
test/fuzz/signature_checker \
9495
test/fuzz/snapshotmetadata_deserialize \
9596
test/fuzz/spanparsing \
9697
test/fuzz/string \
@@ -809,6 +810,12 @@ test_fuzz_service_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)
809810
test_fuzz_service_deserialize_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
810811
test_fuzz_service_deserialize_SOURCES = $(FUZZ_SUITE) test/fuzz/deserialize.cpp
811812

813+
test_fuzz_signature_checker_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
814+
test_fuzz_signature_checker_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
815+
test_fuzz_signature_checker_LDADD = $(FUZZ_SUITE_LD_COMMON)
816+
test_fuzz_signature_checker_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
817+
test_fuzz_signature_checker_SOURCES = $(FUZZ_SUITE) test/fuzz/signature_checker.cpp
818+
812819
test_fuzz_snapshotmetadata_deserialize_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -DSNAPSHOTMETADATA_DESERIALIZE=1
813820
test_fuzz_snapshotmetadata_deserialize_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
814821
test_fuzz_snapshotmetadata_deserialize_LDADD = $(FUZZ_SUITE_LD_COMMON)

src/test/fuzz/signature_checker.cpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright (c) 2009-2019 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <pubkey.h>
6+
#include <script/interpreter.h>
7+
#include <test/fuzz/FuzzedDataProvider.h>
8+
#include <test/fuzz/fuzz.h>
9+
#include <util/memory.h>
10+
11+
#include <cstdint>
12+
#include <limits>
13+
#include <string>
14+
#include <vector>
15+
16+
void initialize()
17+
{
18+
static const auto verify_handle = MakeUnique<ECCVerifyHandle>();
19+
}
20+
21+
namespace {
22+
class FuzzedSignatureChecker : public BaseSignatureChecker
23+
{
24+
FuzzedDataProvider& m_fuzzed_data_provider;
25+
26+
public:
27+
FuzzedSignatureChecker(FuzzedDataProvider& fuzzed_data_provider) : m_fuzzed_data_provider(fuzzed_data_provider)
28+
{
29+
}
30+
31+
virtual bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const
32+
{
33+
return m_fuzzed_data_provider.ConsumeBool();
34+
}
35+
36+
virtual bool CheckLockTime(const CScriptNum& nLockTime) const
37+
{
38+
return m_fuzzed_data_provider.ConsumeBool();
39+
}
40+
41+
virtual bool CheckSequence(const CScriptNum& nSequence) const
42+
{
43+
return m_fuzzed_data_provider.ConsumeBool();
44+
}
45+
46+
virtual ~FuzzedSignatureChecker() {}
47+
};
48+
} // namespace
49+
50+
void test_one_input(const std::vector<uint8_t>& buffer)
51+
{
52+
FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
53+
const unsigned int flags = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
54+
const SigVersion sig_version = fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0});
55+
const std::string script_string_1 = fuzzed_data_provider.ConsumeRandomLengthString(65536);
56+
const std::vector<uint8_t> script_bytes_1{script_string_1.begin(), script_string_1.end()};
57+
const std::string script_string_2 = fuzzed_data_provider.ConsumeRandomLengthString(65536);
58+
const std::vector<uint8_t> script_bytes_2{script_string_2.begin(), script_string_2.end()};
59+
std::vector<std::vector<unsigned char>> stack;
60+
(void)EvalScript(stack, {script_bytes_1.begin(), script_bytes_1.end()}, flags, FuzzedSignatureChecker(fuzzed_data_provider), sig_version, nullptr);
61+
if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0 && ((flags & SCRIPT_VERIFY_P2SH) == 0 || (flags & SCRIPT_VERIFY_WITNESS) == 0)) {
62+
return;
63+
}
64+
if ((flags & SCRIPT_VERIFY_WITNESS) != 0 && (flags & SCRIPT_VERIFY_P2SH) == 0) {
65+
return;
66+
}
67+
(void)VerifyScript({script_bytes_1.begin(), script_bytes_1.end()}, {script_bytes_2.begin(), script_bytes_2.end()}, nullptr, flags, FuzzedSignatureChecker(fuzzed_data_provider), nullptr);
68+
}

0 commit comments

Comments
 (0)