|
| 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