mirror of
https://mirror.suhoan.cn/https://github.com/EasyTier/EasyTier.git
synced 2025-12-14 05:37:23 +08:00
support encryption (#60)
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::hash::Hasher;
|
||||
use std::{net::SocketAddr, pin::Pin, sync::Arc};
|
||||
|
||||
use async_trait::async_trait;
|
||||
@@ -197,3 +199,17 @@ impl TunnelUrl {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_digest_from_str(str1: &str, str2: &str, digest: &mut [u8]) {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
hasher.write(str1.as_bytes());
|
||||
hasher.write(str2.as_bytes());
|
||||
|
||||
assert_eq!(digest.len() % 8, 0, "digest length must be multiple of 8");
|
||||
|
||||
let shard_count = digest.len() / 8;
|
||||
for i in 0..shard_count {
|
||||
digest[i * 8..(i + 1) * 8].copy_from_slice(&hasher.finish().to_be_bytes());
|
||||
hasher.write(&digest[..(i + 1) * 8]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,16 +56,53 @@ pub enum PacketType {
|
||||
Route = 7,
|
||||
}
|
||||
|
||||
bitflags::bitflags! {
|
||||
struct PeerManagerHeaderFlags: u8 {
|
||||
const ENCRYPTED = 0b0000_0001;
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C, packed)]
|
||||
#[derive(AsBytes, FromBytes, FromZeroes, Clone, Debug, Default)]
|
||||
pub struct PeerManagerHeader {
|
||||
pub from_peer_id: U32<DefaultEndian>,
|
||||
pub to_peer_id: U32<DefaultEndian>,
|
||||
pub packet_type: u8,
|
||||
pub flags: u8,
|
||||
reserved: U16<DefaultEndian>,
|
||||
pub len: U32<DefaultEndian>,
|
||||
}
|
||||
pub const PEER_MANAGER_HEADER_SIZE: usize = std::mem::size_of::<PeerManagerHeader>();
|
||||
|
||||
impl PeerManagerHeader {
|
||||
pub fn is_encrypted(&self) -> bool {
|
||||
PeerManagerHeaderFlags::from_bits(self.flags)
|
||||
.unwrap()
|
||||
.contains(PeerManagerHeaderFlags::ENCRYPTED)
|
||||
}
|
||||
|
||||
pub fn set_encrypted(&mut self, encrypted: bool) {
|
||||
let mut flags = PeerManagerHeaderFlags::from_bits(self.flags).unwrap();
|
||||
if encrypted {
|
||||
flags.insert(PeerManagerHeaderFlags::ENCRYPTED);
|
||||
} else {
|
||||
flags.remove(PeerManagerHeaderFlags::ENCRYPTED);
|
||||
}
|
||||
self.flags = flags.bits();
|
||||
}
|
||||
}
|
||||
|
||||
// reserve the space for aes tag and nonce
|
||||
#[repr(C, packed)]
|
||||
#[derive(AsBytes, FromBytes, FromZeroes, Clone, Debug, Default)]
|
||||
pub struct AesGcmTail {
|
||||
pub tag: [u8; 16],
|
||||
pub nonce: [u8; 12],
|
||||
}
|
||||
pub const AES_GCM_ENCRYPTION_RESERVED: usize = std::mem::size_of::<AesGcmTail>();
|
||||
|
||||
pub const TAIL_RESERVED_SIZE: usize = AES_GCM_ENCRYPTION_RESERVED;
|
||||
|
||||
const fn max(a: usize, b: usize) -> usize {
|
||||
[a, b][(a < b) as usize]
|
||||
}
|
||||
@@ -308,6 +345,7 @@ impl ZCPacket {
|
||||
hdr.from_peer_id.set(from_peer_id);
|
||||
hdr.to_peer_id.set(to_peer_id);
|
||||
hdr.packet_type = packet_type;
|
||||
hdr.flags = 0;
|
||||
hdr.len.set(payload_len as u32);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
use std::{
|
||||
collections::hash_map::DefaultHasher,
|
||||
fmt::{Debug, Formatter},
|
||||
hash::Hasher,
|
||||
net::SocketAddr,
|
||||
pin::Pin,
|
||||
sync::{atomic::AtomicBool, Arc},
|
||||
@@ -33,6 +31,7 @@ use crate::{
|
||||
use super::{
|
||||
check_scheme_and_get_socket_addr,
|
||||
common::{setup_sokcet2, setup_sokcet2_ext, wait_for_connect_futures},
|
||||
generate_digest_from_str,
|
||||
packet_def::{ZCPacketType, PEER_MANAGER_HEADER_SIZE},
|
||||
ring::create_ring_tunnel_pair,
|
||||
Tunnel, TunnelError, TunnelListener, TunnelUrl, ZCPacketSink, ZCPacketStream,
|
||||
@@ -62,16 +61,7 @@ pub struct WgConfig {
|
||||
impl WgConfig {
|
||||
pub fn new_from_network_identity(network_name: &str, network_secret: &str) -> Self {
|
||||
let mut my_sec = [0u8; 32];
|
||||
let mut hasher = DefaultHasher::new();
|
||||
hasher.write(network_name.as_bytes());
|
||||
hasher.write(network_secret.as_bytes());
|
||||
my_sec[0..8].copy_from_slice(&hasher.finish().to_be_bytes());
|
||||
hasher.write(&my_sec[0..8]);
|
||||
my_sec[8..16].copy_from_slice(&hasher.finish().to_be_bytes());
|
||||
hasher.write(&my_sec[0..16]);
|
||||
my_sec[16..24].copy_from_slice(&hasher.finish().to_be_bytes());
|
||||
hasher.write(&my_sec[0..24]);
|
||||
my_sec[24..32].copy_from_slice(&hasher.finish().to_be_bytes());
|
||||
generate_digest_from_str(network_name, network_secret, &mut my_sec);
|
||||
|
||||
let my_secret_key = StaticSecret::from(my_sec);
|
||||
let my_public_key = PublicKey::from(&my_secret_key);
|
||||
@@ -491,6 +481,7 @@ impl WgTunnelListener {
|
||||
|
||||
let mut buf = vec![0u8; MAX_PACKET];
|
||||
loop {
|
||||
tracing::info!("Waiting for incoming UDP packet");
|
||||
let Ok((n, addr)) = socket.recv_from(&mut buf).await else {
|
||||
tracing::error!("Failed to receive from UDP socket");
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user