mirror of
https://github.com/aljazceru/lightning.git
synced 2026-02-23 15:04:19 +01:00
hsmd: Create derive_secret and makesecret RPC for deriving pseudorandom keys from HSM
This commit is contained in:
@@ -660,6 +660,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
|
||||
case WIRE_HSMD_ECDH_REQ:
|
||||
case WIRE_HSMD_CHECK_FUTURE_SECRET:
|
||||
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY:
|
||||
case WIRE_HSMD_DERIVE_SECRET:
|
||||
case WIRE_HSMD_CANNOUNCEMENT_SIG_REQ:
|
||||
case WIRE_HSMD_NODE_ANNOUNCEMENT_SIG_REQ:
|
||||
case WIRE_HSMD_CUPDATE_SIG_REQ:
|
||||
@@ -681,6 +682,7 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
|
||||
case WIRE_HSMD_SIGN_WITHDRAWAL_REPLY:
|
||||
case WIRE_HSMD_SIGN_INVOICE_REPLY:
|
||||
case WIRE_HSMD_INIT_REPLY:
|
||||
case WIRE_HSMD_DERIVE_SECRET_REPLY:
|
||||
case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST:
|
||||
case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY:
|
||||
case WIRE_HSMD_VALIDATE_COMMITMENT_TX_REPLY:
|
||||
|
||||
@@ -281,3 +281,11 @@ 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,
|
||||
|
||||
# Reply with the derived secret
|
||||
msgtype,hsmd_derive_secret_reply,27
|
||||
msgdata,hsmd_derive_secret_reply,secret,secret,
|
||||
|
||||
msgtype,hsmd_derive_secret,127
|
||||
msgdata,hsmd_derive_secret,len,u16,
|
||||
msgdata,hsmd_derive_secret,info,u8,len
|
||||
|
||||
|
@@ -23,11 +23,13 @@ struct secret *dev_force_bip32_seed;
|
||||
#endif
|
||||
|
||||
/*~ Nobody will ever find it here! hsm_secret is our root secret, the bip32
|
||||
* tree and bolt12 payer_id keys are derived from that, and cached here. */
|
||||
* tree, bolt12 payer_id keys and derived_secret are derived from that, and
|
||||
* cached here. */
|
||||
struct {
|
||||
struct secret hsm_secret;
|
||||
struct ext_key bip32;
|
||||
secp256k1_keypair bolt12;
|
||||
struct secret derived_secret;
|
||||
} secretstuff;
|
||||
|
||||
/* Have we initialized the secretstuff? */
|
||||
@@ -117,6 +119,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
|
||||
case WIRE_HSMD_SIGN_MESSAGE:
|
||||
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY:
|
||||
case WIRE_HSMD_SIGN_BOLT12:
|
||||
case WIRE_HSMD_DERIVE_SECRET:
|
||||
return (client->capabilities & HSM_CAP_MASTER) != 0;
|
||||
|
||||
/*~ These are messages sent by the HSM so we should never receive them. */
|
||||
@@ -145,6 +148,7 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
|
||||
case WIRE_HSMD_SIGN_MESSAGE_REPLY:
|
||||
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY_REPLY:
|
||||
case WIRE_HSMD_SIGN_BOLT12_REPLY:
|
||||
case WIRE_HSMD_DERIVE_SECRET_REPLY:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@@ -257,6 +261,22 @@ static void hsm_channel_secret_base(struct secret *channel_seed_base)
|
||||
"peer seed", strlen("peer seed"));
|
||||
}
|
||||
|
||||
/* This will derive pseudorandom secret Key from a derived key */
|
||||
static u8 *handle_derive_secret(struct hsmd_client *c, const u8 *msg_in)
|
||||
{
|
||||
u8 *info;
|
||||
struct secret secret;
|
||||
|
||||
if (!fromwire_hsmd_derive_secret(tmpctx, msg_in, &info))
|
||||
return hsmd_status_malformed_request(c, msg_in);
|
||||
|
||||
hkdf_sha256(&secret, sizeof(struct secret), NULL, 0,
|
||||
&secretstuff.derived_secret, sizeof(&secretstuff.derived_secret),
|
||||
info, tal_bytelen(info));
|
||||
|
||||
return towire_hsmd_derive_secret_reply(NULL, &secret);
|
||||
}
|
||||
|
||||
/*~ 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)
|
||||
@@ -1593,9 +1613,12 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
|
||||
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_DERIVE_SECRET:
|
||||
return handle_derive_secret(client, msg);
|
||||
|
||||
case WIRE_HSMD_DEV_MEMLEAK:
|
||||
case WIRE_HSMD_ECDH_RESP:
|
||||
case WIRE_HSMD_DERIVE_SECRET_REPLY:
|
||||
case WIRE_HSMD_CANNOUNCEMENT_SIG_REPLY:
|
||||
case WIRE_HSMD_CUPDATE_SIG_REPLY:
|
||||
case WIRE_HSMD_CLIENT_HSMFD_REPLY:
|
||||
@@ -1760,6 +1783,12 @@ u8 *hsmd_init(struct secret hsm_secret,
|
||||
sizeof(secretstuff.hsm_secret),
|
||||
"onion reply secret", strlen("onion reply secret"));
|
||||
|
||||
/* We derive the derived_secret key for generating pseudorandom keys
|
||||
* by taking input string from the makesecret RPC */
|
||||
hkdf_sha256(&secretstuff.derived_secret, sizeof(struct secret), NULL, 0,
|
||||
&secretstuff.hsm_secret, sizeof(secretstuff.hsm_secret),
|
||||
"derived secrets", strlen("derived secrets"));
|
||||
|
||||
/*~ Note: marshalling a bip32 tree only marshals the public side,
|
||||
* not the secrets! So we're not actually handing them out here!
|
||||
*/
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
#include <common/ecdh.h>
|
||||
#include <common/errcode.h>
|
||||
#include <common/hsm_encryption.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
#include <common/param.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <errno.h>
|
||||
@@ -146,6 +148,45 @@ static struct command_result *json_getsharedsecret(struct command *cmd,
|
||||
return command_success(cmd, response);
|
||||
}
|
||||
|
||||
static struct command_result *json_makesecret(struct command *cmd,
|
||||
const char *buffer,
|
||||
const jsmntok_t *obj UNNEEDED,
|
||||
const jsmntok_t *params)
|
||||
{
|
||||
u8 *info;
|
||||
struct json_stream *response;
|
||||
struct secret secret;
|
||||
|
||||
if (!param(cmd, buffer, params,
|
||||
p_req("info_hex", param_bin_from_hex, &info),
|
||||
NULL))
|
||||
return command_param_failed();
|
||||
|
||||
u8 *msg = towire_hsmd_derive_secret(cmd, info);
|
||||
if (!wire_sync_write(cmd->ld->hsm_fd, take(msg)))
|
||||
return command_fail(cmd, LIGHTNINGD,
|
||||
"Could not write to HSM: %s", strerror(errno));
|
||||
|
||||
|
||||
msg = wire_sync_read(tmpctx, cmd->ld->hsm_fd);
|
||||
if (!fromwire_hsmd_derive_secret_reply(msg, &secret))
|
||||
return command_fail(cmd, LIGHTNINGD,
|
||||
"Bad reply from HSM: %s", strerror(errno));
|
||||
|
||||
|
||||
response = json_stream_success(cmd);
|
||||
json_add_secret(response, "secret", &secret);
|
||||
return command_success(cmd, response);
|
||||
}
|
||||
|
||||
static const struct json_command makesecret_command = {
|
||||
"makesecret",
|
||||
"utility",
|
||||
&json_makesecret,
|
||||
"Get a pseudorandom secret key, using an info string."
|
||||
};
|
||||
AUTODATA(json_command, &makesecret_command);
|
||||
|
||||
static const struct json_command getsharedsecret_command = {
|
||||
"getsharedsecret",
|
||||
"utility", /* FIXME: Or "crypto"? */
|
||||
|
||||
Reference in New Issue
Block a user