diff --git a/vnt/Cargo.toml b/vnt/Cargo.toml index fd8954e..3a1ee64 100644 --- a/vnt/Cargo.toml +++ b/vnt/Cargo.toml @@ -23,6 +23,8 @@ aes-gcm = { version = "0.10.2", optional = true } ring = { version = "0.17.0", optional = true } cbc = { version = "0.1.2", optional = true } ecb = { version = "0.1.2", optional = true } +chacha20poly1305 = { version = "0.10.1", optional = true } +chacha20 = { version = "0.9.1", optional = true } aes = "0.8.3" stun-format = { version = "1.0.1", features = ["fmt", "rfc3489"] } rsa = { version = "0.9.2", features = [], optional = true } @@ -39,6 +41,7 @@ tokio = { version = "1.37.0", features = ["full"], optional = true } lz4_flex = { version = "0.11", default-features = false, optional = true } zstd = { version = "0.13.1", optional = true } + [target.'cfg(target_os = "windows")'.dependencies] libloading = "0.8.0" @@ -46,9 +49,10 @@ libloading = "0.8.0" [build-dependencies] protobuf-codegen = "3.2.0" protoc-bin-vendored = "3.0.0" +cfg_aliases = "0.2.1" [features] -default = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "ip_proxy", "port_mapping", "lz4_compress","zstd_compress"] +default = ["server_encrypt", "aes_gcm", "aes_cbc", "aes_ecb", "sm4_cbc", "chacha20_poly1305", "ip_proxy", "port_mapping", "lz4_compress", "zstd_compress"] openssl = ["openssl-sys"] # 从源码编译 openssl-vendored = ["openssl-sys/vendored"] @@ -57,6 +61,7 @@ aes_cbc = ["cbc"] aes_ecb = ["ecb"] sm4_cbc = ["libsm"] aes_gcm = ["aes-gcm"] +chacha20_poly1305 = ["chacha20poly1305", "chacha20"] server_encrypt = ["aes-gcm", "rsa", "spki"] ip_proxy = ["tokio"] port_mapping = ["tokio"] diff --git a/vnt/src/protocol/body.rs b/vnt/src/protocol/body.rs index 384175d..bfa5fd2 100644 --- a/vnt/src/protocol/body.rs +++ b/vnt/src/protocol/body.rs @@ -253,6 +253,85 @@ impl + AsMut<[u8]>> AesCbcSecretBody { &mut self.buffer.as_mut()[..end] } } +/* ChaCah20加密数据体 + 0 15 31 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | 数据体 | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | finger(32) | + | finger(32) | + | finger(32) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + 注:finger用于快速校验数据是否被修改,上层可使用token、协议头参与计算finger, + 确保服务端和客户端都能感知修改(服务端不能解密也能校验指纹) +*/ +pub struct ChaCah20SecretBody { + buffer: B, + exist_finger: bool, +} + +impl> ChaCah20SecretBody { + pub fn new(buffer: B, exist_finger: bool) -> io::Result> { + let len = buffer.as_ref().len(); + let min_len = if exist_finger { 12 } else { 0 }; + // 不能大于udp最大载荷长度 + if len < min_len || len > 65535 - 20 - 8 - 12 { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "ChaCah20SecretBody length overflow", + )); + } + Ok(ChaCah20SecretBody { + buffer, + exist_finger, + }) + } + pub fn en_body(&self) -> &[u8] { + let mut end = self.buffer.as_ref().len(); + if self.exist_finger { + end -= 12; + } + &self.buffer.as_ref()[..end] + } + pub fn finger(&self) -> &[u8] { + if self.exist_finger { + let end = self.buffer.as_ref().len(); + &self.buffer.as_ref()[end - 12..end] + } else { + &[] + } + } +} + +impl + AsMut<[u8]>> ChaCah20SecretBody { + pub fn set_finger(&mut self, finger: &[u8]) -> io::Result<()> { + if self.exist_finger { + if finger.len() != 12 { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "finger.len != 12", + )); + } + let end = self.buffer.as_ref().len(); + self.buffer.as_mut()[end - 12..end].copy_from_slice(finger); + Ok(()) + } else { + Err(io::Error::new( + io::ErrorKind::InvalidData, + "cbc not exist finger", + )) + } + } + pub fn en_body_mut(&mut self) -> &mut [u8] { + let mut end = self.buffer.as_ref().len(); + if self.exist_finger { + end -= 12; + } + &mut self.buffer.as_mut()[..end] + } +} /* rsa加密数据体 0 15 31