From 85167986452814507ffb66489cae51aada53ecc3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 4 Jun 2015 21:06:42 +0930 Subject: [PATCH] signature: fix signatures for p2sh inputs. The subscript in this case is the redeemscript, not the input script. Signed-off-by: Rusty Russell --- check-commit-sig.c | 18 ++++++++++-------- open-commit-sig.c | 14 ++++++++++---- signature.c | 7 +++---- signature.h | 2 +- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/check-commit-sig.c b/check-commit-sig.c index 184ff2264..25df03075 100644 --- a/check-commit-sig.c +++ b/check-commit-sig.c @@ -28,7 +28,7 @@ int main(int argc, char *argv[]) OpenCommitSig *cs2; struct bitcoin_tx *anchor, *commit; struct sha256_double txid; - u8 *tx_arr; + u8 *tx_arr, *subscript; size_t *inmap, *outmap; struct pubkey pubkey1, pubkey2; struct bitcoin_signature sig1, sig2; @@ -58,6 +58,10 @@ int main(int argc, char *argv[]) if (!testnet) errx(1, "Private key '%s' not on testnet!", argv[4]); + /* Pubkey well-formed? */ + if (!proto_to_pubkey(o2->anchor->pubkey, &pubkey2)) + errx(1, "Invalid anchor-2 key"); + /* Get the transaction ID of the anchor. */ anchor = anchor_tx_create(ctx, o1, o2, &inmap, &outmap); if (!anchor) @@ -79,19 +83,17 @@ int main(int argc, char *argv[]) * is overkill: if their signature and pubkey signed the commit txin, * we're happy. */ sig1.stype = SIGHASH_ALL; - sign_tx_input(ctx, commit, 0, anchor->output[outmap[0]].script, - anchor->output[outmap[0]].script_length, privkey, - &sig1.sig); + subscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); + sign_tx_input(ctx, commit, 0, subscript, tal_count(subscript), + privkey, &sig1.sig); - /* Signatures and pubkeys well-formed? */ + /* Signatures well-formed? */ if (!proto_to_signature(cs2->sig, &sig2.sig)) errx(1, "Invalid commit-sig-2"); sig2.stype = SIGHASH_ALL; - if (!proto_to_pubkey(o2->anchor->pubkey, &pubkey2)) - errx(1, "Invalid anchor-2 key"); /* Combined signatures must validate correctly. */ - if (!check_2of2_sig(commit, 0, &anchor->output[outmap[0]], + if (!check_2of2_sig(commit, 0, subscript, tal_count(subscript), &pubkey1, &pubkey2, &sig1, &sig2)) errx(1, "Signature failed"); diff --git a/open-commit-sig.c b/open-commit-sig.c index b087a6b28..3b85d1b30 100644 --- a/open-commit-sig.c +++ b/open-commit-sig.c @@ -32,7 +32,8 @@ int main(int argc, char *argv[]) size_t *inmap, *outmap; EC_KEY *privkey; bool testnet; - struct pubkey pubkey; + struct pubkey pubkey1, pubkey2; + u8 *subscript; err_set_progname(argv[0]); @@ -49,7 +50,7 @@ int main(int argc, char *argv[]) o1 = pkt_from_file(argv[1], PKT__PKT_OPEN)->open; o2 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open; - privkey = key_from_base58(argv[3], strlen(argv[3]), &testnet, &pubkey); + privkey = key_from_base58(argv[3], strlen(argv[3]), &testnet, &pubkey1); if (!privkey) errx(1, "Invalid private key '%s'", argv[3]); if (!testnet) @@ -74,9 +75,14 @@ int main(int argc, char *argv[]) (long long)o1->commitment_fee, (long long)o2->commitment_fee); + /* Their pubkey must be valid */ + if (!proto_to_pubkey(o2->anchor->pubkey, &pubkey2)) + errx(1, "Invalid public open-channel-file2"); + /* Sign it for them. */ - sign_tx_input(ctx, commit, 0, anchor->output[outmap[0]].script, - anchor->output[outmap[0]].script_length, privkey, &sig); + subscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2); + sign_tx_input(ctx, commit, 0, subscript, tal_count(subscript), + privkey, &sig); pkt = open_commit_sig_pkt(ctx, &sig); if (!write_all(STDOUT_FILENO, pkt, diff --git a/signature.c b/signature.c index 01c2f7bc8..bd9d5b452 100644 --- a/signature.c +++ b/signature.c @@ -137,7 +137,7 @@ out: } bool check_2of2_sig(struct bitcoin_tx *tx, size_t input_num, - const struct bitcoin_tx_output *output, + const u8 *redeemscript, size_t redeemscript_len, const struct pubkey *key1, const struct pubkey *key2, const struct bitcoin_signature *sig1, const struct bitcoin_signature *sig2) @@ -145,9 +145,8 @@ bool check_2of2_sig(struct bitcoin_tx *tx, size_t input_num, struct sha256_double hash; assert(input_num < tx->input_count); - assert(is_p2sh(output->script, output->script_length)); - sha256_tx_one_input(tx, input_num, - output->script, output->script_length, &hash); + sha256_tx_one_input(tx, input_num, redeemscript, redeemscript_len, + &hash); /* We only use SIGHASH_ALL for the moment. */ if (sig1->stype != SIGHASH_ALL || sig2->stype != SIGHASH_ALL) diff --git a/signature.h b/signature.h index 777108d6b..c9c9d6d87 100644 --- a/signature.h +++ b/signature.h @@ -35,7 +35,7 @@ bool sign_tx_input(const tal_t *ctx, struct bitcoin_tx *tx, EC_KEY *privkey, struct signature *sig); bool check_2of2_sig(struct bitcoin_tx *tx, size_t input_num, - const struct bitcoin_tx_output *spending, + const u8 *redeemscript, size_t redeemscript_len, const struct pubkey *key1, const struct pubkey *key2, const struct bitcoin_signature *sig1, const struct bitcoin_signature *sig2);