Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hsmd: Added fields to hsm_sign_remote_commitment_tx to allow complete validation. #3363

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bitcoin/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ struct bitcoin_tx *bitcoin_tx(const tal_t *ctx,
tx->input_amounts = tal_arrz(tx, struct amount_sat*, input_count);
tx->wtx->locktime = 0;
tx->wtx->version = 2;
tx->output_witscripts = tal_arrz(tx, struct witscript*, output_count);
ksedgwic marked this conversation as resolved.
Show resolved Hide resolved
tx->chainparams = chainparams;
return tx;
}
Expand Down
7 changes: 7 additions & 0 deletions bitcoin/tx.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

#define BITCOIN_TX_DEFAULT_SEQUENCE 0xFFFFFFFF

struct witscript {
u8 *ptr;
};

cdecker marked this conversation as resolved.
Show resolved Hide resolved
struct bitcoin_txid {
struct sha256_double shad;
};
Expand All @@ -24,6 +28,9 @@ struct bitcoin_tx {
struct amount_sat **input_amounts;
struct wally_tx *wtx;

/* Need the output wscripts in the HSM to validate transaction */
struct witscript **output_witscripts;

/* Keep a reference to the ruleset we have to abide by */
const struct chainparams *chainparams;
};
Expand Down
5 changes: 4 additions & 1 deletion channeld/channeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,10 @@ static secp256k1_ecdsa_signature *calc_commitsigs(const tal_t *ctx,

msg = towire_hsm_sign_remote_commitment_tx(NULL, txs[0],
&peer->channel->funding_pubkey[REMOTE],
*txs[0]->input_amounts[0]);
*txs[0]->input_amounts[0],
(const struct witscript **) txs[0]->output_witscripts,
cdecker marked this conversation as resolved.
Show resolved Hide resolved
&peer->remote_per_commit,
peer->channel->option_static_remotekey);

msg = hsm_req(tmpctx, take(msg));
if (!fromwire_hsm_sign_tx_reply(msg, commit_sig))
Expand Down
26 changes: 22 additions & 4 deletions channeld/commit_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ size_t commit_tx_num_untrimmed(const struct htlc **htlcs,

static void add_offered_htlc_out(struct bitcoin_tx *tx, size_t n,
const struct htlc *htlc,
const struct keyset *keyset)
const struct keyset *keyset,
struct witscript *o_wscript)
{
struct ripemd160 ripemd;
u8 *wscript, *p2wsh;
Expand All @@ -49,12 +50,15 @@ static void add_offered_htlc_out(struct bitcoin_tx *tx, size_t n,
SUPERVERBOSE("# HTLC %" PRIu64 " offered %s wscript %s\n", htlc->id,
type_to_string(tmpctx, struct amount_sat, &amount),
tal_hex(wscript, wscript));
o_wscript->ptr = tal_dup_arr(o_wscript, u8, wscript,
tal_count(wscript), 0);
tal_free(wscript);
}

static void add_received_htlc_out(struct bitcoin_tx *tx, size_t n,
const struct htlc *htlc,
const struct keyset *keyset)
const struct keyset *keyset,
struct witscript *o_wscript)
{
struct ripemd160 ripemd;
u8 *wscript, *p2wsh;
Expand All @@ -72,6 +76,8 @@ static void add_received_htlc_out(struct bitcoin_tx *tx, size_t n,
type_to_string(tmpctx, struct amount_sat,
&amount),
tal_hex(wscript, wscript));
o_wscript->ptr = tal_dup_arr(o_wscript, u8,
wscript, tal_count(wscript), 0);
tal_free(wscript);
}

Expand Down Expand Up @@ -169,7 +175,10 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
continue;
if (trim(htlcs[i], feerate_per_kw, dust_limit, side))
continue;
add_offered_htlc_out(tx, n, htlcs[i], keyset);
tx->output_witscripts[n] =
tal(tx->output_witscripts, struct witscript);
add_offered_htlc_out(tx, n, htlcs[i],
keyset, tx->output_witscripts[n]);
(*htlcmap)[n] = htlcs[i];
cltvs[n] = abs_locktime_to_blocks(&htlcs[i]->expiry);
n++;
Expand All @@ -185,7 +194,10 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
continue;
if (trim(htlcs[i], feerate_per_kw, dust_limit, side))
continue;
add_received_htlc_out(tx, n, htlcs[i], keyset);
tx->output_witscripts[n] =
tal(tx->output_witscripts, struct witscript);
add_received_htlc_out(tx, n, htlcs[i], keyset,
tx->output_witscripts[n]);
(*htlcmap)[n] = htlcs[i];
cltvs[n] = abs_locktime_to_blocks(&htlcs[i]->expiry);
n++;
Expand All @@ -209,6 +221,11 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
SUPERVERBOSE("# to-local amount %s wscript %s\n",
type_to_string(tmpctx, struct amount_sat, &amount),
tal_hex(tmpctx, wscript));
tx->output_witscripts[n] =
tal(tx->output_witscripts, struct witscript);
tx->output_witscripts[n]->ptr =
tal_dup_arr(tx->output_witscripts[n], u8,
wscript, tal_count(wscript), 0);
cdecker marked this conversation as resolved.
Show resolved Hide resolved
n++;
}

Expand Down Expand Up @@ -252,6 +269,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,

assert(n <= tx->wtx->outputs_allocation_len);
tal_resize(htlcmap, n);
tal_resize(&(tx->output_witscripts), n);

/* BOLT #3:
*
Expand Down
7 changes: 7 additions & 0 deletions common/initial_commit_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
int pos = bitcoin_tx_add_output(
tx, scriptpubkey_p2wsh(tx, wscript), amount);
assert(pos == n);
tx->output_witscripts[n] =
tal(tx->output_witscripts, struct witscript);
tx->output_witscripts[n]->ptr =
tal_dup_arr(tx->output_witscripts[n], u8,
wscript, tal_count(wscript), 0);
n++;
}

Expand Down Expand Up @@ -202,6 +207,8 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,

assert(n <= tx->wtx->num_outputs);

tal_resize(&(tx->output_witscripts), n);

/* BOLT #3:
*
* 7. Sort the outputs into [BIP 69+CLTV
Expand Down
7 changes: 7 additions & 0 deletions common/permute_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,5 +174,12 @@ void permute_outputs(struct bitcoin_tx *tx, u32 *cltvs, const void **map)

/* Swap best into first place. */
swap_wally_outputs(tx->wtx->outputs, map, cltvs, i, best_pos);

/* If output_witscripts are present, swap them to match. */
if (tx->output_witscripts) {
struct witscript *tmp = tx->output_witscripts[i];
tx->output_witscripts[i] = tx->output_witscripts[best_pos];
tx->output_witscripts[best_pos] = tmp;
}
}
}
4 changes: 4 additions & 0 deletions hsmd/hsm_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ msgtype,hsm_sign_remote_commitment_tx,19
msgdata,hsm_sign_remote_commitment_tx,tx,bitcoin_tx,
msgdata,hsm_sign_remote_commitment_tx,remote_funding_key,pubkey,
msgdata,hsm_sign_remote_commitment_tx,funding_amount,amount_sat,
msgdata,hsm_sign_remote_commitment_tx,num_witscripts,u16,
msgdata,hsm_sign_remote_commitment_tx,output_witscripts,witscript,num_witscripts
msgdata,hsm_sign_remote_commitment_tx,remote_per_commit,pubkey,
msgdata,hsm_sign_remote_commitment_tx,option_static_remotekey,bool,

# channeld asks HSM to sign remote HTLC tx.
msgtype,hsm_sign_remote_htlc_tx,20
Expand Down
10 changes: 9 additions & 1 deletion hsmd/hsmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -996,11 +996,17 @@ static struct io_plan *handle_sign_remote_commitment_tx(struct io_conn *conn,
struct bitcoin_signature sig;
struct secrets secrets;
const u8 *funding_wscript;
struct witscript **output_witscripts;
struct pubkey remote_per_commit;
bool option_static_remotekey;

if (!fromwire_hsm_sign_remote_commitment_tx(tmpctx, msg_in,
&tx,
&remote_funding_pubkey,
&funding))
&funding,
&output_witscripts,
&remote_per_commit,
&option_static_remotekey))
bad_req(conn, c, msg_in);
tx->chainparams = c->chainparams;

