Skip to content

Commit c143244

Browse files
committed
Merge bitcoin/bitcoin#29853: sign: don't assume we are parsing a sane TapMiniscript
4d8d213 sign: don't assume we are parsing a sane Miniscript (Antoine Poinsot) Pull request description: The script provided for signature might be externally provided, for instance by way of 'finalizepsbt'. Therefore the script might be ill-crafted, so don't assume pubkeys are always 32 bytes. Thanks to Niklas for finding this. FIxes bitcoin/bitcoin#29851. ACKs for top commit: achow101: ACK 4d8d213 furszy: ACK 4d8d213 with a small nuance that could be tackled in a follow-up by someone else (or never). Tree-SHA512: 29b7948b56e6dc05eac1014d684f2129ab1d19cb1e5d304216c826b7057c0e1d84ceb18731b91124b680e17d90e38de9f9a5526e4f6ecc3ea816881a6599bb47
2 parents 072b118 + 4d8d213 commit c143244

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

src/script/sign.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ struct TapSatisfier: Satisfier<XOnlyPubKey> {
295295
//! Conversion from a raw xonly public key.
296296
template <typename I>
297297
std::optional<XOnlyPubKey> FromPKBytes(I first, I last) const {
298-
CHECK_NONFATAL(last - first == 32);
298+
if (last - first != 32) return {};
299299
XOnlyPubKey pubkey;
300300
std::copy(first, last, pubkey.begin());
301301
return pubkey;

src/test/script_tests.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,6 +1254,30 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
12541254
BOOST_CHECK(combined.scriptSig == partial3c);
12551255
}
12561256

1257+
/**
1258+
* Reproduction of an exception incorrectly raised when parsing a public key inside a TapMiniscript.
1259+
*/
1260+
BOOST_AUTO_TEST_CASE(sign_invalid_miniscript)
1261+
{
1262+
FillableSigningProvider keystore;
1263+
SignatureData sig_data;
1264+
CMutableTransaction prev, curr;
1265+
1266+
// Create a Taproot output which contains a leaf in which a non-32 bytes push is used where a public key is expected
1267+
// by the Miniscript parser. This offending Script was found by the RPC fuzzer.
1268+
const auto invalid_pubkey{ParseHex("173d36c8c9c9c9ffffffffffff0200000000021e1e37373721361818181818181e1e1e1e19000000000000000000b19292929292926b006c9b9b9292")};
1269+
TaprootBuilder builder;
1270+
builder.Add(0, {invalid_pubkey}, 0xc0);
1271+
XOnlyPubKey nums{ParseHex("50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0")};
1272+
builder.Finalize(nums);
1273+
prev.vout.emplace_back(0, GetScriptForDestination(builder.GetOutput()));
1274+
curr.vin.emplace_back(COutPoint{prev.GetHash(), 0});
1275+
sig_data.tr_spenddata = builder.GetSpendData();
1276+
1277+
// SignSignature can fail but it shouldn't raise an exception (nor crash).
1278+
BOOST_CHECK(!SignSignature(keystore, CTransaction(prev), curr, 0, SIGHASH_ALL, sig_data));
1279+
}
1280+
12571281
BOOST_AUTO_TEST_CASE(script_standard_push)
12581282
{
12591283
ScriptError err;

0 commit comments

Comments
 (0)