@@ -119,11 +119,12 @@ use crate::ln::msgs::DecodeError;
119119use crate :: offers:: invoice_macros:: { invoice_accessors_common, invoice_builder_methods_common} ;
120120use crate :: offers:: invoice_request:: { INVOICE_REQUEST_PAYER_ID_TYPE , INVOICE_REQUEST_TYPES , IV_BYTES as INVOICE_REQUEST_IV_BYTES , InvoiceRequest , InvoiceRequestContents , InvoiceRequestTlvStream , InvoiceRequestTlvStreamRef } ;
121121use crate :: offers:: merkle:: { SignError , SignFn , SignatureTlvStream , SignatureTlvStreamRef , TaggedHash , TlvStream , WithoutSignatures , self } ;
122+ use crate :: offers:: nonce:: Nonce ;
122123use crate :: offers:: offer:: { Amount , OFFER_TYPES , OfferTlvStream , OfferTlvStreamRef , Quantity } ;
123124use crate :: offers:: parse:: { Bolt12ParseError , Bolt12SemanticError , ParsedMessage } ;
124125use crate :: offers:: payer:: { PAYER_METADATA_TYPE , PayerTlvStream , PayerTlvStreamRef } ;
125126use crate :: offers:: refund:: { IV_BYTES as REFUND_IV_BYTES , Refund , RefundContents } ;
126- use crate :: offers:: signer;
127+ use crate :: offers:: signer:: { Metadata , self } ;
127128use crate :: util:: ser:: { HighZeroBytesDroppedBigSize , Iterable , Readable , SeekReadable , WithoutLength , Writeable , Writer } ;
128129use crate :: util:: string:: PrintableString ;
129130
@@ -770,12 +771,31 @@ impl Bolt12Invoice {
770771 self . tagged_hash . as_digest ( ) . as_ref ( ) . clone ( )
771772 }
772773
773- /// Verifies that the invoice was for a request or refund created using the given key. Returns
774- /// the associated [`PaymentId`] to use when sending the payment.
774+ /// Verifies that the invoice was for a request or refund created using the given key by
775+ /// checking the payer metadata from the invoice request.
776+ ///
777+ /// Returns the associated [`PaymentId`] to use when sending the payment.
775778 pub fn verify < T : secp256k1:: Signing > (
776779 & self , key : & ExpandedKey , secp_ctx : & Secp256k1 < T >
777780 ) -> Result < PaymentId , ( ) > {
778- self . contents . verify ( TlvStream :: new ( & self . bytes ) , key, secp_ctx)
781+ let metadata = match & self . contents {
782+ InvoiceContents :: ForOffer { invoice_request, .. } => & invoice_request. inner . payer . 0 ,
783+ InvoiceContents :: ForRefund { refund, .. } => & refund. payer . 0 ,
784+ } ;
785+ self . contents . verify ( TlvStream :: new ( & self . bytes ) , metadata, key, secp_ctx)
786+ }
787+
788+ /// Verifies that the invoice was for a request or refund created using the given key by
789+ /// checking a payment id and nonce included with the [`BlindedPath`] for which the invoice was
790+ /// sent through.
791+ pub fn verify_using_payer_data < T : secp256k1:: Signing > (
792+ & self , payment_id : PaymentId , nonce : Nonce , key : & ExpandedKey , secp_ctx : & Secp256k1 < T >
793+ ) -> bool {
794+ let metadata = Metadata :: payer_data ( payment_id, nonce, key) ;
795+ match self . contents . verify ( TlvStream :: new ( & self . bytes ) , & metadata, key, secp_ctx) {
796+ Ok ( extracted_payment_id) => payment_id == extracted_payment_id,
797+ Err ( ( ) ) => false ,
798+ }
779799 }
780800
781801 pub ( crate ) fn as_tlv_stream ( & self ) -> FullInvoiceTlvStreamRef {
@@ -1006,35 +1026,28 @@ impl InvoiceContents {
10061026 }
10071027
10081028 fn verify < T : secp256k1:: Signing > (
1009- & self , tlv_stream : TlvStream < ' _ > , key : & ExpandedKey , secp_ctx : & Secp256k1 < T >
1029+ & self , tlv_stream : TlvStream < ' _ > , metadata : & Metadata , key : & ExpandedKey ,
1030+ secp_ctx : & Secp256k1 < T >
10101031 ) -> Result < PaymentId , ( ) > {
10111032 let offer_records = tlv_stream. clone ( ) . range ( OFFER_TYPES ) ;
10121033 let invreq_records = tlv_stream. range ( INVOICE_REQUEST_TYPES ) . filter ( |record| {
10131034 match record. r#type {
10141035 PAYER_METADATA_TYPE => false , // Should be outside range
1015- INVOICE_REQUEST_PAYER_ID_TYPE => !self . derives_keys ( ) ,
1036+ INVOICE_REQUEST_PAYER_ID_TYPE => !metadata . derives_payer_keys ( ) ,
10161037 _ => true ,
10171038 }
10181039 } ) ;
10191040 let tlv_stream = offer_records. chain ( invreq_records) ;
10201041
1021- let ( metadata, payer_id, iv_bytes) = match self {
1022- InvoiceContents :: ForOffer { invoice_request, .. } => {
1023- ( invoice_request. metadata ( ) , invoice_request. payer_id ( ) , INVOICE_REQUEST_IV_BYTES )
1024- } ,
1025- InvoiceContents :: ForRefund { refund, .. } => {
1026- ( refund. metadata ( ) , refund. payer_id ( ) , REFUND_IV_BYTES )
1027- } ,
1042+ let payer_id = self . payer_id ( ) ;
1043+ let iv_bytes = match self {
1044+ InvoiceContents :: ForOffer { .. } => INVOICE_REQUEST_IV_BYTES ,
1045+ InvoiceContents :: ForRefund { .. } => REFUND_IV_BYTES ,
10281046 } ;
10291047
1030- signer:: verify_payer_metadata ( metadata, key, iv_bytes, payer_id, tlv_stream, secp_ctx)
1031- }
1032-
1033- fn derives_keys ( & self ) -> bool {
1034- match self {
1035- InvoiceContents :: ForOffer { invoice_request, .. } => invoice_request. derives_keys ( ) ,
1036- InvoiceContents :: ForRefund { refund, .. } => refund. derives_keys ( ) ,
1037- }
1048+ signer:: verify_payer_metadata (
1049+ metadata. as_ref ( ) , key, iv_bytes, payer_id, tlv_stream, secp_ctx,
1050+ )
10381051 }
10391052
10401053 fn as_tlv_stream ( & self ) -> PartialInvoiceTlvStreamRef {
0 commit comments