Add length check for read ChannelMonitor keys
[rust-lightning] / lightning / src / sign / mod.rs
index 66217de28ac7f7dd15ba9d9ca354c1c06afe9d2b..f25c947644838f1dfaec843c74c26c8b4f935f72 100644 (file)
@@ -26,10 +26,10 @@ use bitcoin::hashes::sha256::Hash as Sha256;
 use bitcoin::hashes::sha256d::Hash as Sha256dHash;
 use bitcoin::hash_types::WPubkeyHash;
 
-use bitcoin::secp256k1::{SecretKey, PublicKey, Scalar};
-use bitcoin::secp256k1::{Secp256k1, ecdsa::Signature, Signing};
+use bitcoin::secp256k1::{KeyPair, PublicKey, Scalar, Secp256k1, SecretKey, Signing};
 use bitcoin::secp256k1::ecdh::SharedSecret;
-use bitcoin::secp256k1::ecdsa::RecoverableSignature;
+use bitcoin::secp256k1::ecdsa::{RecoverableSignature, Signature};
+use bitcoin::secp256k1::schnorr;
 use bitcoin::{PackedLockTime, secp256k1, Sequence, Witness};
 
 use crate::util::transaction_utils;
@@ -42,6 +42,8 @@ use crate::ln::{chan_utils, PaymentPreimage};
 use crate::ln::chan_utils::{HTLCOutputInCommitment, make_funding_redeemscript, ChannelPublicKeys, HolderCommitmentTransaction, ChannelTransactionParameters, CommitmentTransaction, ClosingTransaction};
 use crate::ln::msgs::{UnsignedChannelAnnouncement, UnsignedGossipMessage};
 use crate::ln::script::ShutdownScript;
+use crate::offers::invoice::UnsignedBolt12Invoice;
+use crate::offers::invoice_request::UnsignedInvoiceRequest;
 
 use crate::prelude::*;
 use core::convert::TryInto;
@@ -54,6 +56,8 @@ use crate::util::atomic_counter::AtomicCounter;
 use crate::util::chacha20::ChaCha20;
 use crate::util::invoice::construct_invoice_preimage;
 
+pub(crate) mod type_resolver;
+
 /// Used as initial key material, to be expanded into multiple secret keys (but not to be used
 /// directly). This is used within LDK to encrypt/decrypt inbound payment data.
 ///
