Skip to main content

iris_core/protocols/stream/tls/
handshake.rs

1//! TLS handshake components.
2//!
3//! See [tls-parser](https://docs.rs/tls-parser/latest/tls_parser/) for dependency type definitions.
4
5use crate::utils::base64;
6
7use serde::Serialize;
8use tls_parser::{
9    NamedGroup, SignatureScheme, TlsCipherSuiteID, TlsCompressionID, TlsExtensionType, TlsVersion,
10};
11
12/// A parsed TLS ClientHello message.
13#[derive(Clone, Debug, Default, Serialize)]
14pub struct ClientHello {
15    pub version: TlsVersion,
16    #[serde(with = "base64")]
17    pub random: Vec<u8>,
18    #[serde(with = "base64")]
19    pub session_id: Vec<u8>,
20    pub cipher_suites: Vec<TlsCipherSuiteID>,
21    pub compression_algs: Vec<TlsCompressionID>,
22    pub extension_list: Vec<TlsExtensionType>,
23    pub server_name: Option<String>,
24    pub supported_groups: Vec<NamedGroup>,
25    pub ec_point_formats: Vec<u8>,
26    pub alpn_protocols: Vec<String>,
27    pub signature_algs: Vec<SignatureScheme>,
28    pub key_shares: Vec<KeyShareEntry>,
29    pub supported_versions: Vec<TlsVersion>,
30}
31
32/// A parsed TLS ServerHello message.
33#[derive(Clone, Debug, Default, Serialize)]
34pub struct ServerHello {
35    pub version: TlsVersion,
36    #[serde(with = "base64")]
37    pub random: Vec<u8>,
38    #[serde(with = "base64")]
39    pub session_id: Vec<u8>,
40    pub cipher_suite: TlsCipherSuiteID,
41    pub compression_alg: TlsCompressionID,
42    pub extension_list: Vec<TlsExtensionType>,
43    pub ec_point_formats: Vec<u8>,
44    pub alpn_protocol: Option<String>,
45    pub key_share: Option<KeyShareEntry>,
46    pub selected_version: Option<TlsVersion>,
47}
48
49/// A raw X509 certificate.
50#[derive(Clone, Debug, Default, Serialize)]
51pub struct Certificate {
52    #[serde(with = "base64")]
53    pub raw: Vec<u8>,
54    // NICE-TO-HAVE: parsed certificate
55}
56
57/// Key data sent by the server in a ServerKeyExchange message.
58#[derive(Clone, Debug, Serialize)]
59#[serde(rename_all = "snake_case")]
60pub enum ServerKeyExchange {
61    Ecdh(ServerECDHParams),
62    Dh(ServerDHParams),
63    Rsa(ServerRSAParams),
64    #[serde(with = "base64")]
65    Unknown(Vec<u8>),
66    // NICE-TO-HAVE: parse signature
67}
68
69impl Default for ServerKeyExchange {
70    fn default() -> Self {
71        ServerKeyExchange::Unknown(vec![])
72    }
73}
74
75/// Key data sent by the client in a ClientKeyExchange message.
76#[derive(Clone, Debug, Serialize)]
77#[serde(rename_all = "snake_case")]
78pub enum ClientKeyExchange {
79    Ecdh(ClientECDHParams),
80    Dh(ClientDHParams),
81    Rsa(ClientRSAParams),
82    #[serde(with = "base64")]
83    Unknown(Vec<u8>),
84}
85
86impl Default for ClientKeyExchange {
87    fn default() -> Self {
88        ClientKeyExchange::Unknown(vec![])
89    }
90}
91
92/// RSA parameters sent by the server in a ServerKeyExchange message. (RSA_EXPORT cipher suites).
93#[derive(Clone, Debug, Default, Serialize)]
94pub struct ServerRSAParams {
95    #[serde(with = "base64")]
96    pub modulus: Vec<u8>,
97    #[serde(with = "base64")]
98    pub exponent: Vec<u8>,
99}
100
101/// Stores the encrypted premaster secret sent by the client in a ClientKeyExchange message in an
102/// RSA handshake.
103#[derive(Clone, Debug, Default, Serialize)]
104pub struct ClientRSAParams {
105    #[serde(with = "base64")]
106    pub encrypted_pms: Vec<u8>,
107}
108
109/// Finite-field Diffie-Hellman parameters sent by the server in a ServerKeyExchange message.
110#[derive(Clone, Debug, Default, Serialize)]
111pub struct ServerDHParams {
112    #[serde(with = "base64")]
113    pub prime: Vec<u8>,
114    #[serde(with = "base64")]
115    pub generator: Vec<u8>,
116    #[serde(with = "base64")]
117    pub kx_data: Vec<u8>,
118}
119
120/// Finite-field Diffie-Hellman parameters sent by the client in a ClientKeyExchange message.
121#[derive(Clone, Debug, Default, Serialize)]
122pub struct ClientDHParams {
123    #[serde(with = "base64")]
124    pub kx_data: Vec<u8>,
125}
126
127/// Elliptic-curve Diffie-Hellman parameters sent by the server in a ServerKeyExchange message.
128#[derive(Clone, Debug, Default, Serialize)]
129pub struct ServerECDHParams {
130    pub curve: NamedGroup,
131    #[serde(with = "base64")]
132    pub kx_data: Vec<u8>,
133}
134
135/// Elliptic-curve Diffie-Hellman parameters sent by the client in a ClientKeyExchange message.
136#[derive(Clone, Debug, Default, Serialize)]
137pub struct ClientECDHParams {
138    #[serde(with = "base64")]
139    pub kx_data: Vec<u8>,
140}
141
142/// A TLS 1.3 key share entry.
143///
144/// ## Remarks.
145/// TLS 1.3 only. `kx_data` contents are determined by the specified group. For Finite Field DH,
146/// `kx_data` contains the DH public value. For ECDH, `kx_data` contains the uncompressed x,y EC
147/// point prepended with the value 0x4. See [Key
148/// Share](https://datatracker.ietf.org/doc/html/rfc8446#section-4.2.8) for details.
149#[derive(Clone, Debug, Default, Serialize)]
150pub struct KeyShareEntry {
151    pub group: NamedGroup,
152    #[serde(with = "base64")]
153    pub kx_data: Vec<u8>,
154}