From 63d5c7fc1f08b2e10e27e424c8d8e4df7dd8dee1 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 17 Jul 2019 10:08:24 +0930 Subject: [PATCH] devtools/onion: allow setting the hop_data. This is also required for actually creating usable onions. For the moment, due to API limitations, we only let them set realm 0. Note that the privkey parsing was broken, requiring an additional two hex digits, overflowing the buffer, and were ignored. Signed-off-by: Rusty Russell --- devtools/onion.c | 60 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/devtools/onion.c b/devtools/onion.c index 0511d4b0d..b1c5ae5ea 100644 --- a/devtools/onion.c +++ b/devtools/onion.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -25,23 +26,56 @@ static void do_generate(int argc, char **argv, memset(&sessionkey, 'A', sizeof(sessionkey)); for (int i = 0; i < num_hops; i++) { - if (!hex_decode(argv[1 + i], 66, privkeys[i], 33)) { + size_t klen = strcspn(argv[1 + i], "/"); + if (!hex_decode(argv[1 + i], klen, privkeys[i], 32)) errx(1, "Invalid private key hex '%s'", argv[1 + i]); - } + if (secp256k1_ec_pubkey_create(secp256k1_ctx, &path[i].pubkey, privkeys[i]) != 1) errx(1, "Could not decode pubkey"); - fprintf(stderr, "Node %d pubkey %s\n", i, secp256k1_pubkey_to_hexstr(ctx, &path[i].pubkey)); - } - - for (int i = 0; i < num_hops; i++) { + printf("# Node %d pubkey %s\n", + i, secp256k1_pubkey_to_hexstr(ctx, &path[i].pubkey)); memset(&hops_data[i], 0, sizeof(hops_data[i])); - hops_data[i].realm = i; - memset(&hops_data[i].channel_id, i, - sizeof(hops_data[i].channel_id)); - hops_data[i].amt_forward.millisatoshis = i; /* Raw: test code */ - hops_data[i].outgoing_cltv = i; - fprintf(stderr, "Hopdata %d: %s\n", i, tal_hexstr(NULL, &hops_data[i], sizeof(hops_data[i]))); + if (argv[1 + i][klen] != '\0') { + /* FIXME: Generic realm support, not this hack! */ + /* FIXME: Multi hop! */ + const char *hopstr = argv[1 + i] + klen + 1; + size_t dsize = hex_data_size(strlen(hopstr)); + be64 scid, msat; + be32 cltv; + u8 padding[12]; + if (dsize != 33) + errx(1, "hopdata expected 33 bytes"); + if (!hex_decode(hopstr, 2, + &hops_data[i].realm, + sizeof(hops_data[i].realm)) + || !hex_decode(hopstr + 2, 16, + &scid, sizeof(scid)) + || !hex_decode(hopstr + 2 + 16, 16, + &msat, sizeof(msat)) + || !hex_decode(hopstr + 2 + 16 + 16, 8, + &cltv, sizeof(cltv)) + || !hex_decode(hopstr + 2 + 16 + 16 + 8, 24, + padding, sizeof(padding))) + errx(1, "hopdata bad hex"); + if (hops_data[i].realm != 0) + errx(1, "FIXME: Only realm 0 supported"); + if (!memeqzero(padding, sizeof(padding))) + errx(1, "FIXME: Only zero padding supported"); + /* Fix endian up */ + hops_data[i].channel_id.u64 + = be64_to_cpu(scid); + hops_data[i].amt_forward.millisatoshis /* Raw: test code */ + = be64_to_cpu(msat); + hops_data[i].outgoing_cltv + = be32_to_cpu(cltv); + } else { + hops_data[i].realm = i; + memset(&hops_data[i].channel_id, i, + sizeof(hops_data[i].channel_id)); + hops_data[i].amt_forward.millisatoshis = i; /* Raw: test code */ + hops_data[i].outgoing_cltv = i; + } } struct onionpacket *res = @@ -130,7 +164,7 @@ int main(int argc, char **argv) SECP256K1_CONTEXT_SIGN); opt_register_noarg("--help|-h", opt_usage_and_exit, - "--generate ... OR\n" + "--generate [/hopdata] [/hopdata]... OR\n" "--decode \n" "Either create an onion message, or decode one step", "Print this message.");