wallet/hsmd: fix signmessagewithkey for BIP86 wallets
The signmessagewithkey RPC was failing for BIP86 (mnemonic-based) wallets because: 1. The wallet RPC was iterating through BIP32-derived addresses only, so it couldn't find BIP86-derived addresses. 2. The HSM's handle_bip137_sign_message always used bitcoin_key() (BIP32 derivation) regardless of wallet type.
This commit is contained in:
committed by
Rusty Russell
parent
c17590379e
commit
5fdc56c544
@@ -767,8 +767,12 @@ static u8 *handle_bip137_sign_message(struct hsmd_client *c, const u8 *msg_in)
|
||||
sha256_update(&sctx, msg, msg_len);
|
||||
sha256_double_done(&sctx, &shad);
|
||||
|
||||
/* get the private key BIP32 */
|
||||
bitcoin_key(&privkey, &pubkey, keyidx);
|
||||
/* Get the private key using appropriate derivation method */
|
||||
if (use_bip86_derivation(tal_bytelen(secretstuff.bip32_seed))) {
|
||||
bip86_key(&privkey, &pubkey, keyidx);
|
||||
} else {
|
||||
bitcoin_key(&privkey, &pubkey, keyidx);
|
||||
}
|
||||
|
||||
if (!secp256k1_ecdsa_sign_recoverable(
|
||||
secp256k1_ctx, &rsig, shad.sha.u.u8, privkey.secret.data, NULL,
|
||||
|
||||
@@ -911,6 +911,7 @@ static struct wallet *create_test_wallet(struct lightningd *ld, const tal_t *ctx
|
||||
w->ld = ld;
|
||||
ld->wallet = w;
|
||||
|
||||
ld->bip86_base = NULL;
|
||||
ld->bip32_base = tal(ld, struct ext_key);
|
||||
CHECK(bip32_key_from_seed(badseed, sizeof(badseed),
|
||||
BIP32_VER_TEST_PRIVATE, 0,
|
||||
|
||||
@@ -1282,38 +1282,24 @@ json_signmessagewithkey(struct command *cmd, const char *buffer,
|
||||
"HSM does not support signing BIP137 signing.");
|
||||
}
|
||||
|
||||
const u32 bip32_max_index =
|
||||
db_get_intvar(cmd->ld->wallet->db, "bip32_max_index", 0);
|
||||
bool match_found = false;
|
||||
u32 keyidx;
|
||||
enum addrtype addrtype;
|
||||
enum addrtype addrtype;
|
||||
|
||||
/* loop over all generated keys, find a matching key */
|
||||
for (keyidx = 1; keyidx <= bip32_max_index; keyidx++) {
|
||||
bip32_pubkey(cmd->ld, &pubkey, keyidx);
|
||||
u8 *redeemscript_p2wpkh;
|
||||
char *out_p2wpkh = encode_pubkey_to_addr(
|
||||
cmd, &pubkey, ADDR_BECH32, &redeemscript_p2wpkh);
|
||||
if (!out_p2wpkh) {
|
||||
abort();
|
||||
}
|
||||
/* wallet_get_addrtype fails for entries prior to v24.11, all
|
||||
* address types are assumed in that case. */
|
||||
if (!wallet_get_addrtype(cmd->ld->wallet, keyidx, &addrtype))
|
||||
addrtype = ADDR_ALL;
|
||||
if (streq(addr, out_p2wpkh) &&
|
||||
(addrtype == ADDR_BECH32 || addrtype == ADDR_ALL)) {
|
||||
match_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!match_found) {
|
||||
/* Use wallet_can_spend which handles both BIP32 and BIP86 addresses */
|
||||
if (!wallet_can_spend(cmd->ld->wallet, scriptpubkey, script_len,
|
||||
&keyidx, &addrtype)) {
|
||||
return command_fail(
|
||||
cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Address is not found in the wallet's database");
|
||||
}
|
||||
|
||||
/* Derive the pubkey for the found key index */
|
||||
if (cmd->ld->bip86_base) {
|
||||
bip86_pubkey(cmd->ld, &pubkey, keyidx);
|
||||
} else {
|
||||
bip32_pubkey(cmd->ld, &pubkey, keyidx);
|
||||
}
|
||||
|
||||
/* wire to hsmd a sign request */
|
||||
u8 *msg = towire_hsmd_bip137_sign_message(
|
||||
cmd, tal_dup_arr(tmpctx, u8, (u8 *)message, strlen(message), 0),
|
||||
|
||||
Reference in New Issue
Block a user