Browse Source

bitcoin: implement sig_valid.

Update libsecp256k1 has a normalize function, which allows us to test
if the signature was in low-S form.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 8 years ago
parent
commit
f2d835522c
  1. 7
      bitcoin/signature.c
  2. 2
      bitcoin/signature.h
  3. 5
      daemon/cryptopkt.c
  4. 9
      daemon/packets.c
  5. 2
      daemon/peer.c
  6. 12
      protobuf_convert.c
  7. 8
      protobuf_convert.h

7
bitcoin/signature.c

@ -252,8 +252,11 @@ size_t signature_to_der(secp256k1_context *secpctx,
}
/* Signature must have low S value. */
bool sig_valid(const struct signature *sig)
bool sig_valid(secp256k1_context *secpctx, const struct signature *sig)
{
/* FIXME! Need libsecp support. */
secp256k1_ecdsa_signature tmp;
if (secp256k1_ecdsa_signature_normalize(secpctx, &tmp, &sig->sig) == 0)
return true;
return false;
}

2
bitcoin/signature.h

@ -52,7 +52,7 @@ bool check_tx_sig(secp256k1_context *secpctx,
const struct bitcoin_signature *sig);
/* Signature must have low S value. */
bool sig_valid(const struct signature *s);
bool sig_valid(secp256k1_context *secpctx, const struct signature *sig);
/* Give DER encoding of signature: returns length used (<= 72). */
size_t signature_to_der(secp256k1_context *secpctx,

5
daemon/cryptopkt.c

@ -356,7 +356,8 @@ static struct io_plan *check_proof(struct io_conn *conn, struct peer *peer)
if (!auth)
return io_close(conn);
if (!proto_to_signature(auth->session_sig, &sig)) {
if (!proto_to_signature(peer->dstate->secpctx, auth->session_sig,
&sig)) {
log_unusual(peer->log, "Invalid auth signature");
return io_close(conn);
}
@ -428,7 +429,7 @@ static Pkt *authenticate_pkt(const tal_t *ctx,
Authenticate *auth = tal(ctx, Authenticate);
authenticate__init(auth);
auth->node_id = pubkey_to_proto(auth, secpctx, node_id);
auth->session_sig = signature_to_proto(auth, sig);
auth->session_sig = signature_to_proto(auth, secpctx, sig);
return pkt_wrap(ctx, auth, PKT__PKT_AUTH);
}

9
daemon/packets.c

@ -146,7 +146,8 @@ void queue_pkt_open_commit_sig(struct peer *peer)
peer->remote.commit->sig->stype = SIGHASH_ALL;
peer_sign_theircommit(peer, peer->remote.commit->tx,
&peer->remote.commit->sig->sig);
s->sig = signature_to_proto(s, &peer->remote.commit->sig->sig);
s->sig = signature_to_proto(s, peer->dstate->secpctx,
&peer->remote.commit->sig->sig);
queue_pkt(peer, PKT__PKT_OPEN_COMMIT_SIG, s);
}
@ -304,7 +305,7 @@ void queue_pkt_commit(struct peer *peer)
/* Now send message */
update_commit__init(u);
u->sig = signature_to_proto(u, &ci->sig->sig);
u->sig = signature_to_proto(u, peer->dstate->secpctx, &ci->sig->sig);
queue_pkt(peer, PKT__PKT_UPDATE_COMMIT, u);
}
@ -456,7 +457,7 @@ void queue_pkt_close_signature(struct peer *peer)
close_tx = peer_create_close_tx(peer, peer->closing.our_fee);
peer_sign_mutual_close(peer, close_tx, &our_close_sig);
c->sig = signature_to_proto(c, &our_close_sig);
c->sig = signature_to_proto(c, peer->dstate->secpctx, &our_close_sig);
c->close_fee = peer->closing.our_fee;
log_info(peer->log, "queue_pkt_close_signature: offered close fee %"
PRIu64, c->close_fee);
@ -530,7 +531,7 @@ static Pkt *check_and_save_commit_sig(struct peer *peer,
assert(!ci->sig);
sig->stype = SIGHASH_ALL;
if (!proto_to_signature(pb, &sig->sig))
if (!proto_to_signature(peer->dstate->secpctx, pb, &sig->sig))
return pkt_err(peer, "Malformed signature");
log_debug(peer->log, "Checking sig for %u/%u msatoshis, %zu/%zu htlcs",

2
daemon/peer.c

@ -268,7 +268,7 @@ static bool closing_pkt_in(struct peer *peer, const Pkt *pkt)
* transaction with the given `close_fee`, and MUST fail the
* connection if it is not. */
theirsig.stype = SIGHASH_ALL;
if (!proto_to_signature(c->sig, &theirsig.sig))
if (!proto_to_signature(peer->dstate->secpctx, c->sig, &theirsig.sig))
return peer_comms_err(peer,
pkt_err(peer, "Invalid signature format"));

12
protobuf_convert.c

@ -4,12 +4,14 @@
#include "protobuf_convert.h"
#include <ccan/crypto/sha256/sha256.h>
Signature *signature_to_proto(const tal_t *ctx, const struct signature *sig)
Signature *signature_to_proto(const tal_t *ctx,
secp256k1_context *secpctx,
const struct signature *sig)
{
Signature *pb = tal(ctx, Signature);
signature__init(pb);
assert(sig_valid(sig));
assert(sig_valid(secpctx, sig));
/* FIXME: Need a portable way to encode signatures in libsecp! */
@ -26,7 +28,9 @@ Signature *signature_to_proto(const tal_t *ctx, const struct signature *sig)
return pb;
}
bool proto_to_signature(const Signature *pb, struct signature *sig)
bool proto_to_signature(secp256k1_context *secpctx,
const Signature *pb,
struct signature *sig)
{
/* Kill me again. */
/* FIXME: Need a portable way to encode signatures in libsecp! */
@ -40,7 +44,7 @@ bool proto_to_signature(const Signature *pb, struct signature *sig)
memcpy(sig->sig.data + 48, &pb->s3, 8);
memcpy(sig->sig.data + 56, &pb->s4, 8);
return sig_valid(sig);
return sig_valid(secpctx, sig);
}
BitcoinPubkey *pubkey_to_proto(const tal_t *ctx,

8
protobuf_convert.h

@ -8,8 +8,12 @@
/* Convert to-from protobuf to internal representation. */
struct signature;
Signature *signature_to_proto(const tal_t *ctx, const struct signature *sig);
bool proto_to_signature(const Signature *pb, struct signature *sig);
Signature *signature_to_proto(const tal_t *ctx,
secp256k1_context *secpctx,
const struct signature *sig);
bool proto_to_signature(secp256k1_context *secpctx,
const Signature *pb,
struct signature *sig);
/* Convert to-from protobuf to internal representation. */
struct pubkey;

Loading…
Cancel
Save