Dummy data instead of HTTP

This commit is contained in:
Pascal Engélibert 2026-02-06 15:05:41 +01:00
commit dec39cf2e3
10 changed files with 1543 additions and 1413 deletions

View file

@ -1,26 +1,8 @@
use std::iter::Peekable;
use crate::record::Direction;
fn hex_digit(c: u8) -> u32 {
((c & !(16 | 32 | 64)) + ((c & 64) >> 6) * 9) as _
}
pub fn parse_hex(s: &[u8]) -> u32 {
let mut r = 0;
for i in s.iter() {
r <<= 4;
r |= hex_digit(*i);
}
r
}
pub fn is_hex(s: &[u8]) -> bool {
s.iter().all(|c| {
let c = *c | 32;
(c >= b'a' && c <= b'f') || (c >= b'0' && c <= b'9')
})
}
use log::info;
use std::iter::Peekable;
use tokio_rustls::rustls::crypto::CryptoProvider;
/// Print ASCII if possible
pub fn print_bin(s: &[u8]) {
@ -46,85 +28,407 @@ pub fn print_bin(s: &[u8]) {
pub struct ResponseStreamer<I: Iterator>(Peekable<I>);
impl<'a, I: Iterator> ResponseStreamer<I> {
impl<I: Iterator> ResponseStreamer<I> {
pub fn new(inner: I) -> Self {
Self(inner.peekable())
}
}
impl<'a, I: Iterator<Item = &'a (Direction, Vec<u8>)>> Iterator for ResponseStreamer<I> {
type Item = (&'a Direction, Vec<&'a Vec<u8>>);
impl<'a, I: Iterator<Item = &'a (u64, Direction, u64)>> Iterator for ResponseStreamer<I> {
type Item = (Direction, Vec<(u64, u64)>);
fn next(&mut self) -> Option<Self::Item> {
let (direction, first_item) = self.0.next()?;
let mut items = vec![first_item];
while let Some((item_direction, _item)) = self.0.peek()
&& item_direction == direction
let (first_req_id, first_direction, first_len) = self.0.next()?;
let mut items = vec![(*first_req_id, *first_len)];
while let Some((_req_id, direction, _len)) = self.0.peek()
&& direction == first_direction
{
items.push(&self.0.next().unwrap().1);
let (req_id, _direction, len) = self.0.next().unwrap();
items.push((*req_id, *len));
}
Some((direction, items))
Some((*first_direction, items))
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_hex_digit() {
assert_eq!(hex_digit(b'0'), 0);
assert_eq!(hex_digit(b'1'), 1);
assert_eq!(hex_digit(b'2'), 2);
assert_eq!(hex_digit(b'3'), 3);
assert_eq!(hex_digit(b'4'), 4);
assert_eq!(hex_digit(b'5'), 5);
assert_eq!(hex_digit(b'6'), 6);
assert_eq!(hex_digit(b'7'), 7);
assert_eq!(hex_digit(b'8'), 8);
assert_eq!(hex_digit(b'9'), 9);
assert_eq!(hex_digit(b'a'), 10);
assert_eq!(hex_digit(b'b'), 11);
assert_eq!(hex_digit(b'c'), 12);
assert_eq!(hex_digit(b'd'), 13);
assert_eq!(hex_digit(b'e'), 14);
assert_eq!(hex_digit(b'f'), 15);
assert_eq!(hex_digit(b'A'), 10);
assert_eq!(hex_digit(b'B'), 11);
assert_eq!(hex_digit(b'C'), 12);
assert_eq!(hex_digit(b'D'), 13);
assert_eq!(hex_digit(b'E'), 14);
assert_eq!(hex_digit(b'F'), 15);
pub fn init_provider() {
let mut ciphers: Option<Vec<String>> = None;
let mut kexes: Option<Vec<String>> = None;
for (var, val) in std::env::vars() {
match var.as_str() {
"CIPHERS" => ciphers = Some(val.split(',').map(str::to_string).collect()),
"KEXES" => kexes = Some(val.split(',').map(str::to_string).collect()),
_ => {}
}
}
// Ensure multiple provider cannot be enabled without compile error.
let _provider;
#[cfg(feature = "aws-lc")]
{
info!("Using RusTLS provider aws-lc");
let mut prov = rustls_post_quantum::provider();
if let Some(ciphers) = ciphers {
prov.cipher_suites.clear();
for cipher in ciphers {
match cipher.as_str() {
"AES_256_GCM_SHA384" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::aws_lc_rs::cipher_suite::TLS13_AES_256_GCM_SHA384),
"AES_128_GCM_SHA256" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::aws_lc_rs::cipher_suite::TLS13_AES_128_GCM_SHA256),
"CHACHA20_POLY1305_SHA256" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::aws_lc_rs::cipher_suite::TLS13_CHACHA20_POLY1305_SHA256),
"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::aws_lc_rs::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384),
"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::aws_lc_rs::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256),
"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::aws_lc_rs::cipher_suite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256),
"ECDHE_RSA_WITH_AES_256_GCM_SHA384" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::aws_lc_rs::cipher_suite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384),
"ECDHE_RSA_WITH_AES_128_GCM_SHA256" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::aws_lc_rs::cipher_suite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256),
"ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::aws_lc_rs::cipher_suite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256),
other => {
log::error!("Unknown cipher `{other}`")
}
}
}
}
if let Some(kexes) = kexes {
prov.kx_groups.clear();
for kex in kexes {
match kex.as_str() {
"X25519" => prov
.kx_groups
.push(tokio_rustls::rustls::crypto::aws_lc_rs::kx_group::X25519),
"SECP256R1" => prov
.kx_groups
.push(tokio_rustls::rustls::crypto::aws_lc_rs::kx_group::SECP256R1),
"SECP384R1" => prov
.kx_groups
.push(tokio_rustls::rustls::crypto::aws_lc_rs::kx_group::SECP384R1),
"X25519MLKEM768" => prov
.kx_groups
.push(tokio_rustls::rustls::crypto::aws_lc_rs::kx_group::X25519MLKEM768),
"SECP256R1MLKEM768" => prov
.kx_groups
.push(tokio_rustls::rustls::crypto::aws_lc_rs::kx_group::SECP256R1MLKEM768),
"MLKEM768" => prov
.kx_groups
.push(tokio_rustls::rustls::crypto::aws_lc_rs::kx_group::MLKEM768),
other => {
log::error!("Unknown kex `{other}`")
}
}
}
}
_provider = CryptoProvider::install_default(prov);
}
#[cfg(feature = "boring")]
{
info!("Using RusTLS provider boring");
let mut prov = boring_rustls_provider::provider();
if let Some(ciphers) = ciphers {
prov.cipher_suites.clear();
for cipher in ciphers {
match cipher.as_str() {
"AES_256_GCM_SHA384" => prov.cipher_suites.push(tokio_rustls::rustls::SupportedCipherSuite::Tls13(
&boring_rustls_provider::tls13::AES_256_GCM_SHA384,
)),
"AES_128_GCM_SHA256" => prov.cipher_suites.push(tokio_rustls::rustls::SupportedCipherSuite::Tls13(
&boring_rustls_provider::tls13::AES_128_GCM_SHA256,
)),
"CHACHA20_POLY1305_SHA256" => prov.cipher_suites.push(tokio_rustls::rustls::SupportedCipherSuite::Tls13(
&boring_rustls_provider::tls13::CHACHA20_POLY1305_SHA256,
)),
"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" => prov.cipher_suites.push(tokio_rustls::rustls::SupportedCipherSuite::Tls12(
&boring_rustls_provider::tls12::ECDHE_ECDSA_AES256_GCM_SHA384,
)),
"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" => prov.cipher_suites.push(tokio_rustls::rustls::SupportedCipherSuite::Tls12(
&boring_rustls_provider::tls12::ECDHE_ECDSA_AES128_GCM_SHA256,
)),
"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" => prov.cipher_suites.push(tokio_rustls::rustls::SupportedCipherSuite::Tls12(
&boring_rustls_provider::tls12::ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
)),
"ECDHE_RSA_WITH_AES_256_GCM_SHA384" => prov.cipher_suites.push(tokio_rustls::rustls::SupportedCipherSuite::Tls12(
&boring_rustls_provider::tls12::ECDHE_RSA_AES256_GCM_SHA384,
)),
"ECDHE_RSA_WITH_AES_128_GCM_SHA256" => prov.cipher_suites.push(tokio_rustls::rustls::SupportedCipherSuite::Tls12(
&boring_rustls_provider::tls12::ECDHE_RSA_AES128_GCM_SHA256,
)),
"ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" => prov.cipher_suites.push(tokio_rustls::rustls::SupportedCipherSuite::Tls12(
&boring_rustls_provider::tls12::ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
)),
other => {
log::error!("Unknown cipher `{other}`")
}
}
}
}
if let Some(kexes) = kexes {
prov.kx_groups.clear();
for kex in kexes {
match kex.as_str() {
"X25519" => prov
.kx_groups
.push(boring_rustls_provider::ALL_KX_GROUPS[0]),
"SECP256R1" => prov
.kx_groups
.push(boring_rustls_provider::ALL_KX_GROUPS[2]),
"SECP384R1" => prov
.kx_groups
.push(boring_rustls_provider::ALL_KX_GROUPS[3]),
other => {
log::error!("Unknown kex `{other}`")
}
}
}
}
_provider = CryptoProvider::install_default(prov);
}
#[test]
fn test_parse_hex() {
assert_eq!(parse_hex(b"abc123"), 0xabc123);
assert_eq!(parse_hex(b"1"), 1);
#[cfg(feature = "graviola")]
{
info!("Using RusTLS provider graviola");
let mut prov = rustls_graviola::default_provider();
if let Some(ciphers) = ciphers {
prov.cipher_suites.clear();
for cipher in ciphers {
match cipher.as_str() {
"AES_256_GCM_SHA384" => prov
.cipher_suites
.push(rustls_graviola::suites::TLS13_AES_256_GCM_SHA384),
"AES_128_GCM_SHA256" => prov
.cipher_suites
.push(rustls_graviola::suites::TLS13_AES_128_GCM_SHA256),
"CHACHA20_POLY1305_SHA256" => prov
.cipher_suites
.push(rustls_graviola::suites::TLS13_CHACHA20_POLY1305_SHA256),
"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" => prov
.cipher_suites
.push(rustls_graviola::suites::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384),
"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" => prov
.cipher_suites
.push(rustls_graviola::suites::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256),
"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" => prov.cipher_suites.push(
rustls_graviola::suites::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
),
"ECDHE_RSA_WITH_AES_256_GCM_SHA384" => prov
.cipher_suites
.push(rustls_graviola::suites::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384),
"ECDHE_RSA_WITH_AES_128_GCM_SHA256" => prov
.cipher_suites
.push(rustls_graviola::suites::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256),
"ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" => prov
.cipher_suites
.push(rustls_graviola::suites::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256),
other => {
log::error!("Unknown cipher `{other}`")
}
}
}
}
if let Some(kexes) = kexes {
prov.kx_groups.clear();
for kex in kexes {
match kex.as_str() {
"X25519" => prov.kx_groups.push(&rustls_graviola::kx::X25519),
"SECP256R1" => prov.kx_groups.push(&rustls_graviola::kx::P256),
"SECP384R1" => prov.kx_groups.push(&rustls_graviola::kx::P384),
"X25519MLKEM768" => prov.kx_groups.push(rustls_graviola::kx::X25519MLKEM768),
other => {
log::error!("Unknown kex `{other}`")
}
}
}
}
_provider = CryptoProvider::install_default(prov);
}
#[test]
fn test_is_hex() {
assert!(is_hex(b"0"));
assert!(is_hex(b"1"));
assert!(is_hex(b"2"));
assert!(is_hex(b"3"));
assert!(is_hex(b"4"));
assert!(is_hex(b"5"));
assert!(is_hex(b"6"));
assert!(is_hex(b"7"));
assert!(is_hex(b"8"));
assert!(is_hex(b"9"));
assert!(is_hex(b"a"));
assert!(is_hex(b"b"));
assert!(is_hex(b"c"));
assert!(is_hex(b"d"));
assert!(is_hex(b"e"));
assert!(is_hex(b"f"));
assert!(is_hex(b"A"));
assert!(is_hex(b"B"));
assert!(is_hex(b"C"));
assert!(is_hex(b"D"));
assert!(is_hex(b"E"));
assert!(is_hex(b"F"));
#[cfg(feature = "openssl")]
{
info!("Using RusTLS provider openssl");
let mut prov = rustls_openssl::default_provider();
if let Some(ciphers) = ciphers {
prov.cipher_suites.clear();
for cipher in ciphers {
match cipher.as_str() {
"AES_256_GCM_SHA384" => prov
.cipher_suites
.push(rustls_openssl::cipher_suite::TLS13_AES_256_GCM_SHA384),
"AES_128_GCM_SHA256" => prov
.cipher_suites
.push(rustls_openssl::cipher_suite::TLS13_AES_128_GCM_SHA256),
"CHACHA20_POLY1305_SHA256" => prov
.cipher_suites
.push(rustls_openssl::cipher_suite::TLS13_CHACHA20_POLY1305_SHA256),
"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" => prov.cipher_suites.push(
rustls_openssl::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
),
"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" => prov.cipher_suites.push(
rustls_openssl::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
),
"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" => prov.cipher_suites.push(
rustls_openssl::cipher_suite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
),
"ECDHE_RSA_WITH_AES_256_GCM_SHA384" => prov
.cipher_suites
.push(rustls_openssl::cipher_suite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384),
"ECDHE_RSA_WITH_AES_128_GCM_SHA256" => prov
.cipher_suites
.push(rustls_openssl::cipher_suite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256),
"ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" => prov.cipher_suites.push(
rustls_openssl::cipher_suite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
),
other => {
log::error!("Unknown cipher `{other}`")
}
}
}
}
if let Some(kexes) = kexes {
prov.kx_groups.clear();
for kex in kexes {
match kex.as_str() {
"X25519" => prov.kx_groups.push(rustls_openssl::kx_group::X25519),
"SECP256R1" => prov.kx_groups.push(rustls_openssl::kx_group::SECP256R1),
"SECP384R1" => prov.kx_groups.push(rustls_openssl::kx_group::SECP384R1),
"X25519MLKEM768" => prov
.kx_groups
.push(rustls_openssl::kx_group::X25519MLKEM768),
"MLKEM768" => prov.kx_groups.push(rustls_openssl::kx_group::MLKEM768),
other => {
log::error!("Unknown kex `{other}`")
}
}
}
}
_provider = CryptoProvider::install_default(prov);
}
#[cfg(feature = "ring")]
{
info!("Using RusTLS provider ring");
let mut prov = tokio_rustls::rustls::crypto::ring::default_provider();
if let Some(ciphers) = ciphers {
prov.cipher_suites.clear();
for cipher in ciphers {
match cipher.as_str() {
"AES_256_GCM_SHA384" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::ring::cipher_suite::TLS13_AES_256_GCM_SHA384),
"AES_128_GCM_SHA256" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::ring::cipher_suite::TLS13_AES_128_GCM_SHA256),
"CHACHA20_POLY1305_SHA256" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::ring::cipher_suite::TLS13_CHACHA20_POLY1305_SHA256),
"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::ring::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384),
"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::ring::cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256),
"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::ring::cipher_suite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256),
"ECDHE_RSA_WITH_AES_256_GCM_SHA384" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::ring::cipher_suite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384),
"ECDHE_RSA_WITH_AES_128_GCM_SHA256" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::ring::cipher_suite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256),
"ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" => prov
.cipher_suites
.push(tokio_rustls::rustls::crypto::ring::cipher_suite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256),
other => {
log::error!("Unknown cipher `{other}`")
}
}
}
}
if let Some(kexes) = kexes {
prov.kx_groups.clear();
for kex in kexes {
match kex.as_str() {
"X25519" => prov
.kx_groups
.push(tokio_rustls::rustls::crypto::ring::kx_group::X25519),
"SECP256R1" => prov
.kx_groups
.push(tokio_rustls::rustls::crypto::ring::kx_group::SECP256R1),
"SECP384R1" => prov
.kx_groups
.push(tokio_rustls::rustls::crypto::ring::kx_group::SECP384R1),
other => {
log::error!("Unknown kex `{other}`")
}
}
}
}
_provider = CryptoProvider::install_default(prov);
}
#[cfg(feature = "symcrypt")]
{
info!("Using RusTLS provider symcrypt");
let mut prov = rustls_symcrypt::default_symcrypt_provider();
if let Some(ciphers) = ciphers {
prov.cipher_suites.clear();
for cipher in ciphers {
match cipher.as_str() {
"AES_256_GCM_SHA384" => prov
.cipher_suites
.push(rustls_symcrypt::TLS13_AES_256_GCM_SHA384),
"AES_128_GCM_SHA256" => prov
.cipher_suites
.push(rustls_symcrypt::TLS13_AES_128_GCM_SHA256),
"CHACHA20_POLY1305_SHA256" => prov
.cipher_suites
.push(rustls_symcrypt::TLS13_CHACHA20_POLY1305_SHA256),
"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" => prov
.cipher_suites
.push(rustls_symcrypt::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384),
"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" => prov
.cipher_suites
.push(rustls_symcrypt::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256),
"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256" => prov
.cipher_suites
.push(rustls_symcrypt::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256),
"ECDHE_RSA_WITH_AES_256_GCM_SHA384" => prov
.cipher_suites
.push(rustls_symcrypt::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384),
"ECDHE_RSA_WITH_AES_128_GCM_SHA256" => prov
.cipher_suites
.push(rustls_symcrypt::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256),
"ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256" => prov
.cipher_suites
.push(rustls_symcrypt::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256),
other => {
log::error!("Unknown cipher `{other}`")
}
}
}
}
if let Some(kexes) = kexes {
prov.kx_groups.clear();
for kex in kexes {
match kex.as_str() {
"X25519" => prov.kx_groups.push(rustls_symcrypt::X25519),
"SECP256R1" => prov.kx_groups.push(rustls_symcrypt::SECP256R1),
"SECP384R1" => prov.kx_groups.push(rustls_symcrypt::SECP384R1),
other => {
log::error!("Unknown kex `{other}`")
}
}
}
}
_provider = CryptoProvider::install_default(prov);
}
}