mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
offers: import latest variant from draft.
In particular, this changes the name of a field in invoice_request: `payer_signature` becomes simply `signature`. So we allow both for now, and send the old one unless deprecated_apis is disabled. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -205,7 +205,7 @@ void merkle_tlv(const struct tlv_field *fields, struct sha256 *merkle)
|
||||
* Merkle-root; "lightning" is the literal 9-byte ASCII string,
|
||||
* `messagename` is the name of the TLV stream being signed (i.e. "offer",
|
||||
* "invoice_request" or "invoice") and the `fieldname` is the TLV field
|
||||
* containing the signature (e.g. "signature" or "payer_signature").
|
||||
* containing the signature (e.g. "signature" or "refund_signature").
|
||||
*/
|
||||
void sighash_from_merkle(const char *messagename,
|
||||
const char *fieldname,
|
||||
|
||||
@@ -60,6 +60,9 @@ void towire_secp256k1_ecdsa_signature(u8 **pptr UNNEEDED,
|
||||
/* Generated stub for towire_sha256 */
|
||||
void towire_sha256(u8 **pptr UNNEEDED, const struct sha256 *sha256 UNNEEDED)
|
||||
{ fprintf(stderr, "towire_sha256 called!\n"); abort(); }
|
||||
/* Generated stub for towire_tu16 */
|
||||
void towire_tu16(u8 **pptr UNNEEDED, u16 v UNNEEDED)
|
||||
{ fprintf(stderr, "towire_tu16 called!\n"); abort(); }
|
||||
/* Generated stub for towire_tu32 */
|
||||
void towire_tu32(u8 **pptr UNNEEDED, u32 v UNNEEDED)
|
||||
{ fprintf(stderr, "towire_tu32 called!\n"); abort(); }
|
||||
|
||||
@@ -422,13 +422,13 @@ static void print_relative_expiry(u64 *created_at, u32 *relative)
|
||||
fmt_time(tmpctx, *created_at + *relative));
|
||||
}
|
||||
|
||||
static void print_fallbacks(const struct tlv_invoice_fallbacks *fallbacks)
|
||||
static void print_fallbacks(struct fallback_address **fallbacks)
|
||||
{
|
||||
for (size_t i = 0; i < tal_count(fallbacks->fallbacks); i++) {
|
||||
for (size_t i = 0; i < tal_count(fallbacks); i++) {
|
||||
/* FIXME: format properly! */
|
||||
printf("fallback: %u %s\n",
|
||||
fallbacks->fallbacks[i]->version,
|
||||
tal_hex(tmpctx, fallbacks->fallbacks[i]->address));
|
||||
fallbacks[i]->version,
|
||||
tal_hex(tmpctx, fallbacks[i]->address));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,12 +556,20 @@ int main(int argc, char *argv[])
|
||||
print_features(invreq->features);
|
||||
if (invreq->quantity)
|
||||
print_quantity(*invreq->quantity);
|
||||
if (must_have(invreq, payer_signature))
|
||||
well_formed &= print_signature("invoice_request",
|
||||
"payer_signature",
|
||||
invreq->fields,
|
||||
invreq->payer_key,
|
||||
invreq->payer_signature);
|
||||
if (must_have(invreq, signature)) {
|
||||
if (!print_signature("invoice_request",
|
||||
"signature",
|
||||
invreq->fields,
|
||||
invreq->payer_key,
|
||||
invreq->signature)) {
|
||||
/* FIXME: We temporarily allow the old "payer_signature" name */
|
||||
well_formed &= print_signature("invoice_request",
|
||||
"payer_signature",
|
||||
invreq->fields,
|
||||
invreq->payer_key,
|
||||
invreq->signature);
|
||||
}
|
||||
}
|
||||
if (invreq->recurrence_counter) {
|
||||
print_recurrence_counter(invreq->recurrence_counter,
|
||||
invreq->recurrence_start);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <ccan/json_escape/json_escape.h>
|
||||
#include <ccan/take/take.h>
|
||||
#include <common/bolt12_merkle.h>
|
||||
#include <common/configdir.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
#include <common/json_tok.h>
|
||||
@@ -466,16 +467,21 @@ static struct command_result *json_createinvoicerequest(struct command *cmd,
|
||||
}
|
||||
|
||||
/* BOLT-offers #12:
|
||||
* - MUST set `payer_signature` `sig` as detailed in
|
||||
* - MUST set `signature` `sig` as detailed in
|
||||
* [Signature Calculation](#signature-calculation) using the `payer_key`.
|
||||
*/
|
||||
/* This populates the ->fields from our entries */
|
||||
invreq->fields = tlv_make_fields(invreq, invoice_request);
|
||||
merkle_tlv(invreq->fields, &merkle);
|
||||
invreq->payer_signature = tal(invreq, struct bip340sig);
|
||||
hsm_sign_b12(cmd->ld, "invoice_request", "payer_signature",
|
||||
&merkle, invreq->payer_info, invreq->payer_key,
|
||||
invreq->payer_signature);
|
||||
invreq->signature = tal(invreq, struct bip340sig);
|
||||
if (deprecated_apis)
|
||||
hsm_sign_b12(cmd->ld, "invoice_request", "payer_signature",
|
||||
&merkle, invreq->payer_info, invreq->payer_key,
|
||||
invreq->signature);
|
||||
else
|
||||
hsm_sign_b12(cmd->ld, "invoice_request", "signature",
|
||||
&merkle, invreq->payer_info, invreq->payer_key,
|
||||
invreq->signature);
|
||||
|
||||
response = json_stream_success(cmd);
|
||||
json_add_string(response, "bolt12", invrequest_encode(tmpctx, invreq));
|
||||
|
||||
@@ -1192,11 +1192,14 @@ force_payer_secret(struct command *cmd,
|
||||
"Could not remarshall invreq %s", tal_hex(tmpctx, msg));
|
||||
|
||||
merkle_tlv(sent->invreq->fields, &merkle);
|
||||
sighash_from_merkle("invoice_request", "payer_signature", &merkle, &sha);
|
||||
if (deprecated_apis)
|
||||
sighash_from_merkle("invoice_request", "payer_signature", &merkle, &sha);
|
||||
else
|
||||
sighash_from_merkle("invoice_request", "signature", &merkle, &sha);
|
||||
|
||||
sent->invreq->payer_signature = tal(invreq, struct bip340sig);
|
||||
sent->invreq->signature = tal(invreq, struct bip340sig);
|
||||
if (!secp256k1_schnorrsig_sign(secp256k1_ctx,
|
||||
sent->invreq->payer_signature->u8,
|
||||
sent->invreq->signature->u8,
|
||||
sha.u.u8,
|
||||
&kp,
|
||||
NULL, NULL)) {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <plugins/offers_offer.h>
|
||||
|
||||
struct point32 id;
|
||||
u32 cltv_final;
|
||||
u16 cltv_final;
|
||||
bool offers_enabled;
|
||||
|
||||
static struct command_result *finished(struct command *cmd,
|
||||
@@ -679,7 +679,7 @@ static void json_add_b12_invoice(struct json_stream *js,
|
||||
if (invoice->fallbacks)
|
||||
valid &= json_add_fallbacks(js,
|
||||
invoice->chain,
|
||||
invoice->fallbacks->fallbacks);
|
||||
invoice->fallbacks);
|
||||
|
||||
/* BOLT-offers #12:
|
||||
* - if the offer contained `refund_for`:
|
||||
@@ -769,23 +769,38 @@ static void json_add_invoice_request(struct json_stream *js,
|
||||
tal_bytelen(invreq->payer_note));
|
||||
|
||||
/* BOLT-offers #12:
|
||||
* - MUST fail the request if there is no `payer_signature` field.
|
||||
* - MUST fail the request if `payer_signature` is not correct.
|
||||
* - MUST fail the request if there is no `signature` field.
|
||||
* - MUST fail the request if `signature` is not correct.
|
||||
*/
|
||||
if (invreq->payer_signature) {
|
||||
if (invreq->signature) {
|
||||
if (invreq->payer_key
|
||||
&& !bolt12_check_signature(invreq->fields,
|
||||
"invoice_request",
|
||||
"payer_signature",
|
||||
"signature",
|
||||
invreq->payer_key,
|
||||
invreq->payer_signature)) {
|
||||
json_add_string(js, "warning_invoice_request_invalid_payer_signature",
|
||||
"Bad payer_signature");
|
||||
valid = false;
|
||||
invreq->signature)) {
|
||||
bool sig_valid;
|
||||
|
||||
if (deprecated_apis) {
|
||||
/* The old name? */
|
||||
sig_valid = bolt12_check_signature(invreq->fields,
|
||||
"invoice_request",
|
||||
"payer_signature",
|
||||
invreq->payer_key,
|
||||
invreq->signature);
|
||||
} else {
|
||||
sig_valid = false;
|
||||
}
|
||||
|
||||
if (!sig_valid) {
|
||||
json_add_string(js, "warning_invoice_request_invalid_signature",
|
||||
"Bad signature");
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
json_add_string(js, "warning_invoice_request_missing_payer_signature",
|
||||
"Missing payer_signature");
|
||||
json_add_string(js, "warning_invoice_request_missing_signature",
|
||||
"Missing signature");
|
||||
valid = false;
|
||||
}
|
||||
|
||||
@@ -836,7 +851,7 @@ static const char *init(struct plugin *p,
|
||||
rpc_scan(p, "listconfigs",
|
||||
take(json_out_obj(NULL, NULL, NULL)),
|
||||
"{cltv-final:%,experimental-offers:%}",
|
||||
JSON_SCAN(json_to_number, &cltv_final),
|
||||
JSON_SCAN(json_to_u16, &cltv_final),
|
||||
JSON_SCAN(json_to_bool, &offers_enabled));
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -417,7 +417,7 @@ static struct command_result *check_previous_invoice(struct command *cmd,
|
||||
}
|
||||
|
||||
/* BOLT-offers #12:
|
||||
* - MUST fail the request if `payer_signature` is not correct.
|
||||
* - MUST fail the request if `signature` is not correct.
|
||||
*/
|
||||
static bool check_payer_sig(const struct tlv_invoice_request *invreq,
|
||||
const struct point32 *payer_key,
|
||||
@@ -425,6 +425,17 @@ static bool check_payer_sig(const struct tlv_invoice_request *invreq,
|
||||
{
|
||||
struct sha256 merkle, sighash;
|
||||
merkle_tlv(invreq->fields, &merkle);
|
||||
sighash_from_merkle("invoice_request", "signature", &merkle, &sighash);
|
||||
|
||||
if (secp256k1_schnorrsig_verify(secp256k1_ctx,
|
||||
sig->u8,
|
||||
sighash.u.u8, &payer_key->pubkey) == 1)
|
||||
return true;
|
||||
|
||||
if (!deprecated_apis)
|
||||
return false;
|
||||
|
||||
/* Try old name */
|
||||
sighash_from_merkle("invoice_request", "payer_signature",
|
||||
&merkle, &sighash);
|
||||
|
||||
@@ -714,13 +725,13 @@ static struct command_result *listoffers_done(struct command *cmd,
|
||||
return err;
|
||||
}
|
||||
|
||||
err = invreq_must_have(cmd, ir, payer_signature);
|
||||
err = invreq_must_have(cmd, ir, signature);
|
||||
if (err)
|
||||
return err;
|
||||
if (!check_payer_sig(ir->invreq,
|
||||
ir->invreq->payer_key,
|
||||
ir->invreq->payer_signature)) {
|
||||
return fail_invreq(cmd, ir, "bad payer_signature");
|
||||
ir->invreq->signature)) {
|
||||
return fail_invreq(cmd, ir, "bad signature");
|
||||
}
|
||||
|
||||
if (ir->offer->recurrence) {
|
||||
@@ -806,7 +817,7 @@ static struct command_result *listoffers_done(struct command *cmd,
|
||||
ir->inv->payment_hash = tal(ir->inv, struct sha256);
|
||||
sha256(ir->inv->payment_hash, &ir->preimage, sizeof(ir->preimage));
|
||||
|
||||
ir->inv->cltv = tal_dup(ir->inv, u32, &cltv_final);
|
||||
ir->inv->cltv = tal_dup(ir->inv, u16, &cltv_final);
|
||||
|
||||
ir->inv->created_at = tal(ir->inv, u64);
|
||||
*ir->inv->created_at = time_now().ts.tv_sec;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "config.h"
|
||||
#include <plugins/libplugin.h>
|
||||
|
||||
extern u32 cltv_final;
|
||||
extern u16 cltv_final;
|
||||
|
||||
/* We got an onionmessage with an invreq! */
|
||||
struct command_result *handle_invoice_request(struct command *cmd,
|
||||
|
||||
@@ -64,8 +64,8 @@ tlvtype,invoice_request,payer_info,50
|
||||
tlvdata,invoice_request,payer_info,blob,byte,...
|
||||
tlvtype,invoice_request,replace_invoice,56
|
||||
tlvdata,invoice_request,replace_invoice,payment_hash,sha256,
|
||||
tlvtype,invoice_request,payer_signature,240
|
||||
tlvdata,invoice_request,payer_signature,sig,bip340sig,
|
||||
tlvtype,invoice_request,signature,240
|
||||
tlvdata,invoice_request,signature,sig,bip340sig,
|
||||
tlvtype,invoice,chain,3
|
||||
tlvdata,invoice,chain,chain,chain_hash,
|
||||
tlvtype,invoice,offer_id,4
|
||||
@@ -101,8 +101,6 @@ tlvtype,invoice,payer_key,38
|
||||
tlvdata,invoice,payer_key,key,point32,
|
||||
tlvtype,invoice,payer_note,39
|
||||
tlvdata,invoice,payer_note,note,utf8,...
|
||||
tlvtype,invoice,payer_info,50
|
||||
tlvdata,invoice,payer_info,blob,byte,...
|
||||
tlvtype,invoice,created_at,40
|
||||
tlvdata,invoice,created_at,timestamp,tu64,
|
||||
tlvtype,invoice,payment_hash,42
|
||||
@@ -110,10 +108,11 @@ tlvdata,invoice,payment_hash,payment_hash,sha256,
|
||||
tlvtype,invoice,relative_expiry,44
|
||||
tlvdata,invoice,relative_expiry,seconds_from_creation,tu32,
|
||||
tlvtype,invoice,cltv,46
|
||||
tlvdata,invoice,cltv,min_final_cltv_expiry,tu32,
|
||||
tlvdata,invoice,cltv,min_final_cltv_expiry,tu16,
|
||||
tlvtype,invoice,fallbacks,48
|
||||
tlvdata,invoice,fallbacks,num,byte,
|
||||
tlvdata,invoice,fallbacks,fallbacks,fallback_address,num
|
||||
tlvdata,invoice,fallbacks,fallbacks,fallback_address,...
|
||||
tlvtype,invoice,payer_info,50
|
||||
tlvdata,invoice,payer_info,blob,byte,...
|
||||
tlvtype,invoice,refund_signature,52
|
||||
tlvdata,invoice,refund_signature,payer_signature,bip340sig,
|
||||
tlvtype,invoice,replace_invoice,56
|
||||
|
||||
|
@@ -64,8 +64,8 @@ tlvtype,invoice_request,payer_info,50
|
||||
tlvdata,invoice_request,payer_info,blob,byte,...
|
||||
tlvtype,invoice_request,replace_invoice,56
|
||||
tlvdata,invoice_request,replace_invoice,payment_hash,sha256,
|
||||
tlvtype,invoice_request,payer_signature,240
|
||||
tlvdata,invoice_request,payer_signature,sig,bip340sig,
|
||||
tlvtype,invoice_request,signature,240
|
||||
tlvdata,invoice_request,signature,sig,bip340sig,
|
||||
tlvtype,invoice,chain,3
|
||||
tlvdata,invoice,chain,chain,chain_hash,
|
||||
tlvtype,invoice,offer_id,4
|
||||
@@ -101,8 +101,6 @@ tlvtype,invoice,payer_key,38
|
||||
tlvdata,invoice,payer_key,key,point32,
|
||||
tlvtype,invoice,payer_note,39
|
||||
tlvdata,invoice,payer_note,note,utf8,...
|
||||
tlvtype,invoice,payer_info,50
|
||||
tlvdata,invoice,payer_info,blob,byte,...
|
||||
tlvtype,invoice,created_at,40
|
||||
tlvdata,invoice,created_at,timestamp,tu64,
|
||||
tlvtype,invoice,payment_hash,42
|
||||
@@ -110,10 +108,11 @@ tlvdata,invoice,payment_hash,payment_hash,sha256,
|
||||
tlvtype,invoice,relative_expiry,44
|
||||
tlvdata,invoice,relative_expiry,seconds_from_creation,tu32,
|
||||
tlvtype,invoice,cltv,46
|
||||
tlvdata,invoice,cltv,min_final_cltv_expiry,tu32,
|
||||
tlvdata,invoice,cltv,min_final_cltv_expiry,tu16,
|
||||
tlvtype,invoice,fallbacks,48
|
||||
tlvdata,invoice,fallbacks,num,byte,
|
||||
tlvdata,invoice,fallbacks,fallbacks,fallback_address,num
|
||||
tlvdata,invoice,fallbacks,fallbacks,fallback_address,...
|
||||
tlvtype,invoice,payer_info,50
|
||||
tlvdata,invoice,payer_info,blob,byte,...
|
||||
tlvtype,invoice,refund_signature,52
|
||||
tlvdata,invoice,refund_signature,payer_signature,bip340sig,
|
||||
tlvtype,invoice,replace_invoice,56
|
||||
|
||||
|
Reference in New Issue
Block a user