gossipd: fix blinded onion forwarding.

We never tested that we can correctly unwrap on the next step after
unblinding: it failed because we mangled the onion in place!  Fix that.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2021-09-21 13:35:24 +09:30
parent 6758164904
commit 8b694907e6
2 changed files with 14 additions and 3 deletions

View file

@ -386,7 +386,7 @@ static u8 *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, ephemeral;
struct route_step *rs; struct route_step *rs;
u8 *onion; u8 *onion;
const u8 *cursor; const u8 *cursor;
@ -412,6 +412,7 @@ static u8 *handle_onion_message(struct peer *peer, const u8 *msg)
return NULL; return NULL;
} }
ephemeral = op->ephemeralkey;
if (tlvs->blinding) { if (tlvs->blinding) {
struct secret hmac; struct secret hmac;
@ -430,7 +431,7 @@ static u8 *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, &ephemeral.pubkey,
hmac.data) != 1) { hmac.data) != 1) {
status_debug("peer %s: onion msg: can't tweak pubkey", status_debug("peer %s: onion msg: can't tweak pubkey",
type_to_string(tmpctx, struct node_id, &peer->id)); type_to_string(tmpctx, struct node_id, &peer->id));
@ -441,7 +442,7 @@ static u8 *handle_onion_message(struct peer *peer, const u8 *msg)
blinding_in = NULL; blinding_in = NULL;
} }
ecdh(&op->ephemeralkey, &ss); ecdh(&ephemeral, &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). */

View file

@ -4117,6 +4117,16 @@ def test_offer(node_factory, bitcoind):
assert 'recurrence: every 600 seconds paywindow -10 to +600 (pay proportional)\n' in output assert 'recurrence: every 600 seconds paywindow -10 to +600 (pay proportional)\n' in output
def test_fetchinvoice_3hop(node_factory, bitcoind):
l1, l2, l3, l4 = node_factory.line_graph(4, wait_for_announce=True,
opts={'experimental-offers': None})
offer1 = l4.rpc.call('offer', {'amount': '2msat',
'description': 'simple test'})
assert offer1['created'] is True
l1.rpc.call('fetchinvoice', {'offer': offer1['bolt12']})
def test_fetchinvoice(node_factory, bitcoind): def test_fetchinvoice(node_factory, bitcoind):
# We remove the conversion plugin on l3, causing it to get upset. # We remove the conversion plugin on l3, causing it to get upset.
l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True, l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True,