From bf3080ca0988b855e79c0f1b9ba37766e11e6a54 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 22 Jan 2016 06:41:48 +1030 Subject: [PATCH] secrets: handle per-peer secrets as well. Signed-off-by: Rusty Russell --- daemon/peer.c | 1 + daemon/peer.h | 4 ++++ daemon/secrets.c | 54 ++++++++++++++++++++++++++++++++++++++++-------- daemon/secrets.h | 9 ++++++++ 4 files changed, 59 insertions(+), 9 deletions(-) diff --git a/daemon/peer.c b/daemon/peer.c index bf9c1910e..f6ee5f3b5 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -70,6 +70,7 @@ static struct peer *new_peer(struct lightningd_state *state, peer->addr.type = addr_type; peer->addr.protocol = addr_protocol; peer->io_data = NULL; + peer->secrets = NULL; /* FIXME: Attach IO logging for this peer. */ tal_add_destructor(peer, destroy_peer); diff --git a/daemon/peer.h b/daemon/peer.h index ea0725b7f..e62c5b1a0 100644 --- a/daemon/peer.h +++ b/daemon/peer.h @@ -26,6 +26,10 @@ struct peer { /* What happened. */ struct log *log; + + /* Keys for transactions with this peer. */ + struct pubkey commitkey, finalkey; + struct peer_secrets *secrets; }; void setup_listeners(struct lightningd_state *state, unsigned int portnum); diff --git a/daemon/secrets.c b/daemon/secrets.c index a6118b7c5..61381c7a2 100644 --- a/daemon/secrets.c +++ b/daemon/secrets.c @@ -6,6 +6,7 @@ #include "peer.h" #include "secrets.h" #include +#include #include #include #include @@ -33,6 +34,49 @@ void privkey_sign(struct peer *peer, const void *src, size_t len, &peer->state->secret->privkey, &h, sig); } +struct peer_secrets { + /* Two private keys, one for commit txs, one for final output. */ + struct privkey commit, final; + /* Seed from which we generate revocation hashes. */ + struct sha256 revocation_seed; +}; + +static void new_keypair(struct lightningd_state *state, + struct privkey *privkey, struct pubkey *pubkey) +{ + do { + if (RAND_bytes(privkey->secret, sizeof(privkey->secret)) != 1) + fatal("Could not get random bytes for privkey"); + } while (!pubkey_from_privkey(state->secpctx, + privkey, pubkey, SECP256K1_EC_COMPRESSED)); +} + +void peer_secrets_init(struct peer *peer) +{ + peer->secrets = tal(peer, struct peer_secrets); + + new_keypair(peer->state, &peer->secrets->commit, &peer->commitkey); + new_keypair(peer->state, &peer->secrets->final, &peer->finalkey); + if (RAND_bytes(peer->secrets->revocation_seed.u.u8, + sizeof(peer->secrets->revocation_seed.u.u8)) != 1) + fatal("Could not get random bytes for revocation seed"); +} + +void peer_get_revocation_preimage(const struct peer *peer, u64 index, + struct sha256 *preimage) +{ + shachain_from_seed(&peer->secrets->revocation_seed, index, preimage); +} + +void peer_get_revocation_hash(const struct peer *peer, u64 index, + struct sha256 *rhash) +{ + struct sha256 preimage; + + peer_get_revocation_preimage(peer, index, &preimage); + sha256(rhash, preimage.u.u8, sizeof(preimage.u.u8)); +} + void secrets_init(struct lightningd_state *state) { int fd; @@ -45,15 +89,7 @@ void secrets_init(struct lightningd_state *state) fatal("Failed to open privkey: %s", strerror(errno)); log_unusual(state->base_log, "Creating privkey file"); - do { - if (RAND_bytes(state->secret->privkey.secret, - sizeof(state->secret->privkey.secret)) - != 1) - fatal("Could not get random bytes for privkey"); - } while (!pubkey_from_privkey(state->secpctx, - &state->secret->privkey, - &state->id, - SECP256K1_EC_COMPRESSED)); + new_keypair(state, &state->secret->privkey, &state->id); fd = open("privkey", O_CREAT|O_EXCL|O_WRONLY, 0400); if (fd < 0) diff --git a/daemon/secrets.h b/daemon/secrets.h index f5f78d34a..a3015eb12 100644 --- a/daemon/secrets.h +++ b/daemon/secrets.h @@ -2,14 +2,23 @@ #define LIGHTNING_DAEMON_SECRETS_H /* Routines to handle private keys. */ #include "config.h" +#include struct peer; struct lightningd_state; struct signature; +struct sha256; void privkey_sign(struct peer *peer, const void *src, size_t len, struct signature *sig); +void peer_secrets_init(struct peer *peer); + +void peer_get_revocation_hash(const struct peer *peer, u64 index, + struct sha256 *rhash); +void peer_get_revocation_preimage(const struct peer *peer, u64 index, + struct sha256 *preimage); + void secrets_init(struct lightningd_state *state); #endif /* LIGHTNING_DAEMON_SECRETS_H */