From 3a7b3762a122947a04ef8e418f5d4505a1a4a78e Mon Sep 17 00:00:00 2001 From: niftynei Date: Tue, 8 Jun 2021 15:45:23 -0500 Subject: [PATCH] hsmd: method to sign liquidity ad offer When we accept a bid to create a channel lease, we send back a signature committing to our max channel lease amounts. --- hsmd/capabilities.h | 1 + hsmd/hsmd.c | 2 ++ hsmd/hsmd_wire.csv | 9 ++++++++ hsmd/hsmd_wiregen.c | 55 ++++++++++++++++++++++++++++++++++++++++++++- hsmd/hsmd_wiregen.h | 14 +++++++++++- hsmd/libhsmd.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 133 insertions(+), 2 deletions(-) diff --git a/hsmd/capabilities.h b/hsmd/capabilities.h index 3a306e778a2a..a95177901a61 100644 --- a/hsmd/capabilities.h +++ b/hsmd/capabilities.h @@ -7,6 +7,7 @@ #define HSM_CAP_COMMITMENT_POINT 8 #define HSM_CAP_SIGN_REMOTE_TX 16 #define HSM_CAP_SIGN_CLOSING_TX 32 +#define HSM_CAP_SIGN_WILL_FUND_OFFER 64 #define HSM_CAP_MASTER 1024 #endif /* LIGHTNING_HSMD_CAPABILITIES_H */ diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index 28eafd153351..39642fc9c473 100644 --- a/hsmd/hsmd.c +++ b/hsmd/hsmd.c @@ -663,6 +663,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c) case WIRE_HSMD_GET_CHANNEL_BASEPOINTS: case WIRE_HSMD_SIGN_INVOICE: case WIRE_HSMD_SIGN_MESSAGE: + case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER: case WIRE_HSMD_SIGN_BOLT12: case WIRE_HSMD_ECDH_REQ: case WIRE_HSMD_CHECK_FUTURE_SECRET: @@ -689,6 +690,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c) case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST: case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY: case WIRE_HSMD_SIGN_TX_REPLY: + case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY: case WIRE_HSMD_GET_PER_COMMITMENT_POINT_REPLY: case WIRE_HSMD_CHECK_FUTURE_SECRET_REPLY: case WIRE_HSMD_GET_CHANNEL_BASEPOINTS_REPLY: diff --git a/hsmd/hsmd_wire.csv b/hsmd/hsmd_wire.csv index 86be49bb13d9..e6126bf9b84c 100644 --- a/hsmd/hsmd_wire.csv +++ b/hsmd/hsmd_wire.csv @@ -212,3 +212,12 @@ msgdata,hsmd_sign_bolt12,publictweak,u8,publictweaklen msgtype,hsmd_sign_bolt12_reply,125 msgdata,hsmd_sign_bolt12_reply,sig,bip340sig, +# Sign an option_will_fund offer hash +msgtype,hsmd_sign_option_will_fund_offer,26 +msgdata,hsmd_sign_option_will_fund_offer,funding_pubkey,pubkey, +msgdata,hsmd_sign_option_will_fund_offer,blockheight,u32, +msgdata,hsmd_sign_option_will_fund_offer,channel_fee_base_max_msat,u32, +msgdata,hsmd_sign_option_will_fund_offer,channel_fee_proportional_basis_max,u16, + +msgtype,hsmd_sign_option_will_fund_offer_reply,126 +msgdata,hsmd_sign_option_will_fund_offer_reply,rsig,secp256k1_ecdsa_signature, diff --git a/hsmd/hsmd_wiregen.c b/hsmd/hsmd_wiregen.c index 57ef6734a536..587250c956e1 100644 --- a/hsmd/hsmd_wiregen.c +++ b/hsmd/hsmd_wiregen.c @@ -62,6 +62,8 @@ const char *hsmd_wire_name(int e) case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY: return "WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY"; case WIRE_HSMD_SIGN_BOLT12: return "WIRE_HSMD_SIGN_BOLT12"; case WIRE_HSMD_SIGN_BOLT12_REPLY: return "WIRE_HSMD_SIGN_BOLT12_REPLY"; + case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER: return "WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER"; + case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY: return "WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY"; } snprintf(invalidbuf, sizeof(invalidbuf), "INVALID %i", e); @@ -112,6 +114,8 @@ bool hsmd_wire_is_defined(u16 type) case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY:; case WIRE_HSMD_SIGN_BOLT12:; case WIRE_HSMD_SIGN_BOLT12_REPLY:; + case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER:; + case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY:; return true; } return false; @@ -1278,4 +1282,53 @@ bool fromwire_hsmd_sign_bolt12_reply(const void *p, struct bip340sig *sig) fromwire_bip340sig(&cursor, &plen, sig); return cursor != NULL; } -// SHA256STAMP:d802e57862a2ced1580824c7419e6c1075864496478c7ca6c47456df279d88df + +/* WIRE: HSMD_SIGN_OPTION_WILL_FUND_OFFER */ +/* Sign an option_will_fund offer hash */ +u8 *towire_hsmd_sign_option_will_fund_offer(const tal_t *ctx, const struct pubkey *funding_pubkey, u32 blockheight, u32 channel_fee_base_max_msat, u16 channel_fee_proportional_basis_max) +{ + u8 *p = tal_arr(ctx, u8, 0); + + towire_u16(&p, WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER); + towire_pubkey(&p, funding_pubkey); + towire_u32(&p, blockheight); + towire_u32(&p, channel_fee_base_max_msat); + towire_u16(&p, channel_fee_proportional_basis_max); + + return memcheck(p, tal_count(p)); +} +bool fromwire_hsmd_sign_option_will_fund_offer(const void *p, struct pubkey *funding_pubkey, u32 *blockheight, u32 *channel_fee_base_max_msat, u16 *channel_fee_proportional_basis_max) +{ + const u8 *cursor = p; + size_t plen = tal_count(p); + + if (fromwire_u16(&cursor, &plen) != WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER) + return false; + fromwire_pubkey(&cursor, &plen, funding_pubkey); + *blockheight = fromwire_u32(&cursor, &plen); + *channel_fee_base_max_msat = fromwire_u32(&cursor, &plen); + *channel_fee_proportional_basis_max = fromwire_u16(&cursor, &plen); + return cursor != NULL; +} + +/* WIRE: HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY */ +u8 *towire_hsmd_sign_option_will_fund_offer_reply(const tal_t *ctx, const secp256k1_ecdsa_signature *rsig) +{ + u8 *p = tal_arr(ctx, u8, 0); + + towire_u16(&p, WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY); + towire_secp256k1_ecdsa_signature(&p, rsig); + + return memcheck(p, tal_count(p)); +} +bool fromwire_hsmd_sign_option_will_fund_offer_reply(const void *p, secp256k1_ecdsa_signature *rsig) +{ + const u8 *cursor = p; + size_t plen = tal_count(p); + + if (fromwire_u16(&cursor, &plen) != WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY) + return false; + fromwire_secp256k1_ecdsa_signature(&cursor, &plen, rsig); + return cursor != NULL; +} +// SHA256STAMP:c1ec339d1925da25ee587ffb4fb5e35d0b3c578e525f519384c8fecc1054dc2a diff --git a/hsmd/hsmd_wiregen.h b/hsmd/hsmd_wiregen.h index 1e64236ced5a..7fbabc6a61a5 100644 --- a/hsmd/hsmd_wiregen.h +++ b/hsmd/hsmd_wiregen.h @@ -79,6 +79,9 @@ enum hsmd_wire { /* Sign a bolt12-style merkle hash */ WIRE_HSMD_SIGN_BOLT12 = 25, WIRE_HSMD_SIGN_BOLT12_REPLY = 125, + /* Sign an option_will_fund offer hash */ + WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER = 26, + WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY = 126, }; const char *hsmd_wire_name(int e); @@ -281,6 +284,15 @@ bool fromwire_hsmd_sign_bolt12(const tal_t *ctx, const void *p, wirestring **mes u8 *towire_hsmd_sign_bolt12_reply(const tal_t *ctx, const struct bip340sig *sig); bool fromwire_hsmd_sign_bolt12_reply(const void *p, struct bip340sig *sig); +/* WIRE: HSMD_SIGN_OPTION_WILL_FUND_OFFER */ +/* Sign an option_will_fund offer hash */ +u8 *towire_hsmd_sign_option_will_fund_offer(const tal_t *ctx, const struct pubkey *funding_pubkey, u32 blockheight, u32 channel_fee_base_max_msat, u16 channel_fee_proportional_basis_max); +bool fromwire_hsmd_sign_option_will_fund_offer(const void *p, struct pubkey *funding_pubkey, u32 *blockheight, u32 *channel_fee_base_max_msat, u16 *channel_fee_proportional_basis_max); + +/* WIRE: HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY */ +u8 *towire_hsmd_sign_option_will_fund_offer_reply(const tal_t *ctx, const secp256k1_ecdsa_signature *rsig); +bool fromwire_hsmd_sign_option_will_fund_offer_reply(const void *p, secp256k1_ecdsa_signature *rsig); + #endif /* LIGHTNING_HSMD_HSMD_WIREGEN_H */ -// SHA256STAMP:d802e57862a2ced1580824c7419e6c1075864496478c7ca6c47456df279d88df +// SHA256STAMP:c1ec339d1925da25ee587ffb4fb5e35d0b3c578e525f519384c8fecc1054dc2a diff --git a/hsmd/libhsmd.c b/hsmd/libhsmd.c index cef38c5b3527..0f2cacdcfb04 100644 --- a/hsmd/libhsmd.c +++ b/hsmd/libhsmd.c @@ -93,6 +93,9 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client, case WIRE_HSMD_SIGN_MUTUAL_CLOSE_TX: return (client->capabilities & HSM_CAP_SIGN_CLOSING_TX) != 0; + case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER: + return (client->capabilities & HSM_CAP_SIGN_WILL_FUND_OFFER) != 0; + case WIRE_HSMD_INIT: case WIRE_HSMD_CLIENT_HSMFD: case WIRE_HSMD_SIGN_WITHDRAWAL: @@ -119,6 +122,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client, case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST: case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY: case WIRE_HSMD_SIGN_TX_REPLY: + case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY: case WIRE_HSMD_GET_PER_COMMITMENT_POINT_REPLY: case WIRE_HSMD_CHECK_FUTURE_SECRET_REPLY: case WIRE_HSMD_GET_CHANNEL_BASEPOINTS_REPLY: @@ -468,6 +472,53 @@ static u8 *handle_sign_message(struct hsmd_client *c, const u8 *msg_in) return towire_hsmd_sign_message_reply(NULL, &rsig); } +/*~ lightningd asks us to sign a liquidity ad offer */ +static u8 *handle_sign_option_will_fund_offer(struct hsmd_client *c, + const u8 *msg_in) +{ + struct pubkey funding_pubkey; + u32 blockheight, channel_fee_base_max_msat; + u16 channel_fee_proportional_basis_max; + struct sha256_ctx sctx = SHA256_INIT; + struct sha256 sha; + secp256k1_ecdsa_signature sig; + struct privkey node_pkey; + + if (!fromwire_hsmd_sign_option_will_fund_offer(msg_in, + &funding_pubkey, + &blockheight, + &channel_fee_base_max_msat, + &channel_fee_proportional_basis_max)) + return hsmd_status_malformed_request(c, msg_in); + + /* BOLT- #2: + * - MUST set `signature` to the ECDSA signature of + * SHA256("option_will_fund" || `funding_pubkey`|| `blockheight` || + * `channel_fee_base_max_msat` || + * `channel_fee_proportional_basis_max`) + */ + sha256_update(&sctx, "option_will_fund", + strlen("option_will_fund")); + sha256_update(&sctx, &funding_pubkey, sizeof(funding_pubkey)); + sha256_update(&sctx, &blockheight, sizeof(blockheight)); + sha256_update(&sctx, &channel_fee_base_max_msat, + sizeof(channel_fee_base_max_msat)); + sha256_update(&sctx, &channel_fee_base_max_msat, + sizeof(channel_fee_base_max_msat)); + sha256_done(&sctx, &sha); + + node_key(&node_pkey, NULL); + + if (!secp256k1_ecdsa_sign(secp256k1_ctx, &sig, + sha.u.u8, + node_pkey.secret.data, + NULL, NULL)) + return hsmd_status_bad_request(c, msg_in, + "Failed to sign message"); + + return towire_hsmd_sign_option_will_fund_offer_reply(NULL, &sig); +} + /*~ lightningd asks us to sign a bolt12 (e.g. offer). */ static u8 *handle_sign_bolt12(struct hsmd_client *c, const u8 *msg_in) { @@ -1352,6 +1403,8 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client, return handle_ecdh(client, msg); case WIRE_HSMD_SIGN_INVOICE: return handle_sign_invoice(client, msg); + case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER: + return handle_sign_option_will_fund_offer(client, msg); case WIRE_HSMD_SIGN_BOLT12: return handle_sign_bolt12(client, msg); case WIRE_HSMD_SIGN_MESSAGE: @@ -1397,6 +1450,7 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client, case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST: case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY: case WIRE_HSMD_SIGN_TX_REPLY: + case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER_REPLY: case WIRE_HSMD_GET_PER_COMMITMENT_POINT_REPLY: case WIRE_HSMD_CHECK_FUTURE_SECRET_REPLY: case WIRE_HSMD_GET_CHANNEL_BASEPOINTS_REPLY: