Skip to content

Commit b7e76c5

Browse files
committed
Always return malformed for BADONION errors
Also be willing to forward something with a pubkey that we know is complete garbage, but upstream will just fail that with BADONION when they get it. I think this is kinda intended by the spec, but it definitely needs to be clarified.
1 parent 7cfb09c commit b7e76c5

File tree

1 file changed

+34
-39
lines changed

1 file changed

+34
-39
lines changed

src/ln/channelmanager.rs

Lines changed: 34 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -972,26 +972,26 @@ impl ChannelManager {
972972
}
973973

974974
fn decode_update_add_htlc_onion(&self, msg: &msgs::UpdateAddHTLC) -> (PendingHTLCStatus, MutexGuard<ChannelHolder>) {
975-
macro_rules! get_onion_hash {
976-
() => {
975+
macro_rules! return_malformed_err {
976+
($msg: expr, $err_code: expr) => {
977977
{
978+
log_info!(self, "Failed to accept/forward incoming HTLC: {}", $msg);
979+
let mut sha256_of_onion = [0; 32];
978980
let mut sha = Sha256::new();
979981
sha.input(&msg.onion_routing_packet.hop_data);
980-
let mut onion_hash = [0; 32];
981-
sha.result(&mut onion_hash);
982-
onion_hash
982+
sha.result(&mut sha256_of_onion);
983+
return (PendingHTLCStatus::Fail(HTLCFailureMsg::Malformed(msgs::UpdateFailMalformedHTLC {
984+
channel_id: msg.channel_id,
985+
htlc_id: msg.htlc_id,
986+
sha256_of_onion,
987+
failure_code: $err_code,
988+
})), self.channel_state.lock().unwrap());
983989
}
984990
}
985991
}
986992

987993
if let Err(_) = msg.onion_routing_packet.public_key {
988-
log_info!(self, "Failed to accept/forward incoming HTLC with invalid ephemeral pubkey");
989-
return (PendingHTLCStatus::Fail(HTLCFailureMsg::Malformed(msgs::UpdateFailMalformedHTLC {
990-
channel_id: msg.channel_id,
991-
htlc_id: msg.htlc_id,
992-
sha256_of_onion: get_onion_hash!(),
993-
failure_code: 0x8000 | 0x4000 | 6,
994-
})), self.channel_state.lock().unwrap());
994+
return_malformed_err!("invalid ephemeral pubkey", 0x8000 | 0x4000 | 6);
995995
}
996996

997997
let shared_secret = {
@@ -1001,6 +1001,23 @@ impl ChannelManager {
10011001
};
10021002
let (rho, mu) = ChannelManager::gen_rho_mu_from_shared_secret(&shared_secret);
10031003

1004+
if msg.onion_routing_packet.version != 0 {
1005+
//TODO: Spec doesn't indicate if we should only hash hop_data here (and in other
1006+
//sha256_of_onion error data packets), or the entire onion_routing_packet. Either way,
1007+
//the hash doesn't really serve any purpuse - in the case of hashing all data, the
1008+
//receiving node would have to brute force to figure out which version was put in the
1009+
//packet by the node that send us the message, in the case of hashing the hop_data, the
1010+
//node knows the HMAC matched, so they already know what is there...
1011+
return_malformed_err!("Unknown onion packet version", 0x8000 | 0x4000 | 4);
1012+
}
1013+
1014+
let mut hmac = Hmac::new(Sha256::new(), &mu);
1015+
hmac.input(&msg.onion_routing_packet.hop_data);
1016+
hmac.input(&msg.payment_hash.0[..]);
1017+
if hmac.result() != MacResult::new(&msg.onion_routing_packet.hmac) {
1018+
return_malformed_err!("HMAC Check failed", 0x8000 | 0x4000 | 5);
1019+
}
1020+
10041021
let mut channel_state = None;
10051022
macro_rules! return_err {
10061023
($msg: expr, $err_code: expr, $data: expr) => {
@@ -1018,23 +1035,6 @@ impl ChannelManager {
10181035
}
10191036
}
10201037

1021-
if msg.onion_routing_packet.version != 0 {
1022-
//TODO: Spec doesn't indicate if we should only hash hop_data here (and in other
1023-
//sha256_of_onion error data packets), or the entire onion_routing_packet. Either way,
1024-
//the hash doesn't really serve any purpuse - in the case of hashing all data, the
1025-
//receiving node would have to brute force to figure out which version was put in the
1026-
//packet by the node that send us the message, in the case of hashing the hop_data, the
1027-
//node knows the HMAC matched, so they already know what is there...
1028-
return_err!("Unknown onion packet version", 0x8000 | 0x4000 | 4, &get_onion_hash!());
1029-
}
1030-
1031-
let mut hmac = Hmac::new(Sha256::new(), &mu);
1032-
hmac.input(&msg.onion_routing_packet.hop_data);
1033-
hmac.input(&msg.payment_hash.0[..]);
1034-
if hmac.result() != MacResult::new(&msg.onion_routing_packet.hmac) {
1035-
return_err!("HMAC Check failed", 0x8000 | 0x4000 | 5, &get_onion_hash!());
1036-
}
1037-
10381038
let mut chacha = ChaCha20::new(&rho, &[0u8; 8]);
10391039
let next_hop_data = {
10401040
let mut decoded = [0; 65];
@@ -1092,21 +1092,16 @@ impl ChannelManager {
10921092
sha.input(&shared_secret);
10931093
let mut res = [0u8; 32];
10941094
sha.result(&mut res);
1095-
match SecretKey::from_slice(&self.secp_ctx, &res) {
1096-
Err(_) => {
1097-
return_err!("Blinding factor is an invalid private key", 0x8000 | 0x4000 | 6, &get_onion_hash!());
1098-
},
1099-
Ok(key) => key
1100-
}
1095+
SecretKey::from_slice(&self.secp_ctx, &res).expect("SHA-256 is broken?")
11011096
};
11021097

1103-
if let Err(_) = new_pubkey.mul_assign(&self.secp_ctx, &blinding_factor) {
1104-
return_err!("New blinding factor is an invalid private key", 0x8000 | 0x4000 | 6, &get_onion_hash!());
1105-
}
1098+
let public_key = if let Err(e) = new_pubkey.mul_assign(&self.secp_ctx, &blinding_factor) {
1099+
Err(e)
1100+
} else { Ok(new_pubkey) };
11061101

11071102
let outgoing_packet = msgs::OnionPacket {
11081103
version: 0,
1109-
public_key: Ok(new_pubkey),
1104+
public_key,
11101105
hop_data: new_packet_data,
11111106
hmac: next_hop_data.hmac.clone(),
11121107
};

0 commit comments

Comments
 (0)