Returns false on failure */
| 82 | |
| 83 | /* Returns false on failure */ |
| 84 | const char *onion_message_parse(const tal_t *ctx, |
| 85 | const u8 *onion_message_packet, |
| 86 | const struct pubkey *path_key, |
| 87 | const struct pubkey *me, |
| 88 | u8 **next_onion_msg, |
| 89 | struct sciddir_or_pubkey *next_node, |
| 90 | struct tlv_onionmsg_tlv **final_om, |
| 91 | struct pubkey *final_alias, |
| 92 | struct secret **final_path_id) |
| 93 | { |
| 94 | enum onion_wire badreason; |
| 95 | struct onionpacket *op; |
| 96 | struct pubkey ephemeral; |
| 97 | struct route_step *rs; |
| 98 | struct tlv_onionmsg_tlv *om; |
| 99 | struct secret ss, onion_ss; |
| 100 | const u8 *cursor; |
| 101 | size_t max, maxlen; |
| 102 | |
| 103 | /* We unwrap the onion now. */ |
| 104 | op = parse_onionpacket(tmpctx, |
| 105 | onion_message_packet, |
| 106 | tal_bytelen(onion_message_packet), |
| 107 | &badreason); |
| 108 | if (!op) { |
| 109 | return tal_fmt(ctx, "onion_message_parse: can't parse onionpacket: %s", |
| 110 | onion_wire_name(badreason)); |
| 111 | } |
| 112 | |
| 113 | ephemeral = op->ephemeralkey; |
| 114 | if (!unblind_onion(path_key, ecdh, &ephemeral, &ss)) { |
| 115 | return tal_fmt(ctx, "onion_message_parse: can't unblind onionpacket"); |
| 116 | } |
| 117 | |
| 118 | /* Now get onion shared secret and parse it. */ |
| 119 | ecdh(&ephemeral, &onion_ss); |
| 120 | rs = process_onionpacket(tmpctx, op, &onion_ss, NULL, 0); |
| 121 | if (!rs) { |
| 122 | return tal_fmt(ctx, "onion_message_parse: can't process onionpacket ss=%s", |
| 123 | fmt_secret(tmpctx, &onion_ss)); |
| 124 | } |
| 125 | |
| 126 | /* The raw payload is prepended with length in the modern onion. */ |
| 127 | cursor = rs->raw_payload; |
| 128 | max = tal_bytelen(rs->raw_payload); |
| 129 | maxlen = fromwire_bigsize(&cursor, &max); |
| 130 | if (!cursor) { |
| 131 | return tal_fmt(ctx, "onion_message_parse: Invalid hop payload %s", |
| 132 | tal_hex(tmpctx, rs->raw_payload)); |
| 133 | } |
| 134 | if (maxlen > max) { |
| 135 | return tal_fmt(ctx, "onion_message_parse: overlong hop payload %s", |
| 136 | tal_hex(tmpctx, rs->raw_payload)); |
| 137 | } |
| 138 | |
| 139 | om = fromwire_tlv_onionmsg_tlv(tmpctx, &cursor, &maxlen); |
| 140 | if (!om) { |
| 141 | return tal_fmt(ctx, "onion_message_parse: invalid onionmsg_tlv %s", |