Skip to content

Commit

Permalink
hsmd: Added fields to hsm_sign_remote_commitment_tx to allow complete…
Browse files Browse the repository at this point in the history
… validation.

Changelog-Added: hsmd: Added fields to hsm_sign_remote_commitment_tx to allow complete validation by signing daemon.
  • Loading branch information
ksedgwic authored Feb 4, 2020
1 parent 149620e commit 5c8f881
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 8 deletions.
1 change: 1 addition & 0 deletions bitcoin/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ struct bitcoin_tx *bitcoin_tx(const tal_t *ctx,
tx->input_amounts = tal_arrz(tx, struct amount_sat*, input_count);
tx->wtx->locktime = nlocktime;
tx->wtx->version = 2;
tx->output_witscripts = tal_arrz(tx, struct witscript*, output_count);
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;
};

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 @@ -995,7 +995,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,
&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);
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 @@ -159,6 +159,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 @@ -719,7 +719,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 @@ -1234,7 +1237,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 @@ -403,6 +403,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;
}

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 @@ -263,6 +263,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 {
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 @@ -30,6 +30,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 @@ -91,6 +92,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 @@ -145,6 +147,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

0 comments on commit 5c8f881

Please sign in to comment.