hsmd: derive an onion_reply secret.

We put this in reply paths, so we can tell if they are used.  This lets us
avoid responding unless the correct reply path is used.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2021-09-22 06:47:25 +09:30
parent 3a966191b8
commit 01161aac68
6 changed files with 24 additions and 8 deletions

View File

@@ -21,6 +21,7 @@ msgtype,hsmd_init_reply,111
msgdata,hsmd_init_reply,node_id,node_id,
msgdata,hsmd_init_reply,bip32,ext_key,
msgdata,hsmd_init_reply,bolt12,pubkey32,
msgdata,hsmd_init_reply,onion_reply_secret,secret,
# Get a new HSM FD, with the specified capabilities
msgtype,hsmd_client_hsmfd,9
1 # Clients should not give a bad request but not the HSM's decision to crash.
21 msgdata,hsmd_init_reply,bolt12,pubkey32,
22 # Get a new HSM FD, with the specified capabilities msgdata,hsmd_init_reply,onion_reply_secret,secret,
23 msgtype,hsmd_client_hsmfd,9 # Get a new HSM FD, with the specified capabilities
24 msgtype,hsmd_client_hsmfd,9
25 # Which identity to use for requests
26 msgdata,hsmd_client_hsmfd,id,node_id,
27 # Database id for this client, if any.

8
hsmd/hsmd_wiregen.c generated
View File

@@ -243,7 +243,7 @@ bool fromwire_hsmd_init(const tal_t *ctx, const void *p, struct bip32_key_versio
}
/* WIRE: HSMD_INIT_REPLY */
u8 *towire_hsmd_init_reply(const tal_t *ctx, const struct node_id *node_id, const struct ext_key *bip32, const struct pubkey32 *bolt12)
u8 *towire_hsmd_init_reply(const tal_t *ctx, const struct node_id *node_id, const struct ext_key *bip32, const struct pubkey32 *bolt12, const struct secret *onion_reply_secret)
{
u8 *p = tal_arr(ctx, u8, 0);
@@ -251,10 +251,11 @@ u8 *towire_hsmd_init_reply(const tal_t *ctx, const struct node_id *node_id, cons
towire_node_id(&p, node_id);
towire_ext_key(&p, bip32);
towire_pubkey32(&p, bolt12);
towire_secret(&p, onion_reply_secret);
return memcheck(p, tal_count(p));
}
bool fromwire_hsmd_init_reply(const void *p, struct node_id *node_id, struct ext_key *bip32, struct pubkey32 *bolt12)
bool fromwire_hsmd_init_reply(const void *p, struct node_id *node_id, struct ext_key *bip32, struct pubkey32 *bolt12, struct secret *onion_reply_secret)
{
const u8 *cursor = p;
size_t plen = tal_count(p);
@@ -264,6 +265,7 @@ bool fromwire_hsmd_init_reply(const void *p, struct node_id *node_id, struct ext
fromwire_node_id(&cursor, &plen, node_id);
fromwire_ext_key(&cursor, &plen, bip32);
fromwire_pubkey32(&cursor, &plen, bolt12);
fromwire_secret(&cursor, &plen, onion_reply_secret);
return cursor != NULL;
}
@@ -1331,4 +1333,4 @@ bool fromwire_hsmd_sign_option_will_fund_offer_reply(const void *p, secp256k1_ec
fromwire_secp256k1_ecdsa_signature(&cursor, &plen, rsig);
return cursor != NULL;
}
// SHA256STAMP:739903bb8c5fedb86d1d35fea7b926f35b117d9cfdb5e3e8e1f62ddca731f54b
// SHA256STAMP:34afee076f2df0aca89c651f73043e5fbf11817a1ae482d70530212b25a82918

6
hsmd/hsmd_wiregen.h generated
View File

@@ -107,8 +107,8 @@ u8 *towire_hsmd_init(const tal_t *ctx, const struct bip32_key_version *bip32_key
bool fromwire_hsmd_init(const tal_t *ctx, const void *p, struct bip32_key_version *bip32_key_version, const struct chainparams **chainparams, struct secret **hsm_encryption_key, struct privkey **dev_force_privkey, struct secret **dev_force_bip32_seed, struct secrets **dev_force_channel_secrets, struct sha256 **dev_force_channel_secrets_shaseed);
/* WIRE: HSMD_INIT_REPLY */
u8 *towire_hsmd_init_reply(const tal_t *ctx, const struct node_id *node_id, const struct ext_key *bip32, const struct pubkey32 *bolt12);
bool fromwire_hsmd_init_reply(const void *p, struct node_id *node_id, struct ext_key *bip32, struct pubkey32 *bolt12);
u8 *towire_hsmd_init_reply(const tal_t *ctx, const struct node_id *node_id, const struct ext_key *bip32, const struct pubkey32 *bolt12, const struct secret *onion_reply_secret);
bool fromwire_hsmd_init_reply(const void *p, struct node_id *node_id, struct ext_key *bip32, struct pubkey32 *bolt12, struct secret *onion_reply_secret);
/* WIRE: HSMD_CLIENT_HSMFD */
/* Get a new HSM FD */
@@ -295,4 +295,4 @@ bool fromwire_hsmd_sign_option_will_fund_offer_reply(const void *p, secp256k1_ec
#endif /* LIGHTNING_HSMD_HSMD_WIREGEN_H */
// SHA256STAMP:739903bb8c5fedb86d1d35fea7b926f35b117d9cfdb5e3e8e1f62ddca731f54b
// SHA256STAMP:34afee076f2df0aca89c651f73043e5fbf11817a1ae482d70530212b25a82918

View File

@@ -1469,6 +1469,7 @@ u8 *hsmd_init(struct secret hsm_secret,
u32 salt = 0;
struct ext_key master_extkey, child_extkey;
struct node_id node_id;
struct secret onion_reply_secret;
/*~ Don't swap this. */
sodium_mlock(secretstuff.hsm_secret.data,
@@ -1588,10 +1589,18 @@ u8 *hsmd_init(struct secret hsm_secret,
hsmd_status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Could derive bolt12 public key.");
/*~ We derive a secret for onion_message's self_id so we can tell
* if it used a path we created (i.e. do not leak our public id!) */
hkdf_sha256(&onion_reply_secret, sizeof(onion_reply_secret),
NULL, 0,
&secretstuff.hsm_secret,
sizeof(secretstuff.hsm_secret),
"onion reply secret", strlen("onion reply secret"));
/*~ Note: marshalling a bip32 tree only marshals the public side,
* not the secrets! So we're not actually handing them out here!
*/
return take(towire_hsmd_init_reply(
NULL, &node_id, &secretstuff.bip32,
&bolt12));
&bolt12, &onion_reply_secret));
}

View File

@@ -116,7 +116,8 @@ struct ext_key *hsm_init(struct lightningd *ld)
msg = wire_sync_read(tmpctx, ld->hsm_fd);
if (!fromwire_hsmd_init_reply(msg,
&ld->id, bip32_base,
&ld->bolt12_base)) {
&ld->bolt12_base,
&ld->onion_reply_secret)) {
if (ld->config.keypass)
errx(1, "Wrong password for encrypted hsm_secret.");
errx(1, "HSM did not give init reply");

View File

@@ -109,6 +109,9 @@ struct lightningd {
/* The public base for our payer_id keys */
struct pubkey32 bolt12_base;
/* The secret we put in onion message paths to know it's ours. */
struct secret onion_reply_secret;
/* Feature set we offer. */
struct feature_set *our_features;