mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-03 20:44:54 +01:00
33bfc2326a
We need to derive this from the fd when they connect in, but we already know it if we're connecting out. We want this so we can tell (in next few patches) master the peer's address. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
226 lines
8.4 KiB
C
226 lines
8.4 KiB
C
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <netinet/tcp.h>
|
|
#include <unistd.h>
|
|
#include <ccan/err/err.h>
|
|
#include <ccan/io/io.h>
|
|
#include <ccan/structeq/structeq.h>
|
|
#include <common/status.h>
|
|
|
|
/* AUTOGENERATED MOCKS START */
|
|
/* AUTOGENERATED MOCKS END */
|
|
|
|
/* No randomness please, we want to replicate test vectors. */
|
|
#include <sodium/randombytes.h>
|
|
|
|
static void seed_randomness(u8 *secret, size_t len);
|
|
#define randombytes_buf(secret, len) seed_randomness((secret), (len))
|
|
|
|
struct handshake;
|
|
static struct io_plan *test_write(struct io_conn *conn,
|
|
const void *data, size_t len,
|
|
struct io_plan *(*next)(struct io_conn *,
|
|
struct handshake *),
|
|
struct handshake *h);
|
|
|
|
static struct io_plan *test_read(struct io_conn *conn,
|
|
void *data, size_t len,
|
|
struct io_plan *(*next)(struct io_conn *,
|
|
struct handshake *),
|
|
struct handshake *h);
|
|
|
|
#define SUPERVERBOSE status_trace
|
|
void status_trace(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
vprintf(fmt, ap);
|
|
printf("\n");
|
|
va_end(ap);
|
|
}
|
|
|
|
#undef io_write
|
|
#undef io_read
|
|
|
|
#define io_write(conn, data, len, cb, cb_arg) \
|
|
test_write((conn), (data), (len), (cb), (cb_arg))
|
|
|
|
#define io_read(conn, data, len, cb, cb_arg) \
|
|
test_read((conn), (data), (len), (cb), (cb_arg))
|
|
|
|
#include "../handshake.c"
|
|
#include <common/utils.h>
|
|
#include <ccan/array_size/array_size.h>
|
|
#include <ccan/str/hex/hex.h>
|
|
|
|
static struct pubkey pubkey(const char *str)
|
|
{
|
|
struct pubkey p;
|
|
if (!pubkey_from_hexstr(str, strlen(str), &p))
|
|
abort();
|
|
return p;
|
|
}
|
|
|
|
static struct privkey privkey(const char *str)
|
|
{
|
|
struct privkey p;
|
|
if (!hex_decode(str, strlen(str), &p, sizeof(p)))
|
|
abort();
|
|
return p;
|
|
}
|
|
|
|
static bool secret_eq(const struct secret *s, const char *str)
|
|
{
|
|
struct secret expect;
|
|
if (!hex_decode(str, strlen(str), &expect, sizeof(expect)))
|
|
abort();
|
|
return structeq(s, &expect);
|
|
}
|
|
|
|
secp256k1_context *secp256k1_ctx;
|
|
const void *trc;
|
|
static struct pubkey ls_pub, e_pub;
|
|
static struct privkey ls_priv, e_priv;
|
|
|
|
static void seed_randomness(u8 *secret, size_t len)
|
|
{
|
|
assert(len == sizeof(e_priv));
|
|
memcpy(secret, &e_priv, len);
|
|
}
|
|
|
|
/* BOLT #8:
|
|
* # Act One
|
|
* input: 0x00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a
|
|
* # re=0x036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f7
|
|
* # h=0x9e0e7de8bb75554f21db034633de04be41a2b8a18da7a319a03c803bf02b396c
|
|
* # ss=0x1e2fb3c8fe8fb9f262f649f64d26ecf0f2c0a805a767cf02dc2d77a6ef1fdcc3
|
|
* # HKDF(0x2640f52eebcd9e882958951c794250eedb28002c05d7dc2ea0f195406042caf1,0x1e2fb3c8fe8fb9f262f649f64d26ecf0f2c0a805a767cf02dc2d77a6ef1fdcc3)
|
|
* # ck,temp_k1=0xb61ec1191326fa240decc9564369dbb3ae2b34341d1e11ad64ed89f89180582f,0xe68f69b7f096d7917245f5e5cf8ae1595febe4d4644333c99f9c4a1282031c9f
|
|
* # decryptWithAD(0xe68f69b7f096d7917245f5e5cf8ae1595febe4d4644333c99f9c4a1282031c9f, 0x000000000000000000000000, 0x9e0e7de8bb75554f21db034633de04be41a2b8a18da7a319a03c803bf02b396c, 0x0df6086551151f58b8afe6c195782c6a)
|
|
* # h=0x9d1ffbb639e7e20021d9259491dc7b160aab270fb1339ef135053f6f2cebe9ce
|
|
* # Act Two
|
|
* # e.pub=0x02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27 e.priv=0x2222222222222222222222222222222222222222222222222222222222222222
|
|
* # h=0x38122f669819f906000621a14071802f93f2ef97df100097bcac3ae76c6dc0bf
|
|
* # ss=0xc06363d6cc549bcb7913dbb9ac1c33fc1158680c89e972000ecd06b36c472e47
|
|
* # HKDF(0xb61ec1191326fa240decc9564369dbb3ae2b34341d1e11ad64ed89f89180582f,0xc06363d6cc549bcb7913dbb9ac1c33fc1158680c89e972000ecd06b36c472e47)
|
|
* # ck,temp_k2=0xe89d31033a1b6bf68c07d22e08ea4d7884646c4b60a9528598ccb4ee2c8f56ba,0x908b166535c01a935cf1e130a5fe895ab4e6f3ef8855d87e9b7581c4ab663ddc
|
|
* # encryptWithAD(0x908b166535c01a935cf1e130a5fe895ab4e6f3ef8855d87e9b7581c4ab663ddc, 0x000000000000000000000000, 0x38122f669819f906000621a14071802f93f2ef97df100097bcac3ae76c6dc0bf, <empty>)
|
|
* # c=0x6e2470b93aac583c9ef6eafca3f730ae
|
|
* # h=0x90578e247e98674e661013da3c5c1ca6a8c8f48c90b485c0dfa1494e23d56d72
|
|
* output: 0x0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae
|
|
* # Act Three
|
|
* input: 0x00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba
|
|
* # decryptWithAD(0x908b166535c01a935cf1e130a5fe895ab4e6f3ef8855d87e9b7581c4ab663ddc, 0x000000000100000000000000, 0x90578e247e98674e661013da3c5c1ca6a8c8f48c90b485c0dfa1494e23d56d72, 0xb9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c3822)
|
|
* # rs=0x034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa
|
|
* # h=0x5dcb5ea9b4ccc755e0e3456af3990641276e1d5dc9afd82f974d90a47c918660
|
|
* # ss=0xb36b6d195982c5be874d6d542dc268234379e1ae4ff1709402135b7de5cf0766
|
|
* # HKDF(0xe89d31033a1b6bf68c07d22e08ea4d7884646c4b60a9528598ccb4ee2c8f56ba,0xb36b6d195982c5be874d6d542dc268234379e1ae4ff1709402135b7de5cf0766)
|
|
* # ck,temp_k3=0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01,0x981a46c820fb7a241bc8184ba4bb1f01bcdfafb00dde80098cb8c38db9141520
|
|
* # decryptWithAD(0x981a46c820fb7a241bc8184ba4bb1f01bcdfafb00dde80098cb8c38db9141520, 0x000000000000000000000000, 0x5dcb5ea9b4ccc755e0e3456af3990641276e1d5dc9afd82f974d90a47c918660, 0x8dc68b1c466263b47fdf31e560e139ba)
|
|
* # HKDF(0x919219dbb2920afa8db80f9a51787a840bcf111ed8d588caf9ab4be716e42b01,zero)
|
|
* output: rk,sk=0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9,0xbb9020b8965f4df047e07f955f3c4b88418984aadc5cdb35096b9ea8fa5c3442
|
|
*/
|
|
|
|
/* Here's what we expect: */
|
|
static const char *expect_output[] = {
|
|
"0002466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f276e2470b93aac583c9ef6eafca3f730ae"
|
|
};
|
|
|
|
static const char *expect_input[] = {
|
|
"00036360e856310ce5d294e8be33fc807077dc56ac80d95d9cd4ddbd21325eff73f70df6086551151f58b8afe6c195782c6a",
|
|
"00b9e3a702e93e3a9948c2ed6e5fd7590a6e1c3a0344cfc9d5b57357049aa22355361aa02e55a8fc28fef5bd6d71ad0c38228dc68b1c466263b47fdf31e560e139ba"
|
|
};
|
|
|
|
static const char expect_sk[] =
|
|
"bb9020b8965f4df047e07f955f3c4b88418984aadc5cdb35096b9ea8fa5c3442";
|
|
static const char expect_rk[] =
|
|
"969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9";
|
|
|
|
static struct io_plan *test_write(struct io_conn *conn,
|
|
const void *data, size_t len,
|
|
struct io_plan *(*next)(struct io_conn *,
|
|
struct handshake *),
|
|
struct handshake *h)
|
|
{
|
|
static int upto;
|
|
char *got;
|
|
|
|
assert(upto < ARRAY_SIZE(expect_output));
|
|
got = tal_hexstr(NULL, data, len);
|
|
assert(streq(expect_output[upto], got));
|
|
tal_free(got);
|
|
upto++;
|
|
|
|
return next(conn, h);
|
|
}
|
|
|
|
static struct io_plan *test_read(struct io_conn *conn,
|
|
void *data, size_t len,
|
|
struct io_plan *(*next)(struct io_conn *,
|
|
struct handshake *),
|
|
struct handshake *h)
|
|
{
|
|
static int upto;
|
|
|
|
assert(upto < ARRAY_SIZE(expect_input));
|
|
if (!hex_decode(expect_input[upto], strlen(expect_input[upto]),
|
|
data, len))
|
|
abort();
|
|
upto++;
|
|
|
|
return next(conn, h);
|
|
}
|
|
|
|
static struct io_plan *success(struct io_conn *conn,
|
|
const struct pubkey *them,
|
|
const struct ipaddr *addr,
|
|
const struct crypto_state *cs,
|
|
void *ctx)
|
|
{
|
|
assert(secret_eq(&cs->sk, expect_sk));
|
|
assert(secret_eq(&cs->rk, expect_rk));
|
|
|
|
/* No memory leaks please */
|
|
secp256k1_context_destroy(secp256k1_ctx);
|
|
tal_free(ctx);
|
|
exit(0);
|
|
}
|
|
|
|
bool hsm_do_ecdh(struct secret *ss, const struct pubkey *point)
|
|
{
|
|
return secp256k1_ecdh(secp256k1_ctx, ss->data, &point->pubkey,
|
|
ls_priv.secret.data) == 1;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
tal_t *ctx = tal_tmpctx(NULL);
|
|
struct ipaddr dummy;
|
|
|
|
trc = tal_tmpctx(ctx);
|
|
|
|
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
|
|
| SECP256K1_CONTEXT_SIGN);
|
|
|
|
|
|
/* BOLT #8:
|
|
*
|
|
* name: transport-responder successful handshake
|
|
* ls.priv=2121212121212121212121212121212121212121212121212121212121212121
|
|
* ls.pub=028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7
|
|
* e.priv=0x2222222222222222222222222222222222222222222222222222222222222222
|
|
* e.pub=0x02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27
|
|
*/
|
|
ls_priv = privkey("2121212121212121212121212121212121212121212121212121212121212121");
|
|
ls_pub = pubkey("028d7500dd4c12685d1f568b4c2b5048e8534b873319f3a8daa612b469132ec7f7");
|
|
e_priv = privkey("2222222222222222222222222222222222222222222222222222222222222222");
|
|
e_pub = pubkey("02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27");
|
|
|
|
responder_handshake(ctx, &ls_pub, &dummy, success, ctx);
|
|
/* Should not exit! */
|
|
abort();
|
|
}
|