X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fmsgs.rs;h=66bbc9d1700d13810f399978e3a70cf117eeae23;hb=7dc215edcbf79a286aea7b04fb29d76bc5ad3985;hp=7f502530a9db55f5177aad787380645d8d72fcf0;hpb=a331849005e131da2d27f2848bf6b2598f94836a;p=rust-lightning diff --git a/src/ln/msgs.rs b/src/ln/msgs.rs index 7f502530..66bbc9d1 100644 --- a/src/ln/msgs.rs +++ b/src/ln/msgs.rs @@ -1,11 +1,12 @@ use secp256k1::key::PublicKey; use secp256k1::{Secp256k1, Signature}; +use secp256k1; use bitcoin::util::hash::Sha256dHash; use bitcoin::network::serialize::{deserialize,serialize}; use bitcoin::blockdata::script::Script; use std::error::Error; -use std::fmt; +use std::{cmp, fmt}; use std::result::Result; use util::{byte_utils, internal_traits, events}; @@ -280,7 +281,7 @@ pub struct ChannelReestablish { pub next_local_commitment_number: u64, pub next_remote_commitment_number: u64, pub your_last_per_commitment_secret: Option<[u8; 32]>, - pub my_current_per_commitment_point: PublicKey, + pub my_current_per_commitment_point: Option, } #[derive(Clone)] @@ -376,11 +377,6 @@ pub struct ChannelUpdate { /// Used to put an error message in a HandleError pub enum ErrorAction { - /// Indicates an inbound HTLC add resulted in a failure, and the UpdateFailHTLC provided in msg - /// should be sent back to the sender. - UpdateFailHTLC { - msg: UpdateFailHTLC - }, /// The peer took some action which made us think they were useless. Disconnect them. DisconnectPeer { msg: Option @@ -404,6 +400,7 @@ pub struct CommitmentUpdate { pub update_add_htlcs: Vec, pub update_fulfill_htlcs: Vec, pub update_fail_htlcs: Vec, + pub update_fail_malformed_htlcs: Vec, pub commitment_signed: CommitmentSigned, } @@ -444,12 +441,14 @@ pub trait ChannelMessageHandler : events::EventsProvider + Send + Sync { // Channel-to-announce: fn handle_announcement_signatures(&self, their_node_id: &PublicKey, msg: &AnnouncementSignatures) -> Result<(), HandleError>; - // Informational: + // Error conditions: /// Indicates a connection to the peer failed/an existing connection was lost. If no connection /// is believed to be possible in the future (eg they're sending us messages we don't /// understand or indicate they require unknown feature bits), no_connection_possible is set /// and any outstanding channels should be failed. fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool); + + fn handle_error(&self, their_node_id: &PublicKey, msg: &ErrorMessage); } pub trait RoutingMessageHandler : Send + Sync { @@ -478,7 +477,10 @@ unsafe impl internal_traits::NoDealloc for OnionHopData{} #[derive(Clone)] pub struct OnionPacket { pub version: u8, - pub public_key: PublicKey, + /// In order to ensure we always return an error on Onion decode in compliance with BOLT 4, we + /// have to deserialize OnionPackets contained in UpdateAddHTLCs even if the ephemeral public + /// key (here) is bogus, so we hold a Result instead of a PublicKey as we'd like. + pub public_key: Result, pub hop_data: [u8; 20*65], pub hmac: [u8; 32], } @@ -937,7 +939,7 @@ impl MsgDecodable for UpdateAddHTLC { } impl MsgEncodable for UpdateAddHTLC { fn encode(&self) -> Vec { - let mut res = Vec::with_capacity(32+8+8+32+4+1+1366); + let mut res = Vec::with_capacity(32+8+8+32+4+1366); res.extend_from_slice(&self.channel_id); res.extend_from_slice(&byte_utils::be64_to_array(self.htlc_id)); res.extend_from_slice(&byte_utils::be64_to_array(self.amount_msat)); @@ -1116,38 +1118,34 @@ impl MsgEncodable for UpdateFee { impl MsgDecodable for ChannelReestablish { fn decode(v: &[u8]) -> Result { - if v.len() < 32+2*8+33 { + if v.len() < 32+2*8 { return Err(DecodeError::ShortRead); } - let your_last_per_commitment_secret = if v.len() > 32+2*8+33 { - if v.len() < 32+2*8+33 + 32 { + let (your_last_per_commitment_secret, my_current_per_commitment_point) = if v.len() > 32+2*8 { + if v.len() < 32+2*8 + 33+32 { return Err(DecodeError::ShortRead); } let mut inner_array = [0; 32]; inner_array.copy_from_slice(&v[48..48+32]); - Some(inner_array) - } else { None }; + (Some(inner_array), { + let ctx = Secp256k1::without_caps(); + Some(secp_pubkey!(&ctx, &v[48+32..48+32+33])) + }) + } else { (None, None) }; - let option_size = match &your_last_per_commitment_secret { - &Some(ref _ary) => 32, - &None => 0, - }; Ok(Self { channel_id: deserialize(&v[0..32]).unwrap(), next_local_commitment_number: byte_utils::slice_to_be64(&v[32..40]), next_remote_commitment_number: byte_utils::slice_to_be64(&v[40..48]), your_last_per_commitment_secret: your_last_per_commitment_secret, - my_current_per_commitment_point: { - let ctx = Secp256k1::without_caps(); - secp_pubkey!(&ctx, &v[48+option_size..48+option_size+33]) - } + my_current_per_commitment_point: my_current_per_commitment_point, }) } } impl MsgEncodable for ChannelReestablish { fn encode(&self) -> Vec { - let mut res = Vec::with_capacity(if self.your_last_per_commitment_secret.is_some() { 32+2*3+33 + 32 } else { 32+2*8+33 }); + let mut res = Vec::with_capacity(if self.your_last_per_commitment_secret.is_some() { 32+2*8+33+32 } else { 32+2*8 }); res.extend_from_slice(&serialize(&self.channel_id).unwrap()[..]); res.extend_from_slice(&byte_utils::be64_to_array(self.next_local_commitment_number)); @@ -1155,9 +1153,8 @@ impl MsgEncodable for ChannelReestablish { if let &Some(ref ary) = &self.your_last_per_commitment_secret { res.extend_from_slice(&ary[..]); + res.extend_from_slice(&self.my_current_per_commitment_point.expect("my_current_per_commitment_point should have been filled").serialize()); } - - res.extend_from_slice(&self.my_current_per_commitment_point.serialize()); res } } @@ -1540,7 +1537,7 @@ impl MsgDecodable for OnionPacket { let secp_ctx = Secp256k1::without_caps(); Ok(Self { version: v[0], - public_key: secp_pubkey!(&secp_ctx, &v[1..34]), + public_key: PublicKey::from_slice(&secp_ctx, &v[1..34]), hop_data, hmac, }) @@ -1550,7 +1547,10 @@ impl MsgEncodable for OnionPacket { fn encode(&self) -> Vec { let mut res = Vec::with_capacity(1 + 33 + 20*65 + 32); res.push(self.version); - res.extend_from_slice(&self.public_key.serialize()); + match self.public_key { + Ok(pubkey) => res.extend_from_slice(&pubkey.serialize()), + Err(_) => res.extend_from_slice(&[0; 33]), + } res.extend_from_slice(&self.hop_data); res.extend_from_slice(&self.hmac); res @@ -1629,11 +1629,9 @@ impl MsgDecodable for ErrorMessage { if v.len() < 34 { return Err(DecodeError::ShortRead); } - let len = byte_utils::slice_to_be16(&v[32..34]); - if v.len() < 34 + len as usize { - return Err(DecodeError::ShortRead); - } - let data = match String::from_utf8(v[34..34 + len as usize].to_vec()) { + // Unlike most messages, BOLT 1 requires we truncate our read if the value is out of range + let len = cmp::min(byte_utils::slice_to_be16(&v[32..34]) as usize, v.len() - 34); + let data = match String::from_utf8(v[34..34 + len].to_vec()) { Ok(s) => s, Err(_) => return Err(DecodeError::BadText), }; @@ -1648,7 +1646,7 @@ impl MsgDecodable for ErrorMessage { #[cfg(test)] mod tests { - use bitcoin::util::misc::hex_bytes; + use hex; use ln::msgs::MsgEncodable; use ln::msgs; use secp256k1::key::{PublicKey,SecretKey}; @@ -1658,7 +1656,7 @@ mod tests { fn encoding_channel_reestablish_no_secret() { let public_key = { let secp_ctx = Secp256k1::new(); - PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &hex_bytes("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap()).unwrap() + PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap()) }; let cr = msgs::ChannelReestablish { @@ -1680,7 +1678,7 @@ mod tests { fn encoding_channel_reestablish_with_secret() { let public_key = { let secp_ctx = Secp256k1::new(); - PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &hex_bytes("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap()).unwrap() + PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&secp_ctx, &hex::decode("0101010101010101010101010101010101010101010101010101010101010101").unwrap()[..]).unwrap()) }; let cr = msgs::ChannelReestablish {