From f9c6f6413fd776754173fcd8fc101493a7c461ab Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 26 Oct 2017 13:33:19 +1030 Subject: [PATCH] hsmd: invoice signing support. Signed-off-by: Rusty Russell --- hsmd/Makefile | 1 + hsmd/hsm.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ hsmd/hsm_wire.csv | 10 ++++++++++ 3 files changed, 62 insertions(+) diff --git a/hsmd/Makefile b/hsmd/Makefile index bb2c1ff21..5e5809407 100644 --- a/hsmd/Makefile +++ b/hsmd/Makefile @@ -29,6 +29,7 @@ HSMD_COMMON_OBJS := \ common/daemon_conn.o \ common/debug.o \ common/funding_tx.o \ + common/hash_u5.o \ common/io_debug.o \ common/key_derive.o \ common/msg_queue.o \ diff --git a/hsmd/hsm.c b/hsmd/hsm.c index 50e5e51ee..d322931d1 100644 --- a/hsmd/hsm.c +++ b/hsmd/hsm.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -569,6 +570,51 @@ static void sign_withdrawal_tx(struct daemon_conn *master, const u8 *msg) tal_free(tmpctx); } +/** + * sign_invoice - Sign an invoice with our key. + */ +static void sign_invoice(struct daemon_conn *master, const u8 *msg) +{ + const tal_t *tmpctx = tal_tmpctx(master); + u5 *u5bytes; + u8 *hrpu8; + char *hrp; + struct sha256 sha; + secp256k1_ecdsa_recoverable_signature rsig; + struct hash_u5 hu5; + struct privkey node_pkey; + + if (!fromwire_hsmctl_sign_invoice(tmpctx, msg, NULL, &u5bytes, &hrpu8)) { + status_trace("Failed to parse sign_invoice: %s", + tal_hex(trc, msg)); + return; + } + + /* FIXME: Check invoice! */ + + hrp = tal_dup_arr(tmpctx, char, (char *)hrpu8, tal_len(hrpu8), 1); + hrp[tal_len(hrpu8)] = '\0'; + + hash_u5_init(&hu5, hrp); + hash_u5(&hu5, u5bytes, tal_len(u5bytes)); + hash_u5_done(&hu5, &sha); + + node_key(&node_pkey, NULL); + if (!secp256k1_ecdsa_sign_recoverable(secp256k1_ctx, &rsig, + (const u8 *)&sha, + node_pkey.secret.data, + NULL, NULL)) { + /* FIXME: Now master will freeze... */ + status_trace("Failed to sign invoice: %s", + tal_hex(trc, msg)); + return; + } + + daemon_conn_send(master, + take(towire_hsmctl_sign_invoice_reply(tmpctx, &rsig))); + tal_free(tmpctx); +} + static void sign_node_announcement(struct daemon_conn *master, const u8 *msg) { /* 2 bytes msg type + 64 bytes signature */ @@ -626,6 +672,10 @@ static struct io_plan *control_received_req(struct io_conn *conn, sign_withdrawal_tx(master, master->msg_in); return daemon_conn_read_next(conn, master); + case WIRE_HSMCTL_SIGN_INVOICE: + sign_invoice(master, master->msg_in); + return daemon_conn_read_next(conn, master); + case WIRE_HSMCTL_NODE_ANNOUNCEMENT_SIG_REQ: sign_node_announcement(master, master->msg_in); return daemon_conn_read_next(conn, master); @@ -635,6 +685,7 @@ static struct io_plan *control_received_req(struct io_conn *conn, case WIRE_HSMCTL_HSMFD_CHANNELD_REPLY: case WIRE_HSMCTL_SIGN_FUNDING_REPLY: case WIRE_HSMCTL_SIGN_WITHDRAWAL_REPLY: + case WIRE_HSMCTL_SIGN_INVOICE_REPLY: case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST: case WIRE_HSMCTL_NODE_ANNOUNCEMENT_SIG_REPLY: break; diff --git a/hsmd/hsm_wire.csv b/hsmd/hsm_wire.csv index 3e79a3f96..c9b92d13d 100644 --- a/hsmd/hsm_wire.csv +++ b/hsmd/hsm_wire.csv @@ -63,3 +63,13 @@ hsmctl_sign_withdrawal,,inputs,num_inputs*struct utxo hsmctl_sign_withdrawal_reply,107 hsmctl_sign_withdrawal_reply,,num_sigs,u16 hsmctl_sign_withdrawal_reply,,sig,num_sigs*secp256k1_ecdsa_signature + +# Sign an invoice +hsmctl_sign_invoice,8 +hsmctl_sign_invoice,,len,u16 +hsmctl_sign_invoice,,u5bytes,len*u8 +hsmctl_sign_invoice,,hrplen,u16 +hsmctl_sign_invoice,,hrp,hrplen*u8 + +hsmctl_sign_invoice_reply,108 +hsmctl_sign_invoice_reply,,sig,secp256k1_ecdsa_recoverable_signature