From 32d66b2740deed55d8bc459da81b6dacac986b39 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 14 Dec 2020 11:51:19 +1030 Subject: [PATCH] bolt11: expose routine to parse bolt11 string except signature. This means we can hand around unsigned bolt11s. Signed-off-by: Rusty Russell --- common/bolt11.c | 52 ++++++++++++++++++++++++++++++++++++------------- common/bolt11.h | 10 ++++++++++ 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/common/bolt11.c b/common/bolt11.c index a87a41383..f91801607 100644 --- a/common/bolt11.c +++ b/common/bolt11.c @@ -550,24 +550,25 @@ struct bolt11 *new_bolt11(const tal_t *ctx, return b11; } -/* Decodes and checks signature; returns NULL on error. */ -struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str, - const struct feature_set *our_features, - const char *description, - const struct chainparams *must_be_chain, - char **fail) +/* Extracts signature but does not check it. */ +struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str, + const struct feature_set *our_features, + const char *description, + const struct chainparams *must_be_chain, + struct sha256 *hash, + u5 **sig, + bool *have_n, + char **fail) { char *hrp, *amountstr, *prefix; u5 *data; size_t data_len; struct bolt11 *b11 = new_bolt11(ctx, NULL); - u8 sig_and_recid[65]; - secp256k1_ecdsa_recoverable_signature sig; struct hash_u5 hu5; - struct sha256 hash; - bool have_p = false, have_n = false, have_d = false, have_h = false, + bool have_p = false, have_d = false, have_h = false, have_x = false, have_c = false, have_s = false; + *have_n = false; b11->routes = tal_arr(b11, struct route_info *, 0); /* BOLT #11: @@ -737,7 +738,7 @@ struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str, case 'n': problem = decode_n(b11, &hu5, &data, &data_len, data_length, - &have_n); + have_n); break; case 'x': @@ -795,7 +796,31 @@ struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str, "h: does not match description"); } - hash_u5_done(&hu5, &hash); + hash_u5_done(&hu5, hash); + *sig = tal_dup_arr(ctx, u5, data, data_len, 0); + return b11; +} + +/* Decodes and checks signature; returns NULL on error. */ +struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str, + const struct feature_set *our_features, + const char *description, + const struct chainparams *must_be_chain, + char **fail) +{ + u5 *sigdata; + size_t data_len; + u8 sig_and_recid[65]; + secp256k1_ecdsa_recoverable_signature sig; + struct bolt11 *b11; + struct sha256 hash; + bool have_n; + + b11 = bolt11_decode_nosig(ctx, str, our_features, description, + must_be_chain, &hash, &sigdata, &have_n, + fail); + if (!b11) + return NULL; /* BOLT #11: * @@ -807,7 +832,8 @@ struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str, * boundary, with a trailing byte containing the recovery ID * (0, 1, 2, or 3). */ - if (!pull_bits(NULL, &data, &data_len, sig_and_recid, 520, false)) + 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); diff --git a/common/bolt11.h b/common/bolt11.h index 77b066462..9a89fb3ba 100644 --- a/common/bolt11.h +++ b/common/bolt11.h @@ -94,6 +94,16 @@ struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str, const struct chainparams *must_be_chain, char **fail); +/* Extracts signature but does not check it. */ +struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str, + const struct feature_set *our_features, + const char *description, + const struct chainparams *must_be_chain, + struct sha256 *hash, + u5 **sig, + bool *have_n, + char **fail); + /* Initialize an empty bolt11 struct with optional amount */ struct bolt11 *new_bolt11(const tal_t *ctx, const struct amount_msat *msat TAKES);