| 122 | } |
| 123 | |
| 124 | static struct command_result *listinvreqs_done(struct command *cmd, |
| 125 | const char *method, |
| 126 | const char *buf, |
| 127 | const jsmntok_t *result, |
| 128 | struct inv *inv) |
| 129 | { |
| 130 | const jsmntok_t *arr = json_get_member(buf, result, "invoicerequests"); |
| 131 | const jsmntok_t *activetok; |
| 132 | bool active; |
| 133 | struct amount_msat amt; |
| 134 | struct out_req *req; |
| 135 | struct sha256 merkle, sighash; |
| 136 | |
| 137 | /* BOLT #12: |
| 138 | * A reader of an invoice: |
| 139 | *... |
| 140 | * - if the invoice is a response to an `invoice_request`: |
| 141 | * - MUST reject the invoice if all fields in ranges 0 to 159 and 1000000000 to 2999999999 (inclusive) do not exactly match the invoice request. |
| 142 | * - if `offer_issuer_id` is present (invoice_request for an offer): |
| 143 | * - MUST reject the invoice if `invoice_node_id` is not equal to `offer_issuer_id` |
| 144 | * - otherwise, if `offer_paths` is present (invoice_request for an offer without id): |
| 145 | * - MUST reject the invoice if `invoice_node_id` is not equal to the final `blinded_node_id` it sent the invoice request to. |
| 146 | * - otherwise (invoice_request without an offer): |
| 147 | * - MAY reject the invoice if it cannot confirm that `invoice_node_id` is correct, out-of-band. |
| 148 | */ |
| 149 | |
| 150 | /* Since the invreq_id hashes all fields in those ranges, we know it matches */ |
| 151 | if (arr->size == 0) |
| 152 | return fail_inv(cmd, inv, "Unknown invoice_request %s", |
| 153 | fmt_sha256(tmpctx, &inv->invreq_id)); |
| 154 | |
| 155 | activetok = json_get_member(buf, arr + 1, "active"); |
| 156 | if (!activetok) { |
| 157 | return fail_internalerr(cmd, inv, |
| 158 | "Missing active: %.*s", |
| 159 | json_tok_full_len(arr), |
| 160 | json_tok_full(buf, arr)); |
| 161 | } |
| 162 | json_to_bool(buf, activetok, &active); |
| 163 | if (!active) |
| 164 | return fail_inv(cmd, inv, "invoice_request no longer available"); |
| 165 | |
| 166 | /* We only save ones without offers to the db! */ |
| 167 | assert(!inv->inv->offer_issuer_id && !inv->inv->offer_paths); |
| 168 | |
| 169 | /* BOLT #12: |
| 170 | * - MUST reject the invoice if `signature` is not a valid signature |
| 171 | * using `invoice_node_id` as described in [Signature |
| 172 | * Calculation](#signature-calculation). |
| 173 | */ |
| 174 | if (!inv->inv->signature) |
| 175 | return fail_inv(cmd, inv, "invoice missing signature"); |
| 176 | |
| 177 | merkle_tlv(inv->inv->fields, &merkle); |
| 178 | sighash_from_merkle("invoice", "signature", &merkle, &sighash); |
| 179 | if (!check_schnorr_sig(&sighash, &inv->inv->invoice_node_id->pubkey, inv->inv->signature)) |
| 180 | return fail_inv(cmd, inv, "invalid invoice signature"); |
| 181 |
nothing calls this directly
no test coverage detected