use serde::{Deserialize, Serialize};
use crate::model::tls::{AlpnProtocol, CipherSuite, NamedGroup, TlsVersion};
use crate::origin::Origin;
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
pub enum HandshakeStage {
#[default]
Idle,
ClientHello,
ServerHello,
Certificate,
ServerCertificate,
ServerKeyExchange,
ServerHelloDone,
ClientKeyExchange,
ClientFinished,
ServerFinished,
ApplicationData,
Errored,
}
impl HandshakeStage {
#[must_use]
pub const fn ordered() -> &'static [HandshakeStage] {
&[
HandshakeStage::ClientHello,
HandshakeStage::ServerHello,
HandshakeStage::Certificate,
HandshakeStage::ClientFinished,
HandshakeStage::ServerFinished,
HandshakeStage::ApplicationData,
]
}
#[must_use]
pub const fn ordered_tls12() -> &'static [HandshakeStage] {
&[
HandshakeStage::ClientHello,
HandshakeStage::ServerHello,
HandshakeStage::ServerCertificate,
HandshakeStage::ServerKeyExchange,
HandshakeStage::ServerHelloDone,
HandshakeStage::ClientKeyExchange,
HandshakeStage::ClientFinished,
HandshakeStage::ServerFinished,
HandshakeStage::ApplicationData,
]
}
#[must_use]
pub const fn label(self) -> &'static str {
match self {
HandshakeStage::Idle => "Idle",
HandshakeStage::ClientHello => "ClientHello",
HandshakeStage::ServerHello => "ServerHello",
HandshakeStage::Certificate => "Certificate",
HandshakeStage::ServerCertificate => "Server Cert",
HandshakeStage::ServerKeyExchange => "Svr Key Exch",
HandshakeStage::ServerHelloDone => "Svr Hello Done",
HandshakeStage::ClientKeyExchange => "Clt Key Exch",
HandshakeStage::ClientFinished => "Clt Finished",
HandshakeStage::ServerFinished => "Svr Finished",
HandshakeStage::ApplicationData => "App Data",
HandshakeStage::Errored => "Errored",
}
}
}
impl std::fmt::Display for HandshakeStage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.label())
}
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct HandshakeInfo {
pub stage: HandshakeStage,
pub sni: Option<String>,
pub alpn_offered: Vec<AlpnProtocol>,
pub alpn_selected: Option<AlpnProtocol>,
pub cipher_suites_offered: Vec<CipherSuite>,
pub cipher_suite_selected: Option<CipherSuite>,
pub groups_offered: Vec<NamedGroup>,
pub key_share_group: Option<NamedGroup>,
pub tls_version: Option<TlsVersion>,
pub certificate_subject: Option<String>,
pub certificate_issuer: Option<String>,
pub error: Option<String>,
pub origin: Option<Origin>,
}
impl HandshakeInfo {
#[must_use]
pub fn new() -> Self {
Self::default()
}
}