@@ -348,14 +348,13 @@ static struct command_result *param_b12_invreq(struct command *cmd,
348348 if (!* invreq )
349349 return command_fail_badparam (cmd , name , buffer , tok , fail );
350350
351- /* We use this for testing with known payer_info */
352- if ((* invreq )-> invreq_metadata && !cmd -> ld -> developer )
351+ if (!(* invreq )-> invreq_metadata )
353352 return command_fail_badparam (cmd , name , buffer , tok ,
354- "must not have invreq_metadata" );
353+ "must have invreq_metadata" );
355354
356- if ((* invreq )-> invreq_payer_id )
355+ if (! (* invreq )-> invreq_payer_id )
357356 return command_fail_badparam (cmd , name , buffer , tok ,
358- "must not have invreq_payer_id" );
357+ "must have invreq_payer_id" );
359358 return NULL ;
360359}
361360
@@ -400,15 +399,15 @@ static struct command_result *json_createinvoicerequest(struct command *cmd,
400399 struct json_stream * response ;
401400 u64 * prev_basetime = NULL ;
402401 struct sha256 merkle ;
403- bool * save , * single_use , * exposeid ;
402+ bool * save , * single_use ;
404403 enum offer_status status ;
405404 struct sha256 invreq_id ;
406405 const char * b12str ;
406+ const u8 * tweak ;
407407
408408 if (!param_check (cmd , buffer , params ,
409409 p_req ("bolt12" , param_b12_invreq , & invreq ),
410410 p_req ("savetodb" , param_bool , & save ),
411- p_opt_def ("exposeid" , param_bool , & exposeid , false),
412411 p_opt ("recurrence_label" , param_label , & label ),
413412 p_opt_def ("single_use" , param_bool , & single_use , true),
414413 NULL ))
@@ -419,14 +418,6 @@ static struct command_result *json_createinvoicerequest(struct command *cmd,
419418 else
420419 status = OFFER_MULTIPLE_USE_UNUSED ;
421420
422- if (!invreq -> invreq_metadata )
423- return command_fail (cmd , JSONRPC2_INVALID_PARAMS ,
424- "invoice_request has no invreq_metadata" );
425-
426- if (invreq -> invreq_payer_id )
427- return command_fail (cmd , JSONRPC2_INVALID_PARAMS ,
428- "invoice_request already has invreq_payer_id" );
429-
430421 /* If it's a recurring payment, we look for previous to copy basetime */
431422 if (invreq -> invreq_recurrence_counter ) {
432423 if (!label )
@@ -442,27 +433,25 @@ static struct command_result *json_createinvoicerequest(struct command *cmd,
442433 }
443434 }
444435
445- /* BOLT-offers #12:
446- *
447- * `invreq_metadata` might typically contain information about
448- * the derivation of the `invreq_payer_id`. This should not
449- * leak any information (such as using a simple BIP-32
450- * derivation path); a valid system might be for a node to
451- * maintain a base payer key and encode a 128-bit tweak here.
452- * The payer_id would be derived by tweaking the base key with
453- * SHA256(payer_base_pubkey || tweak). It's also the first
454- * entry (if present), ensuring an unpredictable nonce for
455- * hashing.
456- */
457- invreq -> invreq_payer_id = tal (invreq , struct pubkey );
458- if (* exposeid ) {
459- * invreq -> invreq_payer_id = cmd -> ld -> our_pubkey ;
460- } else if (!payer_key (cmd -> ld ,
461- invreq -> invreq_metadata ,
462- tal_bytelen (invreq -> invreq_metadata ),
463- invreq -> invreq_payer_id )) {
464- return command_fail (cmd , JSONRPC2_INVALID_PARAMS ,
465- "Invalid tweak" );
436+ /* If the payer_id is not our node id, we sanity check that it
437+ * correctly maps from invreq_metadata */
438+ if (!pubkey_eq (invreq -> invreq_payer_id , & cmd -> ld -> our_pubkey )) {
439+ struct pubkey expected ;
440+ if (!payer_key (cmd -> ld ,
441+ invreq -> invreq_metadata ,
442+ tal_bytelen (invreq -> invreq_metadata ),
443+ & expected )) {
444+ return command_fail (cmd , JSONRPC2_INVALID_PARAMS ,
445+ "Invalid tweak" );
446+ }
447+ if (!pubkey_eq (invreq -> invreq_payer_id , & expected )) {
448+ return command_fail (cmd , JSONRPC2_INVALID_PARAMS ,
449+ "payer_id did not match invreq_metadata derivation %s" ,
450+ fmt_pubkey (tmpctx , & expected ));
451+ }
452+ tweak = invreq -> invreq_metadata ;
453+ } else {
454+ tweak = NULL ;
466455 }
467456
468457 if (command_check_only (cmd ))
@@ -477,7 +466,7 @@ static struct command_result *json_createinvoicerequest(struct command *cmd,
477466 merkle_tlv (invreq -> fields , & merkle );
478467 invreq -> signature = tal (invreq , struct bip340sig );
479468 hsm_sign_b12 (cmd -> ld , "invoice_request" , "signature" ,
480- & merkle , * exposeid ? NULL : invreq -> invreq_metadata ,
469+ & merkle , tweak ,
481470 invreq -> invreq_payer_id , invreq -> signature );
482471
483472 b12str = invrequest_encode (cmd , invreq );
0 commit comments