#![allow(rustdoc::bare_urls)]
use std::{any::Any, str, sync::Arc};
use bytes::BytesMut;
use thiserror::Error;
use crate::{
ConnectError, Side, TransportError, shared::ConnectionId,
transport_parameters::TransportParameters,
};
pub(crate) mod ring_like;
pub mod rustls;
pub mod certificate_manager;
pub mod raw_public_keys;
pub mod pqc;
pub mod tls_extensions;
pub mod tls_extension_simulation;
pub mod extension_handlers;
pub mod certificate_negotiation;
#[cfg(test)]
mod test_tls_simulation;
pub trait Session: Send + Sync + 'static {
fn initial_keys(&self, dst_cid: &ConnectionId, side: Side) -> Keys;
fn handshake_data(&self) -> Option<Box<dyn Any>>;
fn peer_identity(&self) -> Option<Box<dyn Any>>;
fn early_crypto(&self) -> Option<(Box<dyn HeaderKey>, Box<dyn PacketKey>)>;
fn early_data_accepted(&self) -> Option<bool>;
fn is_handshaking(&self) -> bool;
fn read_handshake(&mut self, buf: &[u8]) -> Result<bool, TransportError>;
fn transport_parameters(&self) -> Result<Option<TransportParameters>, TransportError>;
fn write_handshake(&mut self, buf: &mut Vec<u8>) -> Option<Keys>;
fn next_1rtt_keys(&mut self) -> Option<KeyPair<Box<dyn PacketKey>>>;
fn is_valid_retry(&self, orig_dst_cid: &ConnectionId, header: &[u8], payload: &[u8]) -> bool;
fn export_keying_material(
&self,
output: &mut [u8],
label: &[u8],
context: &[u8],
) -> Result<(), ExportKeyingMaterialError>;
}
pub struct KeyPair<T> {
pub local: T,
pub remote: T,
}
pub struct Keys {
pub header: KeyPair<Box<dyn HeaderKey>>,
pub packet: KeyPair<Box<dyn PacketKey>>,
}
pub trait ClientConfig: Send + Sync {
fn start_session(
self: Arc<Self>,
version: u32,
server_name: &str,
params: &TransportParameters,
) -> Result<Box<dyn Session>, ConnectError>;
}
#[derive(Debug, Error, Clone, PartialEq, Eq)]
pub enum ServerStartError {
#[error("transport parameter encoding failed: {0}")]
TransportParameters(#[from] crate::transport_parameters::Error),
#[error("TLS error: {0}")]
TlsError(String),
}
pub trait ServerConfig: Send + Sync {
fn initial_keys(
&self,
version: u32,
dst_cid: &ConnectionId,
) -> Result<Keys, UnsupportedVersion>;
fn retry_tag(&self, version: u32, orig_dst_cid: &ConnectionId, packet: &[u8]) -> [u8; 16];
fn start_session(
self: Arc<Self>,
version: u32,
params: &TransportParameters,
) -> Result<Box<dyn Session>, ServerStartError>;
}
pub trait PacketKey: Send + Sync {
fn encrypt(&self, packet: u64, buf: &mut [u8], header_len: usize);
fn decrypt(
&self,
packet: u64,
header: &[u8],
payload: &mut BytesMut,
) -> Result<(), CryptoError>;
fn tag_len(&self) -> usize;
fn confidentiality_limit(&self) -> u64;
fn integrity_limit(&self) -> u64;
}
pub trait HeaderKey: Send + Sync {
fn decrypt(&self, pn_offset: usize, packet: &mut [u8]);
fn encrypt(&self, pn_offset: usize, packet: &mut [u8]);
fn sample_size(&self) -> usize;
}
pub trait HmacKey: Send + Sync {
fn sign(&self, data: &[u8], signature_out: &mut [u8]);
fn signature_len(&self) -> usize;
fn verify(&self, data: &[u8], signature: &[u8]) -> Result<(), CryptoError>;
}
#[derive(Debug, PartialEq, Eq)]
pub struct ExportKeyingMaterialError;
#[derive(Debug)]
pub struct CryptoError;
#[derive(Debug)]
pub struct UnsupportedVersion;
impl From<UnsupportedVersion> for ConnectError {
fn from(_: UnsupportedVersion) -> Self {
Self::UnsupportedVersion
}
}
impl From<crate::TransportError> for ConnectError {
fn from(_err: crate::TransportError) -> Self {
Self::EndpointStopping
}
}