Expand All @@ -1009,6 +1015,8 @@ static struct io_plan *handle_sign_remote_commitment_tx(struct io_conn *conn,
return bad_req_fmt(conn, c, msg_in, "tx must have 1 input");
if (tx->wtx->num_outputs == 0)
return bad_req_fmt(conn, c, msg_in, "tx must have > 0 outputs");
if (tal_count(output_witscripts) != tx->wtx->num_outputs)
return bad_req_fmt(conn, c, msg_in, "tx must have matching witscripts");

get_channel_seed(&c->id, c->dbid, &channel_seed);
derive_basepoints(&channel_seed,
Expand Down
10 changes: 8 additions & 2 deletions openingd/openingd.c
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,10 @@ static bool funder_finalize_channel_setup(struct state *state,
msg = towire_hsm_sign_remote_commitment_tx(NULL,
*tx,
&state->channel->funding_pubkey[REMOTE],
state->channel->funding);
state->channel->funding,
(const struct witscript **) (*tx)->output_witscripts,
&state->first_per_commitment_point[REMOTE],
state->channel->option_static_remotekey);

wire_sync_write(HSM_FD, take(msg));
msg = wire_sync_read(tmpctx, HSM_FD);
Expand Down Expand Up @@ -1233,7 +1236,10 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
msg = towire_hsm_sign_remote_commitment_tx(NULL,
remote_commit,
&state->channel->funding_pubkey[REMOTE],
state->channel->funding);
state->channel->funding,
(const struct witscript **) remote_commit->output_witscripts,
&state->first_per_commitment_point[REMOTE],
state->channel->option_static_remotekey);

wire_sync_write(HSM_FD, take(msg));
msg = wire_sync_read(tmpctx, HSM_FD);
Expand Down
1 change: 1 addition & 0 deletions tools/generate-wire.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ class Type(FieldSet):
'exclude_entry',
'fee_states',
'onionreply',
'witscript',
]

# Some BOLT types are re-typed based on their field name
Expand Down
12 changes: 12 additions & 0 deletions wire/fromwire.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,18 @@ struct bitcoin_tx_output *fromwire_bitcoin_tx_output(const tal_t *ctx,
return output;
}

struct witscript *fromwire_witscript(const tal_t *ctx, const u8 **cursor, size_t *max)
{
struct witscript *retval;
u16 len = fromwire_u16(cursor, max);
if (!len)
return NULL;
retval = tal(ctx, struct witscript);
retval->ptr = tal_arr(retval, u8, len);
fromwire_u8_array(cursor, max, retval->ptr, len);
return retval;
ksedgwic marked this conversation as resolved.
Show resolved Hide resolved
}

void fromwire_chainparams(const u8 **cursor, size_t *max,
const struct chainparams **chainparams)
{
Expand Down
11 changes: 11 additions & 0 deletions wire/towire.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,17 @@ void towire_bitcoin_tx_output(u8 **pptr, const struct bitcoin_tx_output *output)
towire_u8_array(pptr, output->script, tal_count(output->script));
}

void towire_witscript(u8 **pptr, const struct witscript *script)
{
if (script == NULL) {
towire_u16(pptr, 0);
} else {
ksedgwic marked this conversation as resolved.
Show resolved Hide resolved
assert(script->ptr != NULL);
towire_u16(pptr, tal_count(script->ptr));
towire_u8_array(pptr, script->ptr, tal_count(script->ptr));
}
}

void towire_chainparams(u8 **cursor, const struct chainparams *chainparams)
{
towire_bitcoin_blkid(cursor, &chainparams->genesis_blockhash);
Expand Down
4 changes: 4 additions & 0 deletions wire/wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct bitcoin_txid;
struct preimage;
struct ripemd160;
struct siphash_seed;
struct witscript;

/* Makes generate-wire.py work */
typedef char wirestring;
Expand Down Expand Up @@ -90,6 +91,7 @@ void towire_siphash_seed(u8 **cursor, const struct siphash_seed *seed);

void towire_bip32_key_version(u8 **cursor, const struct bip32_key_version *version);
void towire_bitcoin_tx_output(u8 **pptr, const struct bitcoin_tx_output *output);
void towire_witscript(u8 **pptr, const struct witscript *script);
void towire_chainparams(u8 **cursor, const struct chainparams *chainparams);

const u8 *fromwire(const u8 **cursor, size_t *max, void *copy, size_t n);
Expand Down Expand Up @@ -144,6 +146,8 @@ void fromwire_bip32_key_version(const u8 **cursor, size_t *max,
struct bip32_key_version *version);
struct bitcoin_tx_output *fromwire_bitcoin_tx_output(const tal_t *ctx,
const u8 **cursor, size_t *max);
struct witscript *fromwire_witscript(const tal_t *ctx,
const u8 **cursor, size_t *max);

void fromwire_chainparams(const u8 **cursor, size_t *max,
const struct chainparams **chainparams);
Expand Down