mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
libhsmd: Migrate handle_sign_delayer_payment_to_us
This commit is contained in:
parent
fe82181fe3
commit
1efa792edc
129
hsmd/hsmd.c
129
hsmd/hsmd.c
@ -350,49 +350,6 @@ static void node_key(struct privkey *node_privkey, struct pubkey *node_id)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*~ This secret is the basis for all per-channel secrets: the per-channel seeds
|
||||
* will be generated by mixing in the dbid and the peer node_id. */
|
||||
static void hsm_channel_secret_base(struct secret *channel_seed_base)
|
||||
{
|
||||
hkdf_sha256(channel_seed_base, sizeof(struct secret), NULL, 0,
|
||||
&secretstuff.hsm_secret, sizeof(secretstuff.hsm_secret),
|
||||
/*~ Initially, we didn't support multiple channels per
|
||||
* peer at all: a channel had to be completely forgotten
|
||||
* before another could exist. That was slightly relaxed,
|
||||
* but the phrase "peer seed" is wired into the seed
|
||||
* generation here, so we need to keep it that way for
|
||||
* existing clients, rather than using "channel seed". */
|
||||
"peer seed", strlen("peer seed"));
|
||||
}
|
||||
|
||||
/*~ This gets the seed for this particular channel. */
|
||||
static void get_channel_seed(const struct node_id *peer_id, u64 dbid,
|
||||
struct secret *channel_seed)
|
||||
{
|
||||
struct secret channel_base;
|
||||
u8 input[sizeof(peer_id->k) + sizeof(dbid)];
|
||||
/*~ Again, "per-peer" should be "per-channel", but Hysterical Raisins */
|
||||
const char *info = "per-peer seed";
|
||||
|
||||
/*~ We use the DER encoding of the pubkey, because it's platform
|
||||
* independent. Since the dbid is unique, however, it's completely
|
||||
* unnecessary, but again, existing users can't be broken. */
|
||||
/* FIXME: lnd has a nicer BIP32 method for deriving secrets which we
|
||||
* should migrate to. */
|
||||
hsm_channel_secret_base(&channel_base);
|
||||
memcpy(input, peer_id->k, sizeof(peer_id->k));
|
||||
BUILD_ASSERT(sizeof(peer_id->k) == PUBKEY_CMPR_LEN);
|
||||
/*~ For all that talk about platform-independence, note that this
|
||||
* field is endian-dependent! But let's face it, little-endian won.
|
||||
* In related news, we don't support EBCDIC or middle-endian. */
|
||||
memcpy(input + PUBKEY_CMPR_LEN, &dbid, sizeof(dbid));
|
||||
|
||||
hkdf_sha256(channel_seed, sizeof(*channel_seed),
|
||||
input, sizeof(input),
|
||||
&channel_base, sizeof(channel_base),
|
||||
info, strlen(info));
|
||||
}
|
||||
|
||||
/*~ Called at startup to derive the bip32 field. */
|
||||
static void populate_secretstuff(void)
|
||||
{
|
||||
@ -732,88 +689,6 @@ static struct io_plan *init_hsm(struct io_conn *conn,
|
||||
&bolt12)));
|
||||
}
|
||||
|
||||
/*~ This covers several cases where onchaind is creating a transaction which
|
||||
* sends funds to our internal wallet. */
|
||||
/* FIXME: Derive output address for this client, and check it here! */
|
||||
static struct io_plan *handle_sign_to_us_tx(struct io_conn *conn,
|
||||
struct client *c,
|
||||
const u8 *msg_in,
|
||||
struct bitcoin_tx *tx,
|
||||
const struct privkey *privkey,
|
||||
const u8 *wscript,
|
||||
enum sighash_type sighash_type)
|
||||
{
|
||||
struct bitcoin_signature sig;
|
||||
struct pubkey pubkey;
|
||||
|
||||
if (!pubkey_from_privkey(privkey, &pubkey))
|
||||
return bad_req_fmt(conn, c, msg_in, "bad pubkey_from_privkey");
|
||||
|
||||
if (tx->wtx->num_inputs != 1)
|
||||
return bad_req_fmt(conn, c, msg_in, "bad txinput count");
|
||||
|
||||
sign_tx_input(tx, 0, NULL, wscript, privkey, &pubkey, sighash_type, &sig);
|
||||
|
||||
return req_reply(conn, c, take(towire_hsmd_sign_tx_reply(NULL, &sig)));
|
||||
}
|
||||
|
||||
/*~ When we send a commitment transaction onchain (unilateral close), there's
|
||||
* a delay before we can spend it. onchaind does an explicit transaction to
|
||||
* transfer it to the wallet so that doesn't need to remember how to spend
|
||||
* this complex transaction. */
|
||||
static struct io_plan *handle_sign_delayed_payment_to_us(struct io_conn *conn,
|
||||
struct client *c,
|
||||
const u8 *msg_in)
|
||||
{
|
||||
u64 commit_num;
|
||||
struct secret channel_seed, basepoint_secret;
|
||||
struct pubkey basepoint;
|
||||
struct bitcoin_tx *tx;
|
||||
struct sha256 shaseed;
|
||||
struct pubkey per_commitment_point;
|
||||
struct privkey privkey;
|
||||
u8 *wscript;
|
||||
|
||||
/*~ We don't derive the wscript ourselves, but perhaps we should? */
|
||||
if (!fromwire_hsmd_sign_delayed_payment_to_us(tmpctx, msg_in,
|
||||
&commit_num,
|
||||
&tx, &wscript))
|
||||
return bad_req(conn, c, msg_in);
|
||||
tx->chainparams = c->chainparams;
|
||||
get_channel_seed(&c->id, c->dbid, &channel_seed);
|
||||
|
||||
/*~ ccan/crypto/shachain how we efficiently derive 2^48 ordered
|
||||
* preimages from a single seed; the twist is that as the preimages
|
||||
* are revealed, you can generate the previous ones yourself, needing
|
||||
* to only keep log(N) of them at any time. */
|
||||
if (!derive_shaseed(&channel_seed, &shaseed))
|
||||
return bad_req_fmt(conn, c, msg_in, "bad derive_shaseed");
|
||||
|
||||
/*~ BOLT #3 describes exactly how this is used to generate the Nth
|
||||
* per-commitment point. */
|
||||
if (!per_commit_point(&shaseed, &per_commitment_point, commit_num))
|
||||
return bad_req_fmt(conn, c, msg_in,
|
||||
"bad per_commitment_point %"PRIu64,
|
||||
commit_num);
|
||||
|
||||
/*~ ... which is combined with the basepoint to generate then N'th key.
|
||||
*/
|
||||
if (!derive_delayed_payment_basepoint(&channel_seed,
|
||||
&basepoint,
|
||||
&basepoint_secret))
|
||||
return bad_req_fmt(conn, c, msg_in, "failed deriving basepoint");
|
||||
|
||||
if (!derive_simple_privkey(&basepoint_secret,
|
||||
&basepoint,
|
||||
&per_commitment_point,
|
||||
&privkey))
|
||||
return bad_req_fmt(conn, c, msg_in, "failed deriving privkey");
|
||||
|
||||
return handle_sign_to_us_tx(conn, c, msg_in,
|
||||
tx, &privkey, wscript,
|
||||
SIGHASH_ALL);
|
||||
}
|
||||
|
||||
/*~ Since we process requests then service them in strict order, and because
|
||||
* only lightningd can request a new client fd, we can get away with a global
|
||||
* here! But because we are being tricky, I set it to an invalid value when
|
||||
@ -972,9 +847,6 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
|
||||
case WIRE_HSMD_CLIENT_HSMFD:
|
||||
return pass_client_hsmfd(conn, c, c->msg_in);
|
||||
|
||||
case WIRE_HSMD_SIGN_DELAYED_PAYMENT_TO_US:
|
||||
return handle_sign_delayed_payment_to_us(conn, c, c->msg_in);
|
||||
|
||||
case WIRE_HSMD_SIGN_COMMITMENT_TX:
|
||||
case WIRE_HSMD_SIGN_PENALTY_TO_US:
|
||||
case WIRE_HSMD_SIGN_REMOTE_COMMITMENT_TX:
|
||||
@ -994,6 +866,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
|
||||
case WIRE_HSMD_CUPDATE_SIG_REQ:
|
||||
case WIRE_HSMD_SIGN_LOCAL_HTLC_TX:
|
||||
case WIRE_HSMD_SIGN_REMOTE_HTLC_TO_US:
|
||||
case WIRE_HSMD_SIGN_DELAYED_PAYMENT_TO_US:
|
||||
/* Hand off to libhsmd for processing */
|
||||
return req_reply(conn, c,
|
||||
take(hsmd_handle_client_message(
|
||||
|
@ -1251,6 +1251,62 @@ static u8 *handle_sign_remote_htlc_to_us(struct hsmd_client *c,
|
||||
: SIGHASH_ALL);
|
||||
}
|
||||
|
||||
/*~ When we send a commitment transaction onchain (unilateral close), there's
|
||||
* a delay before we can spend it. onchaind does an explicit transaction to
|
||||
* transfer it to the wallet so that doesn't need to remember how to spend
|
||||
* this complex transaction. */
|
||||
static u8 *handle_sign_delayed_payment_to_us(struct hsmd_client *c,
|
||||
const u8 *msg_in)
|
||||
{
|
||||
u64 commit_num;
|
||||
struct secret channel_seed, basepoint_secret;
|
||||
struct pubkey basepoint;
|
||||
struct bitcoin_tx *tx;
|
||||
struct sha256 shaseed;
|
||||
struct pubkey per_commitment_point;
|
||||
struct privkey privkey;
|
||||
u8 *wscript;
|
||||
|
||||
/*~ We don't derive the wscript ourselves, but perhaps we should? */
|
||||
if (!fromwire_hsmd_sign_delayed_payment_to_us(tmpctx, msg_in,
|
||||
&commit_num,
|
||||
&tx, &wscript))
|
||||
return hsmd_status_malformed_request(c, msg_in);
|
||||
tx->chainparams = c->chainparams;
|
||||
get_channel_seed(&c->id, c->dbid, &channel_seed);
|
||||
|
||||
/*~ ccan/crypto/shachain how we efficiently derive 2^48 ordered
|
||||
* preimages from a single seed; the twist is that as the preimages
|
||||
* are revealed, you can generate the previous ones yourself, needing
|
||||
* to only keep log(N) of them at any time. */
|
||||
if (!derive_shaseed(&channel_seed, &shaseed))
|
||||
return hsmd_status_bad_request(c, msg_in, "bad derive_shaseed");
|
||||
|
||||
/*~ BOLT #3 describes exactly how this is used to generate the Nth
|
||||
* per-commitment point. */
|
||||
if (!per_commit_point(&shaseed, &per_commitment_point, commit_num))
|
||||
return hsmd_status_bad_request_fmt(
|
||||
c, msg_in, "bad per_commitment_point %" PRIu64, commit_num);
|
||||
|
||||
/*~ ... which is combined with the basepoint to generate then N'th key.
|
||||
*/
|
||||
if (!derive_delayed_payment_basepoint(&channel_seed,
|
||||
&basepoint,
|
||||
&basepoint_secret))
|
||||
return hsmd_status_bad_request(c, msg_in,
|
||||
"failed deriving basepoint");
|
||||
|
||||
if (!derive_simple_privkey(&basepoint_secret,
|
||||
&basepoint,
|
||||
&per_commitment_point,
|
||||
&privkey))
|
||||
return hsmd_status_bad_request(c, msg_in,
|
||||
"failed deriving privkey");
|
||||
|
||||
return handle_sign_to_us_tx(c, msg_in, tx, &privkey, wscript,
|
||||
SIGHASH_ALL);
|
||||
}
|
||||
|
||||
u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
|
||||
const u8 *msg)
|
||||
{
|
||||
@ -1277,7 +1333,6 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
|
||||
switch (t) {
|
||||
case WIRE_HSMD_INIT:
|
||||
case WIRE_HSMD_CLIENT_HSMFD:
|
||||
case WIRE_HSMD_SIGN_DELAYED_PAYMENT_TO_US:
|
||||
/* Not implemented yet. Should not have been passed here yet. */
|
||||
return hsmd_status_bad_request_fmt(client, msg, "Not implemented yet.");
|
||||
|
||||
@ -1319,6 +1374,8 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
|
||||
return handle_sign_commitment_tx(client, msg);
|
||||
case WIRE_HSMD_SIGN_REMOTE_HTLC_TO_US:
|
||||
return handle_sign_remote_htlc_to_us(client, msg);
|
||||
case WIRE_HSMD_SIGN_DELAYED_PAYMENT_TO_US:
|
||||
return handle_sign_delayed_payment_to_us(client, msg);
|
||||
|
||||
case WIRE_HSMD_DEV_MEMLEAK:
|
||||
case WIRE_HSMD_ECDH_RESP:
|
||||
|
Loading…
Reference in New Issue
Block a user