From 36b7973e334313f2af69ee5ec7be7bf4bdfb8688 Mon Sep 17 00:00:00 2001 From: niftynei Date: Sun, 23 Jul 2023 23:15:21 -0500 Subject: [PATCH] bolt11: Don't push the size of the witness program for v1+ scripts For non-v0 witness programs we weren't stripping the data push byte before writing into the fallback address. According to BIP14, all witness scripts will be data pushes (up to 40-bytes) so trimming the datapush byte should be kosher. From BIP141: A scriptPubKey (or redeemScript as defined in BIP16/P2SH) that consists of a 1-byte push opcode (for 0 to 16) followed by a data push between 2 and 40 bytes gets a new special meaning. The value of the first push is called the "version byte". The following byte vector pushed is called the "witness program". Changelog-Fixed: Adding a >0 version witness program to a fallback address now is *just* the witness program, as per bolt11 spec --- common/bolt11.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/common/bolt11.c b/common/bolt11.c index e608474deb12..825d850d69f1 100644 --- a/common/bolt11.c +++ b/common/bolt11.c @@ -412,6 +412,17 @@ static const char *decode_f(struct bolt11 *b11, "f: witness v0 bad length %zu", tal_count(f)); } + if (version == 1 && tal_count(f) != 32) { + return tal_fmt(b11, + "f: witness v1 bad length %zu", + tal_count(f)); + } + if (tal_count(f) > 40) { + return tal_fmt(b11, + "f: witness v%ld bad length %zu", + version, + tal_count(f)); + } fallback = scriptpubkey_witness_raw(b11, version, f, tal_count(f)); } else { @@ -1129,12 +1140,12 @@ static void encode_f(u5 **data, const u8 *fallback) push_fallback_addr(data, 0, &pkh, sizeof(pkh)); } else if (is_p2wsh(fallback, &wsh)) { push_fallback_addr(data, 0, &wsh, sizeof(wsh)); - } else if (tal_count(fallback) + } else if (tal_count(fallback) > 1 && fallback[0] >= 0x50 && fallback[0] < (0x50+16)) { /* Other (future) witness versions: turn OP_N into N */ - push_fallback_addr(data, fallback[0] - 0x50, fallback + 1, - tal_count(fallback) - 1); + push_fallback_addr(data, fallback[0] - 0x50, fallback + 2, + tal_count(fallback) - 2); } else { /* Copy raw. */ push_field(data, 'f',