X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fchannelmanager.rs;h=5216882d4a90126be786776f60781443eb2b31f2;hb=8783a748bb952168623cb674f8ea3230d7c94b25;hp=b8eef0339efec3ad7b3055b2cf2676d052bd22e8;hpb=7cfb09c79752ec68dd36af36689e3f75834e39d6;p=rust-lightning diff --git a/src/ln/channelmanager.rs b/src/ln/channelmanager.rs index b8eef033..5216882d 100644 --- a/src/ln/channelmanager.rs +++ b/src/ln/channelmanager.rs @@ -972,26 +972,26 @@ impl ChannelManager { } fn decode_update_add_htlc_onion(&self, msg: &msgs::UpdateAddHTLC) -> (PendingHTLCStatus, MutexGuard) { - macro_rules! get_onion_hash { - () => { + macro_rules! return_malformed_err { + ($msg: expr, $err_code: expr) => { { + log_info!(self, "Failed to accept/forward incoming HTLC: {}", $msg); + let mut sha256_of_onion = [0; 32]; let mut sha = Sha256::new(); sha.input(&msg.onion_routing_packet.hop_data); - let mut onion_hash = [0; 32]; - sha.result(&mut onion_hash); - onion_hash + sha.result(&mut sha256_of_onion); + return (PendingHTLCStatus::Fail(HTLCFailureMsg::Malformed(msgs::UpdateFailMalformedHTLC { + channel_id: msg.channel_id, + htlc_id: msg.htlc_id, + sha256_of_onion, + failure_code: $err_code, + })), self.channel_state.lock().unwrap()); } } } if let Err(_) = msg.onion_routing_packet.public_key { - log_info!(self, "Failed to accept/forward incoming HTLC with invalid ephemeral pubkey"); - return (PendingHTLCStatus::Fail(HTLCFailureMsg::Malformed(msgs::UpdateFailMalformedHTLC { - channel_id: msg.channel_id, - htlc_id: msg.htlc_id, - sha256_of_onion: get_onion_hash!(), - failure_code: 0x8000 | 0x4000 | 6, - })), self.channel_state.lock().unwrap()); + return_malformed_err!("invalid ephemeral pubkey", 0x8000 | 0x4000 | 6); } let shared_secret = { @@ -1001,6 +1001,23 @@ impl ChannelManager { }; let (rho, mu) = ChannelManager::gen_rho_mu_from_shared_secret(&shared_secret); + if msg.onion_routing_packet.version != 0 { + //TODO: Spec doesn't indicate if we should only hash hop_data here (and in other + //sha256_of_onion error data packets), or the entire onion_routing_packet. Either way, + //the hash doesn't really serve any purpuse - in the case of hashing all data, the + //receiving node would have to brute force to figure out which version was put in the + //packet by the node that send us the message, in the case of hashing the hop_data, the + //node knows the HMAC matched, so they already know what is there... + return_malformed_err!("Unknown onion packet version", 0x8000 | 0x4000 | 4); + } + + let mut hmac = Hmac::new(Sha256::new(), &mu); + hmac.input(&msg.onion_routing_packet.hop_data); + hmac.input(&msg.payment_hash.0[..]); + if hmac.result() != MacResult::new(&msg.onion_routing_packet.hmac) { + return_malformed_err!("HMAC Check failed", 0x8000 | 0x4000 | 5); + } + let mut channel_state = None; macro_rules! return_err { ($msg: expr, $err_code: expr, $data: expr) => { @@ -1018,23 +1035,6 @@ impl ChannelManager { } } - if msg.onion_routing_packet.version != 0 { - //TODO: Spec doesn't indicate if we should only hash hop_data here (and in other - //sha256_of_onion error data packets), or the entire onion_routing_packet. Either way, - //the hash doesn't really serve any purpuse - in the case of hashing all data, the - //receiving node would have to brute force to figure out which version was put in the - //packet by the node that send us the message, in the case of hashing the hop_data, the - //node knows the HMAC matched, so they already know what is there... - return_err!("Unknown onion packet version", 0x8000 | 0x4000 | 4, &get_onion_hash!()); - } - - let mut hmac = Hmac::new(Sha256::new(), &mu); - hmac.input(&msg.onion_routing_packet.hop_data); - hmac.input(&msg.payment_hash.0[..]); - if hmac.result() != MacResult::new(&msg.onion_routing_packet.hmac) { - return_err!("HMAC Check failed", 0x8000 | 0x4000 | 5, &get_onion_hash!()); - } - let mut chacha = ChaCha20::new(&rho, &[0u8; 8]); let next_hop_data = { let mut decoded = [0; 65]; @@ -1092,21 +1092,16 @@ impl ChannelManager { sha.input(&shared_secret); let mut res = [0u8; 32]; sha.result(&mut res); - match SecretKey::from_slice(&self.secp_ctx, &res) { - Err(_) => { - return_err!("Blinding factor is an invalid private key", 0x8000 | 0x4000 | 6, &get_onion_hash!()); - }, - Ok(key) => key - } + SecretKey::from_slice(&self.secp_ctx, &res).expect("SHA-256 is broken?") }; - if let Err(_) = new_pubkey.mul_assign(&self.secp_ctx, &blinding_factor) { - return_err!("New blinding factor is an invalid private key", 0x8000 | 0x4000 | 6, &get_onion_hash!()); - } + let public_key = if let Err(e) = new_pubkey.mul_assign(&self.secp_ctx, &blinding_factor) { + Err(e) + } else { Ok(new_pubkey) }; let outgoing_packet = msgs::OnionPacket { version: 0, - public_key: Ok(new_pubkey), + public_key, hop_data: new_packet_data, hmac: next_hop_data.hmac.clone(), }; @@ -3575,6 +3570,7 @@ mod tests { chain_monitor: Arc, tx_broadcaster: Arc, chan_monitor: Arc, + keys_manager: Arc, node: Arc, router: Router, node_seed: [u8; 32], @@ -3782,6 +3778,8 @@ mod tests { let as_update = match events_8[0] { MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => { assert!(*announcement == *msg); + assert_eq!(update_msg.contents.short_channel_id, announcement.contents.short_channel_id); + assert_eq!(update_msg.contents.short_channel_id, bs_update.contents.short_channel_id); update_msg }, _ => panic!("Unexpected event"), @@ -4306,14 +4304,14 @@ mod tests { let tx_broadcaster = Arc::new(test_utils::TestBroadcaster{txn_broadcasted: Mutex::new(Vec::new())}); let mut seed = [0; 32]; rng.fill_bytes(&mut seed); - let keys_manager = Arc::new(keysinterface::KeysManager::new(&seed, Network::Testnet, Arc::clone(&logger))); + let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&seed, Network::Testnet, Arc::clone(&logger))); let chan_monitor = Arc::new(test_utils::TestChannelMonitor::new(chain_monitor.clone(), tx_broadcaster.clone(), logger.clone())); let mut config = UserConfig::new(); config.channel_options.announced_channel = true; config.channel_limits.force_announced_channel_preference = false; let node = ChannelManager::new(Network::Testnet, feeest.clone(), chan_monitor.clone(), chain_monitor.clone(), tx_broadcaster.clone(), Arc::clone(&logger), keys_manager.clone(), config).unwrap(); let router = Router::new(PublicKey::from_secret_key(&secp_ctx, &keys_manager.get_node_secret()), chain_monitor.clone(), Arc::clone(&logger)); - nodes.push(Node { chain_monitor, tx_broadcaster, chan_monitor, node, router, node_seed: seed, + nodes.push(Node { chain_monitor, tx_broadcaster, chan_monitor, node, router, keys_manager, node_seed: seed, network_payment_count: payment_count.clone(), network_chan_count: chan_count.clone(), });