NAT + STUN Probes...
This commit is contained in:
@@ -55,6 +55,49 @@ pub fn crc32(data: &[u8]) -> u32 {
|
||||
crc32fast::hash(data)
|
||||
}
|
||||
|
||||
/// Build the exact prekey buffer used by Telegram Middle Proxy KDF.
|
||||
///
|
||||
/// Returned buffer layout (IPv4):
|
||||
/// nonce_srv | nonce_clt | clt_ts | srv_ip | clt_port | purpose | clt_ip | srv_port | secret | nonce_srv | [clt_v6 | srv_v6] | nonce_clt
|
||||
pub fn build_middleproxy_prekey(
|
||||
nonce_srv: &[u8; 16],
|
||||
nonce_clt: &[u8; 16],
|
||||
clt_ts: &[u8; 4],
|
||||
srv_ip: Option<&[u8]>,
|
||||
clt_port: &[u8; 2],
|
||||
purpose: &[u8],
|
||||
clt_ip: Option<&[u8]>,
|
||||
srv_port: &[u8; 2],
|
||||
secret: &[u8],
|
||||
clt_ipv6: Option<&[u8; 16]>,
|
||||
srv_ipv6: Option<&[u8; 16]>,
|
||||
) -> Vec<u8> {
|
||||
const EMPTY_IP: [u8; 4] = [0, 0, 0, 0];
|
||||
|
||||
let srv_ip = srv_ip.unwrap_or(&EMPTY_IP);
|
||||
let clt_ip = clt_ip.unwrap_or(&EMPTY_IP);
|
||||
|
||||
let mut s = Vec::with_capacity(256);
|
||||
s.extend_from_slice(nonce_srv);
|
||||
s.extend_from_slice(nonce_clt);
|
||||
s.extend_from_slice(clt_ts);
|
||||
s.extend_from_slice(srv_ip);
|
||||
s.extend_from_slice(clt_port);
|
||||
s.extend_from_slice(purpose);
|
||||
s.extend_from_slice(clt_ip);
|
||||
s.extend_from_slice(srv_port);
|
||||
s.extend_from_slice(secret);
|
||||
s.extend_from_slice(nonce_srv);
|
||||
|
||||
if let (Some(clt_v6), Some(srv_v6)) = (clt_ipv6, srv_ipv6) {
|
||||
s.extend_from_slice(clt_v6);
|
||||
s.extend_from_slice(srv_v6);
|
||||
}
|
||||
|
||||
s.extend_from_slice(nonce_clt);
|
||||
s
|
||||
}
|
||||
|
||||
/// Middle Proxy key derivation
|
||||
///
|
||||
/// Uses MD5 + SHA-1 as mandated by the Telegram Middle Proxy protocol.
|
||||
@@ -73,30 +116,20 @@ pub fn derive_middleproxy_keys(
|
||||
clt_ipv6: Option<&[u8; 16]>,
|
||||
srv_ipv6: Option<&[u8; 16]>,
|
||||
) -> ([u8; 32], [u8; 16]) {
|
||||
const EMPTY_IP: [u8; 4] = [0, 0, 0, 0];
|
||||
|
||||
let srv_ip = srv_ip.unwrap_or(&EMPTY_IP);
|
||||
let clt_ip = clt_ip.unwrap_or(&EMPTY_IP);
|
||||
|
||||
let mut s = Vec::with_capacity(256);
|
||||
s.extend_from_slice(nonce_srv);
|
||||
s.extend_from_slice(nonce_clt);
|
||||
s.extend_from_slice(clt_ts);
|
||||
s.extend_from_slice(srv_ip);
|
||||
s.extend_from_slice(clt_port);
|
||||
s.extend_from_slice(purpose);
|
||||
s.extend_from_slice(clt_ip);
|
||||
s.extend_from_slice(srv_port);
|
||||
s.extend_from_slice(secret);
|
||||
s.extend_from_slice(nonce_srv);
|
||||
|
||||
if let (Some(clt_v6), Some(srv_v6)) = (clt_ipv6, srv_ipv6) {
|
||||
s.extend_from_slice(clt_v6);
|
||||
s.extend_from_slice(srv_v6);
|
||||
}
|
||||
|
||||
s.extend_from_slice(nonce_clt);
|
||||
|
||||
let s = build_middleproxy_prekey(
|
||||
nonce_srv,
|
||||
nonce_clt,
|
||||
clt_ts,
|
||||
srv_ip,
|
||||
clt_port,
|
||||
purpose,
|
||||
clt_ip,
|
||||
srv_port,
|
||||
secret,
|
||||
clt_ipv6,
|
||||
srv_ipv6,
|
||||
);
|
||||
|
||||
let md5_1 = md5(&s[1..]);
|
||||
let sha1_sum = sha1(&s);
|
||||
let md5_2 = md5(&s[2..]);
|
||||
@@ -106,4 +139,40 @@ pub fn derive_middleproxy_keys(
|
||||
key[12..].copy_from_slice(&sha1_sum);
|
||||
|
||||
(key, md5_2)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn middleproxy_prekey_sha_is_stable() {
|
||||
let nonce_srv = [0x11u8; 16];
|
||||
let nonce_clt = [0x22u8; 16];
|
||||
let clt_ts = 0x44332211u32.to_le_bytes();
|
||||
let srv_ip = Some([149u8, 154, 175, 50].as_ref());
|
||||
let clt_ip = Some([10u8, 0, 0, 1].as_ref());
|
||||
let clt_port = 0x1f90u16.to_le_bytes(); // 8080
|
||||
let srv_port = 0x22b8u16.to_le_bytes(); // 8888
|
||||
let secret = vec![0x55u8; 128];
|
||||
|
||||
let prekey = build_middleproxy_prekey(
|
||||
&nonce_srv,
|
||||
&nonce_clt,
|
||||
&clt_ts,
|
||||
srv_ip,
|
||||
&clt_port,
|
||||
b"CLIENT",
|
||||
clt_ip,
|
||||
&srv_port,
|
||||
&secret,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
let digest = sha256(&prekey);
|
||||
assert_eq!(
|
||||
hex::encode(digest),
|
||||
"a4595b75f1f610f2575ace802ddc65c91b5acef3b0e0d18189e0c7c9f787d15c"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user