Skip to content

Commit c686c23

Browse files
committed
DRY up verification of invreq TLV records
1 parent c0ddf3c commit c686c23

File tree

3 files changed

+49
-46
lines changed

3 files changed

+49
-46
lines changed

lightning/src/offers/invoice.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,13 @@ use crate::ln::PaymentHash;
108108
use crate::ln::features::{BlindedHopFeatures, Bolt12InvoiceFeatures};
109109
use crate::ln::inbound_payment::ExpandedKey;
110110
use crate::ln::msgs::DecodeError;
111-
use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestContents, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef};
111+
use crate::offers::invoice_request::{INVOICE_REQUEST_PAYER_ID_TYPE, INVOICE_REQUEST_TYPES, IV_BYTES as INVOICE_REQUEST_IV_BYTES, InvoiceRequest, InvoiceRequestContents, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef};
112112
use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, TlvStream, WithoutSignatures, self};
113-
use crate::offers::offer::{Amount, OfferTlvStream, OfferTlvStreamRef};
113+
use crate::offers::offer::{Amount, OFFER_TYPES, OfferTlvStream, OfferTlvStreamRef};
114114
use crate::offers::parse::{ParseError, ParsedMessage, SemanticError};
115-
use crate::offers::payer::{PayerTlvStream, PayerTlvStreamRef};
116-
use crate::offers::refund::{Refund, RefundContents};
115+
use crate::offers::payer::{PAYER_METADATA_TYPE, PayerTlvStream, PayerTlvStreamRef};
116+
use crate::offers::refund::{IV_BYTES as REFUND_IV_BYTES, Refund, RefundContents};
117+
use crate::offers::signer;
117118
use crate::onion_message::BlindedPath;
118119
use crate::util::ser::{HighZeroBytesDroppedBigSize, Iterable, SeekReadable, WithoutLength, Writeable, Writer};
119120

@@ -531,13 +532,32 @@ impl InvoiceContents {
531532
fn verify<T: secp256k1::Signing>(
532533
&self, tlv_stream: TlvStream<'_>, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
533534
) -> bool {
534-
match self {
535+
let offer_records = tlv_stream.clone().range(OFFER_TYPES);
536+
let invreq_records = tlv_stream.range(INVOICE_REQUEST_TYPES).filter(|record| {
537+
match record.r#type {
538+
PAYER_METADATA_TYPE => false, // Should be outside range
539+
INVOICE_REQUEST_PAYER_ID_TYPE => !self.derives_keys(),
540+
_ => true,
541+
}
542+
});
543+
let tlv_stream = offer_records.chain(invreq_records);
544+
545+
let (metadata, payer_id, iv_bytes) = match self {
535546
InvoiceContents::ForOffer { invoice_request, .. } => {
536-
invoice_request.verify(tlv_stream, key, secp_ctx)
547+
(invoice_request.metadata(), invoice_request.payer_id(), INVOICE_REQUEST_IV_BYTES)
537548
},
538549
InvoiceContents::ForRefund { refund, .. } => {
539-
refund.verify(tlv_stream, key, secp_ctx)
550+
(refund.metadata(), refund.payer_id(), REFUND_IV_BYTES)
540551
},
552+
};
553+
554+
signer::verify_metadata(metadata, key, iv_bytes, payer_id, tlv_stream, secp_ctx)
555+
}
556+
557+
fn derives_keys(&self) -> bool {
558+
match self {
559+
InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.derives_keys(),
560+
InvoiceContents::ForRefund { refund, .. } => refund.derives_keys(),
541561
}
542562
}
543563

lightning/src/offers/invoice_request.rs

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ use crate::ln::inbound_payment::{ExpandedKey, IV_LEN, Nonce};
6666
use crate::ln::msgs::DecodeError;
6767
use crate::offers::invoice::{BlindedPayInfo, InvoiceBuilder};
6868
use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, TlvStream, self};
69-
use crate::offers::offer::{OFFER_TYPES, Offer, OfferContents, OfferTlvStream, OfferTlvStreamRef};
69+
use crate::offers::offer::{Offer, OfferContents, OfferTlvStream, OfferTlvStreamRef};
7070
use crate::offers::parse::{ParseError, ParsedMessage, SemanticError};
71-
use crate::offers::payer::{PAYER_METADATA_TYPE, PayerContents, PayerTlvStream, PayerTlvStreamRef};
72-
use crate::offers::signer::{Metadata, MetadataMaterial, self};
71+
use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef};
72+
use crate::offers::signer::{Metadata, MetadataMaterial};
7373
use crate::onion_message::BlindedPath;
7474
use crate::util::ser::{HighZeroBytesDroppedBigSize, SeekReadable, WithoutLength, Writeable, Writer};
7575
use crate::util::string::PrintableString;
@@ -78,7 +78,7 @@ use crate::prelude::*;
7878

7979
const SIGNATURE_TAG: &'static str = concat!("lightning", "invoice_request", "signature");
8080

81-
const IV_BYTES: &[u8; IV_LEN] = b"LDK Invreq ~~~~~";
81+
pub(super) const IV_BYTES: &[u8; IV_LEN] = b"LDK Invreq ~~~~~";
8282

