Browse Source

common/sphinx: make onionpacket.routinginfo a dynamic member.

Still asserts that it's the standard size, but makes it a dynamic
member.  For simpliciy, changes the parse_onionpacket API (it must be
a tal object now, so we might as well allocate it here to catch all
the callers).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
fix-mocks
Rusty Russell 4 years ago
committed by Christian Decker
parent
commit
32c7c133f4
  1. 10
      channeld/channeld.c
  2. 95
      common/sphinx.c
  3. 26
      common/sphinx.h
  4. 3
      common/test/run-sphinx-xor_cipher_stream.c
  5. 10
      devtools/blindedpath.c
  6. 14
      devtools/onion.c
  7. 2
      lightningd/onion_message.c
  8. 12
      lightningd/pay.c
  9. 26
      lightningd/peer_htlcs.c
  10. 2
      wallet/db_postgres_sqlgen.c
  11. 2
      wallet/db_sqlite3_sqlgen.c
  12. 4
      wallet/statements_gettextgen.po
  13. 7
      wallet/test/run-wallet.c

10
channeld/channeld.c

@ -1809,7 +1809,7 @@ static bool channeld_handle_custommsg(const u8 *msg)
static void handle_onion_message(struct peer *peer, const u8 *msg) static void handle_onion_message(struct peer *peer, const u8 *msg)
{ {
enum onion_wire badreason; enum onion_wire badreason;
struct onionpacket op; struct onionpacket *op;
struct secret ss, *blinding_ss; struct secret ss, *blinding_ss;
struct pubkey *blinding_in; struct pubkey *blinding_in;
struct route_step *rs; struct route_step *rs;
@ -1825,7 +1825,7 @@ static void handle_onion_message(struct peer *peer, const u8 *msg)
"Bad onion_message %s", tal_hex(peer, msg)); "Bad onion_message %s", tal_hex(peer, msg));
/* We unwrap the onion now. */ /* We unwrap the onion now. */
badreason = parse_onionpacket(onion, TOTAL_PACKET_SIZE(ROUTING_INFO_SIZE), &op); op = parse_onionpacket(tmpctx, onion, TOTAL_PACKET_SIZE(ROUTING_INFO_SIZE), &badreason);
if (badreason != 0) { if (badreason != 0) {
status_debug("onion msg: can't parse onionpacket: %s", status_debug("onion msg: can't parse onionpacket: %s",
onion_wire_name(badreason)); onion_wire_name(badreason));
@ -1849,7 +1849,7 @@ static void handle_onion_message(struct peer *peer, const u8 *msg)
* our normal privkey: since hsmd knows only how to ECDH with * our normal privkey: since hsmd knows only how to ECDH with
* our real key */ * our real key */
if (secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx, if (secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx,
&op.ephemeralkey.pubkey, &op->ephemeralkey.pubkey,
hmac.data) != 1) { hmac.data) != 1) {
status_debug("onion msg: can't tweak pubkey"); status_debug("onion msg: can't tweak pubkey");
return; return;
@ -1859,11 +1859,11 @@ static void handle_onion_message(struct peer *peer, const u8 *msg)
blinding_in = NULL; blinding_in = NULL;
} }
ecdh(&op.ephemeralkey, &ss); ecdh(&op->ephemeralkey, &ss);
/* We make sure we can parse onion packet, so we know if shared secret /* We make sure we can parse onion packet, so we know if shared secret
* is actually valid (this checks hmac). */ * is actually valid (this checks hmac). */
rs = process_onionpacket(tmpctx, &op, &ss, NULL, 0, false); rs = process_onionpacket(tmpctx, op, &ss, NULL, 0, false);
if (!rs) { if (!rs) {
status_debug("onion msg: can't process onionpacket ss=%s", status_debug("onion msg: can't process onionpacket ss=%s",
type_to_string(tmpctx, struct secret, &ss)); type_to_string(tmpctx, struct secret, &ss));

95
common/sphinx.c

@ -20,7 +20,6 @@
#define BLINDING_FACTOR_SIZE 32 #define BLINDING_FACTOR_SIZE 32
#define NUM_STREAM_BYTES (2*ROUTING_INFO_SIZE)
#define ONION_REPLY_SIZE 256 #define ONION_REPLY_SIZE 256
#define RHO_KEYTYPE "rho" #define RHO_KEYTYPE "rho"
@ -131,7 +130,7 @@ u8 *serialize_onionpacket(
const tal_t *ctx, const tal_t *ctx,
const struct onionpacket *m) const struct onionpacket *m)
{ {
u8 *dst = tal_arr(ctx, u8, TOTAL_PACKET_SIZE(ROUTING_INFO_SIZE)); u8 *dst = tal_arr(ctx, u8, TOTAL_PACKET_SIZE(tal_bytelen(m->routinginfo)));
u8 der[PUBKEY_CMPR_LEN]; u8 der[PUBKEY_CMPR_LEN];
int p = 0; int p = 0;
@ -139,35 +138,48 @@ u8 *serialize_onionpacket(
pubkey_to_der(der, &m->ephemeralkey); pubkey_to_der(der, &m->ephemeralkey);
write_buffer(dst, &m->version, 1, &p); write_buffer(dst, &m->version, 1, &p);
write_buffer(dst, der, sizeof(der), &p); write_buffer(dst, der, sizeof(der), &p);
write_buffer(dst, m->routinginfo, ROUTING_INFO_SIZE, &p); write_buffer(dst, m->routinginfo, tal_bytelen(m->routinginfo), &p);
write_buffer(dst, m->hmac.bytes, sizeof(m->hmac.bytes), &p); write_buffer(dst, m->hmac.bytes, sizeof(m->hmac.bytes), &p);
return dst; return dst;
} }
enum onion_wire parse_onionpacket(const u8 *src, struct onionpacket *parse_onionpacket(const tal_t *ctx,
const size_t srclen, const u8 *src,
struct onionpacket *dest) const size_t srclen,
enum onion_wire *failcode)
{ {
struct onionpacket *dest = tal(ctx, struct onionpacket);
const u8 *cursor = src; const u8 *cursor = src;
size_t max = srclen; size_t max = srclen;
/* FIXME: Allow parsing other sizes! */
assert(srclen == TOTAL_PACKET_SIZE(ROUTING_INFO_SIZE)); assert(srclen == TOTAL_PACKET_SIZE(ROUTING_INFO_SIZE));
dest->version = fromwire_u8(&cursor, &max); dest->version = fromwire_u8(&cursor, &max);
if (dest->version != 0x00) { if (dest->version != 0x00) {
// FIXME add logging // FIXME add logging
return WIRE_INVALID_ONION_VERSION; *failcode = WIRE_INVALID_ONION_VERSION;
return tal_free(dest);
} }
fromwire_pubkey(&cursor, &max, &dest->ephemeralkey); fromwire_pubkey(&cursor, &max, &dest->ephemeralkey);
if (cursor == NULL) { if (cursor == NULL) {
return WIRE_INVALID_ONION_KEY; *failcode = WIRE_INVALID_ONION_KEY;
return tal_free(dest);
} }
fromwire_u8_array(&cursor, &max, dest->routinginfo, ROUTING_INFO_SIZE); /* If max underflows, this returns NULL and fromwire fails. */
dest->routinginfo = fromwire_tal_arrn(dest, &cursor, &max,
max - HMAC_SIZE);
fromwire_hmac(&cursor, &max, &dest->hmac); fromwire_hmac(&cursor, &max, &dest->hmac);
assert(max == 0); assert(max == 0);
return 0; if (cursor == NULL) {
*failcode = WIRE_INVALID_REALM;
return tal_free(dest);
}
return dest;
} }
/* /*
@ -248,12 +260,13 @@ static void compute_packet_hmac(const struct onionpacket *packet,
struct hmac *hmac) struct hmac *hmac)
{ {
compute_hmac(mukey, compute_hmac(mukey,
packet->routinginfo, ROUTING_INFO_SIZE, packet->routinginfo, tal_bytelen(packet->routinginfo),
assocdata, assocdatalen, assocdata, assocdatalen,
hmac); hmac);
} }
static void generate_header_padding(void *dst, size_t dstlen, static void generate_header_padding(void *dst, size_t dstlen,
size_t fixed_size,
const struct sphinx_path *path, const struct sphinx_path *path,
struct hop_params *params) struct hop_params *params)
{ {
@ -269,12 +282,12 @@ static void generate_header_padding(void *dst, size_t dstlen,
fillerSize = 0; fillerSize = 0;
for (int j = 0; j < i; j++) for (int j = 0; j < i; j++)
fillerSize += sphinx_hop_size(&path->hops[j]); fillerSize += sphinx_hop_size(&path->hops[j]);
fillerStart = ROUTING_INFO_SIZE - fillerSize; fillerStart = fixed_size - fillerSize;
/* The filler will dangle off of the end by the current /* The filler will dangle off of the end by the current
* hop-size, we'll make sure to copy it into the correct * hop-size, we'll make sure to copy it into the correct
* position in the next step. */ * position in the next step. */
fillerEnd = ROUTING_INFO_SIZE + sphinx_hop_size(&path->hops[i]); fillerEnd = fixed_size + sphinx_hop_size(&path->hops[i]);
/* Apply the cipher-stream to the part of the filler that'll /* Apply the cipher-stream to the part of the filler that'll
* be added by this hop */ * be added by this hop */
@ -284,6 +297,7 @@ static void generate_header_padding(void *dst, size_t dstlen,
} }
static void generate_prefill(void *dst, size_t dstlen, static void generate_prefill(void *dst, size_t dstlen,
size_t fixed_size,
const struct sphinx_path *path, const struct sphinx_path *path,
struct hop_params *params) struct hop_params *params)
{ {
@ -299,7 +313,7 @@ static void generate_prefill(void *dst, size_t dstlen,
fillerSize = 0; fillerSize = 0;
for (int j = 0; j < i; j++) for (int j = 0; j < i; j++)
fillerSize += sphinx_hop_size(&path->hops[j]); fillerSize += sphinx_hop_size(&path->hops[j]);
fillerStart = ROUTING_INFO_SIZE - fillerSize - dstlen; fillerStart = fixed_size - fillerSize - dstlen;
/* Apply the cipher-stream to the part of the filler that'll /* Apply the cipher-stream to the part of the filler that'll
* be added by this hop */ * be added by this hop */
@ -444,21 +458,23 @@ static void sphinx_prefill_stream_xor(u8 *dst, size_t dstlen,
} }
static void sphinx_prefill(u8 *routinginfo, const struct sphinx_path *sp, static void sphinx_prefill(u8 *routinginfo, const struct sphinx_path *sp,
size_t prefill_size, struct hop_params *params) size_t prefill_size, struct hop_params *params,
size_t fixed_size)
{ {
int num_hops = tal_count(sp->hops); int num_hops = tal_count(sp->hops);
size_t fillerSize = sphinx_path_payloads_size(sp) - size_t fillerSize = sphinx_path_payloads_size(sp) -
sphinx_hop_size(&sp->hops[num_hops - 1]); sphinx_hop_size(&sp->hops[num_hops - 1]);
size_t last_hop_size = sphinx_hop_size(&sp->hops[num_hops - 1]); size_t last_hop_size = sphinx_hop_size(&sp->hops[num_hops - 1]);
int prefill_offset = int prefill_offset =
ROUTING_INFO_SIZE - fillerSize - last_hop_size - prefill_size; fixed_size - fillerSize - last_hop_size - prefill_size;
struct secret shared_secret; struct secret shared_secret;
/* Generate the prefill stream, which cancels out the layers of /* Generate the prefill stream, which cancels out the layers of
* encryption that will be applied while wrapping the onion. This * encryption that will be applied while wrapping the onion. This
* leaves the middle, unused, section with all 0x00 bytes after * leaves the middle, unused, section with all 0x00 bytes after
* encrypting. */ * encrypting. */
generate_prefill(routinginfo + prefill_offset, prefill_size, sp, params); generate_prefill(routinginfo + prefill_offset, prefill_size,
fixed_size, sp, params);
/* Now fill in the obfuscation stream, which can be regenerated by the /* Now fill in the obfuscation stream, which can be regenerated by the
* node processing this onion. */ * node processing this onion. */
@ -469,6 +485,7 @@ static void sphinx_prefill(u8 *routinginfo, const struct sphinx_path *sp,
struct onionpacket *create_onionpacket( struct onionpacket *create_onionpacket(
const tal_t *ctx, const tal_t *ctx,
struct sphinx_path *sp, struct sphinx_path *sp,
size_t fixed_size,
struct secret **path_secrets struct secret **path_secrets
) )
{ {
@ -476,20 +493,21 @@ struct onionpacket *create_onionpacket(
int i, num_hops = tal_count(sp->hops); int i, num_hops = tal_count(sp->hops);
size_t fillerSize = sphinx_path_payloads_size(sp) - size_t fillerSize = sphinx_path_payloads_size(sp) -
sphinx_hop_size(&sp->hops[num_hops - 1]); sphinx_hop_size(&sp->hops[num_hops - 1]);
u8 filler[fillerSize]; u8 *filler;
struct keyset keys; struct keyset keys;
struct secret padkey; struct secret padkey;
struct hmac nexthmac; struct hmac nexthmac;
struct hop_params *params; struct hop_params *params;
struct secret *secrets = tal_arr(ctx, struct secret, num_hops); struct secret *secrets = tal_arr(ctx, struct secret, num_hops);
size_t payloads_size = sphinx_path_payloads_size(sp); size_t payloads_size = sphinx_path_payloads_size(sp);
size_t max_prefill = ROUTING_INFO_SIZE - payloads_size; size_t max_prefill = fixed_size - payloads_size;
if (sphinx_path_payloads_size(sp) > ROUTING_INFO_SIZE) { if (sphinx_path_payloads_size(sp) > fixed_size) {
tal_free(packet); tal_free(packet);
tal_free(secrets); tal_free(secrets);
return NULL; return NULL;
} }
packet->routinginfo = tal_arr(packet, u8, fixed_size);
if (sp->session_key == NULL) { if (sp->session_key == NULL) {
sp->session_key = tal(sp, struct secret); sp->session_key = tal(sp, struct secret);
@ -513,14 +531,16 @@ struct onionpacket *create_onionpacket(
/* Note that this is just hop_payloads: the rest of the packet is /* Note that this is just hop_payloads: the rest of the packet is
* overwritten below or above anyway. */ * overwritten below or above anyway. */
subkey_from_hmac("pad", sp->session_key, &padkey); subkey_from_hmac("pad", sp->session_key, &padkey);
generate_cipher_stream(packet->routinginfo, &padkey, ROUTING_INFO_SIZE); generate_cipher_stream(packet->routinginfo, &padkey, fixed_size);
generate_header_padding(filler, sizeof(filler), sp, params); filler = tal_arr(tmpctx, u8, fillerSize);
generate_header_padding(filler, tal_bytelen(filler), fixed_size, sp, params);
if (sp->rendezvous_id != NULL) if (sp->rendezvous_id != NULL)
/* FIXME: Fuzz this or expose to the caller to hide encoded /* FIXME: Fuzz this or expose to the caller to hide encoded
* route length. */ * route length. */
sphinx_prefill(packet->routinginfo, sp, max_prefill, params); sphinx_prefill(packet->routinginfo, sp, max_prefill, params,
fixed_size);
for (i = num_hops - 1; i >= 0; i--) { for (i = num_hops - 1; i >= 0; i--) {
sp->hops[i].hmac = nexthmac; sp->hops[i].hmac = nexthmac;
@ -529,13 +549,13 @@ struct onionpacket *create_onionpacket(
/* Rightshift mix-header by FRAME_SIZE */ /* Rightshift mix-header by FRAME_SIZE */
size_t shiftSize = sphinx_hop_size(&sp->hops[i]); size_t shiftSize = sphinx_hop_size(&sp->hops[i]);
memmove(packet->routinginfo + shiftSize, packet->routinginfo, memmove(packet->routinginfo + shiftSize, packet->routinginfo,
ROUTING_INFO_SIZE-shiftSize); fixed_size - shiftSize);
sphinx_write_frame(packet->routinginfo, &sp->hops[i]); sphinx_write_frame(packet->routinginfo, &sp->hops[i]);
xor_cipher_stream(packet->routinginfo, &keys.rho, xor_cipher_stream(packet->routinginfo, &keys.rho,
ROUTING_INFO_SIZE); fixed_size);
if (i == num_hops - 1) { if (i == num_hops - 1) {
memcpy(packet->routinginfo + ROUTING_INFO_SIZE - fillerSize, filler, fillerSize); memcpy(packet->routinginfo + fixed_size - fillerSize, filler, fillerSize);
} }
compute_packet_hmac(packet, sp->associated_data, tal_bytelen(sp->associated_data), &keys.mu, compute_packet_hmac(packet, sp->associated_data, tal_bytelen(sp->associated_data), &keys.mu,
@ -573,7 +593,7 @@ struct route_step *process_onionpacket(
struct hmac hmac; struct hmac hmac;
struct keyset keys; struct keyset keys;
u8 blind[BLINDING_FACTOR_SIZE]; u8 blind[BLINDING_FACTOR_SIZE];
u8 paddedheader[2*ROUTING_INFO_SIZE]; u8 *paddedheader;
size_t payload_size; size_t payload_size;
bigsize_t shift_size; bigsize_t shift_size;
bool valid; bool valid;
@ -591,15 +611,17 @@ struct route_step *process_onionpacket(
} }
//FIXME:store seen secrets to avoid replay attacks //FIXME:store seen secrets to avoid replay attacks
memset(paddedheader, 0, sizeof(paddedheader)); paddedheader = tal_arrz(step, u8, tal_bytelen(msg->routinginfo)*2);
memcpy(paddedheader, msg->routinginfo, ROUTING_INFO_SIZE); memcpy(paddedheader, msg->routinginfo, tal_bytelen(msg->routinginfo));
xor_cipher_stream(paddedheader, &keys.rho, sizeof(paddedheader)); xor_cipher_stream(paddedheader, &keys.rho, tal_bytelen(paddedheader));
compute_blinding_factor(&msg->ephemeralkey, shared_secret, blind); compute_blinding_factor(&msg->ephemeralkey, shared_secret, blind);
if (!blind_group_element(&step->next->ephemeralkey, &msg->ephemeralkey, blind)) if (!blind_group_element(&step->next->ephemeralkey, &msg->ephemeralkey, blind))
return tal_free(step); return tal_free(step);
payload_size = onion_payload_length(paddedheader, ROUTING_INFO_SIZE, has_realm, payload_size = onion_payload_length(paddedheader,
tal_bytelen(msg->routinginfo),
has_realm,
&valid, NULL); &valid, NULL);
/* Can't decode? Treat it as terminal. */ /* Can't decode? Treat it as terminal. */
@ -607,7 +629,7 @@ struct route_step *process_onionpacket(
shift_size = payload_size; shift_size = payload_size;
memset(step->next->hmac.bytes, 0, sizeof(step->next->hmac.bytes)); memset(step->next->hmac.bytes, 0, sizeof(step->next->hmac.bytes));
} else { } else {
assert(payload_size <= ROUTING_INFO_SIZE - HMAC_SIZE); assert(payload_size <= tal_bytelen(msg->routinginfo) - HMAC_SIZE);
/* Copy hmac */ /* Copy hmac */
shift_size = payload_size + HMAC_SIZE; shift_size = payload_size + HMAC_SIZE;
memcpy(step->next->hmac.bytes, memcpy(step->next->hmac.bytes,
@ -616,8 +638,10 @@ struct route_step *process_onionpacket(
step->raw_payload = tal_dup_arr(step, u8, paddedheader, payload_size, 0); step->raw_payload = tal_dup_arr(step, u8, paddedheader, payload_size, 0);
/* Left shift the current payload out and make the remainder the new onion */ /* Left shift the current payload out and make the remainder the new onion */
memcpy(&step->next->routinginfo, paddedheader + shift_size, step->next->routinginfo = tal_dup_arr(step->next,
ROUTING_INFO_SIZE); u8,
paddedheader + shift_size,
tal_bytelen(msg->routinginfo), 0);
if (memeqzero(step->next->hmac.bytes, sizeof(step->next->hmac.bytes))) { if (memeqzero(step->next->hmac.bytes, sizeof(step->next->hmac.bytes))) {
step->nextcase = ONION_END; step->nextcase = ONION_END;
@ -625,6 +649,7 @@ struct route_step *process_onionpacket(
step->nextcase = ONION_FORWARD; step->nextcase = ONION_FORWARD;
} }
tal_free(paddedheader);
return step; return step;
} }
@ -775,7 +800,7 @@ struct onionpacket *sphinx_decompress(const tal_t *ctx,
/* Decompress routinginfo by copying the unmodified prefix, setting /* Decompress routinginfo by copying the unmodified prefix, setting
* the compressed suffix to 0x00 bytes and then xoring the obfuscation * the compressed suffix to 0x00 bytes and then xoring the obfuscation
* stream in place. */ * stream in place. */
memset(res->routinginfo, 0, ROUTING_INFO_SIZE); res->routinginfo = tal_arrz(res, u8, ROUTING_INFO_SIZE);
memcpy(res->routinginfo, src->routinginfo, srclen); memcpy(res->routinginfo, src->routinginfo, srclen);
sphinx_prefill_stream_xor(res->routinginfo + srclen, prefill_size, sphinx_prefill_stream_xor(res->routinginfo + srclen, prefill_size,
shared_secret); shared_secret);

26
common/sphinx.h

@ -28,8 +28,8 @@ struct onionpacket {
struct hmac hmac; struct hmac hmac;
struct pubkey ephemeralkey; struct pubkey ephemeralkey;
/* Encrypted information */ /* Encrypted information (tal arr)*/
u8 routinginfo[ROUTING_INFO_SIZE]; u8 *routinginfo;
}; };
struct sphinx_compressed_onion { struct sphinx_compressed_onion {
@ -99,18 +99,14 @@ struct route_step {
* over a path of intermediate nodes. * over a path of intermediate nodes.
* *
* @ctx: tal context to allocate from * @ctx: tal context to allocate from
* @path: public keys of nodes along the path. * @sphinx_path: path to encode along.
* @hoppayloads: payloads destined for individual hosts (limited to * @fixed_size: the size of the onion packet eg ROUTING_INFO_SIZE (fails if input is larger)
* HOP_PAYLOAD_SIZE bytes) * @secrets: (out) shared secrets generated for the entire path
* @num_hops: path length in nodes
* @sessionkey: 32 byte random session key to derive secrets from
* @assocdata: associated data to commit to in HMACs
* @assocdatalen: length of the assocdata
* @path_secrets: (out) shared secrets generated for the entire path
*/ */
struct onionpacket *create_onionpacket( struct onionpacket *create_onionpacket(
const tal_t * ctx, const tal_t * ctx,
struct sphinx_path *sp, struct sphinx_path *sp,
size_t fixed_size,
struct secret **path_secrets struct secret **path_secrets
); );
@ -160,13 +156,15 @@ u8 *serialize_onionpacket(
/** /**
* parse_onionpacket - Parse an onionpacket from a buffer. * parse_onionpacket - Parse an onionpacket from a buffer.
* *
* @ctx: the context to allocate return value from.
* @src: buffer to read the packet from * @src: buffer to read the packet from
* @srclen: length of the @src (must be TOTAL_PACKET_SIZE) * @srclen: length of the @src (must be TOTAL_PACKET_SIZE)
* @dest: the destination into which we should parse the packet * @failcode: the failure code (set iff this returns NULL)
*/ */
enum onion_wire parse_onionpacket(const u8 *src, struct onionpacket *parse_onionpacket(const tal_t *ctx,
const size_t srclen, const u8 *src,
struct onionpacket *dest); const size_t srclen,
enum onion_wire *failcode);
/** /**
* create_onionreply - Format a failure message so we can return it * create_onionreply - Format a failure message so we can return it

3
common/test/run-sphinx-xor_cipher_stream.c

@ -74,9 +74,6 @@ u64 fromwire_u64(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
/* Generated stub for fromwire_u8 */ /* Generated stub for fromwire_u8 */
u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED) u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
{ fprintf(stderr, "fromwire_u8 called!\n"); abort(); } { fprintf(stderr, "fromwire_u8 called!\n"); abort(); }
/* Generated stub for fromwire_u8_array */
void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED)
{ fprintf(stderr, "fromwire_u8_array called!\n"); abort(); }
/* Generated stub for hmac_done */ /* Generated stub for hmac_done */
void hmac_done(crypto_auth_hmacsha256_state *state UNNEEDED, void hmac_done(crypto_auth_hmacsha256_state *state UNNEEDED,
struct hmac *hmac UNNEEDED) struct hmac *hmac UNNEEDED)

10
devtools/blindedpath.c

@ -206,7 +206,7 @@ int main(int argc, char **argv)
struct privkey privkey; struct privkey privkey;
struct pubkey blinding; struct pubkey blinding;
u8 onion[TOTAL_PACKET_SIZE(ROUTING_INFO_SIZE)], *dec; u8 onion[TOTAL_PACKET_SIZE(ROUTING_INFO_SIZE)], *dec;
struct onionpacket op; struct onionpacket *op;
struct secret ss, onion_ss; struct secret ss, onion_ss;
struct secret hmac, rho; struct secret hmac, rho;
struct route_step *rs; struct route_step *rs;
@ -216,6 +216,7 @@ int main(int argc, char **argv)
struct pubkey res; struct pubkey res;
struct sha256 h; struct sha256 h;
int ret; int ret;
enum onion_wire failcode;
const unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; const unsigned char npub[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
if (argc != 5) if (argc != 5)
@ -232,7 +233,8 @@ int main(int argc, char **argv)
if (!pubkey_from_hexstr(argv[4], strlen(argv[4]), &blinding)) if (!pubkey_from_hexstr(argv[4], strlen(argv[4]), &blinding))
errx(1, "Invalid blinding %s", argv[4]); errx(1, "Invalid blinding %s", argv[4]);
if (parse_onionpacket(onion, sizeof(onion), &op) != 0) op = parse_onionpacket(tmpctx, onion, sizeof(onion), &failcode);
if (!op)
errx(1, "Unparsable onion"); errx(1, "Unparsable onion");
/* ss(r) = H(k(r) * E(r)) */ /* ss(r) = H(k(r) * E(r)) */
@ -249,7 +251,7 @@ int main(int argc, char **argv)
* and use our raw privkey: this models how lightningd * and use our raw privkey: this models how lightningd
* will do it, since hsmd knows only how to ECDH with * will do it, since hsmd knows only how to ECDH with
* our real key */ * our real key */
res = op.ephemeralkey; res = op->ephemeralkey;
if (!first) { if (!first) {
if (secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx, if (secp256k1_ec_pubkey_tweak_mul(secp256k1_ctx,
&res.pubkey, &res.pubkey,
@ -262,7 +264,7 @@ int main(int argc, char **argv)
privkey.secret.data, NULL, NULL) != 1) privkey.secret.data, NULL, NULL) != 1)
abort(); abort();
rs = process_onionpacket(tmpctx, &op, &onion_ss, NULL, 0, false); rs = process_onionpacket(tmpctx, op, &onion_ss, NULL, 0, false);
if (!rs) if (!rs)
errx(1, "Could not process onionpacket"); errx(1, "Could not process onionpacket");

14
devtools/onion.c

@ -102,7 +102,7 @@ static void do_generate(int argc, char **argv,
} }
} }
packet = create_onionpacket(ctx, sp, &shared_secrets); packet = create_onionpacket(ctx, sp, ROUTING_INFO_SIZE, &shared_secrets);
if (rvnode_id != NULL) { if (rvnode_id != NULL) {
comp = sphinx_compress(ctx, packet, sp); comp = sphinx_compress(ctx, packet, sp);
@ -123,21 +123,21 @@ static struct route_step *decode_with_privkey(const tal_t *ctx, const u8 *onion,
{ {
struct privkey seckey; struct privkey seckey;
struct route_step *step; struct route_step *step;
struct onionpacket packet; struct onionpacket *packet;
enum onion_wire why_bad; enum onion_wire why_bad;
struct secret shared_secret; struct secret shared_secret;
if (!hex_decode(hexprivkey, strlen(hexprivkey), &seckey, sizeof(seckey))) if (!hex_decode(hexprivkey, strlen(hexprivkey), &seckey, sizeof(seckey)))
errx(1, "Invalid private key hex '%s'", hexprivkey); errx(1, "Invalid private key hex '%s'", hexprivkey);
why_bad = parse_onionpacket(onion, TOTAL_PACKET_SIZE(ROUTING_INFO_SIZE), &packet); packet = parse_onionpacket(tmpctx, onion, TOTAL_PACKET_SIZE(ROUTING_INFO_SIZE), &why_bad);
if (why_bad != 0) if (!packet)
errx(1, "Error parsing message: %s", onion_wire_name(why_bad)); errx(1, "Error parsing message: %s", onion_wire_name(why_bad));
if (!onion_shared_secret(&shared_secret, &packet, &seckey)) if (!onion_shared_secret(&shared_secret, packet, &seckey))
errx(1, "Error creating shared secret."); errx(1, "Error creating shared secret.");
step = process_onionpacket(ctx, &packet, &shared_secret, assocdata, step = process_onionpacket(ctx, packet, &shared_secret, assocdata,
tal_bytelen(assocdata), true); tal_bytelen(assocdata), true);
return step; return step;
@ -257,7 +257,7 @@ static void runtest(const char *filename)
} }
sphinx_add_hop(path, &pubkey, full); sphinx_add_hop(path, &pubkey, full);
} }
res = create_onionpacket(ctx, path, &shared_secrets); res = create_onionpacket(ctx, path, ROUTING_INFO_SIZE, &shared_secrets);
serialized = serialize_onionpacket(ctx, res); serialized = serialize_onionpacket(ctx, res);
if (!serialized) if (!serialized)

2
lightningd/onion_message.c

@ -447,7 +447,7 @@ static struct command_result *json_send_onion_message(struct command *cmd,
hops[i].rawtlv, tal_bytelen(hops[i].rawtlv)); hops[i].rawtlv, tal_bytelen(hops[i].rawtlv));
sphinx_add_hop(sphinx_path, &hops[i].id, take(tlv_with_len)); sphinx_add_hop(sphinx_path, &hops[i].id, take(tlv_with_len));
} }
op = create_onionpacket(tmpctx, sphinx_path, &path_secrets); op = create_onionpacket(tmpctx, sphinx_path, ROUTING_INFO_SIZE, &path_secrets);
if (!op) if (!op)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Creating onion failed (tlvs too long?)"); "Creating onion failed (tlvs too long?)");

12
lightningd/pay.c

@ -1113,7 +1113,7 @@ send_payment(struct lightningd *ld,
log_info(ld->log, "Sending %s over %zu hops to deliver %s", log_info(ld->log, "Sending %s over %zu hops to deliver %s",
type_to_string(tmpctx, struct amount_msat, &route[0].amount), type_to_string(tmpctx, struct amount_msat, &route[0].amount),
n_hops, type_to_string(tmpctx, struct amount_msat, &msat)); n_hops, type_to_string(tmpctx, struct amount_msat, &msat));
packet = create_onionpacket(tmpctx, path, &path_secrets); packet = create_onionpacket(tmpctx, path, ROUTING_INFO_SIZE, &path_secrets);
return send_payment_core(ld, cmd, rhash, partid, &route[0], return send_payment_core(ld, cmd, rhash, partid, &route[0],
msat, total_msat, label, b11str, msat, total_msat, label, b11str,
packet, &ids[n_hops - 1], ids, packet, &ids[n_hops - 1], ids,
@ -1192,7 +1192,7 @@ static struct command_result *json_sendonion(struct command *cmd,
const jsmntok_t *params) const jsmntok_t *params)
{ {
u8 *onion; u8 *onion;
struct onionpacket packet; struct onionpacket *packet;
enum onion_wire failcode; enum onion_wire failcode;
struct route_hop *first_hop; struct route_hop *first_hop;
struct sha256 *payment_hash; struct sha256 *payment_hash;
@ -1216,9 +1216,9 @@ static struct command_result *json_sendonion(struct command *cmd,
NULL)) NULL))
return command_param_failed(); return command_param_failed();
failcode = parse_onionpacket(onion, tal_bytelen(onion), &packet); packet = parse_onionpacket(cmd, onion, tal_bytelen(onion), &failcode);
if (failcode != 0) if (!packet)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Could not parse the onion. Parsing failed " "Could not parse the onion. Parsing failed "
"with failcode=%d", "with failcode=%d",
@ -1226,7 +1226,7 @@ static struct command_result *json_sendonion(struct command *cmd,
return send_payment_core(ld, cmd, payment_hash, *partid, return send_payment_core(ld, cmd, payment_hash, *partid,
first_hop, *msat, AMOUNT_MSAT(0), first_hop, *msat, AMOUNT_MSAT(0),
label, b11str, &packet, destination, NULL, NULL, label, b11str, packet, destination, NULL, NULL,
path_secrets); path_secrets);
} }
@ -1616,7 +1616,7 @@ static struct command_result *json_createonion(struct command *cmd,
cmd, JSONRPC2_INVALID_PARAMS, cmd, JSONRPC2_INVALID_PARAMS,
"Payloads exceed maximum onion packet size."); "Payloads exceed maximum onion packet size.");
packet = create_onionpacket(cmd, sp, &shared_secrets); packet = create_onionpacket(cmd, sp, ROUTING_INFO_SIZE, &shared_secrets);
if (!packet) if (!packet)
return command_fail(cmd, LIGHTNINGD, return command_fail(cmd, LIGHTNINGD,
"Could not create onion packet"); "Could not create onion packet");

26
lightningd/peer_htlcs.c

@ -1141,7 +1141,7 @@ static bool peer_accepted_htlc(const tal_t *ctx,
{ {
struct htlc_in *hin; struct htlc_in *hin;
struct route_step *rs; struct route_step *rs;
struct onionpacket op; struct onionpacket *op;
struct lightningd *ld = channel->peer->ld; struct lightningd *ld = channel->peer->ld;
struct htlc_accepted_hook_payload *hook_payload; struct htlc_accepted_hook_payload *hook_payload;
@ -1195,10 +1195,10 @@ static bool peer_accepted_htlc(const tal_t *ctx,
* a subset of the cltv check done in handle_localpay and * a subset of the cltv check done in handle_localpay and
* forward_htlc. */ * forward_htlc. */
*badonion = parse_onionpacket(hin->onion_routing_packet, op = parse_onionpacket(tmpctx, hin->onion_routing_packet,
sizeof(hin->onion_routing_packet), sizeof(hin->onion_routing_packet),
&op); badonion);
if (*badonion) { if (!op) {
log_debug(channel->log, log_debug(channel->log,
"Rejecting their htlc %"PRIu64 "Rejecting their htlc %"PRIu64
" since onion is unparsable %s", " since onion is unparsable %s",
@ -1207,7 +1207,7 @@ static bool peer_accepted_htlc(const tal_t *ctx,
goto fail; goto fail;
} }
rs = process_onionpacket(tmpctx, &op, hin->shared_secret, rs = process_onionpacket(tmpctx, op, hin->shared_secret,
hin->payment_hash.u.u8, hin->payment_hash.u.u8,
sizeof(hin->payment_hash), true); sizeof(hin->payment_hash), true);
if (!rs) { if (!rs) {
@ -1793,7 +1793,7 @@ static bool channel_added_their_htlc(struct channel *channel,
struct lightningd *ld = channel->peer->ld; struct lightningd *ld = channel->peer->ld;
struct htlc_in *hin; struct htlc_in *hin;
struct secret shared_secret; struct secret shared_secret;
struct onionpacket op; struct onionpacket *op;
enum onion_wire failcode; enum onion_wire failcode;
/* BOLT #2: /* BOLT #2:
@ -1817,11 +1817,11 @@ static bool channel_added_their_htlc(struct channel *channel,
/* Do the work of extracting shared secret now if possible. */ /* Do the work of extracting shared secret now if possible. */
/* FIXME: We do this *again* in peer_accepted_htlc! */ /* FIXME: We do this *again* in peer_accepted_htlc! */
failcode = parse_onionpacket(added->onion_routing_packet, op = parse_onionpacket(tmpctx, added->onion_routing_packet,
sizeof(added->onion_routing_packet), sizeof(added->onion_routing_packet),
&op); &failcode);
if (!failcode) { if (op) {
if (!ecdh_maybe_blinding(&op.ephemeralkey, if (!ecdh_maybe_blinding(&op->ephemeralkey,
added->blinding, &added->blinding_ss, added->blinding, &added->blinding_ss,
&shared_secret)) { &shared_secret)) {
log_debug(channel->log, "htlc %"PRIu64 log_debug(channel->log, "htlc %"PRIu64
@ -1834,7 +1834,7 @@ static bool channel_added_their_htlc(struct channel *channel,
* part of the current commitment. */ * part of the current commitment. */
hin = new_htlc_in(channel, channel, added->id, added->amount, hin = new_htlc_in(channel, channel, added->id, added->amount,
added->cltv_expiry, &added->payment_hash, added->cltv_expiry, &added->payment_hash,
failcode ? NULL : &shared_secret, op ? &shared_secret : NULL,
added->blinding, &added->blinding_ss, added->blinding, &added->blinding_ss,
added->onion_routing_packet); added->onion_routing_packet);

2
wallet/db_postgres_sqlgen.c

@ -1690,4 +1690,4 @@ struct db_query db_postgres_queries[] = {
#endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */ #endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */
// SHA256STAMP:fac2fa6846e0deadf6f24fc9deb6efb0bac04b5947c254ae39300663366178af // SHA256STAMP:a51ae4928fd56f2b22d0dd8f498f1288e2c3df7be872ddf1240f4b8fded6fd22

2
wallet/db_sqlite3_sqlgen.c

@ -1690,4 +1690,4 @@ struct db_query db_sqlite3_queries[] = {
#endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */ #endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */
// SHA256STAMP:fac2fa6846e0deadf6f24fc9deb6efb0bac04b5947c254ae39300663366178af // SHA256STAMP:a51ae4928fd56f2b22d0dd8f498f1288e2c3df7be872ddf1240f4b8fded6fd22

4
wallet/statements_gettextgen.po

@ -1110,7 +1110,7 @@ msgstr ""
msgid "not a valid SQL statement" msgid "not a valid SQL statement"
msgstr "" msgstr ""
#: wallet/test/run-wallet.c:1376 #: wallet/test/run-wallet.c:1377
msgid "INSERT INTO channels (id) VALUES (1);" msgid "INSERT INTO channels (id) VALUES (1);"
msgstr "" msgstr ""
# SHA256STAMP:8f226711a58166b481aaa7b8c0593c7159711bee623737e3b4750f6c154d4f65 # SHA256STAMP:ebfc7675e32b832d172d040d0120cd339a1e1e924969373f8d7d6b75a7836c5b

7
wallet/test/run-wallet.c

@ -569,9 +569,10 @@ struct command_result *param_tok(struct command *cmd UNNEEDED, const char *name
const jsmntok_t **out UNNEEDED) const jsmntok_t **out UNNEEDED)
{ fprintf(stderr, "param_tok called!\n"); abort(); } { fprintf(stderr, "param_tok called!\n"); abort(); }
/* Generated stub for parse_onionpacket */ /* Generated stub for parse_onionpacket */
enum onion_wire parse_onionpacket(const u8 *src UNNEEDED, struct onionpacket *parse_onionpacket(const tal_t *ctx UNNEEDED,
const size_t srclen UNNEEDED, const u8 *src UNNEEDED,
struct onionpacket *dest UNNEEDED) const size_t srclen UNNEEDED,
enum onion_wire *failcode UNNEEDED)
{ fprintf(stderr, "parse_onionpacket called!\n"); abort(); } { fprintf(stderr, "parse_onionpacket called!\n"); abort(); }
/* Generated stub for payment_failed */ /* Generated stub for payment_failed */
void payment_failed(struct lightningd *ld UNNEEDED, const struct htlc_out *hout UNNEEDED, void payment_failed(struct lightningd *ld UNNEEDED, const struct htlc_out *hout UNNEEDED,

Loading…
Cancel
Save