Skip to content

Commit b9d1024

Browse files
authored
Merge pull request #108 from TheBlueMatt/2018-08-fuzz-fixes
Asorted Fixes from full_stack_target work
2 parents 830343f + c52825d commit b9d1024

File tree

5 files changed

+66
-29
lines changed

5 files changed

+66
-29
lines changed

src/ln/channel.rs

+32-15
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ pub struct Channel {
271271
/// to detect unconfirmation after a serialize-unserialize roudtrip where we may not see a full
272272
/// series of block_connected/block_disconnected calls. Obviously this is not a guarantee as we
273273
/// could miss the funding_tx_confirmed_in block as well, but it serves as a useful fallback.
274-
funding_tx_confirmed_in: Sha256dHash,
274+
funding_tx_confirmed_in: Option<Sha256dHash>,
275275
short_channel_id: Option<u64>,
276276
/// Used to deduplicate block_connected callbacks
277277
last_block_connected: Sha256dHash,
@@ -401,7 +401,7 @@ impl Channel {
401401

402402
last_sent_closing_fee: None,
403403

404-
funding_tx_confirmed_in: Default::default(),
404+
funding_tx_confirmed_in: None,
405405
short_channel_id: None,
406406
last_block_connected: Default::default(),
407407
funding_tx_confirmations: 0,
@@ -519,7 +519,7 @@ impl Channel {
519519

520520
last_sent_closing_fee: None,
521521

522-
funding_tx_confirmed_in: Default::default(),
522+
funding_tx_confirmed_in: None,
523523
short_channel_id: None,
524524
last_block_connected: Default::default(),
525525
funding_tx_confirmations: 0,
@@ -1827,6 +1827,7 @@ impl Channel {
18271827
self.user_id
18281828
}
18291829

1830+
/// May only be called after funding has been initiated (ie is_funding_initiated() is true)
18301831
pub fn channel_monitor(&self) -> ChannelMonitor {
18311832
if self.channel_state < ChannelState::FundingCreated as u32 {
18321833
panic!("Can't get a channel monitor until funding has been created");
@@ -1904,6 +1905,11 @@ impl Channel {
19041905
self.is_usable()
19051906
}
19061907

1908+
/// Returns true if funding_created was sent/received.
1909+
pub fn is_funding_initiated(&self) -> bool {
1910+
self.channel_state >= ChannelState::FundingCreated as u32
1911+
}
1912+
19071913
/// Returns true if this channel is fully shut down. True here implies that no further actions
19081914
/// may/will be taken on this channel, and thus this object should be freed. Any future changes
19091915
/// will be handled appropriately by the chain monitor.
@@ -1927,27 +1933,38 @@ impl Channel {
19271933
self.last_block_connected = header.bitcoin_hash();
19281934
self.funding_tx_confirmations += 1;
19291935
if self.funding_tx_confirmations == CONF_TARGET as u64 {
1930-
if non_shutdown_state == ChannelState::FundingSent as u32 {
1936+
let need_commitment_update = if non_shutdown_state == ChannelState::FundingSent as u32 {
19311937
self.channel_state |= ChannelState::OurFundingLocked as u32;
1938+
true
19321939
} else if non_shutdown_state == (ChannelState::FundingSent as u32 | ChannelState::TheirFundingLocked as u32) {
19331940
self.channel_state = ChannelState::ChannelFunded as u32 | (self.channel_state & BOTH_SIDES_SHUTDOWN_MASK);
19341941
self.channel_update_count += 1;
1935-
//TODO: Something about a state where we "lost confirmation"
1942+
true
1943+
} else if self.channel_state == (ChannelState::FundingSent as u32 | ChannelState::OurFundingLocked as u32) {
1944+
// We got a reorg but not enough to trigger a force close, just update
1945+
// funding_tx_confirmed_in and return.
1946+
false
19361947
} else if self.channel_state < ChannelState::ChannelFunded as u32 {
1937-
panic!("Started confirming a channel in a state pre-FundingSent?");
1938-
}
1939-
self.funding_tx_confirmed_in = header.bitcoin_hash();
1948+
panic!("Started confirming a channel in a state pre-FundingSent?: {}", self.channel_state);
1949+
} else {
1950+
// We got a reorg but not enough to trigger a force close, just update
1951+
// funding_tx_confirmed_in and return.
1952+
false
1953+
};
1954+
self.funding_tx_confirmed_in = Some(header.bitcoin_hash());
19401955

19411956
//TODO: Note that this must be a duplicate of the previous commitment point they sent us,
19421957
//as otherwise we will have a commitment transaction that they can't revoke (well, kinda,
19431958
//they can by sending two revoke_and_acks back-to-back, but not really). This appears to be
19441959
//a protocol oversight, but I assume I'm just missing something.
1945-
let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number);
1946-
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret).unwrap();
1947-
return Ok(Some(msgs::FundingLocked {
1948-
channel_id: self.channel_id,
1949-
next_per_commitment_point: next_per_commitment_point,
1950-
}));
1960+
if need_commitment_update {
1961+
let next_per_commitment_secret = self.build_local_commitment_secret(self.cur_local_commitment_transaction_number);
1962+
let next_per_commitment_point = PublicKey::from_secret_key(&self.secp_ctx, &next_per_commitment_secret).unwrap();
1963+
return Ok(Some(msgs::FundingLocked {
1964+
channel_id: self.channel_id,
1965+
next_per_commitment_point: next_per_commitment_point,
1966+
}));
1967+
}
19511968
}
19521969
}
19531970
}
@@ -1982,7 +1999,7 @@ impl Channel {
19821999
return true;
19832000
}
19842001
}
1985-
if header.bitcoin_hash() == self.funding_tx_confirmed_in {
2002+
if Some(header.bitcoin_hash()) == self.funding_tx_confirmed_in {
19862003
self.funding_tx_confirmations = CONF_TARGET as u64 - 1;
19872004
}
19882005
false

src/ln/channelmanager.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ use ln::msgs;
1919
use ln::msgs::{HandleError,ChannelMessageHandler,MsgEncodable,MsgDecodable};
2020
use util::{byte_utils, events, internal_traits, rng};
2121
use util::sha2::Sha256;
22+
use util::chacha20poly1305rfc::ChaCha20;
2223

2324
use crypto;
2425
use crypto::mac::{Mac,MacResult};
2526
use crypto::hmac::Hmac;
2627
use crypto::digest::Digest;
2728
use crypto::symmetriccipher::SynchronousStreamCipher;
28-
use crypto::chacha20::ChaCha20;
2929

3030
use std::{ptr, mem};
3131
use std::collections::HashMap;
@@ -1188,7 +1188,7 @@ impl ChainListener for ChannelManager {
11881188
}
11891189
}
11901190
}
1191-
if channel.channel_monitor().would_broadcast_at_height(height) {
1191+
if channel.is_funding_initiated() && channel.channel_monitor().would_broadcast_at_height(height) {
11921192
if let Some(short_id) = channel.get_short_channel_id() {
11931193
short_to_id.remove(&short_id);
11941194
}
@@ -1268,13 +1268,13 @@ impl ChannelMessageHandler for ChannelManager {
12681268

12691269
let chan_keys = if cfg!(feature = "fuzztarget") {
12701270
ChannelKeys {
1271-
funding_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(),
1272-
revocation_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(),
1273-
payment_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(),
1274-
delayed_payment_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(),
1275-
htlc_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(),
1276-
channel_close_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(),
1277-
channel_monitor_claim_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(),
1271+
funding_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]).unwrap(),
1272+
revocation_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0]).unwrap(),
1273+
payment_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0]).unwrap(),
1274+
delayed_payment_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0]).unwrap(),
1275+
htlc_base_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0]).unwrap(),
1276+
channel_close_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0]).unwrap(),
1277+
channel_monitor_claim_key: SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0]).unwrap(),
12781278
commitment_seed: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
12791279
}
12801280
} else {

src/ln/channelmonitor.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,9 @@ impl ChannelMonitor {
423423

424424
pub fn insert_combine(&mut self, mut other: ChannelMonitor) -> Result<(), HandleError> {
425425
if self.funding_txo.is_some() {
426-
if other.funding_txo.is_some() && other.funding_txo.as_ref().unwrap() != self.funding_txo.as_ref().unwrap() {
426+
// We should be able to compare the entire funding_txo, but in fuzztarget its trivially
427+
// easy to collide the funding_txo hash and have a different scriptPubKey.
428+
if other.funding_txo.is_some() && other.funding_txo.as_ref().unwrap().0 != self.funding_txo.as_ref().unwrap().0 {
427429
return Err(HandleError{err: "Funding transaction outputs are not identical!", action: None});
428430
}
429431
} else {

src/ln/msgs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ impl MsgDecodable for UpdateAddHTLC {
937937
}
938938
impl MsgEncodable for UpdateAddHTLC {
939939
fn encode(&self) -> Vec<u8> {
940-
let mut res = Vec::with_capacity(32+8+8+32+4+1+1366);
940+
let mut res = Vec::with_capacity(32+8+8+32+4+1366);
941941
res.extend_from_slice(&self.channel_id);
942942
res.extend_from_slice(&byte_utils::be64_to_array(self.htlc_id));
943943
res.extend_from_slice(&byte_utils::be64_to_array(self.amount_msat));

src/util/chacha20poly1305rfc.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@
1313
#[cfg(not(feature = "fuzztarget"))]
1414
mod real_chachapoly {
1515
use crypto::aead::{AeadEncryptor,AeadDecryptor};
16-
use crypto::chacha20::ChaCha20;
1716
use crypto::symmetriccipher::SynchronousStreamCipher;
1817
use crypto::poly1305::Poly1305;
1918
use crypto::mac::Mac;
2019
use crypto::util::fixed_time_eq;
2120

21+
pub use crypto::chacha20::ChaCha20;
22+
2223
use util::byte_utils;
2324

2425
#[derive(Clone, Copy)]
@@ -104,11 +105,12 @@ mod real_chachapoly {
104105
}
105106
}
106107
#[cfg(not(feature = "fuzztarget"))]
107-
pub use self::real_chachapoly::ChaCha20Poly1305RFC;
108+
pub use self::real_chachapoly::{ChaCha20Poly1305RFC, ChaCha20};
108109

109110
#[cfg(feature = "fuzztarget")]
110111
mod fuzzy_chachapoly {
111112
use crypto::aead::{AeadEncryptor,AeadDecryptor};
113+
use crypto::symmetriccipher::SynchronousStreamCipher;
112114

113115
#[derive(Clone, Copy)]
114116
pub struct ChaCha20Poly1305RFC {
@@ -155,6 +157,22 @@ mod fuzzy_chachapoly {
155157
true
156158
}
157159
}
160+
161+
pub struct ChaCha20 {}
162+
163+
impl ChaCha20 {
164+
pub fn new(key: &[u8], nonce: &[u8]) -> ChaCha20 {
165+
assert!(key.len() == 16 || key.len() == 32);
166+
assert!(nonce.len() == 8 || nonce.len() == 12);
167+
Self {}
168+
}
169+
}
170+
171+
impl SynchronousStreamCipher for ChaCha20 {
172+
fn process(&mut self, input: &[u8], output: &mut [u8]) {
173+
output.copy_from_slice(input);
174+
}
175+
}
158176
}
159177
#[cfg(feature = "fuzztarget")]
160-
pub use self::fuzzy_chachapoly::ChaCha20Poly1305RFC;
178+
pub use self::fuzzy_chachapoly::{ChaCha20Poly1305RFC, ChaCha20};

0 commit comments

Comments
 (0)