8383
/// Builds an [`InvoiceRequest`] from an [`Offer`] for the "offer to be paid" flow.
8484
///
@@ -528,24 +528,16 @@ impl InvoiceRequestContents {
528528
self.inner.metadata()
529529
}
530530

531+
pub(super) fn derives_keys(&self) -> bool {
532+
self.inner.payer.0.derives_keys()
533+
}
534+
531535
pub(super) fn chain(&self) -> ChainHash {
532536
self.inner.chain()
533537
}
534538

535-
/// Verifies that the payer metadata was produced from the invoice request in the TLV stream.
536-
pub(super) fn verify<T: secp256k1::Signing>(
537-
&self, tlv_stream: TlvStream<'_>, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
538-
) -> bool {
539-
let offer_records = tlv_stream.clone().range(OFFER_TYPES);
540-
let invreq_records = tlv_stream.range(INVOICE_REQUEST_TYPES).filter(|record| {
541-
match record.r#type {
542-
PAYER_METADATA_TYPE => false, // Should be outside range
543-
INVOICE_REQUEST_PAYER_ID_TYPE => !self.inner.payer.0.derives_keys(),
544-
_ => true,
545-
}
546-
});
547-
let tlv_stream = offer_records.chain(invreq_records);
548-
signer::verify_metadata(self.metadata(), key, IV_BYTES, self.payer_id, tlv_stream, secp_ctx)
539+
pub(super) fn payer_id(&self) -> PublicKey {
540+
self.payer_id
549541
}
550542

551543
pub(super) fn as_tlv_stream(&self) -> PartialInvoiceRequestTlvStreamRef {

lightning/src/offers/refund.rs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,11 @@ use crate::ln::features::InvoiceRequestFeatures;
8585
use crate::ln::inbound_payment::{ExpandedKey, IV_LEN, Nonce};
8686
use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
8787
use crate::offers::invoice::{BlindedPayInfo, InvoiceBuilder};
88-
use crate::offers::invoice_request::{INVOICE_REQUEST_PAYER_ID_TYPE, INVOICE_REQUEST_TYPES, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef};
89-
use crate::offers::merkle::TlvStream;
90-
use crate::offers::offer::{OFFER_TYPES, OfferTlvStream, OfferTlvStreamRef};
88+
use crate::offers::invoice_request::{InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef};
89+
use crate::offers::offer::{OfferTlvStream, OfferTlvStreamRef};
9190
use crate::offers::parse::{Bech32Encode, ParseError, ParsedMessage, SemanticError};
92-
use crate::offers::payer::{PAYER_METADATA_TYPE, PayerContents, PayerTlvStream, PayerTlvStreamRef};
93-
use crate::offers::signer::{Metadata, MetadataMaterial, self};
91+
use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef};
92+
use crate::offers::signer::{Metadata, MetadataMaterial};
9493
use crate::onion_message::BlindedPath;
9594
use crate::util::ser::{SeekReadable, WithoutLength, Writeable, Writer};
9695
use crate::util::string::PrintableString;
@@ -100,7 +99,7 @@ use crate::prelude::*;
10099
#[cfg(feature = "std")]
101100
use std::time::SystemTime;
102101

103-
const IV_BYTES: &[u8; IV_LEN] = b"LDK Refund ~~~~~";
102+
pub(super) const IV_BYTES: &[u8; IV_LEN] = b"LDK Refund ~~~~~";
104103

105104
/// Builds a [`Refund`] for the "offer for money" flow.
106105
///
@@ -456,7 +455,7 @@ impl RefundContents {
456455
}
457456
}
458457

459-
fn metadata(&self) -> &[u8] {
458+
pub(super) fn metadata(&self) -> &[u8] {
460459
self.payer.0.as_bytes().map(|bytes| bytes.as_slice()).unwrap_or(&[])
461460
}
462461

@@ -468,20 +467,12 @@ impl RefundContents {
468467
ChainHash::using_genesis_block(Network::Bitcoin)
469468
}
470469

471-
/// Verifies that the payer metadata was produced from the refund in the TLV stream.
472-
pub(super) fn verify<T: secp256k1::Signing>(
473-
&self, tlv_stream: TlvStream<'_>, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
474-
) -> bool {
475-
let offer_records = tlv_stream.clone().range(OFFER_TYPES);
476-
let invreq_records = tlv_stream.range(INVOICE_REQUEST_TYPES).filter(|record| {
477-
match record.r#type {
478-
PAYER_METADATA_TYPE => false, // Should be outside range
479-
INVOICE_REQUEST_PAYER_ID_TYPE => !self.payer.0.derives_keys(),
480-
_ => true,
481-
}
482-
});
483-
let tlv_stream = offer_records.chain(invreq_records);
484-
signer::verify_metadata(self.metadata(), key, IV_BYTES, self.payer_id, tlv_stream, secp_ctx)
470+
pub(super) fn derives_keys(&self) -> bool {
471+
self.payer.0.derives_keys()
472+
}
473+
474+
pub(super) fn payer_id(&self) -> PublicKey {
475+
self.payer_id
485476
}
486477

487478
pub(super) fn as_tlv_stream(&self) -> RefundTlvStreamRef {

0 commit comments

Comments
 (0)