mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-25 07:17:40 +01:00
DRY up verification of invreq TLV records
This commit is contained in:
parent
2298af4d0b
commit
259aa9aac3
3 changed files with 49 additions and 46 deletions
|
@ -108,12 +108,13 @@ use crate::ln::PaymentHash;
|
|||
use crate::ln::features::{BlindedHopFeatures, Bolt12InvoiceFeatures};
|
||||
use crate::ln::inbound_payment::ExpandedKey;
|
||||
use crate::ln::msgs::DecodeError;
|
||||
use crate::offers::invoice_request::{InvoiceRequest, InvoiceRequestContents, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef};
|
||||
use crate::offers::invoice_request::{INVOICE_REQUEST_PAYER_ID_TYPE, INVOICE_REQUEST_TYPES, IV_BYTES as INVOICE_REQUEST_IV_BYTES, InvoiceRequest, InvoiceRequestContents, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef};
|
||||
use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, TlvStream, WithoutSignatures, self};
|
||||
use crate::offers::offer::{Amount, OfferTlvStream, OfferTlvStreamRef};
|
||||
use crate::offers::offer::{Amount, OFFER_TYPES, OfferTlvStream, OfferTlvStreamRef};
|
||||
use crate::offers::parse::{ParseError, ParsedMessage, SemanticError};
|
||||
use crate::offers::payer::{PayerTlvStream, PayerTlvStreamRef};
|
||||
use crate::offers::refund::{Refund, RefundContents};
|
||||
use crate::offers::payer::{PAYER_METADATA_TYPE, PayerTlvStream, PayerTlvStreamRef};
|
||||
use crate::offers::refund::{IV_BYTES as REFUND_IV_BYTES, Refund, RefundContents};
|
||||
use crate::offers::signer;
|
||||
use crate::onion_message::BlindedPath;
|
||||
use crate::util::ser::{HighZeroBytesDroppedBigSize, Iterable, SeekReadable, WithoutLength, Writeable, Writer};
|
||||
|
||||
|
@ -531,13 +532,32 @@ impl InvoiceContents {
|
|||
fn verify<T: secp256k1::Signing>(
|
||||
&self, tlv_stream: TlvStream<'_>, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
|
||||
) -> bool {
|
||||
match self {
|
||||
let offer_records = tlv_stream.clone().range(OFFER_TYPES);
|
||||
let invreq_records = tlv_stream.range(INVOICE_REQUEST_TYPES).filter(|record| {
|
||||
match record.r#type {
|
||||
PAYER_METADATA_TYPE => false, // Should be outside range
|
||||
INVOICE_REQUEST_PAYER_ID_TYPE => !self.derives_keys(),
|
||||
_ => true,
|
||||
}
|
||||
});
|
||||
let tlv_stream = offer_records.chain(invreq_records);
|
||||
|
||||
let (metadata, payer_id, iv_bytes) = match self {
|
||||
InvoiceContents::ForOffer { invoice_request, .. } => {
|
||||
invoice_request.verify(tlv_stream, key, secp_ctx)
|
||||
(invoice_request.metadata(), invoice_request.payer_id(), INVOICE_REQUEST_IV_BYTES)
|
||||
},
|
||||
InvoiceContents::ForRefund { refund, .. } => {
|
||||
refund.verify(tlv_stream, key, secp_ctx)
|
||||
(refund.metadata(), refund.payer_id(), REFUND_IV_BYTES)
|
||||
},
|
||||
};
|
||||
|
||||
signer::verify_metadata(metadata, key, iv_bytes, payer_id, tlv_stream, secp_ctx)
|
||||
}
|
||||
|
||||
fn derives_keys(&self) -> bool {
|
||||
match self {
|
||||
InvoiceContents::ForOffer { invoice_request, .. } => invoice_request.derives_keys(),
|
||||
InvoiceContents::ForRefund { refund, .. } => refund.derives_keys(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,10 +66,10 @@ use crate::ln::inbound_payment::{ExpandedKey, IV_LEN, Nonce};
|
|||
use crate::ln::msgs::DecodeError;
|
||||
use crate::offers::invoice::{BlindedPayInfo, InvoiceBuilder};
|
||||
use crate::offers::merkle::{SignError, SignatureTlvStream, SignatureTlvStreamRef, TlvStream, self};
|
||||
use crate::offers::offer::{OFFER_TYPES, Offer, OfferContents, OfferTlvStream, OfferTlvStreamRef};
|
||||
use crate::offers::offer::{Offer, OfferContents, OfferTlvStream, OfferTlvStreamRef};
|
||||
use crate::offers::parse::{ParseError, ParsedMessage, SemanticError};
|
||||
use crate::offers::payer::{PAYER_METADATA_TYPE, PayerContents, PayerTlvStream, PayerTlvStreamRef};
|
||||
use crate::offers::signer::{Metadata, MetadataMaterial, self};
|
||||
use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef};
|
||||
use crate::offers::signer::{Metadata, MetadataMaterial};
|
||||
use crate::onion_message::BlindedPath;
|
||||
use crate::util::ser::{HighZeroBytesDroppedBigSize, SeekReadable, WithoutLength, Writeable, Writer};
|
||||
use crate::util::string::PrintableString;
|
||||
|
@ -78,7 +78,7 @@ use crate::prelude::*;
|
|||
|
||||
const SIGNATURE_TAG: &'static str = concat!("lightning", "invoice_request", "signature");
|
||||
|
||||
const IV_BYTES: &[u8; IV_LEN] = b"LDK Invreq ~~~~~";
|
||||
pub(super) const IV_BYTES: &[u8; IV_LEN] = b"LDK Invreq ~~~~~";
|
||||
|
||||
/// Builds an [`InvoiceRequest`] from an [`Offer`] for the "offer to be paid" flow.
|
||||
///
|
||||
|
@ -528,24 +528,16 @@ impl InvoiceRequestContents {
|
|||
self.inner.metadata()
|
||||
}
|
||||
|
||||
pub(super) fn derives_keys(&self) -> bool {
|
||||
self.inner.payer.0.derives_keys()
|
||||
}
|
||||
|
||||
pub(super) fn chain(&self) -> ChainHash {
|
||||
self.inner.chain()
|
||||
}
|
||||
|
||||
/// Verifies that the payer metadata was produced from the invoice request in the TLV stream.
|
||||
pub(super) fn verify<T: secp256k1::Signing>(
|
||||
&self, tlv_stream: TlvStream<'_>, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
|
||||
) -> bool {
|
||||
let offer_records = tlv_stream.clone().range(OFFER_TYPES);
|
||||
let invreq_records = tlv_stream.range(INVOICE_REQUEST_TYPES).filter(|record| {
|
||||
match record.r#type {
|
||||
PAYER_METADATA_TYPE => false, // Should be outside range
|
||||
INVOICE_REQUEST_PAYER_ID_TYPE => !self.inner.payer.0.derives_keys(),
|
||||
_ => true,
|
||||
}
|
||||
});
|
||||
let tlv_stream = offer_records.chain(invreq_records);
|
||||
signer::verify_metadata(self.metadata(), key, IV_BYTES, self.payer_id, tlv_stream, secp_ctx)
|
||||
pub(super) fn payer_id(&self) -> PublicKey {
|
||||
self.payer_id
|
||||
}
|
||||
|
||||
pub(super) fn as_tlv_stream(&self) -> PartialInvoiceRequestTlvStreamRef {
|
||||
|
|
|
@ -85,12 +85,11 @@ use crate::ln::features::InvoiceRequestFeatures;
|
|||
use crate::ln::inbound_payment::{ExpandedKey, IV_LEN, Nonce};
|
||||
use crate::ln::msgs::{DecodeError, MAX_VALUE_MSAT};
|
||||
use crate::offers::invoice::{BlindedPayInfo, InvoiceBuilder};
|
||||
use crate::offers::invoice_request::{INVOICE_REQUEST_PAYER_ID_TYPE, INVOICE_REQUEST_TYPES, InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef};
|
||||
use crate::offers::merkle::TlvStream;
|
||||
use crate::offers::offer::{OFFER_TYPES, OfferTlvStream, OfferTlvStreamRef};
|
||||
use crate::offers::invoice_request::{InvoiceRequestTlvStream, InvoiceRequestTlvStreamRef};
|
||||
use crate::offers::offer::{OfferTlvStream, OfferTlvStreamRef};
|
||||
use crate::offers::parse::{Bech32Encode, ParseError, ParsedMessage, SemanticError};
|
||||
use crate::offers::payer::{PAYER_METADATA_TYPE, PayerContents, PayerTlvStream, PayerTlvStreamRef};
|
||||
use crate::offers::signer::{Metadata, MetadataMaterial, self};
|
||||
use crate::offers::payer::{PayerContents, PayerTlvStream, PayerTlvStreamRef};
|
||||
use crate::offers::signer::{Metadata, MetadataMaterial};
|
||||
use crate::onion_message::BlindedPath;
|
||||
use crate::util::ser::{SeekReadable, WithoutLength, Writeable, Writer};
|
||||
use crate::util::string::PrintableString;
|
||||
|
@ -100,7 +99,7 @@ use crate::prelude::*;
|
|||
#[cfg(feature = "std")]
|
||||
use std::time::SystemTime;
|
||||
|
||||
const IV_BYTES: &[u8; IV_LEN] = b"LDK Refund ~~~~~";
|
||||
pub(super) const IV_BYTES: &[u8; IV_LEN] = b"LDK Refund ~~~~~";
|
||||
|
||||
/// Builds a [`Refund`] for the "offer for money" flow.
|
||||
///
|
||||
|
@ -456,7 +455,7 @@ impl RefundContents {
|
|||
}
|
||||
}
|
||||
|
||||
fn metadata(&self) -> &[u8] {
|
||||
pub(super) fn metadata(&self) -> &[u8] {
|
||||
self.payer.0.as_bytes().map(|bytes| bytes.as_slice()).unwrap_or(&[])
|
||||
}
|
||||
|
||||
|
@ -468,20 +467,12 @@ impl RefundContents {
|
|||
ChainHash::using_genesis_block(Network::Bitcoin)
|
||||
}
|
||||
|
||||
/// Verifies that the payer metadata was produced from the refund in the TLV stream.
|
||||
pub(super) fn verify<T: secp256k1::Signing>(
|
||||
&self, tlv_stream: TlvStream<'_>, key: &ExpandedKey, secp_ctx: &Secp256k1<T>
|
||||
) -> bool {
|
||||
let offer_records = tlv_stream.clone().range(OFFER_TYPES);
|
||||
let invreq_records = tlv_stream.range(INVOICE_REQUEST_TYPES).filter(|record| {
|
||||
match record.r#type {
|
||||
PAYER_METADATA_TYPE => false, // Should be outside range
|
||||
INVOICE_REQUEST_PAYER_ID_TYPE => !self.payer.0.derives_keys(),
|
||||
_ => true,
|
||||
}
|
||||
});
|
||||
let tlv_stream = offer_records.chain(invreq_records);
|
||||
signer::verify_metadata(self.metadata(), key, IV_BYTES, self.payer_id, tlv_stream, secp_ctx)
|
||||
pub(super) fn derives_keys(&self) -> bool {
|
||||
self.payer.0.derives_keys()
|
||||
}
|
||||
|
||||
pub(super) fn payer_id(&self) -> PublicKey {
|
||||
self.payer_id
|
||||
}
|
||||
|
||||
pub(super) fn as_tlv_stream(&self) -> RefundTlvStreamRef {
|
||||
|
|
Loading…
Add table
Reference in a new issue