Compare commits

...
14 Commits
Author SHA1 Message Date
lbl8603 3045e239ff Merge branch 'refs/heads/1.2.x' into 2024-05-31 2024-06-07 22:42:29 +08:00
lbl8603 5363558118 忽略io interrupted 2024-06-06 21:42:14 +08:00
lbl8603 13ba7cf0b8 优化提示 2024-06-06 21:41:56 +08:00
lbl8603 a5a43e762d 修改命令处理 2024-06-06 21:39:46 +08:00
lbl8603 cb6101a835 修改tap模式说明 2024-06-05 23:11:56 +08:00
lbl8603 255f84c969 提示创建tun失败的信息 2024-06-05 22:58:56 +08:00
lbl8603 7617d6c409 修改加密描述 2024-06-05 22:39:02 +08:00
lbl8603 f75691b483 过滤非vnt包 2024-06-05 22:38:51 +08:00
lbl8603 c5dbb79ed2 完善代码说明 2024-06-04 23:41:56 +08:00
lbl8603 60ba3c64b2 调整加密逻辑 2024-06-04 23:12:51 +08:00
lbl8603 080e58eeb7 调整代码 2024-06-04 23:00:27 +08:00
lbl8603 5d228b9c27 使用fnv 2024-06-04 22:58:35 +08:00
lbl8603 ba87a2780d Update README.md 2024-06-01 16:59:54 +08:00
lbl8603 fccc3478c8 增加GUI程序 2024-06-01 16:38:17 +08:00
30 changed files with 607 additions and 345 deletions
Generated
+1
View File
@@ -1672,6 +1672,7 @@ dependencies = [
"crossbeam-utils", "crossbeam-utils",
"dns-parser", "dns-parser",
"ecb", "ecb",
"fnv",
"libc", "libc",
"libloading", "libloading",
"libsm", "libsm",
+11 -2
View File
@@ -174,12 +174,14 @@ sudo pfctl -f /etc/pf.conf -e
- Mac - Mac
- Linux - Linux
- Arch Linux `yay -Syu vnt`
- Windows - Windows
- 默认使用tun网卡 依赖wintun.dll([win-tun](https://www.wintun.net/))(将dll放到同目录下,建议使用版本0.14.1) - 默认使用tun网卡 依赖wintun.dll([win-tun](https://www.wintun.net/))(将dll放到同目录下,建议使用版本0.14.1)
- 使用tap网卡 依赖tap-windows([win-tap](https://build.openvpn.net/downloads/releases/))(建议使用版本9.24.7) - 使用tap网卡 依赖tap-windows([win-tap](https://build.openvpn.net/downloads/releases/))(建议使用版本9.24.7)
- Android - Android
- [VntApp](https://github.com/lbl8603/VntApp)
### GUI
支持安卓和Windows [下载](https://github.com/lbl8603/VntApp/releases/)
### 特性 ### 特性
@@ -283,13 +285,20 @@ vnt默认使用10.26.0.0/24网段,和本地网络适配器的ip冲突
### 交流群 ### 交流群
对VNT有任何问题均可以加群联系作者
QQ: 1034868233 QQ: 1034868233
### 赞助
如果VNT对你有帮助,欢迎打赏作者
<img width="300" alt="" src="https://github.com/lbl8603/vnt/assets/49143209/0d3a7311-43fc-4ed7-9507-863b5d69b6b2">
### 其他 ### 其他
可使用社区小伙伴搭建的中继服务器 可使用社区小伙伴搭建的中继服务器
1. -s vnt.8443.eu.org:29871 1. -s vnt.8443.eu.org:29871
2. -s vnt.wherewego.top:29872
### 参与贡献 ### 参与贡献
+9 -7
View File
@@ -34,6 +34,8 @@
注意:仅在windows上支持使用tap,用于兼容低版本windows系统(低版本windows不支持wintun 注意:仅在windows上支持使用tap,用于兼容低版本windows系统(低版本windows不支持wintun
使用tap模式需要手动创建tap网卡,使用--nic参数指定已经创建好的tap网卡名称
### --nic `<tun0>` ### --nic `<tun0>`
指定虚拟网卡名称,默认tun模式使用vnt-tuntap模式使用vnt-tap 指定虚拟网卡名称,默认tun模式使用vnt-tuntap模式使用vnt-tap
@@ -93,13 +95,13 @@ aes_gcm/aes_cbc/aes_ecb/sm4_cbc/chacha20_poly1305/chacha20/xor,默认使用aes
特别说明:xor只是对数据进行简单异或,仅仅避免了明文传输,安全性很差,同时对性能影响也极小; 特别说明:xor只是对数据进行简单异或,仅仅避免了明文传输,安全性很差,同时对性能影响也极小;
| 密码位数 | model | 加密算法 | | 密码位数 | model | 加密算法 |
|-------|-------------------|-------------------| |--------|-------------------|-------------------|
| 1~8位 | aes_gcm | AES128-GCM | | `< 8` | aes_gcm | AES128-GCM |
| `>=`8 | aes_gcm | AES256-GCM | | `>= 8` | aes_gcm | AES256-GCM |
| 1~8位 | aes_cbc | AES128-CBC | | `< 8` | aes_cbc | AES128-CBC |
| `>=`8 | aes_cbc | AES256-CBC | | `>= 8` | aes_cbc | AES256-CBC |
| 1~8位 | aes_ecb | AES128-ECB | | `< 8` | aes_ecb | AES128-ECB |
| `>=`8 | aes_ecb | AES256-ECB | | `>= 8` | aes_ecb | AES256-ECB |
| `> 0` | sm4_cbc | SM4-CBC | | `> 0` | sm4_cbc | SM4-CBC |
| `> 0` | chacha20_poly1305 | ChaCha20-Poly1305 | | `> 0` | chacha20_poly1305 | ChaCha20-Poly1305 |
| `> 0` | chacha20 | ChaCha20 | | `> 0` | chacha20 | ChaCha20 |
+12 -4
View File
@@ -7,7 +7,7 @@ use std::time::Duration;
use crate::command::entity::{DeviceItem, Info, RouteItem}; use crate::command::entity::{DeviceItem, Info, RouteItem};
pub struct CommandClient { pub struct CommandClient {
buf: [u8; 10240], buf: Vec<u8>,
udp: UdpSocket, udp: UdpSocket,
} }
@@ -25,7 +25,7 @@ impl CommandClient {
)))?; )))?;
Ok(Self { Ok(Self {
udp, udp,
buf: [0; 10240], buf: vec![0; 65536 * 8],
}) })
} }
} }
@@ -59,8 +59,16 @@ impl CommandClient {
match serde_yaml::from_slice::<V>(&self.buf[..len]) { match serde_yaml::from_slice::<V>(&self.buf[..len]) {
Ok(val) => Ok(val), Ok(val) => Ok(val),
Err(e) => { Err(e) => {
log::error!("{:?},{:?}", &self.buf[..len], e); log::error!(
Err(io::Error::new(io::ErrorKind::Other, "data error")) "send_cmd {:?} {:?},{:?}",
std::str::from_utf8(cmd),
std::str::from_utf8(&self.buf[..len]),
e
);
Err(io::Error::new(
io::ErrorKind::Other,
format!("data error {:?} buf_len={}", e, len),
))
} }
} }
} }
+8 -2
View File
@@ -326,7 +326,7 @@ fn main() {
Ok(config) => config, Ok(config) => config,
Err(e) => { Err(e) => {
println!("config.toml error: {}", e); println!("config.toml error: {}", e);
return; std::process::exit(1);
} }
}; };
(config, cmd) (config, cmd)
@@ -353,7 +353,13 @@ fn main0(config: Config, _show_cmd: bool) {
println!("UDP port mapping {}->{}", addr, dest) println!("UDP port mapping {}->{}", addr, dest)
} }
} }
let vnt_util = Vnt::new(config, callback::VntHandler {}).unwrap(); let vnt_util = match Vnt::new(config, callback::VntHandler {}) {
Ok(vnt) => vnt,
Err(e) => {
println!("error: {:?}", e);
std::process::exit(1);
}
};
#[cfg(any(target_os = "linux", target_os = "macos"))] #[cfg(any(target_os = "linux", target_os = "macos"))]
{ {
let vnt_c = vnt_util.clone(); let vnt_c = vnt_util.clone();
+1
View File
@@ -42,6 +42,7 @@ tokio = { version = "1.37.0", features = ["full"], optional = true }
lz4_flex = { version = "0.11", default-features = false, optional = true } lz4_flex = { version = "0.11", default-features = false, optional = true }
zstd = { version = "0.13.1", optional = true } zstd = { version = "0.13.1", optional = true }
fnv = "1.0.7"
[target.'cfg(target_os = "windows")'.dependencies] [target.'cfg(target_os = "windows")'.dependencies]
libloading = "0.8.0" libloading = "0.8.0"
+6 -6
View File
@@ -1,4 +1,4 @@
use std::collections::HashMap; use fnv::FnvHashMap;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV6, UdpSocket}; use std::net::{Ipv4Addr, SocketAddr, SocketAddrV6, UdpSocket};
use std::ops::Deref; use std::ops::Deref;
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
@@ -44,8 +44,8 @@ impl ChannelContext {
.unwrap_or(0); .unwrap_or(0);
let inner = ContextInner { let inner = ContextInner {
main_udp_socket, main_udp_socket,
sub_udp_socket: RwLock::new(Vec::with_capacity(64)), sub_udp_socket: RwLock::new(Vec::new()),
tcp_map: RwLock::new(HashMap::with_capacity(64)), tcp_map: RwLock::new(FnvHashMap::default()),
route_table: RouteTable::new(use_channel_type, first_latency, channel_num), route_table: RouteTable::new(use_channel_type, first_latency, channel_num),
is_tcp, is_tcp,
packet_loss_rate, packet_loss_rate,
@@ -80,7 +80,7 @@ pub struct ContextInner {
// 对称网络增加的udp socket // 对称网络增加的udp socket
sub_udp_socket: RwLock<Vec<UdpSocket>>, sub_udp_socket: RwLock<Vec<UdpSocket>>,
// tcp数据发送器 // tcp数据发送器
pub(crate) tcp_map: RwLock<HashMap<SocketAddr, PacketSender>>, pub(crate) tcp_map: RwLock<FnvHashMap<SocketAddr, PacketSender>>,
// 路由信息 // 路由信息
pub route_table: RouteTable, pub route_table: RouteTable,
// 是否使用tcp连接服务器 // 是否使用tcp连接服务器
@@ -288,7 +288,7 @@ impl ContextInner {
pub struct RouteTable { pub struct RouteTable {
pub(crate) route_table: pub(crate) route_table:
RwLock<HashMap<Ipv4Addr, (AtomicUsize, Vec<(Route, AtomicCell<Instant>)>)>>, RwLock<FnvHashMap<Ipv4Addr, (AtomicUsize, Vec<(Route, AtomicCell<Instant>)>)>>,
first_latency: bool, first_latency: bool,
channel_num: usize, channel_num: usize,
use_channel_type: UseChannelType, use_channel_type: UseChannelType,
@@ -297,7 +297,7 @@ pub struct RouteTable {
impl RouteTable { impl RouteTable {
fn new(use_channel_type: UseChannelType, first_latency: bool, channel_num: usize) -> Self { fn new(use_channel_type: UseChannelType, first_latency: bool, channel_num: usize) -> Self {
Self { Self {
route_table: RwLock::new(HashMap::with_capacity(64)), route_table: RwLock::new(FnvHashMap::with_capacity_and_hasher(64, Default::default())),
use_channel_type, use_channel_type,
first_latency, first_latency,
channel_num, channel_num,
+8 -2
View File
@@ -89,7 +89,10 @@ where
HashMap::with_capacity(32); HashMap::with_capacity(32);
let mut extend = [0; BUFFER_SIZE]; let mut extend = [0; BUFFER_SIZE];
loop { loop {
poll.poll(&mut events, None)?; if let Err(e) = poll.poll(&mut events, None) {
crate::ignore_io_interrupted(e)?;
continue;
}
for event in events.iter() { for event in events.iter() {
match event.token() { match event.token() {
SERVER => loop { SERVER => loop {
@@ -208,7 +211,10 @@ fn tcp_writable_listen(
), ),
> = HashMap::with_capacity(32); > = HashMap::with_capacity(32);
loop { loop {
poll.poll(&mut events, None)?; if let Err(e) = poll.poll(&mut events, None) {
crate::ignore_io_interrupted(e)?;
continue;
}
for event in events.iter() { for event in events.iter() {
match event.token() { match event.token() {
NOTIFY => { NOTIFY => {
+8 -2
View File
@@ -73,7 +73,10 @@ where
let mut extend = [0; BUFFER_SIZE]; let mut extend = [0; BUFFER_SIZE];
let mut read_map: HashMap<Token, UdpSocket> = HashMap::with_capacity(32); let mut read_map: HashMap<Token, UdpSocket> = HashMap::with_capacity(32);
loop { loop {
poll.poll(&mut events, None)?; if let Err(e) = poll.poll(&mut events, None) {
crate::ignore_io_interrupted(e)?;
continue;
}
for event in events.iter() { for event in events.iter() {
match event.token() { match event.token() {
NOTIFY => { NOTIFY => {
@@ -256,7 +259,10 @@ where
let mut events = Events::with_capacity(udps.len()); let mut events = Events::with_capacity(udps.len());
let mut extend = [0; BUFFER_SIZE]; let mut extend = [0; BUFFER_SIZE];
loop { loop {
poll.poll(&mut events, None)?; if let Err(e) = poll.poll(&mut events, None) {
crate::ignore_io_interrupted(e)?;
continue;
}
for x in events.iter() { for x in events.iter() {
let index = match x.token() { let index = match x.token() {
NOTIFY => return Ok(()), NOTIFY => return Ok(()),
+17 -12
View File
@@ -59,12 +59,7 @@ impl AesCbcCipher {
return Err(anyhow!("aes_cbc data err")); return Err(anyhow!("aes_cbc data err"));
} }
let mut iv = [0; 16]; let mut iv = [0; 16];
iv[0..4].copy_from_slice(&net_packet.source().octets()); iv[0..12].copy_from_slice(&net_packet.head_tag());
iv[4..8].copy_from_slice(&net_packet.destination().octets());
iv[8] = net_packet.protocol().into();
iv[9] = net_packet.transport_protocol();
iv[10] = net_packet.is_gateway() as u8;
iv[11] = net_packet.source_ttl();
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
iv[12..16].copy_from_slice(&finger.hash[0..4]); iv[12..16].copy_from_slice(&finger.hash[0..4]);
} }
@@ -102,12 +97,7 @@ impl AesCbcCipher {
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let data_len = net_packet.data_len(); let data_len = net_packet.data_len();
let mut iv = [0; 16]; let mut iv = [0; 16];
iv[0..4].copy_from_slice(&net_packet.source().octets()); iv[0..12].copy_from_slice(&net_packet.head_tag());
iv[4..8].copy_from_slice(&net_packet.destination().octets());
iv[8] = net_packet.protocol().into();
iv[9] = net_packet.transport_protocol();
iv[10] = net_packet.is_gateway() as u8;
iv[11] = net_packet.source_ttl();
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
iv[12..16].copy_from_slice(&finger.hash[0..4]); iv[12..16].copy_from_slice(&finger.hash[0..4]);
net_packet.set_data_len(data_len + 16)?; net_packet.set_data_len(data_len + 16)?;
@@ -146,3 +136,18 @@ impl AesCbcCipher {
}; };
} }
} }
#[test]
fn test_aes_cbc() {
let d = AesCbcCipher::new_128([0; 16], Some(Finger::new("123")));
let mut p = NetPacket::new_encrypt([0; 100]).unwrap();
let src = p.buffer().to_vec();
d.encrypt_ipv4(&mut p).unwrap();
d.decrypt_ipv4(&mut p).unwrap();
assert_eq!(p.buffer(), &src);
let d = AesCbcCipher::new_128([0; 16], None);
let mut p = NetPacket::new_encrypt([0; 100]).unwrap();
let src = p.buffer().to_vec();
d.encrypt_ipv4(&mut p).unwrap();
d.decrypt_ipv4(&mut p).unwrap();
assert_eq!(p.buffer(), &src);
}
+4 -14
View File
@@ -110,13 +110,7 @@ impl AesEcbCipher {
} }
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
let mut nonce_raw = [0; 12]; let nonce_raw = net_packet.head_tag();
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
nonce_raw[8] = net_packet.protocol().into();
nonce_raw[9] = net_packet.transport_protocol();
nonce_raw[10] = net_packet.is_gateway() as u8;
nonce_raw[11] = net_packet.source_ttl();
let len = net_packet.payload().len(); let len = net_packet.payload().len();
if len < 12 { if len < 12 {
return Err(anyhow!("data len err")); return Err(anyhow!("data len err"));
@@ -202,13 +196,7 @@ impl AesEcbCipher {
net_packet.payload_mut().copy_from_slice(ciphertext); net_packet.payload_mut().copy_from_slice(ciphertext);
net_packet.set_encrypt_flag(true); net_packet.set_encrypt_flag(true);
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
let mut nonce_raw = [0; 12]; let nonce_raw = net_packet.head_tag();
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
nonce_raw[8] = net_packet.protocol().into();
nonce_raw[9] = net_packet.transport_protocol();
nonce_raw[10] = net_packet.is_gateway() as u8;
nonce_raw[11] = net_packet.source_ttl();
let finger = finger.calculate_finger(&nonce_raw, ciphertext); let finger = finger.calculate_finger(&nonce_raw, ciphertext);
let src_data_len = net_packet.data_len(); let src_data_len = net_packet.data_len();
//设置实际长度 //设置实际长度
@@ -224,6 +212,8 @@ impl AesEcbCipher {
fn test_openssl_aes_ecb() { fn test_openssl_aes_ecb() {
let d = AesEcbCipher::new_128([0; 16], Some(Finger::new("123"))); let d = AesEcbCipher::new_128([0; 16], Some(Finger::new("123")));
let mut p = NetPacket::new_encrypt([0; 100]).unwrap(); let mut p = NetPacket::new_encrypt([0; 100]).unwrap();
let src = p.buffer().to_vec();
d.encrypt_ipv4(&mut p).unwrap(); d.encrypt_ipv4(&mut p).unwrap();
d.decrypt_ipv4(&mut p).unwrap(); d.decrypt_ipv4(&mut p).unwrap();
assert_eq!(p.buffer(), &src);
} }
+2 -14
View File
@@ -54,13 +54,7 @@ impl AesEcbCipher {
} }
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
let mut nonce_raw = [0; 12]; let nonce_raw = net_packet.head_tag();
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
nonce_raw[8] = net_packet.protocol().into();
nonce_raw[9] = net_packet.transport_protocol();
nonce_raw[10] = net_packet.is_gateway() as u8;
nonce_raw[11] = net_packet.source_ttl();
let len = net_packet.payload().len(); let len = net_packet.payload().len();
if len < 12 { if len < 12 {
return Err(anyhow!("payload len <12")); return Err(anyhow!("payload len <12"));
@@ -134,13 +128,7 @@ impl AesEcbCipher {
net_packet.set_encrypt_flag(true); net_packet.set_encrypt_flag(true);
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
let mut nonce_raw = [0; 12]; let nonce_raw = net_packet.head_tag();
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
nonce_raw[8] = net_packet.protocol().into();
nonce_raw[9] = net_packet.transport_protocol();
nonce_raw[10] = net_packet.is_gateway() as u8;
nonce_raw[11] = net_packet.source_ttl();
let finger = finger.calculate_finger(&nonce_raw, buf); let finger = finger.calculate_finger(&nonce_raw, buf);
let src_data_len = net_packet.data_len(); let src_data_len = net_packet.data_len();
//设置实际长度 //设置实际长度
+21 -14
View File
@@ -47,13 +47,7 @@ impl AesGcmCipher {
log::error!("数据异常,长度小于{}", AES_GCM_ENCRYPTION_RESERVED); log::error!("数据异常,长度小于{}", AES_GCM_ENCRYPTION_RESERVED);
return Err(anyhow!("data err")); return Err(anyhow!("data err"));
} }
let mut nonce_raw = [0; 12]; let nonce_raw = net_packet.head_tag();
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
nonce_raw[8] = net_packet.protocol().into();
nonce_raw[9] = net_packet.transport_protocol();
nonce_raw[10] = net_packet.is_gateway() as u8;
nonce_raw[11] = net_packet.source_ttl();
let nonce: &GenericArray<u8, U12> = Nonce::from_slice(&nonce_raw); let nonce: &GenericArray<u8, U12> = Nonce::from_slice(&nonce_raw);
let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?; let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
@@ -89,13 +83,7 @@ impl AesGcmCipher {
if net_packet.reserve() < AES_GCM_ENCRYPTION_RESERVED { if net_packet.reserve() < AES_GCM_ENCRYPTION_RESERVED {
return Err(anyhow!("too short")); return Err(anyhow!("too short"));
} }
let mut nonce_raw = [0; 12]; let nonce_raw = net_packet.head_tag();
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
nonce_raw[8] = net_packet.protocol().into();
nonce_raw[9] = net_packet.transport_protocol();
nonce_raw[10] = net_packet.is_gateway() as u8;
nonce_raw[11] = net_packet.source_ttl();
let nonce: &GenericArray<u8, U12> = Nonce::from_slice(&nonce_raw); let nonce: &GenericArray<u8, U12> = Nonce::from_slice(&nonce_raw);
let data_len = net_packet.data_len() + AES_GCM_ENCRYPTION_RESERVED; let data_len = net_packet.data_len() + AES_GCM_ENCRYPTION_RESERVED;
net_packet.set_data_len(data_len)?; net_packet.set_data_len(data_len)?;
@@ -123,3 +111,22 @@ impl AesGcmCipher {
}; };
} }
} }
#[test]
fn test_aes_gcm() {
let d = AesGcmCipher::new_256([0; 32], Some(Finger::new("123")));
let mut p =
NetPacket::new_encrypt([1; 13 + crate::protocol::body::ENCRYPTION_RESERVED]).unwrap();
let src = p.buffer().to_vec();
d.encrypt_ipv4(&mut p).unwrap();
d.decrypt_ipv4(&mut p).unwrap();
assert_eq!(p.buffer(), &src);
let d = AesGcmCipher::new_256([0; 32], None);
let mut p =
NetPacket::new_encrypt([0; 13 + crate::protocol::body::ENCRYPTION_RESERVED]).unwrap();
let src = p.buffer().to_vec();
d.encrypt_ipv4(&mut p).unwrap();
d.decrypt_ipv4(&mut p).unwrap();
assert_eq!(p.buffer(), &src);
}
+21 -14
View File
@@ -62,13 +62,7 @@ impl AesGcmCipher {
log::error!("数据异常,长度小于{}", AES_GCM_ENCRYPTION_RESERVED); log::error!("数据异常,长度小于{}", AES_GCM_ENCRYPTION_RESERVED);
return Err(anyhow!("data err")); return Err(anyhow!("data err"));
} }
let mut nonce_raw = [0; 12]; let nonce_raw = net_packet.head_tag();
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
nonce_raw[8] = net_packet.protocol().into();
nonce_raw[9] = net_packet.transport_protocol();
nonce_raw[10] = net_packet.is_gateway() as u8;
nonce_raw[11] = net_packet.source_ttl();
let nonce = aead::Nonce::assume_unique_for_key(nonce_raw); let nonce = aead::Nonce::assume_unique_for_key(nonce_raw);
let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?; let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
@@ -100,13 +94,7 @@ impl AesGcmCipher {
&self, &self,
net_packet: &mut NetPacket<B>, net_packet: &mut NetPacket<B>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let mut nonce_raw = [0; 12]; let nonce_raw = net_packet.head_tag();
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
nonce_raw[8] = net_packet.protocol().into();
nonce_raw[9] = net_packet.transport_protocol();
nonce_raw[10] = net_packet.is_gateway() as u8;
nonce_raw[11] = net_packet.source_ttl();
let nonce = aead::Nonce::assume_unique_for_key(nonce_raw); let nonce = aead::Nonce::assume_unique_for_key(nonce_raw);
let data_len = net_packet.data_len() + AES_GCM_ENCRYPTION_RESERVED; let data_len = net_packet.data_len() + AES_GCM_ENCRYPTION_RESERVED;
net_packet.set_data_len(data_len)?; net_packet.set_data_len(data_len)?;
@@ -139,3 +127,22 @@ impl AesGcmCipher {
}; };
} }
} }
#[test]
fn test_aes_gcm() {
let d = AesGcmCipher::new_256([0; 32], Some(Finger::new("123")));
let mut p =
NetPacket::new_encrypt([0; 13 + crate::protocol::body::ENCRYPTION_RESERVED]).unwrap();
let src = p.buffer().to_vec();
d.encrypt_ipv4(&mut p).unwrap();
d.decrypt_ipv4(&mut p).unwrap();
assert_eq!(p.buffer(), &src);
let d = AesGcmCipher::new_256([0; 32], None);
let mut p =
NetPacket::new_encrypt([0; 13 + crate::protocol::body::ENCRYPTION_RESERVED]).unwrap();
let src = p.buffer().to_vec();
d.encrypt_ipv4(&mut p).unwrap();
d.decrypt_ipv4(&mut p).unwrap();
assert_eq!(p.buffer(), &src);
}
+25 -32
View File
@@ -3,8 +3,11 @@ use anyhow::anyhow;
use chacha20::cipher::{Key, KeyIvInit, StreamCipher}; use chacha20::cipher::{Key, KeyIvInit, StreamCipher};
use chacha20::ChaCha20; use chacha20::ChaCha20;
use crate::cipher::finger::{gen_nonce, gen_random_nonce};
use crate::cipher::Finger; use crate::cipher::Finger;
use crate::protocol::body::ChaCah20SecretBody; use crate::protocol::body::{
IVSecretBody, SecretTail, SecretTailMut, FINGER_RESERVED, RANDOM_RESERVED,
};
use crate::protocol::NetPacket; use crate::protocol::NetPacket;
#[derive(Clone)] #[derive(Clone)]
@@ -34,29 +37,22 @@ impl ChaCha20Cipher {
//未加密的数据直接丢弃 //未加密的数据直接丢弃
return Err(anyhow!("not encrypt")); return Err(anyhow!("not encrypt"));
} }
let mut iv = [0; 12]; let mut head_tag = net_packet.head_tag();
iv[0..4].copy_from_slice(&net_packet.source().octets());
iv[4..8].copy_from_slice(&net_packet.destination().octets());
iv[8] = net_packet.protocol().into();
iv[9] = net_packet.transport_protocol();
iv[10] = net_packet.is_gateway() as u8;
iv[11] = net_packet.source_ttl();
let mut secret_body = let mut secret_body = IVSecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
ChaCah20SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
let finger = finger.calculate_finger(&iv[..12], secret_body.en_body()); let finger = finger.calculate_finger(&head_tag, secret_body.data());
if &finger != secret_body.finger() { if &finger != secret_body.finger() {
return Err(anyhow!("ChaCha20 finger err")); return Err(anyhow!("ChaCha20 finger err"));
} }
} }
gen_nonce(&mut head_tag, secret_body.random_buf());
ChaCha20::new( ChaCha20::new(
Key::<ChaCha20>::from_slice(&self.key), Key::<ChaCha20>::from_slice(&self.key),
Iv::<ChaCha20>::from_slice(&iv), Iv::<ChaCha20>::from_slice(&head_tag),
) )
.apply_keystream(secret_body.en_body_mut()); .apply_keystream(secret_body.data_mut());
let len = secret_body.en_body().len(); let len = secret_body.data().len();
net_packet.set_encrypt_flag(false); net_packet.set_encrypt_flag(false);
net_packet.set_payload_len(len)?; net_packet.set_payload_len(len)?;
Ok(()) Ok(())
@@ -66,29 +62,26 @@ impl ChaCha20Cipher {
net_packet: &mut NetPacket<B>, net_packet: &mut NetPacket<B>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let data_len = net_packet.data_len(); let data_len = net_packet.data_len();
let mut iv = [0; 12]; let head_tag = net_packet.head_tag();
iv[0..4].copy_from_slice(&net_packet.source().octets());
iv[4..8].copy_from_slice(&net_packet.destination().octets());
iv[8] = net_packet.protocol().into();
iv[9] = net_packet.transport_protocol();
iv[10] = net_packet.is_gateway() as u8;
iv[11] = net_packet.source_ttl();
if let Some(_) = &self.finger { if let Some(_) = &self.finger {
net_packet.set_data_len(data_len + 12)?; net_packet.set_data_len(data_len + RANDOM_RESERVED + FINGER_RESERVED)?;
} else {
net_packet.set_data_len(data_len + RANDOM_RESERVED)?;
} }
let mut secret_body = let mut secret_body = IVSecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
ChaCah20SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?; let mut nonce = head_tag;
secret_body.set_random(&gen_random_nonce(&mut nonce));
ChaCha20::new( ChaCha20::new(
Key::<ChaCha20>::from_slice(&self.key), Key::<ChaCha20>::from_slice(&self.key),
Iv::<ChaCha20>::from_slice(&iv), Iv::<ChaCha20>::from_slice(&nonce),
) )
.apply_keystream(secret_body.en_body_mut()); .apply_keystream(secret_body.data_mut());
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
let finger = finger.calculate_finger(&iv[..12], secret_body.en_body_mut()); let finger = finger.calculate_finger(&head_tag, secret_body.data());
let mut secret_body = ChaCah20SecretBody::new(net_packet.payload_mut(), true)?; let mut secret_body = IVSecretBody::new(net_packet.payload_mut(), true)?;
secret_body.set_finger(&finger)?; secret_body.set_finger(&finger)?;
} }
net_packet.set_encrypt_flag(true); net_packet.set_encrypt_flag(true);
Ok(()) Ok(())
} }
@@ -98,7 +91,7 @@ impl ChaCha20Cipher {
fn test_chacha20() { fn test_chacha20() {
let d = ChaCha20Cipher::new_256([0; 32], Some(Finger::new("123"))); let d = ChaCha20Cipher::new_256([0; 32], Some(Finger::new("123")));
let mut p = let mut p =
NetPacket::new_encrypt([0; 13 + crate::protocol::body::ENCRYPTION_RESERVED]).unwrap(); NetPacket::new_encrypt([1; 13 + crate::protocol::body::ENCRYPTION_RESERVED]).unwrap();
let src = p.buffer().to_vec(); let src = p.buffer().to_vec();
d.encrypt_ipv4(&mut p).unwrap(); d.encrypt_ipv4(&mut p).unwrap();
d.decrypt_ipv4(&mut p).unwrap(); d.decrypt_ipv4(&mut p).unwrap();
@@ -106,7 +99,7 @@ fn test_chacha20() {
let d = ChaCha20Cipher::new_256([0; 32], None); let d = ChaCha20Cipher::new_256([0; 32], None);
let mut p = let mut p =
NetPacket::new_encrypt([0; 13 + crate::protocol::body::ENCRYPTION_RESERVED]).unwrap(); NetPacket::new_encrypt([2; 13 + crate::protocol::body::ENCRYPTION_RESERVED]).unwrap();
let src = p.buffer().to_vec(); let src = p.buffer().to_vec();
d.encrypt_ipv4(&mut p).unwrap(); d.encrypt_ipv4(&mut p).unwrap();
d.decrypt_ipv4(&mut p).unwrap(); d.decrypt_ipv4(&mut p).unwrap();
@@ -3,8 +3,11 @@ use anyhow::anyhow;
use ring::aead; use ring::aead;
use ring::aead::{LessSafeKey, UnboundKey}; use ring::aead::{LessSafeKey, UnboundKey};
use crate::cipher::finger::{gen_nonce, gen_random_nonce};
use crate::cipher::Finger; use crate::cipher::Finger;
use crate::protocol::body::{SecretBody, AES_GCM_ENCRYPTION_RESERVED}; use crate::protocol::body::{
AEADSecretBody, SecretTail, SecretTailMut, FINGER_RESERVED, RANDOM_RESERVED, TAG_RESERVED,
};
use crate::protocol::NetPacket; use crate::protocol::NetPacket;
#[derive(Clone)] #[derive(Clone)]
@@ -40,34 +43,29 @@ impl ChaCha20Poly1305Cipher {
//未加密的数据直接丢弃 //未加密的数据直接丢弃
return Err(anyhow!("not encrypt")); return Err(anyhow!("not encrypt"));
} }
if net_packet.payload().len() < AES_GCM_ENCRYPTION_RESERVED { if net_packet.payload().len() < TAG_RESERVED {
log::error!("数据异常,长度小于{}", AES_GCM_ENCRYPTION_RESERVED); log::error!("数据异常,长度小于{}", TAG_RESERVED);
return Err(anyhow!("data err")); return Err(anyhow!("data err"));
} }
let mut nonce_raw = [0; 12]; let mut head_tag = net_packet.head_tag();
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets()); let mut secret_body = AEADSecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
nonce_raw[8] = net_packet.protocol().into();
nonce_raw[9] = net_packet.transport_protocol();
nonce_raw[10] = net_packet.is_gateway() as u8;
nonce_raw[11] = net_packet.source_ttl();
let nonce = aead::Nonce::assume_unique_for_key(nonce_raw);
let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body()); let finger = finger.calculate_finger(&head_tag, secret_body.data_tag_mut());
if &finger != secret_body.finger() { if &finger != secret_body.finger() {
return Err(anyhow!("ring CHACHA20_POLY1305 finger err")); return Err(anyhow!("ring CHACHA20_POLY1305 finger err"));
} }
} }
gen_nonce(&mut head_tag, secret_body.random_buf());
let nonce = aead::Nonce::assume_unique_for_key(head_tag);
let rs = self let rs = self
.cipher .cipher
.open_in_place(nonce, aead::Aad::empty(), secret_body.en_body_mut()); .open_in_place(nonce, aead::Aad::empty(), secret_body.data_tag_mut());
if let Err(e) = rs { if let Err(e) = rs {
return Err(anyhow!("ring CHACHA20_POLY1305 解密失败:{}", e)); return Err(anyhow!("ring CHACHA20_POLY1305 解密失败:{}", e));
} }
let len = secret_body.data().len();
net_packet.set_encrypt_flag(false); net_packet.set_encrypt_flag(false);
net_packet.set_data_len(net_packet.data_len() - AES_GCM_ENCRYPTION_RESERVED)?; net_packet.set_payload_len(len)?;
return Ok(()); return Ok(());
} }
/// net_packet 必须预留足够长度 /// net_packet 必须预留足够长度
@@ -77,23 +75,23 @@ impl ChaCha20Poly1305Cipher {
&self, &self,
net_packet: &mut NetPacket<B>, net_packet: &mut NetPacket<B>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let mut nonce_raw = [0; 12]; let head_tag = net_packet.head_tag();
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets()); let data_len = net_packet.data_len();
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets()); if self.finger.is_some() {
nonce_raw[8] = net_packet.protocol().into(); net_packet.set_data_len(data_len + TAG_RESERVED + RANDOM_RESERVED + FINGER_RESERVED)?;
nonce_raw[9] = net_packet.transport_protocol(); } else {
nonce_raw[10] = net_packet.is_gateway() as u8; net_packet.set_data_len(data_len + TAG_RESERVED + RANDOM_RESERVED)?;
nonce_raw[11] = net_packet.source_ttl(); }
let nonce = aead::Nonce::assume_unique_for_key(nonce_raw); let mut secret_body = AEADSecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
let data_len = net_packet.data_len() + AES_GCM_ENCRYPTION_RESERVED; let mut nonce = head_tag;
net_packet.set_data_len(data_len)?; secret_body.set_random(&gen_random_nonce(&mut nonce));
let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?; let nonce = aead::Nonce::assume_unique_for_key(nonce);
let rs = self.cipher.seal_in_place_separate_tag( let rs = self.cipher.seal_in_place_separate_tag(
nonce, nonce,
aead::Aad::empty(), aead::Aad::empty(),
secret_body.body_mut(), secret_body.data_mut(),
); );
return match rs { match rs {
Ok(tag) => { Ok(tag) => {
let tag = tag.as_ref(); let tag = tag.as_ref();
if tag.len() != 16 { if tag.len() != 16 {
@@ -101,14 +99,14 @@ impl ChaCha20Poly1305Cipher {
} }
secret_body.set_tag(tag)?; secret_body.set_tag(tag)?;
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body()); let finger = finger.calculate_finger(&head_tag, secret_body.data_tag_mut());
secret_body.set_finger(&finger)?; secret_body.set_finger(&finger)?;
} }
net_packet.set_encrypt_flag(true); net_packet.set_encrypt_flag(true);
Ok(()) Ok(())
} }
Err(e) => Err(anyhow!("ring CHACHA20_POLY1305 加密失败:{}", e)), Err(e) => Err(anyhow!("ring CHACHA20_POLY1305 加密失败:{}", e)),
}; }
} }
} }
@@ -1,11 +1,13 @@
use crate::cipher::finger::{gen_nonce, gen_random_nonce};
use crate::cipher::Finger;
use crate::protocol::body::{
AEADSecretBody, SecretTail, SecretTailMut, FINGER_RESERVED, RANDOM_RESERVED, TAG_RESERVED,
};
use crate::protocol::NetPacket;
use anyhow::anyhow; use anyhow::anyhow;
use chacha20poly1305::aead::{Nonce, Tag}; use chacha20poly1305::aead::{Nonce, Tag};
use chacha20poly1305::{AeadInPlace, ChaCha20Poly1305, Key, KeyInit}; use chacha20poly1305::{AeadInPlace, ChaCha20Poly1305, Key, KeyInit};
use crate::cipher::Finger;
use crate::protocol::body::{SecretBody, AES_GCM_ENCRYPTION_RESERVED};
use crate::protocol::NetPacket;
#[derive(Clone)] #[derive(Clone)]
pub struct ChaCha20Poly1305Cipher { pub struct ChaCha20Poly1305Cipher {
key: Vec<u8>, key: Vec<u8>,
@@ -24,6 +26,7 @@ impl ChaCha20Poly1305Cipher {
} }
} }
} }
impl ChaCha20Poly1305Cipher { impl ChaCha20Poly1305Cipher {
pub fn key(&self) -> &[u8] { pub fn key(&self) -> &[u8] {
&self.key &self.key
@@ -39,35 +42,31 @@ impl ChaCha20Poly1305Cipher {
//未加密的数据直接丢弃 //未加密的数据直接丢弃
return Err(anyhow!("not encrypt")); return Err(anyhow!("not encrypt"));
} }
if net_packet.payload().len() < AES_GCM_ENCRYPTION_RESERVED { if net_packet.payload().len() < TAG_RESERVED {
log::error!("数据异常,长度小于{}", AES_GCM_ENCRYPTION_RESERVED); log::error!("数据异常,长度小于{}", TAG_RESERVED);
return Err(anyhow!("data err")); return Err(anyhow!("data err"));
} }
let mut nonce_raw = [0; 12]; let mut head_tag = net_packet.head_tag();
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets()); let mut secret_body = AEADSecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
nonce_raw[8] = net_packet.protocol().into();
nonce_raw[9] = net_packet.transport_protocol();
nonce_raw[10] = net_packet.is_gateway() as u8;
nonce_raw[11] = net_packet.source_ttl();
let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body()); let finger = finger.calculate_finger(&head_tag, secret_body.data_tag_mut());
if &finger != secret_body.finger() { if &finger != secret_body.finger() {
return Err(anyhow!("rs CHACHA20_POLY1305 finger err")); return Err(anyhow!("rs CHACHA20_POLY1305 finger err"));
} }
} }
let nonce: Nonce<ChaCha20Poly1305> = nonce_raw.into(); gen_nonce(&mut head_tag, secret_body.random_buf());
let nonce: Nonce<ChaCha20Poly1305> = head_tag.into();
let tag: Tag<ChaCha20Poly1305> = let tag: Tag<ChaCha20Poly1305> =
Tag::<ChaCha20Poly1305>::from_slice(secret_body.tag()).clone(); Tag::<ChaCha20Poly1305>::from_slice(secret_body.tag()).clone();
if let Err(e) = if let Err(e) =
self.cipher self.cipher
.decrypt_in_place_detached(&nonce, &[], secret_body.body_mut(), &tag) .decrypt_in_place_detached(&nonce, &[], secret_body.data_mut(), &tag)
{ {
return Err(anyhow!("rs CHACHA20_POLY1305 decrypt_ipv4 {:?}", e)); return Err(anyhow!("rs CHACHA20_POLY1305 decrypt_ipv4 {:?}", e));
} }
let len = secret_body.data().len();
net_packet.set_encrypt_flag(false); net_packet.set_encrypt_flag(false);
net_packet.set_data_len(net_packet.data_len() - AES_GCM_ENCRYPTION_RESERVED)?; net_packet.set_payload_len(len)?;
Ok(()) Ok(())
} }
/// net_packet 必须预留足够长度 /// net_packet 必须预留足够长度
@@ -77,21 +76,21 @@ impl ChaCha20Poly1305Cipher {
&self, &self,
net_packet: &mut NetPacket<B>, net_packet: &mut NetPacket<B>,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
let mut nonce_raw = [0; 12]; let head_tag = net_packet.head_tag();
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets()); let data_len = net_packet.data_len();
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets()); if self.finger.is_some() {
nonce_raw[8] = net_packet.protocol().into(); net_packet.set_data_len(data_len + TAG_RESERVED + RANDOM_RESERVED + FINGER_RESERVED)?;
nonce_raw[9] = net_packet.transport_protocol(); } else {
nonce_raw[10] = net_packet.is_gateway() as u8; net_packet.set_data_len(data_len + TAG_RESERVED + RANDOM_RESERVED)?;
nonce_raw[11] = net_packet.source_ttl(); }
let nonce = nonce_raw.into(); let mut secret_body = AEADSecretBody::new(net_packet.payload_mut(), self.finger.is_some())?;
let data_len = net_packet.data_len() + AES_GCM_ENCRYPTION_RESERVED; let mut nonce = head_tag;
net_packet.set_data_len(data_len)?; secret_body.set_random(&gen_random_nonce(&mut nonce));
let mut secret_body = SecretBody::new(net_packet.payload_mut(), self.finger.is_some())?; let nonce = nonce.into();
let rs = self let rs = self
.cipher .cipher
.encrypt_in_place_detached(&nonce, &[], secret_body.body_mut()); .encrypt_in_place_detached(&nonce, &[], secret_body.data_mut());
return match rs { match rs {
Ok(tag) => { Ok(tag) => {
let tag: &[u8] = tag.as_ref(); let tag: &[u8] = tag.as_ref();
if tag.len() != 16 { if tag.len() != 16 {
@@ -99,14 +98,14 @@ impl ChaCha20Poly1305Cipher {
} }
secret_body.set_tag(tag)?; secret_body.set_tag(tag)?;
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
let finger = finger.calculate_finger(&nonce_raw, secret_body.en_body()); let finger = finger.calculate_finger(&head_tag, secret_body.data_tag_mut());
secret_body.set_finger(&finger)?; secret_body.set_finger(&finger)?;
} }
net_packet.set_encrypt_flag(true); net_packet.set_encrypt_flag(true);
Ok(()) Ok(())
} }
Err(e) => Err(anyhow!("rs CHACHA20_POLY1305 加密失败:{}", e)), Err(e) => Err(anyhow!("rs CHACHA20_POLY1305 加密失败:{}", e)),
}; }
} }
} }
@@ -118,4 +117,10 @@ fn test_rs_chacha20_poly1305() {
d.encrypt_ipv4(&mut p).unwrap(); d.encrypt_ipv4(&mut p).unwrap();
d.decrypt_ipv4(&mut p).unwrap(); d.decrypt_ipv4(&mut p).unwrap();
assert_eq!(p.buffer(), &src); assert_eq!(p.buffer(), &src);
let d = ChaCha20Poly1305Cipher::new_256([0; 32], None);
let mut p = NetPacket::new_encrypt([0; 73]).unwrap();
let src = p.buffer().to_vec();
d.encrypt_ipv4(&mut p).unwrap();
d.decrypt_ipv4(&mut p).unwrap();
assert_eq!(p.buffer(), &src);
} }
+19 -15
View File
@@ -122,7 +122,7 @@ impl Cipher {
model: CipherModel, model: CipherModel,
password: Option<String>, password: Option<String>,
token: Option<String>, token: Option<String>,
) -> Self { ) -> anyhow::Result<Self> {
if let Some(password) = password { if let Some(password) = password {
#[cfg(cipher)] #[cfg(cipher)]
let key: [u8; 32] = { let key: [u8; 32] = {
@@ -136,33 +136,33 @@ impl Cipher {
let finger = token.map(|token| Finger::new(&token)); let finger = token.map(|token| Finger::new(&token));
if password.len() < 8 { if password.len() < 8 {
let aes = AesGcmCipher::new_128(key[..16].try_into().unwrap(), finger); let aes = AesGcmCipher::new_128(key[..16].try_into().unwrap(), finger);
Cipher::AesGcm((aes, key[..16].to_vec())) Ok(Cipher::AesGcm((aes, key[..16].to_vec())))
} else { } else {
let aes = AesGcmCipher::new_256(key, finger); let aes = AesGcmCipher::new_256(key, finger);
Cipher::AesGcm((aes, key.to_vec())) Ok(Cipher::AesGcm((aes, key.to_vec())))
} }
} }
#[cfg(feature = "chacha20_poly1305")] #[cfg(feature = "chacha20_poly1305")]
CipherModel::Chacha20Poly1305 => { CipherModel::Chacha20Poly1305 => {
let finger = token.map(|token| Finger::new(&token)); let finger = token.map(|token| Finger::new(&token));
let chacha = ChaCha20Poly1305Cipher::new_256(key, finger); let chacha = ChaCha20Poly1305Cipher::new_256(key, finger);
Cipher::Chacha20Poly1305(chacha) Ok(Cipher::Chacha20Poly1305(chacha))
} }
#[cfg(feature = "chacha20_poly1305")] #[cfg(feature = "chacha20_poly1305")]
CipherModel::Chacha20 => { CipherModel::Chacha20 => {
let finger = token.map(|token| Finger::new(&token)); let finger = token.map(|token| Finger::new(&token));
let chacha = ChaCha20Cipher::new_256(key, finger); let chacha = ChaCha20Cipher::new_256(key, finger);
Cipher::Chacha20(chacha) Ok(Cipher::Chacha20(chacha))
} }
#[cfg(feature = "aes_cbc")] #[cfg(feature = "aes_cbc")]
CipherModel::AesCbc => { CipherModel::AesCbc => {
let finger = token.map(|token| Finger::new(&token)); let finger = token.map(|token| Finger::new(&token));
if password.len() < 8 { if password.len() < 8 {
let aes = AesCbcCipher::new_128(key[..16].try_into().unwrap(), finger); let aes = AesCbcCipher::new_128(key[..16].try_into().unwrap(), finger);
Cipher::AesCbc(aes) Ok(Cipher::AesCbc(aes))
} else { } else {
let aes = AesCbcCipher::new_256(key, finger); let aes = AesCbcCipher::new_256(key, finger);
Cipher::AesCbc(aes) Ok(Cipher::AesCbc(aes))
} }
} }
#[cfg(feature = "aes_ecb")] #[cfg(feature = "aes_ecb")]
@@ -170,28 +170,32 @@ impl Cipher {
let finger = token.map(|token| Finger::new(&token)); let finger = token.map(|token| Finger::new(&token));
if password.len() < 8 { if password.len() < 8 {
let aes = AesEcbCipher::new_128(key[..16].try_into().unwrap(), finger); let aes = AesEcbCipher::new_128(key[..16].try_into().unwrap(), finger);
Cipher::AesEcb(aes) Ok(Cipher::AesEcb(aes))
} else { } else {
let aes = AesEcbCipher::new_256(key, finger); let aes = AesEcbCipher::new_256(key, finger);
Cipher::AesEcb(aes) Ok(Cipher::AesEcb(aes))
} }
} }
#[cfg(feature = "sm4_cbc")] #[cfg(feature = "sm4_cbc")]
CipherModel::Sm4Cbc => { CipherModel::Sm4Cbc => {
let finger = token.map(|token| Finger::new(&token)); let finger = token.map(|token| Finger::new(&token));
let aes = Sm4CbcCipher::new_128(key[..16].try_into().unwrap(), finger); let aes = Sm4CbcCipher::new_128(key[..16].try_into().unwrap(), finger);
Cipher::Sm4Cbc(aes) Ok(Cipher::Sm4Cbc(aes))
} }
CipherModel::Xor => { CipherModel::Xor => {
let _token = token; if token.is_some() {
Cipher::Xor(XORCipher::new_256(crate::cipher::xor::simple_hash( Err(anyhow::anyhow!(
&password, "'finger' and 'xor' cannot be used simultaneously"
))?
}
Ok(Cipher::Xor(XORCipher::new_256(
crate::cipher::xor::simple_hash(&password),
))) )))
} }
CipherModel::None => Cipher::None, CipherModel::None => Ok(Cipher::None),
} }
} else { } else {
Cipher::None Ok(Cipher::None)
} }
} }
#[cfg(not(any(feature = "aes_gcm", feature = "server_encrypt")))] #[cfg(not(any(feature = "aes_gcm", feature = "server_encrypt")))]
+25
View File
@@ -1,4 +1,5 @@
use anyhow::anyhow; use anyhow::anyhow;
use rand::RngCore;
use sha2::Digest; use sha2::Digest;
@@ -49,3 +50,27 @@ impl Finger {
return key[20..].try_into().unwrap(); return key[20..].try_into().unwrap();
} }
} }
impl<B: AsRef<[u8]>> NetPacket<B> {
pub fn head_tag(&self) -> [u8; 12] {
let mut tag = [0; 12];
tag[0..4].copy_from_slice(&self.buffer()[4..8]);
tag[4..8].copy_from_slice(&self.buffer()[8..12]);
tag[8] = self.protocol().into();
tag[9] = self.transport_protocol();
tag[10] = self.is_gateway() as u8;
tag[11] = self.source_ttl();
tag
}
}
pub fn gen_nonce(tag: &mut [u8], random: &[u8]) {
tag[8] = random[0] ^ tag[8];
tag[9] = random[1] ^ tag[9];
tag[10] = random[2] ^ tag[10];
tag[11] = random[3] ^ tag[11];
}
pub fn gen_random_nonce(tag: &mut [u8; 12]) -> [u8; 4] {
let mut random = [0; 4];
rand::thread_rng().fill_bytes(&mut random);
gen_nonce(tag, &random);
random
}
+2 -14
View File
@@ -48,13 +48,7 @@ impl Sm4CbcCipher {
} }
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
let mut nonce_raw = [0; 12]; let nonce_raw = net_packet.head_tag();
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
nonce_raw[8] = net_packet.protocol().into();
nonce_raw[9] = net_packet.transport_protocol();
nonce_raw[10] = net_packet.is_gateway() as u8;
nonce_raw[11] = net_packet.source_ttl();
let len = net_packet.payload().len(); let len = net_packet.payload().len();
if len < 12 { if len < 12 {
return Err(anyhow!("payload len <12")); return Err(anyhow!("payload len <12"));
@@ -126,13 +120,7 @@ impl Sm4CbcCipher {
net_packet.payload_mut()[..len].copy_from_slice(&out[..len]); net_packet.payload_mut()[..len].copy_from_slice(&out[..len]);
net_packet.payload_mut()[len..].copy_from_slice(&iv); net_packet.payload_mut()[len..].copy_from_slice(&iv);
if let Some(finger) = &self.finger { if let Some(finger) = &self.finger {
let mut nonce_raw = [0; 12]; let nonce_raw = net_packet.head_tag();
nonce_raw[0..4].copy_from_slice(&net_packet.source().octets());
nonce_raw[4..8].copy_from_slice(&net_packet.destination().octets());
nonce_raw[8] = net_packet.protocol().into();
nonce_raw[9] = net_packet.transport_protocol();
nonce_raw[10] = net_packet.is_gateway() as u8;
nonce_raw[11] = net_packet.source_ttl();
let finger = finger.calculate_finger(&nonce_raw, net_packet.payload()); let finger = finger.calculate_finger(&nonce_raw, net_packet.payload());
let src_data_len = net_packet.data_len(); let src_data_len = net_packet.data_len();
//设置实际长度 //设置实际长度
+4 -2
View File
@@ -135,6 +135,7 @@ impl Compressor {
} }
#[test] #[test]
#[cfg(feature = "zstd_compress")]
fn test_lz4() { fn test_lz4() {
use crate::protocol::extension::{CompressionAlgorithm, ExtensionTailPacket}; use crate::protocol::extension::{CompressionAlgorithm, ExtensionTailPacket};
let lz4 = Compressor::Lz4; let lz4 = Compressor::Lz4;
@@ -166,7 +167,7 @@ fn test_lz4() {
unimplemented!() unimplemented!()
} }
}, },
ExtensionTailPacket::Unknown => { _ => {
unimplemented!() unimplemented!()
} }
} }
@@ -174,6 +175,7 @@ fn test_lz4() {
assert_eq!(in_packet.payload(), src_out_packet.payload()) assert_eq!(in_packet.payload(), src_out_packet.payload())
} }
#[test] #[test]
#[cfg(feature = "zstd_compress")]
fn test_zstd() { fn test_zstd() {
use crate::protocol::extension::{CompressionAlgorithm, ExtensionTailPacket}; use crate::protocol::extension::{CompressionAlgorithm, ExtensionTailPacket};
let zstd = Compressor::Zstd(22); let zstd = Compressor::Zstd(22);
@@ -209,7 +211,7 @@ fn test_zstd() {
unimplemented!() unimplemented!()
} }
}, },
ExtensionTailPacket::Unknown => { _ => {
unimplemented!() unimplemented!()
} }
} }
+7 -3
View File
@@ -1,3 +1,4 @@
use anyhow::Context;
use std::collections::HashMap; use std::collections::HashMap;
use std::net::Ipv4Addr; use std::net::Ipv4Addr;
use std::sync::Arc; use std::sync::Arc;
@@ -66,7 +67,7 @@ impl Vnt {
}; };
//客户端对称加密 //客户端对称加密
let client_cipher = let client_cipher =
Cipher::new_password(config.cipher_model, config.password.clone(), finger); Cipher::new_password(config.cipher_model, config.password.clone(), finger)?;
//当前设备信息 //当前设备信息
let current_device = Arc::new(AtomicCell::new(CurrentDeviceInfo::new0( let current_device = Arc::new(AtomicCell::new(CurrentDeviceInfo::new0(
config.server_address, config.server_address,
@@ -133,9 +134,12 @@ impl Vnt {
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))] #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
let device = { let device = {
log::info!("开始创建tun"); log::info!("开始创建tun");
let device = tun_tap_device::create_device(&config)?; let device = tun_tap_device::create_device(&config).context("create tun failed")?;
log::info!("创建tun成功"); log::info!("创建tun成功");
let tun_info = DeviceInfo::new(device.name()?, device.version()?); let tun_info = DeviceInfo::new(
device.name().unwrap_or("unknown".into()),
device.version().unwrap_or("unknown".into()),
);
log::info!("tun信息{:?}", tun_info); log::info!("tun信息{:?}", tun_info);
callback.create_tun(tun_info); callback.create_tun(tun_info);
device device
+5 -2
View File
@@ -24,7 +24,7 @@ use crate::handle::{BaseConfigInfo, CurrentDeviceInfo, PeerDeviceInfo, SELF_IP};
#[cfg(feature = "ip_proxy")] #[cfg(feature = "ip_proxy")]
use crate::ip_proxy::IpProxyMap; use crate::ip_proxy::IpProxyMap;
use crate::nat::NatTest; use crate::nat::NatTest;
use crate::protocol::NetPacket; use crate::protocol::{NetPacket, HEAD_LEN};
use crate::tun_tap_device::tun_create_helper::DeviceAdapter; use crate::tun_tap_device::tun_create_helper::DeviceAdapter;
use crate::util::U64Adder; use crate::util::U64Adder;
@@ -50,6 +50,9 @@ impl<Call: VntCallback> RecvChannelHandler for RecvDataHandler<Call> {
route_key: RouteKey, route_key: RouteKey,
context: &ChannelContext, context: &ChannelContext,
) { ) {
if buf.len() < HEAD_LEN {
return;
}
//判断stun响应包 //判断stun响应包
if !route_key.is_tcp() { if !route_key.is_tcp() {
if let Ok(rs) = self if let Ok(rs) = self
@@ -136,7 +139,7 @@ impl<Call: VntCallback> RecvDataHandler<Call> {
let net_packet = NetPacket::new(buf)?; let net_packet = NetPacket::new(buf)?;
let extend = NetPacket::unchecked(extend); let extend = NetPacket::unchecked(extend);
if net_packet.ttl() == 0 || net_packet.source_ttl() < net_packet.ttl() { if net_packet.ttl() == 0 || net_packet.source_ttl() < net_packet.ttl() {
log::warn!("丢弃过时包:{:?}", net_packet.head()); log::warn!("丢弃过时包:{:?} {}", net_packet.head(), route_key.addr);
return Ok(()); return Ok(());
} }
let current_device = self.current_device.load(); let current_device = self.current_device.load();
+6 -3
View File
@@ -79,14 +79,17 @@ fn start_simple0(
let fd = device.as_tun_fd(); let fd = device.as_tun_fd();
fd.set_nonblock()?; fd.set_nonblock()?;
SourceFd(&fd.as_raw_fd()).register(poll.registry(), FD, Interest::READABLE)?; SourceFd(&fd.as_raw_fd()).register(poll.registry(), FD, Interest::READABLE)?;
let mut evnets = Events::with_capacity(4); let mut events = Events::with_capacity(4);
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
let start = 12; let start = 12;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
let start = 12 - 4; let start = 12 - 4;
loop { loop {
poll.poll(&mut evnets, None)?; if let Err(e) = poll.poll(&mut events, None) {
for event in evnets.iter() { crate::ignore_io_interrupted(e)?;
continue;
}
for event in events.iter() {
if event.token() == STOP { if event.token() == STOP {
return Ok(()); return Ok(());
} }
+10
View File
@@ -16,4 +16,14 @@ pub mod tun_tap_device;
pub mod util; pub mod util;
pub use handle::callback::*; pub use handle::callback::*;
pub mod compression; pub mod compression;
pub(crate) fn ignore_io_interrupted(e: std::io::Error) -> std::io::Result<()> {
if e.kind() == std::io::ErrorKind::Interrupted {
log::warn!("ignore_io_interrupted");
Ok(())
} else {
Err(e)
}
}
+19 -6
View File
@@ -224,7 +224,23 @@ impl NatTest {
source_addr: SocketAddr, source_addr: SocketAddr,
buf: &[u8], buf: &[u8],
) -> anyhow::Result<bool> { ) -> anyhow::Result<bool> {
if buf[0] == 0x01 && buf[1] == 0x01 {
if let Some(addr) = stun::recv_stun_response(buf) { if let Some(addr) = stun::recv_stun_response(buf) {
if let Err(e) = self.recv_data_(index, source_addr, addr) {
log::warn!("{:?}", e);
}
}
Ok(true)
} else {
Ok(false)
}
}
fn recv_data_(
&self,
index: usize,
source_addr: SocketAddr,
addr: SocketAddr,
) -> anyhow::Result<()> {
if let SocketAddr::V4(addr) = addr { if let SocketAddr::V4(addr) = addr {
let mut check_fail = true; let mut check_fail = true;
let source_ip = match source_addr.ip() { let source_ip = match source_addr.ip() {
@@ -233,7 +249,7 @@ impl NatTest {
if let Some(ip) = ip.to_ipv4_mapped() { if let Some(ip) = ip.to_ipv4_mapped() {
ip ip
} else { } else {
return Ok(false); return Ok(());
} }
} }
}; };
@@ -249,9 +265,7 @@ impl NatTest {
} }
} }
} }
if check_fail { if !check_fail {
return Ok(false);
}
let ip = addr.ip(); let ip = addr.ip();
if !ip.is_multicast() if !ip.is_multicast()
&& !ip.is_broadcast() && !ip.is_broadcast()
@@ -260,10 +274,9 @@ impl NatTest {
&& !ip.is_private() && !ip.is_private()
{ {
self.update_addr(index, *addr.ip(), addr.port()); self.update_addr(index, *addr.ip(), addr.port());
return Ok(true);
} }
} }
} }
return Ok(false); Ok(())
} }
} }
-3
View File
@@ -198,9 +198,6 @@ pub fn send_stun_request() -> Vec<u8> {
} }
pub fn recv_stun_response(buf: &[u8]) -> Option<SocketAddr> { pub fn recv_stun_response(buf: &[u8]) -> Option<SocketAddr> {
if buf[0] != 0x01 && buf[1] != 0x01 {
return None;
}
let msg = stun_format::Msg::from(buf); let msg = stun_format::Msg::from(buf);
if let Some(tid) = msg.tid() { if let Some(tid) = msg.tid() {
if tid & TAG != TAG { if tid & TAG != TAG {
+5 -1
View File
@@ -6,7 +6,11 @@ pub async fn tcp_mapping(bind_addr: SocketAddr, destination: String) -> anyhow::
let tcp_listener = TcpListener::bind(bind_addr) let tcp_listener = TcpListener::bind(bind_addr)
.await .await
.with_context(|| format!("TCP binding {:?} failed", bind_addr))?; .with_context(|| format!("TCP binding {:?} failed", bind_addr))?;
tokio::spawn(tcp_mapping_(bind_addr, tcp_listener, destination)); tokio::spawn(async move {
if let Err(e) = tcp_mapping_(bind_addr, tcp_listener, destination).await {
log::warn!("tcp_mapping {:?}", e);
}
});
Ok(()) Ok(())
} }
+255 -79
View File
@@ -4,6 +4,261 @@ pub const ENCRYPTION_RESERVED: usize = 16 + 32 + 12;
pub const AES_GCM_ENCRYPTION_RESERVED: usize = 32; pub const AES_GCM_ENCRYPTION_RESERVED: usize = 32;
pub const RSA_ENCRYPTION_RESERVED: usize = 32; pub const RSA_ENCRYPTION_RESERVED: usize = 32;
pub const RANDOM_RESERVED: usize = 4;
pub const FINGER_RESERVED: usize = 12;
pub const TAG_RESERVED: usize = 16;
/*
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| random(32) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| finger(32) |
| finger(32) |
| finger(32) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
pub trait SecretTail {
fn buffer(&self) -> &[u8];
fn exist_finger(&self) -> bool;
fn random_buf(&self) -> &[u8] {
let buf = self.buffer();
let mut end = buf.len();
if self.exist_finger() {
end -= FINGER_RESERVED;
}
&buf[end - RANDOM_RESERVED..end]
}
fn finger(&self) -> &[u8] {
if self.exist_finger() {
let buf = self.buffer();
let end = buf.len();
&buf[end - FINGER_RESERVED..end]
} else {
&[]
}
}
}
pub trait SecretTailMut: SecretTail {
fn buffer_mut(&mut self) -> &mut [u8];
fn set_random(&mut self, random: &[u8]) {
let f = self.exist_finger();
let buf = self.buffer_mut();
let mut end = buf.len();
if f {
end -= FINGER_RESERVED;
}
buf[end - RANDOM_RESERVED..end].copy_from_slice(random);
}
fn set_finger(&mut self, finger: &[u8]) -> io::Result<()> {
if self.exist_finger() {
if finger.len() != FINGER_RESERVED {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"finger.len != 12",
));
}
let buf = self.buffer_mut();
let end = buf.len();
buf[end - FINGER_RESERVED..end].copy_from_slice(finger);
Ok(())
} else {
Err(io::Error::new(
io::ErrorKind::InvalidData,
"not exist finger",
))
}
}
}
/* aead加密数据体
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| tag(32) |
| tag(32) |
| tag(32) |
| tag(32) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| random(32) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| finger(32) |
| finger(32) |
| finger(32) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
finger用于快速校验数据是否被修改使tokenfinger
()
*/
pub struct AEADSecretBody<B> {
buffer: B,
exist_finger: bool,
}
impl<B: AsRef<[u8]>> AEADSecretBody<B> {
pub fn new(buffer: B, exist_finger: bool) -> io::Result<AEADSecretBody<B>> {
let len = buffer.as_ref().len();
let min_len = if exist_finger {
TAG_RESERVED + RANDOM_RESERVED + FINGER_RESERVED
} else {
TAG_RESERVED + RANDOM_RESERVED
};
// 不能大于udp最大载荷长度
if len < min_len || len > 65535 - 20 - 8 - 12 {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("AEADSecretBody length overflow {}", len),
));
}
Ok(AEADSecretBody {
buffer,
exist_finger,
})
}
pub fn data(&self) -> &[u8] {
let mut end = self.buffer.as_ref().len() - TAG_RESERVED - RANDOM_RESERVED;
if self.exist_finger {
end -= FINGER_RESERVED;
}
&self.buffer.as_ref()[..end]
}
pub fn tag(&self) -> &[u8] {
let mut end = self.buffer.as_ref().len() - RANDOM_RESERVED;
if self.exist_finger {
end -= FINGER_RESERVED;
}
&self.buffer.as_ref()[end - TAG_RESERVED..end]
}
}
impl<B: AsRef<[u8]>> SecretTail for AEADSecretBody<B> {
#[inline]
fn buffer(&self) -> &[u8] {
self.buffer.as_ref()
}
#[inline]
fn exist_finger(&self) -> bool {
self.exist_finger
}
}
impl<B: AsRef<[u8]> + AsMut<[u8]>> SecretTailMut for AEADSecretBody<B> {
#[inline]
fn buffer_mut(&mut self) -> &mut [u8] {
self.buffer.as_mut()
}
}
impl<B: AsRef<[u8]> + AsMut<[u8]>> AEADSecretBody<B> {
/// 数据部分
pub fn data_mut(&mut self) -> &mut [u8] {
let mut end = self.buffer.as_ref().len() - RANDOM_RESERVED - TAG_RESERVED;
if self.exist_finger {
end -= FINGER_RESERVED;
}
&mut self.buffer.as_mut()[..end]
}
/// 数据和tag部分
pub fn data_tag_mut(&mut self) -> &mut [u8] {
let mut end = self.buffer.as_ref().len() - RANDOM_RESERVED;
if self.exist_finger {
end -= FINGER_RESERVED;
}
&mut self.buffer.as_mut()[..end]
}
pub fn set_tag(&mut self, tag: &[u8]) -> io::Result<()> {
if tag.len() != 16 {
return Err(io::Error::new(io::ErrorKind::InvalidData, "tag.len != 16"));
}
let mut end = self.buffer.as_ref().len() - RANDOM_RESERVED;
if self.exist_finger {
end -= FINGER_RESERVED;
}
self.buffer.as_mut()[end - TAG_RESERVED..end].copy_from_slice(tag);
Ok(())
}
}
/* 带随机数的加密数据体
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| random(32) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| finger(32) |
| finger(32) |
| finger(32) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
finger用于快速校验数据是否被修改使tokenfinger
()
*/
pub struct IVSecretBody<B> {
buffer: B,
exist_finger: bool,
}
impl<B: AsRef<[u8]>> IVSecretBody<B> {
pub fn new(buffer: B, exist_finger: bool) -> io::Result<IVSecretBody<B>> {
let len = buffer.as_ref().len();
let min_len = if exist_finger {
FINGER_RESERVED + RANDOM_RESERVED
} else {
RANDOM_RESERVED
};
// 不能大于udp最大载荷长度
if len < min_len || len > 65535 - 20 - 8 - 12 {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("IVSecretBody length overflow {}", len),
));
}
Ok(IVSecretBody {
buffer,
exist_finger,
})
}
pub fn data(&self) -> &[u8] {
let mut end = self.buffer.as_ref().len() - RANDOM_RESERVED;
if self.exist_finger {
end -= FINGER_RESERVED;
}
&self.buffer.as_ref()[..end]
}
}
impl<B: AsRef<[u8]> + AsMut<[u8]>> IVSecretBody<B> {
pub fn data_mut(&mut self) -> &mut [u8] {
let mut end = self.buffer.as_ref().len() - RANDOM_RESERVED;
if self.exist_finger {
end -= FINGER_RESERVED;
}
&mut self.buffer.as_mut()[..end]
}
}
impl<B: AsRef<[u8]>> SecretTail for IVSecretBody<B> {
#[inline]
fn buffer(&self) -> &[u8] {
self.buffer.as_ref()
}
#[inline]
fn exist_finger(&self) -> bool {
self.exist_finger
}
}
impl<B: AsRef<[u8]> + AsMut<[u8]>> SecretTailMut for IVSecretBody<B> {
#[inline]
fn buffer_mut(&mut self) -> &mut [u8] {
self.buffer.as_mut()
}
}
/* aes_gcm加密数据体 /* aes_gcm加密数据体
0 15 31 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 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
@@ -253,85 +508,6 @@ impl<B: AsRef<[u8]> + AsMut<[u8]>> AesCbcSecretBody<B> {
&mut self.buffer.as_mut()[..end] &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用于快速校验数据是否被修改使tokenfinger
()
*/
pub struct ChaCah20SecretBody<B> {
buffer: B,
exist_finger: bool,
}
impl<B: AsRef<[u8]>> ChaCah20SecretBody<B> {
pub fn new(buffer: B, exist_finger: bool) -> io::Result<ChaCah20SecretBody<B>> {
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<B: AsRef<[u8]> + AsMut<[u8]>> ChaCah20SecretBody<B> {
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加密数据体 /* rsa加密数据体
0 15 31 0 15 31
+3 -2
View File
@@ -6,7 +6,7 @@ use std::{fmt, io};
0 15 31 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 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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|e |s |u |u| (4) | (8) | (8) | ttl(4) | (4) | |e |s |x |u| (4) | (8) | (8) | ttl(4) | (4) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ip地址(32) | | ip地址(32) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -14,7 +14,7 @@ use std::{fmt, io};
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
e为是否加密标志s为服务端通信包标志u未使用 e为是否加密标志s为服务端通信包标志x扩展标志u未使用
*/ */
pub const HEAD_LEN: usize = 12; pub const HEAD_LEN: usize = 12;
@@ -137,6 +137,7 @@ impl<B: AsRef<[u8]>> NetPacket<B> {
} }
Ok(NetPacket { data_len, buffer }) Ok(NetPacket { data_len, buffer })
} }
#[inline]
pub fn buffer(&self) -> &[u8] { pub fn buffer(&self) -> &[u8] {
&self.buffer.as_ref()[..self.data_len] &self.buffer.as_ref()[..self.data_len]
} }