diff --git a/common/bolt12_merkle.c b/common/bolt12_merkle.c index 76b8e4ab4..1bc5ad359 100644 --- a/common/bolt12_merkle.c +++ b/common/bolt12_merkle.c @@ -224,16 +224,14 @@ void sighash_from_merkle(const char *messagename, * * Since key used to be x-only, we don't hash first byte! */ -void payer_key_tweak(const struct point32 *bolt12, +void payer_key_tweak(const struct pubkey *bolt12, const u8 *publictweak, size_t publictweaklen, struct sha256 *tweak) { u8 rawkey[PUBKEY_CMPR_LEN]; struct sha256_ctx sha; - struct pubkey pk; - pk.pubkey = bolt12->pubkey; - pubkey_to_der(rawkey, &pk); + pubkey_to_der(rawkey, bolt12); sha256_init(&sha); sha256_update(&sha, rawkey + 1, sizeof(rawkey) - 1); diff --git a/common/bolt12_merkle.h b/common/bolt12_merkle.h index 08ae9fc20..cf7f91813 100644 --- a/common/bolt12_merkle.h +++ b/common/bolt12_merkle.h @@ -25,7 +25,7 @@ void sighash_from_merkle(const char *messagename, /** * payer_key_tweak - get the actual tweak to use for a payer_key */ -void payer_key_tweak(const struct point32 *bolt12, +void payer_key_tweak(const struct pubkey *bolt12, const u8 *publictweak, size_t publictweaklen, struct sha256 *tweak); diff --git a/common/hsm_version.h b/common/hsm_version.h index 41f179d69..ea1bdff93 100644 --- a/common/hsm_version.h +++ b/common/hsm_version.h @@ -11,7 +11,7 @@ #define HSM_MIN_VERSION 1 /* wire/hsmd_wire.csv contents version: - * 409cffa355ab6cc76bd298910adca9936a68223267ddc4815ba16aeac5d0acc3 + * 43c435f61de3af0dd7a91514d94b3e0762c962fce5b39be430538f8c6c4b0695 */ -#define HSM_MAX_VERSION 1 +#define HSM_MAX_VERSION 2 #endif /* LIGHTNING_COMMON_HSM_VERSION_H */ diff --git a/hsmd/hsmd.c b/hsmd/hsmd.c index 3c4b56192..2bc775704 100644 --- a/hsmd/hsmd.c +++ b/hsmd/hsmd.c @@ -444,7 +444,7 @@ static struct io_plan *init_hsm(struct io_conn *conn, struct secret *hsm_encryption_key; struct bip32_key_version bip32_key_version; u32 minversion, maxversion; - const u32 our_minversion = 1, our_maxversion = 1; + const u32 our_minversion = 2, our_maxversion = 2; /* This must be lightningd. */ assert(is_lightningd(c)); @@ -692,7 +692,8 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c) case WIRE_HSMD_NODE_ANNOUNCEMENT_SIG_REPLY: case WIRE_HSMD_SIGN_WITHDRAWAL_REPLY: case WIRE_HSMD_SIGN_INVOICE_REPLY: - case WIRE_HSMD_INIT_REPLY: + case WIRE_HSMD_INIT_REPLY_V1: + case WIRE_HSMD_INIT_REPLY_V2: case WIRE_HSMD_DERIVE_SECRET_REPLY: case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST: case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY: diff --git a/hsmd/hsmd_wire.csv b/hsmd/hsmd_wire.csv index 37ff13806..230848ed7 100644 --- a/hsmd/hsmd_wire.csv +++ b/hsmd/hsmd_wire.csv @@ -19,11 +19,18 @@ msgdata,hsmd_init,hsm_wire_min_version,u32, msgdata,hsmd_init,hsm_wire_max_version,u32, #include -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,point32, -msgdata,hsmd_init_reply,onion_reply_secret,secret, +# DEPRECATED after v0.12, remove in two versions! +msgtype,hsmd_init_reply_v1,111 +msgdata,hsmd_init_reply_v1,node_id,node_id, +msgdata,hsmd_init_reply_v1,bip32,ext_key, +msgdata,hsmd_init_reply_v1,bolt12,u8,32 +msgdata,hsmd_init_reply_v1,onion_reply_secret,secret, + +msgtype,hsmd_init_reply_v2,113 +msgdata,hsmd_init_reply_v2,node_id,node_id, +msgdata,hsmd_init_reply_v2,bip32,ext_key, +msgdata,hsmd_init_reply_v2,bolt12,pubkey, +msgdata,hsmd_init_reply_v2,onion_reply_secret,secret, # Declare a new channel. msgtype,hsmd_new_channel,30 diff --git a/hsmd/libhsmd.c b/hsmd/libhsmd.c index 4fca594ba..b9d3f54b5 100644 --- a/hsmd/libhsmd.c +++ b/hsmd/libhsmd.c @@ -134,7 +134,8 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client, case WIRE_HSMD_NODE_ANNOUNCEMENT_SIG_REPLY: case WIRE_HSMD_SIGN_WITHDRAWAL_REPLY: case WIRE_HSMD_SIGN_INVOICE_REPLY: - case WIRE_HSMD_INIT_REPLY: + case WIRE_HSMD_INIT_REPLY_V1: + case WIRE_HSMD_INIT_REPLY_V2: case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST: case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY: case WIRE_HSMD_VALIDATE_COMMITMENT_TX_REPLY: @@ -635,7 +636,7 @@ static u8 *handle_sign_bolt12(struct hsmd_client *c, const u8 *msg_in) node_schnorrkey(&kp, NULL); } else { /* If we're tweaking key, we use bolt12 key */ - struct point32 bolt12; + struct pubkey bolt12; struct sha256 tweak; if (secp256k1_keypair_pub(secp256k1_ctx, @@ -1629,7 +1630,8 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client, case WIRE_HSMD_NODE_ANNOUNCEMENT_SIG_REPLY: case WIRE_HSMD_SIGN_WITHDRAWAL_REPLY: case WIRE_HSMD_SIGN_INVOICE_REPLY: - case WIRE_HSMD_INIT_REPLY: + case WIRE_HSMD_INIT_REPLY_V1: + case WIRE_HSMD_INIT_REPLY_V2: case WIRE_HSMSTATUS_CLIENT_BAD_REQUEST: case WIRE_HSMD_SIGN_COMMITMENT_TX_REPLY: case WIRE_HSMD_VALIDATE_COMMITMENT_TX_REPLY: @@ -1652,8 +1654,7 @@ u8 *hsmd_init(struct secret hsm_secret, struct bip32_key_version bip32_key_version) { u8 bip32_seed[BIP32_ENTROPY_LEN_256]; - struct pubkey key; - struct point32 bolt12; + struct pubkey key, bolt12; u32 salt = 0; struct ext_key master_extkey, child_extkey; struct node_id node_id; @@ -1777,6 +1778,14 @@ u8 *hsmd_init(struct secret hsm_secret, hsmd_status_failed(STATUS_FAIL_INTERNAL_ERROR, "Could derive bolt12 public key."); + /* For compatibility, we have to invert y-odd keys */ + u8 raw[PUBKEY_CMPR_LEN]; + pubkey_to_der(raw, &bolt12); + if (raw[0] == SECP256K1_TAG_PUBKEY_ODD) { + raw[0] = SECP256K1_TAG_PUBKEY_EVEN; + pubkey_from_der(raw, sizeof(raw), &bolt12); + } + /*~ 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), @@ -1794,7 +1803,7 @@ u8 *hsmd_init(struct secret hsm_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( + return take(towire_hsmd_init_reply_v2( NULL, &node_id, &secretstuff.bip32, &bolt12, &onion_reply_secret)); } diff --git a/lightningd/hsm_control.c b/lightningd/hsm_control.c index b1b46db51..1efd6c518 100644 --- a/lightningd/hsm_control.c +++ b/lightningd/hsm_control.c @@ -117,13 +117,26 @@ struct ext_key *hsm_init(struct lightningd *ld) bip32_base = tal(ld, struct ext_key); msg = wire_sync_read(tmpctx, ld->hsm_fd); - if (!fromwire_hsmd_init_reply(msg, - &ld->id, bip32_base, - &ld->bolt12_base, - &ld->onion_reply_secret)) { - if (ld->config.keypass) - errx(EXITCODE_HSM_BAD_PASSWORD, "Wrong password for encrypted hsm_secret."); - errx(EXITCODE_HSM_GENERIC_ERROR, "HSM did not give init reply"); + if (!fromwire_hsmd_init_reply_v2(msg, + &ld->id, bip32_base, + &ld->bolt12_base, + &ld->onion_reply_secret)) { + /* v1 had x-only pubkey */ + u8 pubkey32[33]; + + pubkey32[0] = SECP256K1_TAG_PUBKEY_EVEN; + if (!fromwire_hsmd_init_reply_v1(msg, + &ld->id, bip32_base, + pubkey32 + 1, + &ld->onion_reply_secret)) { + if (ld->config.keypass) + errx(EXITCODE_HSM_BAD_PASSWORD, "Wrong password for encrypted hsm_secret."); + errx(EXITCODE_HSM_GENERIC_ERROR, "HSM did not give init reply"); + } + if (!pubkey_from_der(pubkey32, sizeof(pubkey32), + &ld->bolt12_base)) + errx(EXITCODE_HSM_GENERIC_ERROR, + "HSM gave invalid v1 bolt12_base"); } return bip32_base; diff --git a/lightningd/lightningd.h b/lightningd/lightningd.h index 4fe6b45e9..e3b037f7d 100644 --- a/lightningd/lightningd.h +++ b/lightningd/lightningd.h @@ -122,7 +122,7 @@ struct lightningd { struct node_id id; /* The public base for our payer_id keys */ - struct point32 bolt12_base; + struct pubkey bolt12_base; /* The secret we put in onion message paths to know it's ours. */ struct secret onion_reply_secret; diff --git a/lightningd/offer.c b/lightningd/offer.c index b66a4184c..f9fc2081a 100644 --- a/lightningd/offer.c +++ b/lightningd/offer.c @@ -78,7 +78,7 @@ static void hsm_sign_b12(struct lightningd *ld, if (!check_schnorr_sig(&sighash, &key->pubkey, sig)) fatal("HSM gave bad signature %s for pubkey %s", type_to_string(tmpctx, struct bip340sig, sig), - type_to_string(tmpctx, struct point32, key)); + type_to_string(tmpctx, struct pubkey, (struct pubkey *)key)); } static struct command_result *json_createoffer(struct command *cmd,