# Блок `tlseng` — движок TLS-маскировки Минимальный TLS-«стек», задача которого — **не** реализовать TLS, а правдоподобно его *имитировать*. Цель: чтобы первый пакет сессии (`ClientHello`) по отпечатку (JA3/JA4) был неотличим от популярного браузера, и DPI считал туннель обычным HTTPS-сёрфингом. Фокус блока — **fingerprint mimicry**, а не криптография: настоящие ключи живут в [`crypto`](../crypto), а их обмен спрятан внутри полей этих поддельных TLS-сообщений. > Детали — в rustdoc, модуль `tlseng`. ## Файлы | Файл | Что внутри | |-----------------|-----------------------------------------------------------------| | `types.rs` | Wire-константы и enum'ы TLS (content-type, версии, группы, ext). | | `consts.rs` | Точечные «магические числа» протокола. | | `tls_record.rs` | Слой TLS-записи: `type|version|len` + payload. | | `extension.rs` | Сборка/парсинг расширений (`ExtensionStack`/`ExtensionBuilder`). | | `handshake.rs` | `ClientHello`/`ServerHello`: сборка и разбор. | | `profile.rs` | Профили браузеров/сервера: cipher-suites, группы, порядок ext. | ## Где спрятана «контрабанда» Поля поддельного hello переиспользуются под обмен ключами: | Поле TLS | Что несёт на самом деле | |---------------------|------------------------------------------------------| | `random` (32 байта) | локальная соль стороны (для HKDF) | | `session_id` (32 б.)| 16 случайных байт + 16 байт time-based auth-тега | | расширение KeyShare | публичный ключ X25519 | ## Почему порядок и длины критичны JA3/JA4-отпечаток считается из набора и **порядка** cipher-suites и расширений, их содержимого, GREASE-значений и паддинга. Поэтому `profile.rs` хранит точные списки и `ExtensionOrder`, повторяющие реальный браузер байт-в-байт. Любая перестановка ломает маскировку. `ExtensionBuilder::apply_profile` идёт строго по порядку из профиля. ## Чего здесь намеренно нет Полного TLS state machine, проверки сертификатов, `Finished`/verify и самого шифрования — движок изображает рукопожатие ровно настолько, чтобы пройти DPI. ## Связи - Вызывается из `TlsBridge` ([`nrxp`](../nrxp)) при хендшейке. - Извлечённый из KeyShare ключ уходит в [`crypto`](../crypto) для ECDH.