mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 13:25:43 +01:00
hsmd: add command to allow lightningd to sign channel announcement.
Before this it was channeld doing it, which was tied to a particular channel. Create an API for lightningd to sign for any channel. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
3e1d34f6ab
commit
ad4a8a510d
@ -21,7 +21,8 @@
|
||||
* v4 with buried outpoint check: f44fae666895cab0347b3de7c245267c71cc7de834827b83e286e86318c08aec
|
||||
* v4 with forget_channel: d87c6934ea188f92785d38d7cd0b13ed7f76aa7417f3200baf0c7b5aa832fe29
|
||||
* v5 with hsmd_revoke_commitment_tx: 5742538f87ef5d5bf55b66dc19e52c8683cfeb1b887d3e64ba530ba9a4d8e638
|
||||
*/
|
||||
* v5 with sign_any_cannouncement: 5fdb9068c43a21887dc03f7dce410d2e3eeff6277f0d49b4fc56595a798fd4a4
|
||||
*/
|
||||
#define HSM_MIN_VERSION 3
|
||||
#define HSM_MAX_VERSION 5
|
||||
#endif /* LIGHTNING_COMMON_HSM_VERSION_H */
|
||||
|
@ -671,6 +671,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
|
||||
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY:
|
||||
case WIRE_HSMD_DERIVE_SECRET:
|
||||
case WIRE_HSMD_CANNOUNCEMENT_SIG_REQ:
|
||||
case WIRE_HSMD_SIGN_ANY_CANNOUNCEMENT_REQ:
|
||||
case WIRE_HSMD_NODE_ANNOUNCEMENT_SIG_REQ:
|
||||
case WIRE_HSMD_CUPDATE_SIG_REQ:
|
||||
case WIRE_HSMD_SIGN_LOCAL_HTLC_TX:
|
||||
@ -722,6 +723,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
|
||||
case WIRE_HSMD_CHECK_PUBKEY_REPLY:
|
||||
case WIRE_HSMD_SIGN_ANCHORSPEND_REPLY:
|
||||
case WIRE_HSMD_SIGN_HTLC_TX_MINGLE_REPLY:
|
||||
case WIRE_HSMD_SIGN_ANY_CANNOUNCEMENT_REPLY:
|
||||
return bad_req_fmt(conn, c, c->msg_in,
|
||||
"Received an incoming message of type %s, "
|
||||
"which is not a request",
|
||||
|
@ -176,6 +176,16 @@ msgtype,hsmd_cannouncement_sig_reply,102
|
||||
msgdata,hsmd_cannouncement_sig_reply,node_signature,secp256k1_ecdsa_signature,
|
||||
msgdata,hsmd_cannouncement_sig_reply,bitcoin_signature,secp256k1_ecdsa_signature,
|
||||
|
||||
msgtype,hsmd_sign_any_cannouncement_req,4
|
||||
msgdata,hsmd_sign_any_cannouncement_req,calen,u16,
|
||||
msgdata,hsmd_sign_any_cannouncement_req,ca,u8,calen
|
||||
msgdata,hsmd_sign_any_cannouncement_req,peerid,node_id,
|
||||
msgdata,hsmd_sign_any_cannouncement_req,channel_dbid,u64,
|
||||
|
||||
msgtype,hsmd_sign_any_cannouncement_reply,104
|
||||
msgdata,hsmd_sign_any_cannouncement_reply,node_signature,secp256k1_ecdsa_signature,
|
||||
msgdata,hsmd_sign_any_cannouncement_reply,bitcoin_signature,secp256k1_ecdsa_signature,
|
||||
|
||||
msgtype,hsmd_cupdate_sig_req,3
|
||||
msgdata,hsmd_cupdate_sig_req,culen,u16,
|
||||
msgdata,hsmd_cupdate_sig_req,cu,u8,culen
|
||||
|
Can't render this file because it has a wrong number of fields in line 184.
|
@ -139,6 +139,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
|
||||
case WIRE_HSMD_SIGN_ANY_LOCAL_HTLC_TX:
|
||||
case WIRE_HSMD_SIGN_ANCHORSPEND:
|
||||
case WIRE_HSMD_SIGN_HTLC_TX_MINGLE:
|
||||
case WIRE_HSMD_SIGN_ANY_CANNOUNCEMENT_REQ:
|
||||
return (client->capabilities & HSM_PERM_MASTER) != 0;
|
||||
|
||||
/*~ These are messages sent by the HSM so we should never receive them. */
|
||||
@ -178,6 +179,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
|
||||
case WIRE_HSMD_CHECK_PUBKEY_REPLY:
|
||||
case WIRE_HSMD_SIGN_ANCHORSPEND_REPLY:
|
||||
case WIRE_HSMD_SIGN_HTLC_TX_MINGLE_REPLY:
|
||||
case WIRE_HSMD_SIGN_ANY_CANNOUNCEMENT_REPLY:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@ -972,7 +974,12 @@ static u8 *handle_get_output_scriptpubkey(struct hsmd_client *c,
|
||||
* defined in BOLT #7, and requires *two* signatures: one from this node's key
|
||||
* (to prove it's from us), and one from the bitcoin key used to create the
|
||||
* funding transaction (to prove we own the output). */
|
||||
static u8 *handle_cannouncement_sig(struct hsmd_client *c, const u8 *msg_in)
|
||||
static const char *handle_sign_cannouncement(const tal_t *ctx,
|
||||
const struct node_id *peer_id,
|
||||
u64 dbid,
|
||||
const u8 *ca,
|
||||
secp256k1_ecdsa_signature *node_sig,
|
||||
secp256k1_ecdsa_signature *bitcoin_sig)
|
||||
{
|
||||
/*~ Our autogeneration code doesn't define field offsets, so we just
|
||||
* copy this from the spec itself.
|
||||
@ -992,10 +999,7 @@ static u8 *handle_cannouncement_sig(struct hsmd_client *c, const u8 *msg_in)
|
||||
/* First type bytes are the msg type */
|
||||
size_t offset = 2 + 256;
|
||||
struct privkey node_pkey;
|
||||
secp256k1_ecdsa_signature node_sig, bitcoin_sig;
|
||||
struct sha256_double hash;
|
||||
u8 *reply;
|
||||
u8 *ca;
|
||||
struct pubkey funding_pubkey;
|
||||
struct privkey funding_privkey;
|
||||
struct secret channel_seed;
|
||||
@ -1009,32 +1013,61 @@ static u8 *handle_cannouncement_sig(struct hsmd_client *c, const u8 *msg_in)
|
||||
* mind if you fix this for him! */
|
||||
|
||||
/* FIXME: We should cache these. */
|
||||
get_channel_seed(&c->id, c->dbid, &channel_seed);
|
||||
get_channel_seed(peer_id, dbid, &channel_seed);
|
||||
derive_funding_key(&channel_seed, &funding_pubkey, &funding_privkey);
|
||||
|
||||
if (tal_count(ca) < offset)
|
||||
return tal_fmt(ctx, "bad cannounce length %zu", tal_count(ca));
|
||||
|
||||
if (fromwire_peektype(ca) != WIRE_CHANNEL_ANNOUNCEMENT)
|
||||
return tal_fmt(ctx, "Invalid channel announcement");
|
||||
|
||||
node_key(&node_pkey, NULL);
|
||||
sha256_double(&hash, ca + offset, tal_count(ca) - offset);
|
||||
|
||||
sign_hash(&node_pkey, &hash, node_sig);
|
||||
sign_hash(&funding_privkey, &hash, bitcoin_sig);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static u8 *handle_cannouncement_sig(struct hsmd_client *c, const u8 *msg_in)
|
||||
{
|
||||
u8 *ca;
|
||||
secp256k1_ecdsa_signature node_sig, bitcoin_sig;
|
||||
const char *err;
|
||||
|
||||
/*~ fromwire_ routines which need to do allocation take a tal context
|
||||
* as their first field; tmpctx is good here since we won't need it
|
||||
* after this function. */
|
||||
if (!fromwire_hsmd_cannouncement_sig_req(tmpctx, msg_in, &ca))
|
||||
return hsmd_status_malformed_request(c, msg_in);
|
||||
|
||||
if (tal_count(ca) < offset)
|
||||
return hsmd_status_bad_request_fmt(
|
||||
c, msg_in, "bad cannounce length %zu", tal_count(ca));
|
||||
err = handle_sign_cannouncement(tmpctx, &c->id, c->dbid, ca,
|
||||
&node_sig, &bitcoin_sig);
|
||||
if (err)
|
||||
return hsmd_status_bad_request_fmt(c, msg_in, "%s", err);
|
||||
|
||||
if (fromwire_peektype(ca) != WIRE_CHANNEL_ANNOUNCEMENT)
|
||||
return hsmd_status_bad_request_fmt(
|
||||
c, msg_in, "Invalid channel announcement");
|
||||
return towire_hsmd_cannouncement_sig_reply(NULL, &node_sig, &bitcoin_sig);
|
||||
}
|
||||
|
||||
node_key(&node_pkey, NULL);
|
||||
sha256_double(&hash, ca + offset, tal_count(ca) - offset);
|
||||
/* This variant is used by modern lightningd to sign for a particular channel */
|
||||
static u8 *handle_any_cannouncement_sig(struct hsmd_client *c, const u8 *msg_in)
|
||||
{
|
||||
u8 *ca;
|
||||
struct node_id peer_id;
|
||||
u64 dbid;
|
||||
secp256k1_ecdsa_signature node_sig, bitcoin_sig;
|
||||
const char *err;
|
||||
|
||||
sign_hash(&node_pkey, &hash, &node_sig);
|
||||
sign_hash(&funding_privkey, &hash, &bitcoin_sig);
|
||||
if (!fromwire_hsmd_sign_any_cannouncement_req(tmpctx, msg_in, &ca, &peer_id, &dbid))
|
||||
return hsmd_status_malformed_request(c, msg_in);
|
||||
|
||||
reply = towire_hsmd_cannouncement_sig_reply(NULL, &node_sig,
|
||||
&bitcoin_sig);
|
||||
return reply;
|
||||
err = handle_sign_cannouncement(tmpctx, &peer_id, dbid, ca,
|
||||
&node_sig, &bitcoin_sig);
|
||||
if (err)
|
||||
return hsmd_status_bad_request_fmt(c, msg_in, "%s", err);
|
||||
|
||||
return towire_hsmd_sign_any_cannouncement_reply(NULL, &node_sig, &bitcoin_sig);
|
||||
}
|
||||
|
||||
/*~ It's optional for nodes to send node_announcement, but it lets us set our
|
||||
@ -2026,6 +2059,8 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
|
||||
return handle_get_channel_basepoints(client, msg);
|
||||
case WIRE_HSMD_CANNOUNCEMENT_SIG_REQ:
|
||||
return handle_cannouncement_sig(client, msg);
|
||||
case WIRE_HSMD_SIGN_ANY_CANNOUNCEMENT_REQ:
|
||||
return handle_any_cannouncement_sig(client, msg);
|
||||
case WIRE_HSMD_NODE_ANNOUNCEMENT_SIG_REQ:
|
||||
return handle_sign_node_announcement(client, msg);
|
||||
case WIRE_HSMD_CUPDATE_SIG_REQ:
|
||||
@ -2110,6 +2145,7 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
|
||||
case WIRE_HSMD_CHECK_PUBKEY_REPLY:
|
||||
case WIRE_HSMD_SIGN_ANCHORSPEND_REPLY:
|
||||
case WIRE_HSMD_SIGN_HTLC_TX_MINGLE_REPLY:
|
||||
case WIRE_HSMD_SIGN_ANY_CANNOUNCEMENT_REPLY:
|
||||
break;
|
||||
}
|
||||
return hsmd_status_bad_request(client, msg, "Unknown request");
|
||||
|
Loading…
Reference in New Issue
Block a user