Skip to content

Commit e82ef2c

Browse files
authored
Merge pull request #4090 from erickcestari/fix-onionv3-parsing
fix: Onion v3 parse/format order and render lowercase
2 parents 341e8e4 + f9fc879 commit e82ef2c

File tree

1 file changed

+37
-34
lines changed

1 file changed

+37
-34
lines changed

lightning/src/ln/msgs.rs

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,27 +1273,27 @@ impl std::net::ToSocketAddrs for SocketAddress {
12731273
pub fn parse_onion_address(
12741274
host: &str, port: u16,
12751275
) -> Result<SocketAddress, SocketAddressParseError> {
1276-
if host.ends_with(".onion") {
1277-
let domain = &host[..host.len() - ".onion".len()];
1278-
if domain.len() != 56 {
1279-
return Err(SocketAddressParseError::InvalidOnionV3);
1280-
}
1281-
let onion = base32::Alphabet::RFC4648 { padding: false }
1282-
.decode(&domain)
1283-
.map_err(|_| SocketAddressParseError::InvalidOnionV3)?;
1284-
if onion.len() != 35 {
1285-
return Err(SocketAddressParseError::InvalidOnionV3);
1286-
}
1287-
let version = onion[0];
1288-
let first_checksum_flag = onion[1];
1289-
let second_checksum_flag = onion[2];
1290-
let mut ed25519_pubkey = [0; 32];
1291-
ed25519_pubkey.copy_from_slice(&onion[3..35]);
1292-
let checksum = u16::from_be_bytes([first_checksum_flag, second_checksum_flag]);
1293-
return Ok(SocketAddress::OnionV3 { ed25519_pubkey, checksum, version, port });
1294-
} else {
1276+
if !host.ends_with(".onion") {
12951277
return Err(SocketAddressParseError::InvalidInput);
12961278
}
1279+
let domain = &host[..host.len() - ".onion".len()];
1280+
if domain.len() != 56 {
1281+
return Err(SocketAddressParseError::InvalidOnionV3);
1282+
}
1283+
let onion = base32::Alphabet::RFC4648 { padding: false }
1284+
.decode(domain)
1285+
.map_err(|_| SocketAddressParseError::InvalidOnionV3)?;
1286+
if onion.len() != 35 {
1287+
return Err(SocketAddressParseError::InvalidOnionV3);
1288+
}
1289+
1290+
let mut ed25519_pubkey = [0u8; 32];
1291+
ed25519_pubkey.copy_from_slice(&onion[0..32]);
1292+
1293+
let checksum = u16::from_be_bytes([onion[32], onion[33]]);
1294+
let version = onion[34];
1295+
1296+
Ok(SocketAddress::OnionV3 { ed25519_pubkey, checksum, version, port })
12971297
}
12981298

12991299
impl Display for SocketAddress {
@@ -1313,10 +1313,13 @@ impl Display for SocketAddress {
13131313
version,
13141314
port,
13151315
} => {
1316-
let [first_checksum_flag, second_checksum_flag] = checksum.to_be_bytes();
1317-
let mut addr = vec![*version, first_checksum_flag, second_checksum_flag];
1316+
let mut addr = Vec::with_capacity(35);
13181317
addr.extend_from_slice(ed25519_pubkey);
1319-
let onion = base32::Alphabet::RFC4648 { padding: false }.encode(&addr);
1318+
let [c0, c1] = checksum.to_be_bytes();
1319+
addr.push(c0);
1320+
addr.push(c1);
1321+
addr.push(*version);
1322+
let onion = base32::Alphabet::RFC4648 { padding: false }.encode(&addr).to_lowercase();
13201323
write!(f, "{}.onion:{}", onion, port)?
13211324
},
13221325
SocketAddress::Hostname { hostname, port } => write!(f, "{}:{}", hostname, port)?,
@@ -6666,21 +6669,21 @@ mod tests {
66666669

66676670
let onion_v3 = SocketAddress::OnionV3 {
66686671
ed25519_pubkey: [
6669-
37, 24, 75, 5, 25, 73, 117, 194, 139, 102, 182, 107, 4, 105, 247, 246, 85, 111,
6670-
177, 172, 49, 137, 167, 155, 64, 221, 163, 47, 31, 33, 71, 3,
6672+
121, 188, 198, 37, 24, 75, 5, 25, 73, 117, 194, 139, 102, 182, 107, 4, 105, 247,
6673+
246, 85, 111, 177, 172, 49, 137, 167, 155, 64, 221, 163, 47, 31,
66716674
],
6672-
checksum: 48326,
6673-
version: 121,
6675+
checksum: 8519,
6676+
version: 3,
66746677
port: 1234,
66756678
};
6676-
assert_eq!(
6677-
onion_v3,
6678-
SocketAddress::from_str(
6679-
"pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion:1234"
6680-
)
6681-
.unwrap()
6682-
);
6683-
assert_eq!(onion_v3, SocketAddress::from_str(&onion_v3.to_string()).unwrap());
6679+
let onion_v3_str = "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion:1234";
6680+
let parsed = SocketAddress::from_str(onion_v3_str).unwrap();
6681+
assert_eq!(onion_v3, parsed);
6682+
assert_eq!(onion_v3_str, parsed.to_string());
6683+
match parsed {
6684+
SocketAddress::OnionV3 { version, .. } => assert_eq!(version, 3),
6685+
_ => panic!("expected OnionV3"),
6686+
}
66846687

66856688
assert_eq!(
66866689
Err(SocketAddressParseError::InvalidOnionV3),

0 commit comments

Comments
 (0)