big changes

This commit is contained in:
2026-02-25 18:09:20 +07:00
parent bf7d50bcef
commit 2835108b7f
56 changed files with 1111 additions and 775 deletions
+25 -148
View File
@@ -1,172 +1,49 @@
use aead::rand_core::RngCore;
use aead::OsRng;
use bytes::{BufMut, Bytes, BytesMut};
use bytes::{Bytes, BytesMut};
use crate::crypto::chacha::ChaChaCipher;
use crate::crypto::ecdh::ECDH;
use crate::crypto::hmac::generate_auth_tag;
use crate::protocol::interceptors::hello_interceptor::extension_interceptor::ExtensionStack;
use crate::protocol::interceptors::interceptor::Interceptor;
use crate::tlseng::etype::EXT_KEY_SHARE;
use crate::tlseng::extension::ExtensionBuilder;
use crate::tlseng::profile::profile::BrowserProfile;
use crate::tlseng::tls::{
ClientHello, ContentType, HelloHeader, HelloType, ProtocolVersion, ServerHello, TlsRecord,
};
use crate::protocol::codec::bridges::tls::bridge::TlsBridge;
use crate::protocol::codec::session_keys::SessionKeys;
use crate::crypto::aead::AeadPacker;
pub struct Codec {
crypto: ChaChaCipher,
crypto: ChaChaCipher, //rename chacha
pub session_keys: SessionKeys,
}
impl Codec {
pub fn new() -> Self {
pub fn new(is_initiator: bool) -> Self {
Self {
crypto: ChaChaCipher::new(),
session_keys: SessionKeys::new(is_initiator),
}
}
pub fn make_handshake(&mut self, profile: &BrowserProfile, host: &str) -> Bytes {
// 1. Key Exchange: Generate ECDH pair and get public key
let ecdh = ECDH::new();
let pub_key = &ecdh.public_key;
// 2. Authentication: Generate 32 bytes for TLS Random
// [16 bytes entropy] + [16 bytes HMAC(timestamp)]
let mut tls_random = [0u8; 32];
OsRng.fill_bytes(&mut tls_random[..16]);
let auth_token = generate_auth_tag(&[]);
tls_random[16..32].copy_from_slice(&auth_token);
// 3. Extensions: Build the extensions block using the profile
let mut ext_builder = ExtensionBuilder::new();
// Pass the public key into the KeyShare extension via apply_profile
ext_builder.apply_profile(profile, host, pub_key.as_bytes());
let extensions_bytes = ext_builder.build();
let mut session_id = BytesMut::with_capacity(32);
session_id.put_slice(&[0u8; 32]);
// 4. Assemble ClientHello Handshake message
let client_hello = ClientHello {
version: ProtocolVersion::Tls12, // Legacy version for compatibility
random: tls_random,
session_id: session_id.freeze(), // Standard 32-byte session ID
cipher_suites: vec![0x1301, 0x1302, 0x1303], // TLS 1.3 suites
extensions: extensions_bytes,
};
// 5. Wrap ClientHello into a TLS Record
let record = TlsRecord {
content_type: ContentType::Handshake,
version: ProtocolVersion::Tls10, // Standard for ClientHello records
len: client_hello.serialize().len() as u16,
payload: client_hello.serialize(),
};
println!("Client Hello: {:02x?}", record.payload.to_vec());
// Final result: Byte buffer ready for the wire
record.serialize()
pub fn make_handshake(&mut self, buffer: &mut BytesMut) {
println!("Handshake len in codec: {:?}", &buffer.len());
TlsBridge::make_handshake(buffer, self);
}
/// Основная точка входа для входящих данных из сокета
pub fn process_incoming(&mut self, mut buffer: BytesMut) {
// 1. Пытаемся достать TLS Record (самый верхний слой)
match TlsRecord::intercept(&mut buffer) {
Ok(Some(record)) => {
println!(
"Получен Record: type={:?}, len={}",
record.content_type, record.len
);
// 2. Диспетчеризация по типу контента
self.handle_record(record);
}
Ok(None) => {
// Пакет неполный, ждем догрузки в буфер
}
Err(_e) => {
// Заглушка: ошибка парсинга рекорда
}
pub fn unpack(&mut self, buffer: &mut BytesMut) -> Result<Bytes, String> {
println!("App data unpack len in codec?: {:?}", &buffer.len());
let mut data = TlsBridge::unpack_app_data(buffer);
//self.decrypt(&mut data);
match data {
Ok(bytes) => Ok(bytes.freeze()),
Err(e) => Err(e.to_string()),
}
}
fn handle_record(&mut self, record: TlsRecord) {
match record.content_type {
ContentType::Handshake => {
self.handle_handshake(record.payload);
}
ContentType::ApplicationData => {
self.handle_application_data(record.payload);
}
_ => {
// Остальные типы (Alert, ChangeCipherSpec) пока игнорируем
}
}
pub fn pack(&mut self, buffer: &mut BytesMut) -> Bytes {
println!("App data len in codec?: {:?}", &buffer.len());
TlsBridge::pack_in_app_data(buffer)
}
fn handle_handshake(&mut self, mut payload: Bytes) {
// Превращаем Bytes в BytesMut для интерцепторов (без копирования данных)
let mut body = BytesMut::from(payload.as_ref());
// 1. Парсим заголовок Handshake (Type + Length)
match HelloHeader::intercept(&mut body) {
Ok(Some(header)) => {
match header.header_type {
HelloType::Server => {
let mut server_hello_body = body; // Тут уже откушенное тело
if let Ok(Some(server_hello)) =
ServerHello::intercept(&mut server_hello_body)
{
self.process_server_hello(server_hello);
}
}
HelloType::Client => {
let mut client_hello_body = body;
if let Ok(Some(client_hello)) =
ClientHello::intercept(&mut client_hello_body)
{
self.process_client_hello(client_hello);
}
}
_ => { /* Другие типы Handshake (EncryptedExtensions, Certificate и т.д.) */
}
}
}
_ => { /* Заглушка на ошибку */ }
}
pub fn encrypt(&mut self, data: &mut BytesMut) {
self.crypto.encrypt(data);
}
fn process_server_hello(&mut self, hello: ServerHello) {
println!("Server Hello получен! Random: {:02x?}", hello.random);
// Парсим расширения сервера, если нужно
let mut ext_bytes = BytesMut::from(hello.extensions.as_ref());
if let Ok(Some(stack)) = ExtensionStack::intercept(&mut ext_bytes) {
// Например, ищем KeyShare сервера для завершения ECDH
if let Some(key_share) = stack.find_by_type(EXT_KEY_SHARE) {
println!("Найден KeyShare сервера, длина: {}", key_share.len());
}
}
}
fn process_client_hello(&mut self, hello: ClientHello) {
println!("Client Hello получен! Random: {:02x?}", hello.random);
// Парсим расширения сервера, если нужно
let mut ext_bytes = BytesMut::from(hello.extensions.as_ref());
if let Ok(Some(stack)) = ExtensionStack::intercept(&mut ext_bytes) {
if let Some(key_share) = stack.find_by_type(EXT_KEY_SHARE) {
println!("Найден KeyShare сервера, длина: {}", key_share.len());
}
}
}
fn handle_application_data(&mut self, payload: Bytes) {
// Здесь будет логика расшифровки через твой ChaChaCipher
// Пока просто выводим длину зашифрованных данных
println!("Получены Application Data: {} байт", payload.len());
pub fn decrypt(&mut self, data: &mut BytesMut) {
self.crypto.decrypt(data);
}
}