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. 9
      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

9
bitcoin/signature.c

@ -252,8 +252,11 @@ size_t signature_to_der(secp256k1_context *secpctx,
} }
/* Signature must have low S value. */ /* 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;
return true;
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); const struct bitcoin_signature *sig);
/* Signature must have low S value. */ /* 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). */ /* Give DER encoding of signature: returns length used (<= 72). */
size_t signature_to_der(secp256k1_context *secpctx, 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) if (!auth)
return io_close(conn); 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"); log_unusual(peer->log, "Invalid auth signature");
return io_close(conn); return io_close(conn);
} }
@ -428,7 +429,7 @@ static Pkt *authenticate_pkt(const tal_t *ctx,
Authenticate *auth = tal(ctx, Authenticate); Authenticate *auth = tal(ctx, Authenticate);
authenticate__init(auth); authenticate__init(auth);
auth->node_id = pubkey_to_proto(auth, secpctx, node_id); 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); 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->remote.commit->sig->stype = SIGHASH_ALL;
peer_sign_theircommit(peer, peer->remote.commit->tx, peer_sign_theircommit(peer, peer->remote.commit->tx,
&peer->remote.commit->sig->sig); &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); queue_pkt(peer, PKT__PKT_OPEN_COMMIT_SIG, s);
} }
@ -304,7 +305,7 @@ void queue_pkt_commit(struct peer *peer)
/* Now send message */ /* Now send message */
update_commit__init(u); 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); 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); close_tx = peer_create_close_tx(peer, peer->closing.our_fee);
peer_sign_mutual_close(peer, close_tx, &our_close_sig); 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; c->close_fee = peer->closing.our_fee;
log_info(peer->log, "queue_pkt_close_signature: offered close fee %" log_info(peer->log, "queue_pkt_close_signature: offered close fee %"
PRIu64, c->close_fee); PRIu64, c->close_fee);
@ -530,7 +531,7 @@ static Pkt *check_and_save_commit_sig(struct peer *peer,
assert(!ci->sig); assert(!ci->sig);
sig->stype = SIGHASH_ALL; 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"); return pkt_err(peer, "Malformed signature");
log_debug(peer->log, "Checking sig for %u/%u msatoshis, %zu/%zu htlcs", 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 * transaction with the given `close_fee`, and MUST fail the
* connection if it is not. */ * connection if it is not. */
theirsig.stype = SIGHASH_ALL; 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, return peer_comms_err(peer,
pkt_err(peer, "Invalid signature format")); pkt_err(peer, "Invalid signature format"));

12
protobuf_convert.c

@ -4,12 +4,14 @@
#include "protobuf_convert.h" #include "protobuf_convert.h"
#include <ccan/crypto/sha256/sha256.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 *pb = tal(ctx, Signature);
signature__init(pb); signature__init(pb);
assert(sig_valid(sig)); assert(sig_valid(secpctx, sig));
/* FIXME: Need a portable way to encode signatures in libsecp! */ /* 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; 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. */ /* Kill me again. */
/* FIXME: Need a portable way to encode signatures in libsecp! */ /* 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 + 48, &pb->s3, 8);
memcpy(sig->sig.data + 56, &pb->s4, 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, BitcoinPubkey *pubkey_to_proto(const tal_t *ctx,

8
protobuf_convert.h

@ -8,8 +8,12 @@
/* Convert to-from protobuf to internal representation. */ /* Convert to-from protobuf to internal representation. */
struct signature; struct signature;
Signature *signature_to_proto(const tal_t *ctx, const struct signature *sig); Signature *signature_to_proto(const tal_t *ctx,
bool proto_to_signature(const Signature *pb, struct signature *sig); 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. */ /* Convert to-from protobuf to internal representation. */
struct pubkey; struct pubkey;

Loading…
Cancel
Save