nostrdb: bolt11: update to latest version from CLN

Copy the latest, which has parsing fixes.  We make a new explicit
"bolt11_decode_minimal" which doesn't check sigs, rather than neutering
the bolt11_decode logic.

As a bonus, this now correctly parses "LIGHTNING:BECH32..." format
(upper case, with prefix).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
Rusty Russell
2024-08-18 11:28:48 +09:30
committed by Daniel D’Aquino
parent 02e970eb9b
commit 2f5fd54297
3 changed files with 397 additions and 341 deletions

View File

@@ -28,6 +28,10 @@
#include <inttypes.h> #include <inttypes.h>
#include <assert.h> #include <assert.h>
struct secret {
u8 data[32];
};
#define MSAT_PER_SAT ((u64)1000) #define MSAT_PER_SAT ((u64)1000)
#define SAT_PER_BTC ((u64)100000000) #define SAT_PER_BTC ((u64)100000000)
#define MSAT_PER_BTC (MSAT_PER_SAT * SAT_PER_BTC) #define MSAT_PER_BTC (MSAT_PER_SAT * SAT_PER_BTC)
@@ -55,10 +59,11 @@ static struct multiplier multipliers[] = {
}; };
/* If pad is false, we discard any bits which don't fit in the last byte. /* If pad is false, we discard any bits which don't fit in the last byte.
* Otherwise we add an extra byte */ * Otherwise we add an extra byte. Returns error string or NULL on success. */
static bool pull_bits(struct hash_u5 *hu5, static const char *pull_bits(struct hash_u5 *hu5,
u5 **data, size_t *data_len, void *dst, size_t nbits, const u5 **data, size_t *data_len,
bool pad) void *dst, size_t nbits,
bool pad)
{ {
size_t n5 = nbits / 5; size_t n5 = nbits / 5;
size_t len = 0; size_t len = 0;
@@ -67,53 +72,67 @@ static bool pull_bits(struct hash_u5 *hu5,
n5++; n5++;
if (*data_len < n5) if (*data_len < n5)
return false; return "truncated";
if (!bech32_convert_bits(dst, &len, 8, *data, n5, 5, pad)) if (!bech32_convert_bits(dst, &len, 8, *data, n5, 5, pad))
return false; return "non-zero trailing bits";
if (hu5) if (hu5)
hash_u5(hu5, *data, n5); hash_u5(hu5, *data, n5);
*data += n5; *data += n5;
*data_len -= n5; *data_len -= n5;
return true; return NULL;
} }
/* For pulling fields where we should have checked it will succeed already. */
#ifndef NDEBUG
#define pull_bits_certain(hu5, data, data_len, dst, nbits, pad) \
assert(pull_bits((hu5), (data), (data_len), (dst), (nbits), (pad)))
#else
#define pull_bits_certain pull_bits
#endif
/* Helper for pulling a variable-length big-endian int. */ /* Helper for pulling a variable-length big-endian int. */
static bool pull_uint(struct hash_u5 *hu5, static const char *pull_uint(struct hash_u5 *hu5,
u5 **data, size_t *data_len, const u5 **data, size_t *data_len,
u64 *val, size_t databits) u64 *val, size_t databits)
{ {
be64 be_val; be64 be_val;
const char *err;
/* Too big. */ /* Too big. */
if (databits > sizeof(be_val) * CHAR_BIT) if (databits > sizeof(be_val) * CHAR_BIT)
return false; return "integer too large";
if (!pull_bits(hu5, data, data_len, &be_val, databits, true)) err = pull_bits(hu5, data, data_len, &be_val, databits, true);
return false; if (err)
*val = be64_to_cpu(be_val) >> (sizeof(be_val) * CHAR_BIT - databits); return err;
return true; if (databits == 0)
*val = 0;
else
*val = be64_to_cpu(be_val) >>
(sizeof(be_val) * CHAR_BIT - databits);
return NULL;
} }
static size_t num_u8(size_t num_u5) static void *pull_all(const tal_t *ctx,
struct hash_u5 *hu5,
const u5 **data, size_t *data_len,
bool pad,
const char **err)
{ {
return (num_u5 * 5 + 4) / 8; void *ret;
size_t retlen;
if (pad)
retlen = (*data_len * 5 + 7) / 8;
else
retlen = (*data_len * 5) / 8;
ret = tal_arr(ctx, u8, retlen);
*err = pull_bits(hu5, data, data_len, ret, *data_len * 5, pad);
if (*err)
return tal_free(ret);
return ret;
} }
/* Frees bolt11, returns NULL. */ /* Frees bolt11, returns NULL. */
static struct bolt11 *decode_fail(struct bolt11 *b11, char **fail, static struct bolt11 *decode_fail(struct bolt11 *b11, char **fail,
const char *fmt, ...) const char *fmt, ...)
PRINTF_FMT(3,4); PRINTF_FMT(3,4);
static struct bolt11 *decode_fail(struct bolt11 *b11, char **fail, static struct bolt11 *decode_fail(struct bolt11 *b11, char **fail,
const char *fmt, ...) const char *fmt, ...)
{ {
va_list ap; va_list ap;
@@ -127,20 +146,39 @@ static struct bolt11 *decode_fail(struct bolt11 *b11, char **fail,
* These handle specific fields in the payment request; returning the problem * These handle specific fields in the payment request; returning the problem
* if any, or NULL. * if any, or NULL.
*/ */
static char *unknown_field(struct bolt11 *b11, static const char *unknown_field(struct bolt11 *b11,
struct hash_u5 *hu5, struct hash_u5 *hu5,
u5 **data, size_t *data_len, const u5 **data, size_t *field_len,
u5 type, size_t length) u5 type)
{ {
struct bolt11_field *extra = tal(b11, struct bolt11_field); struct bolt11_field *extra = tal(b11, struct bolt11_field);
u8 u8data[num_u8(length)]; const char *err;
extra->tag = type; extra->tag = type;
extra->data = tal_dup_arr(extra, u5, *data, length, 0); /* FIXME: record u8 data here, not u5! */
extra->data = tal_dup_arr(extra, u5, *data, *field_len, 0);
list_add_tail(&b11->extra_fields, &extra->list); list_add_tail(&b11->extra_fields, &extra->list);
pull_bits_certain(hu5, data, data_len, u8data, length * 5, true); tal_free(pull_all(extra, hu5, data, field_len, true, &err));
return NULL; return err;
}
/* If field isn't expected length (in *bech32*!), call unknown_field.
* Otherwise copy into dst without padding, set have_flag if non-NULL. */
static const char *pull_expected_length(struct bolt11 *b11,
struct hash_u5 *hu5,
const u5 **data, size_t *field_len,
size_t expected_length,
u5 type,
bool *have_flag,
void *dst)
{
if (*field_len != expected_length)
return unknown_field(b11, hu5, data, field_len, type);
if (have_flag)
*have_flag = true;
return pull_bits(hu5, data, field_len, dst, *field_len * 5, false);
} }
/* BOLT #11: /* BOLT #11:
@@ -148,34 +186,27 @@ static char *unknown_field(struct bolt11 *b11,
* `p` (1): `data_length` 52. 256-bit SHA256 payment_hash. Preimage of this * `p` (1): `data_length` 52. 256-bit SHA256 payment_hash. Preimage of this
* provides proof of payment * provides proof of payment
*/ */
static void decode_p(struct bolt11 *b11, static const char *decode_p(struct bolt11 *b11,
struct hash_u5 *hu5, const struct feature_set *our_features,
u5 **data, size_t *data_len, struct hash_u5 *hu5,
size_t data_length, bool *have_p) const u5 **data, size_t *field_len,
bool *have_p)
{ {
/* BOLT #11: /* BOLT #11:
* *
* A payer... SHOULD use the first `p` field that it did NOT * A payer... SHOULD use the first `p` field that it did NOT
* skip as the payment hash. * skip as the payment hash.
*/ */
if (*have_p) { assert(!*have_p);
unknown_field(b11, hu5, data, data_len, 'p', data_length);
return;
}
/* BOLT #11: /* BOLT #11:
* *
* A reader... MUST skip over unknown fields, OR an `f` field * A reader... MUST skip over unknown fields, OR an `f` field
* with unknown `version`, OR `p`, `h`, `s` or `n` fields that do * with unknown `version`, OR `p`, `h`, `s` or `n` fields that do
* NOT have `data_length`s of 52, 52, 52 or 53, respectively. * NOT have `data_length`s of 52, 52, 52 or 53, respectively.
*/ */
if (data_length != 52) { return pull_expected_length(b11, hu5, data, field_len, 52, 'p',
unknown_field(b11, hu5, data, data_len, 'p', data_length); have_p, &b11->payment_hash);
return;
}
pull_bits_certain(hu5, data, data_len, &b11->payment_hash, 256, false);
*have_p = true;
} }
/* Check for valid UTF-8 */ /* Check for valid UTF-8 */
@@ -213,23 +244,24 @@ static char *utf8_str(const tal_t *ctx, const u8 *buf TAKES, size_t buflen)
return ret; return ret;
} }
/* BOLT #11: /* BOLT #11:
* *
* `d` (13): `data_length` variable. Short description of purpose of payment * `d` (13): `data_length` variable. Short description of purpose of payment
* (UTF-8), e.g. '1 cup of coffee' or 'ナンセンス 1杯' * (UTF-8), e.g. '1 cup of coffee' or 'ナンセンス 1杯'
*/ */
static char *decode_d(struct bolt11 *b11, static const char *decode_d(struct bolt11 *b11,
struct hash_u5 *hu5, const struct feature_set *our_features,
u5 **data, size_t *data_len, struct hash_u5 *hu5,
size_t data_length, bool *have_d) const u5 **data, size_t *field_len,
bool *have_d)
{ {
u8 *desc; u8 *desc;
if (*have_d) const char *err;
return unknown_field(b11, hu5, data, data_len, 'd', data_length);
desc = tal_arr(NULL, u8, data_length * 5 / 8); assert(!*have_d);
pull_bits_certain(hu5, data, data_len, desc, data_length*5, false); desc = pull_all(NULL, hu5, data, field_len, false, &err);
if (!desc)
return err;
*have_d = true; *have_d = true;
b11->description = utf8_str(b11, take(desc), tal_bytelen(desc)); b11->description = utf8_str(b11, take(desc), tal_bytelen(desc));
@@ -246,30 +278,28 @@ static char *decode_d(struct bolt11 *b11,
* 639 bytes, but the transport mechanism for the description in that case is * 639 bytes, but the transport mechanism for the description in that case is
* transport specific and not defined here. * transport specific and not defined here.
*/ */
static void decode_h(struct bolt11 *b11, static const char *decode_h(struct bolt11 *b11,
struct hash_u5 *hu5, const struct feature_set *our_features,
u5 **data, size_t *data_len, struct hash_u5 *hu5,
size_t data_length, bool *have_h) const u5 **data, size_t *field_len,
bool *have_h)
{ {
if (*have_h) { const char *err;
unknown_field(b11, hu5, data, data_len, 'h', data_length); struct sha256 hash;
return;
}
assert(!*have_h);
/* BOLT #11: /* BOLT #11:
* *
* A reader... MUST skip over unknown fields, OR an `f` field * A reader... MUST skip over unknown fields, OR an `f` field
* with unknown `version`, OR `p`, `h`, `s` or `n` fields that do * with unknown `version`, OR `p`, `h`, `s` or `n` fields that do
* NOT have `data_length`s of 52, 52, 52 or 53, respectively. */ * NOT have `data_length`s of 52, 52, 52 or 53, respectively. */
if (data_length != 52) { err = pull_expected_length(b11, hu5, data, field_len, 52, 'h',
unknown_field(b11, hu5, data, data_len, 'h', data_length); have_h, &hash);
return;
}
b11->description_hash = tal(b11, struct sha256); /* If that gave us the hash, store it */
pull_bits_certain(hu5, data, data_len, b11->description_hash, 256, if (*have_h)
false); b11->description_hash = tal_dup(b11, struct sha256, &hash);
*have_h = true; return err;
} }
/* BOLT #11: /* BOLT #11:
@@ -278,19 +308,20 @@ static void decode_h(struct bolt11 *b11,
* (big-endian). Default is 3600 (1 hour) if not specified. * (big-endian). Default is 3600 (1 hour) if not specified.
*/ */
#define DEFAULT_X 3600 #define DEFAULT_X 3600
static char *decode_x(struct bolt11 *b11, static const char *decode_x(struct bolt11 *b11,
struct hash_u5 *hu5, const struct feature_set *our_features,
u5 **data, size_t *data_len, struct hash_u5 *hu5,
size_t data_length, bool *have_x) const u5 **data, size_t *field_len,
bool *have_x)
{ {
if (*have_x) const char *err;
return unknown_field(b11, hu5, data, data_len, 'x',
data_length); assert(!*have_x);
/* FIXME: Put upper limit in bolt 11 */ /* FIXME: Put upper limit in bolt 11 */
if (!pull_uint(hu5, data, data_len, &b11->expiry, data_length * 5)) err = pull_uint(hu5, data, field_len, &b11->expiry, *field_len * 5);
return tal_fmt(b11, "x: length %zu chars is excessive", if (err)
*data_len); return tal_fmt(b11, "x: %s", err);
*have_x = true; *have_x = true;
return NULL; return NULL;
@@ -298,24 +329,25 @@ static char *decode_x(struct bolt11 *b11,
/* BOLT #11: /* BOLT #11:
* *
* `c` (24): `data_length` variable. `min_final_cltv_expiry` to use for the * `c` (24): `data_length` variable. `min_final_cltv_expiry_delta` to use for the
* last HTLC in the route. Default is 18 if not specified. * last HTLC in the route. Default is 18 if not specified.
*/ */
static char *decode_c(struct bolt11 *b11, static const char *decode_c(struct bolt11 *b11,
struct hash_u5 *hu5, const struct feature_set *our_features,
u5 **data, size_t *data_len, struct hash_u5 *hu5,
size_t data_length, bool *have_c) const u5 **data, size_t *field_len,
bool *have_c)
{ {
u64 c; u64 c;
if (*have_c) const char *err;
return unknown_field(b11, hu5, data, data_len, 'c',
data_length); assert(!*have_c);
/* FIXME: Put upper limit in bolt 11 */ /* FIXME: Put upper limit in bolt 11 */
if (!pull_uint(hu5, data, data_len, &c, data_length * 5)) err = pull_uint(hu5, data, field_len, &c, *field_len * 5);
return tal_fmt(b11, "c: length %zu chars is excessive", if (err)
*data_len); return tal_fmt(b11, "c: %s", err);
b11->min_final_cltv_expiry = (u32)c; b11->min_final_cltv_expiry = c;
/* Can overflow, since c is 64 bits but value must be < 32 bits */ /* Can overflow, since c is 64 bits but value must be < 32 bits */
if (b11->min_final_cltv_expiry != c) if (b11->min_final_cltv_expiry != c)
return tal_fmt(b11, "c: %"PRIu64" is too large", c); return tal_fmt(b11, "c: %"PRIu64" is too large", c);
@@ -324,33 +356,95 @@ static char *decode_c(struct bolt11 *b11,
return NULL; return NULL;
} }
static char *decode_n(struct bolt11 *b11, static const char *decode_n(struct bolt11 *b11,
struct hash_u5 *hu5, const struct feature_set *our_features,
u5 **data, size_t *data_len, struct hash_u5 *hu5,
size_t data_length, bool *have_n) const u5 **data, size_t *field_len,
bool *have_n)
{ {
if (*have_n) const char *err;
return unknown_field(b11, hu5, data, data_len, 'n',
data_length); assert(!*have_n);
/* BOLT #11:
*
* A reader... MUST skip over unknown fields, OR an `f` field
* with unknown `version`, OR `p`, `h`, `s` or `n` fields that do
* NOT have `data_length`s of 52, 52, 52 or 53, respectively. */
err = pull_expected_length(b11, hu5, data, field_len, 53, 'n', have_n,
&b11->receiver_id.k);
return err;
}
/* BOLT #11:
*
* * `s` (16): `data_length` 52. This 256-bit secret prevents
* forwarding nodes from probing the payment recipient.
*/
static const char *decode_s(struct bolt11 *b11,
const struct feature_set *our_features,
struct hash_u5 *hu5,
const u5 **data, size_t *field_len,
bool *have_s)
{
const char *err;
struct secret secret;
assert(!*have_s);
/* BOLT #11: /* BOLT #11:
* *
* A reader... MUST skip over unknown fields, OR an `f` field * A reader... MUST skip over unknown fields, OR an `f` field
* with unknown `version`, OR `p`, `h`, `s` or `n` fields that do * with unknown `version`, OR `p`, `h`, `s` or `n` fields that do
* NOT have `data_length`s of 52, 52, 52 or 53, respectively. */ * NOT have `data_length`s of 52, 52, 52 or 53, respectively. */
if (data_length != 53) err = pull_expected_length(b11, hu5, data, field_len, 52, 's',
return unknown_field(b11, hu5, data, data_len, 'n', have_s, &secret);
data_length); if (*have_s)
b11->payment_secret = tal_dup(b11, struct secret, &secret);
return err;
}
pull_bits_certain(hu5, data, data_len, &b11->receiver_id.k, static void shift_bitmap_down(u8 *bitmap, size_t bits)
data_length * 5, false); {
/* u8 prev = 0;
if (!node_id_valid(&b11->receiver_id)) assert(bits < CHAR_BIT);
return tal_fmt(b11, "n: invalid pubkey %s",
node_id_to_hexstr(b11, &b11->receiver_id));
*/
*have_n = true; for (size_t i = 0; i < tal_bytelen(bitmap); i++) {
/* Save top bits for next one */
u8 v = bitmap[i];
bitmap[i] = (prev | (v >> bits));
prev = (v << (8 - bits));
}
assert(prev == 0);
}
/* BOLT #11:
*
* `9` (5): `data_length` variable. One or more 5-bit values containing features
* supported or required for receiving this payment.
* See [Feature Bits](#feature-bits).
*/
static const char *decode_9(struct bolt11 *b11,
const struct feature_set *our_features,
struct hash_u5 *hu5,
const u5 **data, size_t *field_len,
bool *have_9)
{
size_t flen = (*field_len * 5 + 7) / 8;
size_t databits = *field_len * 5;
const char *err;
assert(!*have_9);
b11->features = pull_all(b11, hu5, data, field_len, true, &err);
if (!b11->features)
return err;
/* pull_bits pads with zero bits: we need to remove them. */
shift_bitmap_down(b11->features,
flen * 8 - databits);
*have_9 = true;
return NULL; return NULL;
} }
@@ -361,80 +455,162 @@ static char *decode_n(struct bolt11 *b11,
* maximum hop payload size. Long metadata fields reduce the maximum * maximum hop payload size. Long metadata fields reduce the maximum
* route length. * route length.
*/ */
static char *decode_m(struct bolt11 *b11, static const char *decode_m(struct bolt11 *b11,
struct hash_u5 *hu5, const struct feature_set *our_features,
u5 **data, size_t *data_len, struct hash_u5 *hu5,
size_t data_length, const u5 **data, size_t *field_len,
bool *have_m) bool *have_m)
{ {
size_t mlen = (data_length * 5) / 8; const char *err;
if (*have_m) assert(!*have_m);
return unknown_field(b11, hu5, data, data_len, 'm',
data_length);
b11->metadata = tal_arr(b11, u8, mlen); b11->metadata = pull_all(b11, hu5, data, field_len, false, &err);
pull_bits_certain(hu5, data, data_len, b11->metadata, if (!b11->metadata)
data_length * 5, false); return err;
*have_m = true; *have_m = true;
return NULL; return NULL;
} }
struct bolt11 *new_bolt11(const tal_t *ctx) static struct bolt11 *new_bolt11(const tal_t *ctx,
const struct amount_msat *msat TAKES)
{ {
struct bolt11 *b11 = tal(ctx, struct bolt11); struct bolt11 *b11 = tal(ctx, struct bolt11);
list_head_init(&b11->extra_fields); list_head_init(&b11->extra_fields);
b11->description = NULL; b11->description = NULL;
b11->description_hash = NULL; b11->description_hash = NULL;
b11->fallbacks = NULL;
b11->msat = NULL; b11->msat = NULL;
b11->expiry = DEFAULT_X; b11->expiry = DEFAULT_X;
b11->features = tal_arr(b11, u8, 0); b11->features = tal_arr(b11, u8, 0);
/* BOLT #11: /* BOLT #11:
* - if the `c` field (`min_final_cltv_expiry`) is not provided: * - if the `c` field (`min_final_cltv_expiry_delta`) is not provided:
* - MUST use an expiry delta of at least 18 when making the payment * - MUST use an expiry delta of at least 18 when making the payment
*/ */
b11->min_final_cltv_expiry = 18; b11->min_final_cltv_expiry = 18;
//b11->payment_secret = NULL; b11->payment_secret = NULL;
b11->metadata = NULL; b11->metadata = NULL;
//if (msat) if (msat)
//b11->msat = tal_dup(b11, struct amount_msat, msat); b11->msat = tal_dup(b11, struct amount_msat, msat);
return b11; return b11;
} }
/* Define sha256_eq. */ struct decoder {
//STRUCTEQ_DEF(sha256, 0, u); /* What BOLT11 letter this is */
const char letter;
/* If false, then any dups get treated as "unknown" fields */
bool allow_duplicates;
/* Routine to decode: returns NULL if it decodes ok, and
* sets *have_field = true if it is not an unknown form.
* Otherwise returns error string (literal or tal off b11). */
const char *(*decode)(struct bolt11 *b11,
const struct feature_set *our_features,
struct hash_u5 *hu5,
const u5 **data, size_t *field_len,
bool *have_field);
};
/* Extracts signature but does not check it. */ static const struct decoder decoders[] = {
struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str, u5 **sig, char **fail) /* BOLT #11:
*
* A payer... SHOULD use the first `p` field that it did NOT
* skip as the payment hash.
*/
{ 'p', false, decode_p },
{ 'd', false, decode_d },
{ 'h', false, decode_h },
{ 'x', false, decode_x },
{ 'c', false, decode_c },
{ 'n', false, decode_n },
{ 's', false, decode_s },
{ '9', false, decode_9 },
{ 'm', false, decode_m },
};
static const struct decoder *find_decoder(char c)
{ {
char *hrp, *amountstr, *prefix; for (size_t i = 0; i < ARRAY_SIZE(decoders); i++) {
u5 *data; if (decoders[i].letter == c)
size_t data_len; return decoders + i;
struct bolt11 *b11 = new_bolt11(ctx); }
struct hash_u5 hu5; return NULL;
bool have_p = false, have_d = false, have_h = false, have_n = false, }
have_x = false, have_c = false, have_m = false;
static bool bech32_decode_alloc(const tal_t *ctx,
const char **hrp_ret,
const u5 **data_ret,
size_t *data_len,
const char *str)
{
char *hrp = tal_arr(ctx, char, strlen(str) - 6);
u5 *data = tal_arr(ctx, u5, strlen(str) - 8);
if (bech32_decode(hrp, data, data_len, str, (size_t)-1)
!= BECH32_ENCODING_BECH32) {
tal_free(hrp);
tal_free(data);
return false;
}
/* We needed temporaries because these are const */
*hrp_ret = hrp;
*data_ret = data;
return true;
}
static bool has_lightning_prefix(const char *invstring)
{
/* BOLT #11: /* BOLT #11:
* *
* If a URI scheme is desired, the current recommendation is to either * If a URI scheme is desired, the current recommendation is to either
* use 'lightning:' as a prefix before the BOLT-11 encoding * use 'lightning:' as a prefix before the BOLT-11 encoding */
*/ return (strstarts(invstring, "lightning:") ||
if (strstarts(str, "lightning:") || strstarts(str, "LIGHTNING:")) strstarts(invstring, "LIGHTNING:"));
str += strlen("lightning:"); }
static char *str_lowering(const void *ctx, const char *string TAKES)
{
char *ret;
ret = tal_strdup(ctx, string);
for (char *p = ret; *p; p++) *p = tolower(*p);
return ret;
}
static const char *to_canonical_invstr(const tal_t *ctx,
const char *invstring)
{
if (has_lightning_prefix(invstring))
invstring += strlen("lightning:");
return str_lowering(ctx, invstring);
}
/* Extracts signature but does not check it. */
static struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str,
const struct feature_set *our_features,
struct sha256 *hash,
const u5 **sig,
bool *have_n,
char **fail)
{
const char *hrp, *prefix;
char *amountstr;
const u5 *data;
size_t data_len;
struct bolt11 *b11 = new_bolt11(ctx, NULL);
struct hash_u5 hu5;
const char *err;
/* We don't need all of these, but in theory we could have 32 types */
bool have_field[32];
memset(have_field, 0, sizeof(have_field));
if (strlen(str) < 8) if (strlen(str) < 8)
return decode_fail(b11, fail, "Bad bech32 string"); return decode_fail(b11, fail, "Bad bech32 string");
hrp = tal_arr(b11, char, strlen(str) - 6); if (!bech32_decode_alloc(b11, &hrp, &data, &data_len, str))
data = tal_arr(b11, u5, strlen(str) - 8);
if (bech32_decode(hrp, data, &data_len, str, (size_t)-1)
!= BECH32_ENCODING_BECH32)
return decode_fail(b11, fail, "Bad bech32 string"); return decode_fail(b11, fail, "Bad bech32 string");
/* For signature checking at the end. */ /* For signature checking at the end. */
@@ -447,7 +623,7 @@ struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str, u5 **sig,
* `lntb` for Bitcoin testnet, `lntbs` for Bitcoin signet, and `lnbcrt` for Bitcoin regtest) * `lntb` for Bitcoin testnet, `lntbs` for Bitcoin signet, and `lnbcrt` for Bitcoin regtest)
* 1. `amount`: optional number in that currency, followed by an optional * 1. `amount`: optional number in that currency, followed by an optional
* `multiplier` letter. The unit encoded here is the 'social' convention of a payment unit -- in the case of Bitcoin the unit is 'bitcoin' NOT satoshis. * `multiplier` letter. The unit encoded here is the 'social' convention of a payment unit -- in the case of Bitcoin the unit is 'bitcoin' NOT satoshis.
*/ */
prefix = tal_strndup(b11, hrp, strcspn(hrp, "0123456789")); prefix = tal_strndup(b11, hrp, strcspn(hrp, "0123456789"));
/* BOLT #11: /* BOLT #11:
@@ -456,7 +632,7 @@ struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str, u5 **sig,
*/ */
if (!strstarts(prefix, "ln")) if (!strstarts(prefix, "ln"))
return decode_fail(b11, fail, return decode_fail(b11, fail,
"Prefix '%s' does not start with ln", prefix); "Prefix '%s' does not start with ln", prefix);
/* BOLT #11: /* BOLT #11:
* *
@@ -493,17 +669,17 @@ struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str, u5 **sig,
amount = strtoull(amountstr, &end, 10); amount = strtoull(amountstr, &end, 10);
if (amount == ULLONG_MAX && errno == ERANGE) if (amount == ULLONG_MAX && errno == ERANGE)
return decode_fail(b11, fail, return decode_fail(b11, fail,
"Invalid amount '%s'", amountstr); "Invalid amount '%s'", amountstr);
if (!*amountstr || *end) if (!*amountstr || *end)
return decode_fail(b11, fail, return decode_fail(b11, fail,
"Invalid amount postfix '%s'", end); "Invalid amount postfix '%s'", end);
/* BOLT #11: /* BOLT #11:
* *
* if the `multiplier` is present... MUST multiply * if the `multiplier` is present... MUST multiply
* `amount` by the `multiplier` value to derive the * `amount` by the `multiplier` value to derive the
* amount required for payment. * amount required for payment.
*/ */
b11->msat = tal(b11, struct amount_msat); b11->msat = tal(b11, struct amount_msat);
/* BOLT #11: /* BOLT #11:
* *
@@ -513,8 +689,8 @@ struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str, u5 **sig,
*/ */
if (amount * m10 % 10 != 0) if (amount * m10 % 10 != 0)
return decode_fail(b11, fail, return decode_fail(b11, fail,
"Invalid sub-millisatoshi amount" "Invalid sub-millisatoshi amount"
" '%sp'", amountstr); " '%sp'", amountstr);
*b11->msat = amount_msat(amount * m10 / 10); *b11->msat = amount_msat(amount * m10 / 10);
} }
@@ -527,12 +703,16 @@ struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str, u5 **sig,
* 1. zero or more tagged parts * 1. zero or more tagged parts
* 1. `signature`: Bitcoin-style signature of above (520 bits) * 1. `signature`: Bitcoin-style signature of above (520 bits)
*/ */
if (!pull_uint(&hu5, &data, &data_len, &b11->timestamp, 35)) err = pull_uint(&hu5, &data, &data_len, &b11->timestamp, 35);
return decode_fail(b11, fail, "Can't get 35-bit timestamp"); if (err)
return decode_fail(b11, fail,
"Can't get 35-bit timestamp: %s", err);
while (data_len > 520 / 5) { while (data_len > 520 / 5) {
const char *problem = NULL; const char *problem = NULL;
u64 type, data_length; u64 type, field_len64;
size_t field_len;
const struct decoder *decoder;
/* BOLT #11: /* BOLT #11:
* *
@@ -542,153 +722,72 @@ struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str, u5 **sig,
* 1. `data_length` (10 bits, big-endian) * 1. `data_length` (10 bits, big-endian)
* 1. `data` (`data_length` x 5 bits) * 1. `data` (`data_length` x 5 bits)
*/ */
if (!pull_uint(&hu5, &data, &data_len, &type, 5) err = pull_uint(&hu5, &data, &data_len, &type, 5);
|| !pull_uint(&hu5, &data, &data_len, &data_length, 10)) if (err)
return decode_fail(b11, fail, return decode_fail(b11, fail,
"Can't get tag and length"); "Can't get tag: %s", err);
err = pull_uint(&hu5, &data, &data_len, &field_len64, 10);
if (err)
return decode_fail(b11, fail,
"Can't get length: %s", err);
/* Can't exceed total data remaining. */ /* Can't exceed total data remaining. */
if (data_length > data_len) if (field_len64 > data_len)
return decode_fail(b11, fail, "%c: truncated", return decode_fail(b11, fail, "%c: truncated",
bech32_charset[type]); bech32_charset[type]);
switch (bech32_charset[type]) { /* These are different types on 32 bit! But since data_len is
case 'p': * also size_t, above check ensures this will fit. */
decode_p(b11, &hu5, &data, &data_len, data_length, field_len = field_len64;
&have_p); assert(field_len == field_len64);
break;
case 'd': /* Do this now: the decode function fixes up the data ptr */
problem = decode_d(b11, &hu5, &data, &data_len, data_len -= field_len;
data_length, &have_d);
break;
case 'h': decoder = find_decoder(bech32_charset[type]);
decode_h(b11, &hu5, &data, &data_len, data_length, if (!decoder || (have_field[type] && !decoder->allow_duplicates)) {
&have_h); problem = unknown_field(b11, &hu5, &data, &field_len,
break; bech32_charset[type]);
} else {
case 'n': problem = decoder->decode(b11, our_features, &hu5,
problem = decode_n(b11, &hu5, &data, &data, &field_len, &have_field[type]);
&data_len, data_length,
&have_n);
break;
case 'x':
problem = decode_x(b11, &hu5, &data,
&data_len, data_length,
&have_x);
break;
case 'c':
problem = decode_c(b11, &hu5, &data,
&data_len, data_length,
&have_c);
break;
/*
case 'f':
problem = decode_f(b11, &hu5, &data,
&data_len, data_length);
break;
case 'r':
problem = decode_r(b11, &hu5, &data, &data_len,
data_length);
break;
case '9':
problem = decode_9(b11, our_features, &hu5,
&data, &data_len,
data_length);
break;
case 's':
problem = decode_s(b11, &hu5, &data, &data_len,
data_length, &have_s);
break;
*/
case 'm':
problem = decode_m(b11, &hu5, &data, &data_len,
data_length, &have_m);
break;
default:
unknown_field(b11, &hu5, &data, &data_len,
bech32_charset[type], data_length);
} }
if (problem) if (problem)
return decode_fail(b11, fail, "%s", problem); return decode_fail(b11, fail, "%s", problem);
if (field_len)
return decode_fail(b11, fail, "%c: extra %zu bytes",
bech32_charset[type], field_len);
} }
if (!have_p) if (!have_field[bech32_charset_rev['p']])
return decode_fail(b11, fail, "No valid 'p' field found"); return decode_fail(b11, fail, "No valid 'p' field found");
/* BOLT #11:
* A writer:
*...
* - MUST include either exactly one `d` or exactly one `h` field.
*/
/* FIXME: It doesn't actually say the reader must check though! */
if (!have_field[bech32_charset_rev['d']]
&& !have_field[bech32_charset_rev['h']])
return decode_fail(b11, fail,
"must have either 'd' or 'h' field");
hash_u5_done(&hu5, hash);
*sig = tal_dup_arr(ctx, u5, data, data_len, 0); *sig = tal_dup_arr(ctx, u5, data, data_len, 0);
*have_n = have_field[bech32_charset_rev['n']];
return b11; return b11;
} }
/* Decodes and checks signature; returns NULL on error. */ struct bolt11 *bolt11_decode_minimal(const tal_t *ctx, const char *str,
struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str, char **fail) char **fail)
{ {
u5 *sigdata; const u5 *sigdata;
size_t data_len; struct sha256 hash;
u8 sig_and_recid[65]; bool have_n;
//secp256k1_ecdsa_recoverable_signature sig;
struct bolt11 *b11;
b11 = bolt11_decode_nosig(ctx, str, &sigdata, fail); str = to_canonical_invstr(ctx, str);
if (!b11) return bolt11_decode_nosig(ctx, str, NULL, &hash, &sigdata, &have_n,
return NULL; fail);
/* BOLT #11:
*
* A writer...MUST set `signature` to a valid 512-bit
* secp256k1 signature of the SHA2 256-bit hash of the
* human-readable part, represented as UTF-8 bytes,
* concatenated with the data part (excluding the signature)
* with 0 bits appended to pad the data to the next byte
* boundary, with a trailing byte containing the recovery ID
* (0, 1, 2, or 3).
*/
data_len = tal_count(sigdata);
if (!pull_bits(NULL, &sigdata, &data_len, sig_and_recid, 520, false))
return decode_fail(b11, fail, "signature truncated");
assert(data_len == 0);
/*
if (!secp256k1_ecdsa_recoverable_signature_parse_compact
(secp256k1_ctx, &sig, sig_and_recid, sig_and_recid[64]))
return decode_fail(b11, fail, "signature invalid");
secp256k1_ecdsa_recoverable_signature_convert(secp256k1_ctx,
&b11->sig, &sig);
*/
/* BOLT #11:
*
* A reader... MUST check that the `signature` is valid (see
* the `n` tagged field specified below). ... A reader...
* MUST use the `n` field to validate the signature instead of
* performing signature recovery.
*/
/*
if (!have_n) {
struct pubkey k;
if (!secp256k1_ecdsa_recover(secp256k1_ctx,
&k.pubkey,
&sig,
(const u8 *)&hash))
return decode_fail(b11, fail,
"signature recovery failed");
node_id_from_pubkey(&b11->receiver_id, &k);
} else {
struct pubkey k;
if (!pubkey_from_node_id(&k, &b11->receiver_id))
abort();
if (!secp256k1_ecdsa_verify(secp256k1_ctx, &b11->sig,
(const u8 *)&hash,
&k.pubkey))
return decode_fail(b11, fail, "invalid signature");
}
*/
return b11;
} }

View File

@@ -1,5 +1,6 @@
#ifndef LIGHTNING_COMMON_BOLT11_H #ifndef LIGHTNING_COMMON_BOLT11_H
#define LIGHTNING_COMMON_BOLT11_H #define LIGHTNING_COMMON_BOLT11_H
/* Borrowed from CLN's common/bolt11.[ch] implementation as of v24.08rc1 */
#include "ccan/short_types/short_types.h" #include "ccan/short_types/short_types.h"
#include "hash_u5.h" #include "hash_u5.h"
@@ -28,25 +29,7 @@ struct bolt11_field {
u5 *data; u5 *data;
}; };
/* BOLT #11:
* * `pubkey` (264 bits)
* * `short_channel_id` (64 bits)
* * `fee_base_msat` (32 bits, big-endian)
* * `fee_proportional_millionths` (32 bits, big-endian)
* * `cltv_expiry_delta` (16 bits, big-endian)
*/
/*
struct route_info {
struct node_id pubkey;
u16 cltv_expiry_delta;
struct short_channel_id short_channel_id;
u32 fee_base_msat, fee_proportional_millionths;
};
*/
struct bolt11 { struct bolt11 {
const struct chainparams *chain;
u64 timestamp; u64 timestamp;
struct amount_msat *msat; /* NULL if not specified. */ struct amount_msat *msat; /* NULL if not specified. */
@@ -63,17 +46,7 @@ struct bolt11 {
/* How many blocks final hop requires. */ /* How many blocks final hop requires. */
u32 min_final_cltv_expiry; u32 min_final_cltv_expiry;
/* If non-NULL, indicates fallback addresses to pay to. */ struct secret *payment_secret;
const u8 **fallbacks;
/* If non-NULL: array of route arrays */
//struct route_info **routes;
/* signature of sha256 of entire thing. */
//secp256k1_ecdsa_signature sig;
/* payment secret, if any. */
//struct secret *payment_secret;
/* Features bitmap, if any. */ /* Features bitmap, if any. */
u8 *features; u8 *features;
@@ -84,23 +57,7 @@ struct bolt11 {
struct list_head extra_fields; struct list_head extra_fields;
}; };
/* Decodes and checks signature; returns NULL on error; description is /* Does not check signature, nor extract node. */
* (optional) out-of-band description of payment, for `h` field. struct bolt11 *bolt11_decode_minimal(const tal_t *ctx, const char *str, char **fail);
* fset is NULL to accept any features (usually not desirable!).
*
* if @must_be_chain is not NULL, fails unless it's this chain.
*/
struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str, char **fail);
/* Extracts signature but does not check it. */
struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str, u5 **sigdata, char **fail);
/* Initialize an empty bolt11 struct with optional amount */
struct bolt11 *new_bolt11(const tal_t *ctx);
#if DEVELOPER
/* Flag for tests to suppress `min_final_cltv_expiry` field generation, to match test vectors */
extern bool dev_bolt11_no_c_generation;
#endif
#endif /* LIGHTNING_COMMON_BOLT11_H */ #endif /* LIGHTNING_COMMON_BOLT11_H */

View File

@@ -168,7 +168,7 @@ static int push_invoice_str(struct ndb_content_parser *p, struct ndb_str_block *
struct bolt11 *bolt11; struct bolt11 *bolt11;
char *fail; char *fail;
if (!(bolt11 = bolt11_decode(NULL, str->str, &fail))) if (!(bolt11 = bolt11_decode_minimal(NULL, str->str, &fail)))
return 0; return 0;
start = p->buffer.p; start = p->buffer.p;