Skip to content

Commit bed4e79

Browse files
committed
HSMD: add new wire api to sign messages ...
with custom keys. Signed-off-by: Lagrang3 <[email protected]>
1 parent 7e831ad commit bed4e79

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

hsmd/hsmd.c

+2
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
689689
case WIRE_HSMD_GET_CHANNEL_BASEPOINTS:
690690
case WIRE_HSMD_SIGN_INVOICE:
691691
case WIRE_HSMD_SIGN_MESSAGE:
692+
case WIRE_HSMD_SIGN_MESSAGE_WITH_KEY:
692693
case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER:
693694
case WIRE_HSMD_SIGN_BOLT12:
694695
case WIRE_HSMD_SIGN_BOLT12_2:
@@ -745,6 +746,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
745746
case WIRE_HSMD_GET_CHANNEL_BASEPOINTS_REPLY:
746747
case WIRE_HSMD_DEV_MEMLEAK_REPLY:
747748
case WIRE_HSMD_SIGN_MESSAGE_REPLY:
749+
case WIRE_HSMD_SIGN_MESSAGE_WITH_KEY_REPLY:
748750
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY:
749751
case WIRE_HSMD_SIGN_BOLT12_REPLY:
750752
case WIRE_HSMD_SIGN_BOLT12_2_REPLY:

hsmd/hsmd_wire.csv

+9
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,15 @@ msgdata,hsmd_sign_message,msg,u8,len
356356
msgtype,hsmd_sign_message_reply,123
357357
msgdata,hsmd_sign_message_reply,sig,secp256k1_ecdsa_recoverable_signature,
358358

359+
# sign a raw message with a derived key
360+
msgtype,hsmd_sign_message_with_key,45
361+
msgdata,hsmd_sign_message_with_key,len,u16,
362+
msgdata,hsmd_sign_message_with_key,msg,u8,len
363+
msgdata,hsmd_sign_message_with_key,keyidx,u32,
364+
365+
msgtype,hsmd_sign_message_with_key_reply,145
366+
msgdata,hsmd_sign_message_with_key_reply,sig,secp256k1_ecdsa_recoverable_signature,
367+
359368
# lightningd needs to get a scriptPubkey for a utxo with closeinfo
360369
msgtype,hsmd_get_output_scriptpubkey,24
361370
msgdata,hsmd_get_output_scriptpubkey,channel_id,u64,

hsmd/libhsmd.c

+48
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
135135
case WIRE_HSMD_GET_CHANNEL_BASEPOINTS:
136136
case WIRE_HSMD_DEV_MEMLEAK:
137137
case WIRE_HSMD_SIGN_MESSAGE:
138+
case WIRE_HSMD_SIGN_MESSAGE_WITH_KEY:
138139
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY:
139140
case WIRE_HSMD_SIGN_BOLT12:
140141
case WIRE_HSMD_SIGN_BOLT12_2:
@@ -181,6 +182,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
181182
case WIRE_HSMD_GET_CHANNEL_BASEPOINTS_REPLY:
182183
case WIRE_HSMD_DEV_MEMLEAK_REPLY:
183184
case WIRE_HSMD_SIGN_MESSAGE_REPLY:
185+
case WIRE_HSMD_SIGN_MESSAGE_WITH_KEY_REPLY:
184186
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY:
185187
case WIRE_HSMD_SIGN_BOLT12_REPLY:
186188
case WIRE_HSMD_SIGN_BOLT12_2_REPLY:
@@ -701,6 +703,49 @@ static u8 *handle_sign_message(struct hsmd_client *c, const u8 *msg_in)
701703
return towire_hsmd_sign_message_reply(NULL, &rsig);
702704
}
703705

706+
/* Raw message signing with provided key using electrum's standard
707+
* signature = base64(SigRec(SHA256(SHA256(
708+
* "\x18Bitcoin Signed Message:\n" + var_int(len(message)) + message
709+
* )))) */
710+
static u8 *handle_sign_message_with_key(struct hsmd_client *c, const u8 *msg_in)
711+
{
712+
u8 *msg;
713+
u32 keyidx;
714+
struct sha256_ctx sctx = SHA256_INIT;
715+
struct sha256_double shad;
716+
secp256k1_ecdsa_recoverable_signature rsig;
717+
struct privkey privkey;
718+
struct pubkey pubkey;
719+
720+
if (!fromwire_hsmd_sign_message_with_key(tmpctx, msg_in, &msg, &keyidx))
721+
return hsmd_status_malformed_request(c, msg_in);
722+
723+
/* double sha256 the message */
724+
const char header[] = "\x18"
725+
"Bitcoin Signed Message:\n";
726+
sha256_update(&sctx, (const u8 *)header, strlen(header));
727+
728+
u8 vt[VARINT_MAX_LEN];
729+
size_t msg_len = tal_count(msg);
730+
size_t vtlen = varint_put(vt, msg_len);
731+
sha256_update(&sctx, vt, vtlen);
732+
733+
sha256_update(&sctx, msg, msg_len);
734+
sha256_double_done(&sctx, &shad);
735+
736+
/* get the private key BIP32 */
737+
bitcoin_key(&privkey, &pubkey, keyidx);
738+
739+
if (!secp256k1_ecdsa_sign_recoverable(
740+
secp256k1_ctx, &rsig, shad.sha.u.u8, privkey.secret.data, NULL,
741+
NULL)) {
742+
return hsmd_status_bad_request(c, msg_in,
743+
"Failed to sign message");
744+
}
745+
746+
return towire_hsmd_sign_message_with_key_reply(NULL, &rsig);
747+
}
748+
704749
/*~ lightningd asks us to sign a liquidity ad offer */
705750
static u8 *handle_sign_option_will_fund_offer(struct hsmd_client *c,
706751
const u8 *msg_in)
@@ -2167,6 +2212,8 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
21672212
return handle_preapprove_keysend(client, msg);
21682213
case WIRE_HSMD_SIGN_MESSAGE:
21692214
return handle_sign_message(client, msg);
2215+
case WIRE_HSMD_SIGN_MESSAGE_WITH_KEY:
2216+
return handle_sign_message_with_key(client, msg);
21702217
case WIRE_HSMD_GET_CHANNEL_BASEPOINTS:
21712218
return handle_get_channel_basepoints(client, msg);
21722219
case WIRE_HSMD_CANNOUNCEMENT_SIG_REQ:
@@ -2249,6 +2296,7 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
22492296
case WIRE_HSMD_GET_CHANNEL_BASEPOINTS_REPLY:
22502297
case WIRE_HSMD_DEV_MEMLEAK_REPLY:
22512298
case WIRE_HSMD_SIGN_MESSAGE_REPLY:
2299+
case WIRE_HSMD_SIGN_MESSAGE_WITH_KEY_REPLY:
22522300
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY:
22532301
case WIRE_HSMD_SIGN_BOLT12_REPLY:
22542302
case WIRE_HSMD_SIGN_BOLT12_2_REPLY:

0 commit comments

Comments
 (0)