@@ -620,6 +624,36 @@ pub trait NodeSigner {
        /// Errors if the [`Recipient`] variant is not supported by the implementation.
        fn sign_invoice(&self, hrp_bytes: &[u8], invoice_data: &[u5], recipient: Recipient) -> Result<RecoverableSignature, ()>;
 
+       /// Signs the [`TaggedHash`] of a BOLT 12 invoice request.
+       ///
+       /// May be called by a function passed to [`UnsignedInvoiceRequest::sign`] where
+       /// `invoice_request` is the callee.
+       ///
+       /// Implementors may check that the `invoice_request` is expected rather than blindly signing
+       /// the tagged hash. An `Ok` result should sign `invoice_request.tagged_hash().as_digest()` with
+       /// the node's signing key or an ephemeral key to preserve privacy, whichever is associated with
+       /// [`UnsignedInvoiceRequest::payer_id`].
+       ///
+       /// [`TaggedHash`]: crate::offers::merkle::TaggedHash
+       fn sign_bolt12_invoice_request(
+               &self, invoice_request: &UnsignedInvoiceRequest
+       ) -> Result<schnorr::Signature, ()>;
+
+       /// Signs the [`TaggedHash`] of a BOLT 12 invoice.
+       ///
+       /// May be called by a function passed to [`UnsignedBolt12Invoice::sign`] where `invoice` is the
+       /// callee.
+       ///
+       /// Implementors may check that the `invoice` is expected rather than blindly signing the tagged
+       /// hash. An `Ok` result should sign `invoice.tagged_hash().as_digest()` with the node's signing
+       /// key or an ephemeral key to preserve privacy, whichever is associated with
+       /// [`UnsignedBolt12Invoice::signing_pubkey`].
+       ///
+       /// [`TaggedHash`]: crate::offers::merkle::TaggedHash
+       fn sign_bolt12_invoice(
+               &self, invoice: &UnsignedBolt12Invoice
+       ) -> Result<schnorr::Signature, ()>;
+
        /// Sign a gossip message.
        ///
        /// Note that if this fails, LDK may panic and the message will not be broadcast to the network
@@ -1030,15 +1064,12 @@ impl EcdsaChannelSigner for InMemorySigner {
                &self, htlc_tx: &Transaction, input: usize, htlc_descriptor: &HTLCDescriptor,
                secp_ctx: &Secp256k1<secp256k1::All>
        ) -> Result<Signature, ()> {
-               let per_commitment_point = self.get_per_commitment_point(
-                       htlc_descriptor.per_commitment_number, &secp_ctx
-               );
-               let witness_script = htlc_descriptor.witness_script(&per_commitment_point, secp_ctx);
+               let witness_script = htlc_descriptor.witness_script(secp_ctx);
                let sighash = &sighash::SighashCache::new(&*htlc_tx).segwit_signature_hash(
                        input, &witness_script, htlc_descriptor.htlc.amount_msat / 1000, EcdsaSighashType::All
                ).map_err(|_| ())?;
                let our_htlc_private_key = chan_utils::derive_private_key(
-                       &secp_ctx, &per_commitment_point, &self.htlc_base_key
+                       &secp_ctx, &htlc_descriptor.per_commitment_point, &self.htlc_base_key
                );
                Ok(sign_with_aux_rand(&secp_ctx, &hash_to_message!(sighash), &our_htlc_private_key, &self))
        }
@@ -1315,7 +1346,7 @@ impl KeysManager {
        ///
        /// May panic if the [`SpendableOutputDescriptor`]s were not generated by channels which used
        /// this [`KeysManager`] or one of the [`InMemorySigner`] created by this [`KeysManager`].
-       pub fn sign_spendable_outputs_psbt<C: Signing>(&self, descriptors: &[&SpendableOutputDescriptor], psbt: &mut PartiallySignedTransaction, secp_ctx: &Secp256k1<C>) -> Result<(), ()> {
+       pub fn sign_spendable_outputs_psbt<C: Signing>(&self, descriptors: &[&SpendableOutputDescriptor], mut psbt: PartiallySignedTransaction, secp_ctx: &Secp256k1<C>) -> Result<PartiallySignedTransaction, ()> {
                let mut keys_cache: Option<(InMemorySigner, [u8; 32])> = None;
                for outp in descriptors {
                        match outp {
@@ -1377,7 +1408,7 @@ impl KeysManager {
                        }
                }
 
-               Ok(())
+               Ok(psbt)
        }
 
        /// Creates a [`Transaction`] which spends the given descriptors to the given outputs, plus an
@@ -1399,7 +1430,7 @@ impl KeysManager {
        /// this [`KeysManager`] or one of the [`InMemorySigner`] created by this [`KeysManager`].
        pub fn spend_spendable_outputs<C: Signing>(&self, descriptors: &[&SpendableOutputDescriptor], outputs: Vec<TxOut>, change_destination_script: Script, feerate_sat_per_1000_weight: u32, locktime: Option<PackedLockTime>, secp_ctx: &Secp256k1<C>) -> Result<Transaction, ()> {
                let (mut psbt, expected_max_weight) = SpendableOutputDescriptor::create_spendable_outputs_psbt(descriptors, outputs, change_destination_script, feerate_sat_per_1000_weight, locktime)?;
-               self.sign_spendable_outputs_psbt(descriptors, &mut psbt, secp_ctx)?;
+               psbt = self.sign_spendable_outputs_psbt(descriptors, psbt, secp_ctx)?;
 
                let spend_tx = psbt.extract_tx();
 
@@ -1453,6 +1484,24 @@ impl NodeSigner for KeysManager {
                Ok(self.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), secret))
        }
 
+       fn sign_bolt12_invoice_request(
+               &self, invoice_request: &UnsignedInvoiceRequest
+       ) -> Result<schnorr::Signature, ()> {
+               let message = invoice_request.tagged_hash().as_digest();
+               let keys = KeyPair::from_secret_key(&self.secp_ctx, &self.node_secret);
+               let aux_rand = self.get_secure_random_bytes();
+               Ok(self.secp_ctx.sign_schnorr_with_aux_rand(message, &keys, &aux_rand))
+       }
+
+       fn sign_bolt12_invoice(
+               &self, invoice: &UnsignedBolt12Invoice
+       ) -> Result<schnorr::Signature, ()> {
+               let message = invoice.tagged_hash().as_digest();
+               let keys = KeyPair::from_secret_key(&self.secp_ctx, &self.node_secret);
+               let aux_rand = self.get_secure_random_bytes();
+               Ok(self.secp_ctx.sign_schnorr_with_aux_rand(message, &keys, &aux_rand))
+       }
+
        fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()> {
                let msg_hash = hash_to_message!(&Sha256dHash::hash(&msg.encode()[..])[..]);
                Ok(self.secp_ctx.sign_ecdsa(&msg_hash, &self.node_secret))
@@ -1561,6 +1610,18 @@ impl NodeSigner for PhantomKeysManager {
                Ok(self.inner.secp_ctx.sign_ecdsa_recoverable(&hash_to_message!(&Sha256::hash(&preimage)), secret))
        }
 
+       fn sign_bolt12_invoice_request(
+               &self, invoice_request: &UnsignedInvoiceRequest
+       ) -> Result<schnorr::Signature, ()> {
+               self.inner.sign_bolt12_invoice_request(invoice_request)
+       }
+
+       fn sign_bolt12_invoice(
+               &self, invoice: &UnsignedBolt12Invoice
+       ) -> Result<schnorr::Signature, ()> {
+               self.inner.sign_bolt12_invoice(invoice)
+       }
+
        fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()> {
                self.inner.sign_gossip_message(msg)
        }