Skip to main content

powhttp_sdk/
tls.rs

1use serde::{Deserialize, Serialize};
2use super::shared::{NamedU8, NamedU16, Side};
3use crate::serde_helpers::hex_2d;
4
5/// A TLS record-layer event observed on one side of the connection.
6#[derive(Debug, Clone, Serialize, Deserialize)]
7#[serde(rename_all = "camelCase")]
8pub struct TlsEvent {
9    pub side: Side,
10    pub message: TlsMessage,
11}
12
13/// Top-level TLS message type.
14#[derive(Debug, Clone, Serialize, Deserialize)]
15#[serde(rename_all = "snake_case", tag = "type", content = "content")]
16pub enum TlsMessage {
17    Alert(Alert),
18    ChangeCipherSpec(ChangeCipherSpec),
19    Handshake(HandshakeMessage),
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
23#[serde(rename_all = "camelCase")]
24pub struct Alert {
25    pub level: NamedU8,
26    pub description: NamedU8,
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
30#[serde(rename_all = "camelCase")]
31pub struct ChangeCipherSpec {
32    #[serde(with = "hex")]
33    pub data: Vec<u8>,
34}
35
36/// A parsed TLS handshake message.
37#[derive(Debug, Clone, Serialize, Deserialize)]
38#[serde(rename_all = "snake_case", tag = "type", content = "content")]
39pub enum HandshakeMessage {
40    ClientHello(ClientHello),
41    ServerHello(ServerHello),
42    NewSessionTicket(NewSessionTicket),
43    EncryptedExtensions(EncryptedExtensions),
44    Certificate(Certificate),
45    ServerKeyExchange(ServerKeyExchange),
46    CertificateRequest(CertificateRequest),
47    ServerHelloDone,
48    CertificateVerify(CertificateVerify),
49    ClientKeyExchange(ClientKeyExchange),
50    Finished(Finished),
51    CompressedCertificate(CompressedCertificate),
52}
53
54/// TLS ClientHello message fields.
55#[derive(Debug, Clone, Serialize, Deserialize)]
56#[serde(rename_all = "camelCase")]
57pub struct ClientHello {
58    pub version: NamedU16,
59    #[serde(with = "hex")]
60    pub random: [u8; 32],
61    #[serde(with = "hex")]
62    pub session_id: Vec<u8>,
63    pub cipher_suites: Vec<NamedU16>,
64    pub compression_methods: Vec<NamedU8>,
65    pub extensions: Vec<ClientExtension>,
66}
67
68/// TLS ServerHello message fields.
69#[derive(Debug, Clone, Serialize, Deserialize)]
70#[serde(rename_all = "camelCase")]
71pub struct ServerHello {
72    pub version: NamedU16,
73    #[serde(with = "hex")]
74    pub random: [u8; 32],
75    #[serde(with = "hex")]
76    pub session_id: Vec<u8>,
77    pub cipher_suite: NamedU16,
78    pub compression_method: NamedU8,
79    pub extensions: Vec<ServerExtension>,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize)]
83#[serde(rename_all = "camelCase")]
84pub struct NewSessionTicket {
85    #[serde(with = "hex")]
86    pub ticket: Vec<u8>,
87}
88
89/// A TLS extension from a ClientHello message.
90#[derive(Debug, Clone, Serialize, Deserialize)]
91#[serde(rename_all = "camelCase")]
92pub struct ClientExtension {
93    pub extension_type: NamedU16,
94    pub extension_data: ClientExtensionData,
95}
96
97/// Parsed data for a client TLS extension.
98#[derive(Debug, Clone, Serialize, Deserialize)]
99#[serde(rename_all = "snake_case", tag = "type", content = "content")]
100pub enum ClientExtensionData {
101    Grease(Grease),
102    SignedCertificateTimestamp,
103    StatusRequest(CertificateStatusRequest),
104    Alpn(Alpn),
105    Ech(Ech),
106    CompressCertificate(CompressCertificateExt),
107    SessionTicket(SessionTicket),
108    SupportedGroups(SupportedGroups),
109    RenegotiationInfo(RenegotiationInfo),
110    ExtendedMasterSecret,
111    KeyShare(KeyShareClientHello),
112    SignatureAlgorithms(SignatureAlgorithms),
113    ServerName(ServerNameList),
114    EcPointFormats(EcPointFormats),
115    SupportedVersions(ClientSupportedVersions),
116    PskKeyExchangeModes(PskKeyExchangeModes),
117    ApplicationSettingsSupport(ApplicationSettingsSupport),
118    ApplicationSettings(ApplicationSettings),
119    EncryptThenMac,
120    CertificateAuthorities(CertificateAuthorities),
121    Padding(Padding),
122    Unknown(UnknownExtension),
123}
124
125/// A TLS extension from a ServerHello message.
126#[derive(Debug, Clone, Serialize, Deserialize)]
127#[serde(rename_all = "camelCase")]
128pub struct ServerExtension {
129    pub extension_type: NamedU16,
130    pub extension_data: ServerExtensionData,
131}
132
133/// Parsed data for a server TLS extension.
134#[derive(Debug, Clone, Serialize, Deserialize)]
135#[serde(rename_all = "snake_case", tag = "type", content = "content")]
136pub enum ServerExtensionData {
137    ServerName,
138    SignatureAlgorithms(SignatureAlgorithms),
139    KeyShareServerHello(KeyShareServerHello),
140    KeyShareHelloRetryRequest(KeyShareHelloRetryRequest),
141    SupportedVersions(ServerSupportedVersions),
142    ExtendedMasterSecret,
143    Alpn(Alpn),
144    Ech(Ech),
145    ApplicationSettings(ApplicationSettings),
146    SessionTicket(SessionTicket),
147    CertificateAuthorities(CertificateAuthorities),
148    Unknown(UnknownExtension),
149}
150
151#[derive(Debug, Clone, Serialize, Deserialize)]
152#[serde(rename_all = "camelCase")]
153pub struct Grease {
154    #[serde(with = "hex")]
155    pub data: Vec<u8>,
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize)]
159#[serde(rename_all = "camelCase")]
160pub struct CertificateStatusRequest {
161    pub status_type: NamedU8,
162    pub request: StatusRequest,
163}
164
165#[derive(Debug, Clone, Serialize, Deserialize)]
166#[serde(rename_all = "snake_case", tag = "type", content = "content")]
167pub enum StatusRequest {
168    Ocsp(OcspStatusRequest),
169}
170
171#[derive(Debug, Clone, Serialize, Deserialize)]
172#[serde(rename_all = "camelCase")]
173pub struct OcspStatusRequest {
174    #[serde(with = "hex_2d")]
175    pub responder_id_list: Vec<Vec<u8>>,
176    #[serde(with = "hex")]
177    pub extensions: Vec<u8>,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
181#[serde(rename_all = "camelCase")]
182pub struct Alpn {
183    pub protocols: Vec<String>,
184}
185
186#[derive(Debug, Clone, Serialize, Deserialize)]
187#[serde(rename_all = "camelCase")]
188pub struct Ech {
189    #[serde(with = "hex")]
190    pub ech: Vec<u8>,
191}
192
193#[derive(Debug, Clone, Serialize, Deserialize)]
194#[serde(rename_all = "camelCase")]
195pub struct CompressCertificateExt {
196    pub algorithms: Vec<NamedU16>,
197}
198
199#[derive(Debug, Clone, Serialize, Deserialize)]
200#[serde(rename_all = "camelCase")]
201pub struct SessionTicket {
202    #[serde(with = "hex")]
203    pub ticket: Vec<u8>,
204}
205
206#[derive(Debug, Clone, Serialize, Deserialize)]
207#[serde(rename_all = "camelCase")]
208pub struct SupportedGroups {
209    pub named_group_list: Vec<NamedU16>,
210}
211
212#[derive(Debug, Clone, Serialize, Deserialize)]
213#[serde(rename_all = "camelCase")]
214pub struct RenegotiationInfo {
215    #[serde(with = "hex")]
216    pub renegotiated_connection: Vec<u8>,
217}
218
219#[derive(Debug, Clone, Serialize, Deserialize)]
220#[serde(rename_all = "camelCase")]
221pub struct KeyShareClientHello {
222    pub client_shares: Vec<KeyShareEntry>,
223}
224
225#[derive(Debug, Clone, Serialize, Deserialize)]
226#[serde(rename_all = "camelCase")]
227pub struct KeyShareEntry {
228    pub group: NamedU16,
229    #[serde(with = "hex")]
230    pub key_exchange: Vec<u8>,
231}
232
233#[derive(Debug, Clone, Serialize, Deserialize)]
234#[serde(rename_all = "camelCase")]
235pub struct SignatureAlgorithms {
236    pub supported_signature_algorithms: Vec<NamedU16>,
237}
238
239#[derive(Debug, Clone, Serialize, Deserialize)]
240#[serde(rename_all = "camelCase")]
241pub struct ServerNameList {
242    pub server_name_list: Vec<ServerName>,
243}
244
245#[derive(Debug, Clone, Serialize, Deserialize)]
246#[serde(rename_all = "camelCase")]
247pub struct ServerName {
248    pub name_type: NamedU8,
249    pub name: String,
250}
251
252#[derive(Debug, Clone, Serialize, Deserialize)]
253#[serde(rename_all = "camelCase")]
254pub struct EcPointFormats {
255    pub ec_point_format_list: Vec<NamedU8>,
256}
257
258#[derive(Debug, Clone, Serialize, Deserialize)]
259#[serde(rename_all = "camelCase")]
260pub struct ClientSupportedVersions {
261    pub versions: Vec<NamedU16>,
262}
263
264#[derive(Debug, Clone, Serialize, Deserialize)]
265#[serde(rename_all = "camelCase")]
266pub struct ServerSupportedVersions {
267    pub selected_version: NamedU16,
268}
269
270#[derive(Debug, Clone, Serialize, Deserialize)]
271#[serde(rename_all = "camelCase")]
272pub struct PskKeyExchangeModes {
273    pub ke_modes: Vec<NamedU8>,
274}
275
276#[derive(Debug, Clone, Serialize, Deserialize)]
277#[serde(rename_all = "camelCase")]
278pub struct ApplicationSettingsSupport {
279    pub supported_protocols: Vec<String>,
280}
281
282#[derive(Debug, Clone, Serialize, Deserialize)]
283#[serde(rename_all = "camelCase")]
284pub struct ApplicationSettings {
285    #[serde(with = "hex")]
286    pub settings: Vec<u8>,
287}
288
289#[derive(Debug, Clone, Serialize, Deserialize)]
290#[serde(rename_all = "camelCase")]
291pub struct CertificateAuthorities {
292    #[serde(with = "hex_2d")]
293    pub authorities: Vec<Vec<u8>>,
294}
295
296#[derive(Debug, Clone, Serialize, Deserialize)]
297#[serde(rename_all = "camelCase")]
298pub struct Padding {
299    #[serde(with = "hex")]
300    pub data: Vec<u8>,
301}
302
303#[derive(Debug, Clone, Serialize, Deserialize)]
304#[serde(rename_all = "camelCase")]
305pub struct UnknownExtension {
306    #[serde(with = "hex")]
307    pub data: Vec<u8>,
308}
309
310#[derive(Debug, Clone, Serialize, Deserialize)]
311#[serde(rename_all = "camelCase")]
312pub struct KeyShareServerHello {
313    pub server_share: KeyShareEntry,
314}
315
316#[derive(Debug, Clone, Serialize, Deserialize)]
317#[serde(rename_all = "camelCase")]
318pub struct KeyShareHelloRetryRequest {
319    pub selected_group: NamedU16,
320}
321
322#[derive(Debug, Clone, Serialize, Deserialize)]
323#[serde(rename_all = "snake_case", tag = "type", content = "content")]
324pub enum EncryptedExtensions {
325    Client(Vec<ClientExtension>),
326    Server(Vec<ServerExtension>),
327}
328
329/// TLS Certificate message in either TLS 1.2 or TLS 1.3 format.
330#[derive(Debug, Clone, Serialize, Deserialize)]
331#[serde(rename_all = "snake_case", tag = "type", content = "content")]
332pub enum Certificate {
333    Tls13(Tls13Certificate),
334    Tls12(Tls12Certificate),
335}
336
337#[derive(Debug, Clone, Serialize, Deserialize)]
338#[serde(rename_all = "camelCase")]
339pub struct Tls13Certificate {
340    #[serde(with = "hex")]
341    pub certificate_request_context: Vec<u8>,
342    pub certificate_list: Vec<CertificateEntry>,
343}
344
345#[derive(Debug, Clone, Serialize, Deserialize)]
346#[serde(rename_all = "camelCase")]
347pub struct CertificateEntry {
348    #[serde(with = "hex")]
349    pub cert_data: Vec<u8>,
350    #[serde(with = "hex")]
351    pub extensions: Vec<u8>,
352}
353
354#[derive(Debug, Clone, Serialize, Deserialize)]
355#[serde(rename_all = "camelCase")]
356pub struct Tls12Certificate {
357    #[serde(with = "hex_2d")]
358    pub certificates: Vec<Vec<u8>>,
359}
360
361/// TLS ServerKeyExchange for either DH or ECDH key exchange.
362#[derive(Debug, Clone, Serialize, Deserialize)]
363#[serde(tag = "type", rename_all = "snake_case", content = "content")]
364pub enum ServerKeyExchange {
365    Dh(DhServerKeyExchange),
366    Ecdh(EcdhServerKeyExchange),
367}
368
369#[derive(Debug, Clone, Serialize, Deserialize)]
370#[serde(rename_all = "camelCase")]
371pub struct DhServerKeyExchange {
372    pub params: ServerDhParams,
373    pub signed_params: Option<DigitallySigned>,
374}
375
376#[derive(Debug, Clone, Serialize, Deserialize)]
377#[serde(rename_all = "camelCase")]
378pub struct ServerDhParams {
379    #[serde(with = "hex")]
380    pub p: Vec<u8>,
381    #[serde(with = "hex")]
382    pub g: Vec<u8>,
383    #[serde(with = "hex")]
384    pub ys: Vec<u8>,
385}
386
387#[derive(Debug, Clone, Serialize, Deserialize)]
388#[serde(rename_all = "camelCase")]
389pub struct DigitallySigned {
390    pub algorithm: NamedU16,
391    #[serde(with = "hex")]
392    pub signature: Vec<u8>,
393}
394
395#[derive(Debug, Clone, Serialize, Deserialize)]
396#[serde(rename_all = "camelCase")]
397pub struct EcdhServerKeyExchange {
398    pub params: ServerEcdhParams,
399    pub signed_params: Option<DigitallySigned>,
400}
401
402#[derive(Debug, Clone, Serialize, Deserialize)]
403#[serde(rename_all = "camelCase")]
404pub struct ServerEcdhParams {
405    pub curve_params: EcParams,
406    #[serde(with = "hex")]
407    pub public: Vec<u8>,
408}
409
410#[derive(Debug, Clone, Serialize, Deserialize)]
411#[serde(tag = "type", rename_all = "snake_case", content = "content")]
412pub enum EcParams {
413    ExplicitPrime(ExplicitPrimeParams),
414    #[serde(rename = "explicit_char2")]
415    ExplicitChar2(ExplicitChar2Params),
416    NamedCurve(NamedCurveParams),
417}
418
419#[derive(Debug, Clone, Serialize, Deserialize)]
420#[serde(rename_all = "camelCase")]
421pub struct ExplicitPrimeParams {
422    #[serde(with = "hex")]
423    pub p: Vec<u8>,
424    pub curve: EcCurve,
425    #[serde(with = "hex")]
426    pub base: Vec<u8>,
427    #[serde(with = "hex")]
428    pub order: Vec<u8>,
429    #[serde(with = "hex")]
430    pub cofactor: Vec<u8>,
431}
432
433#[derive(Debug, Clone, Serialize, Deserialize)]
434#[serde(rename_all = "camelCase")]
435pub struct ExplicitChar2Params {
436    pub m: u16,
437    pub basis: Char2Basis,
438    pub curve: EcCurve,
439    #[serde(with = "hex")]
440    pub base: Vec<u8>,
441    #[serde(with = "hex")]
442    pub order: Vec<u8>,
443    #[serde(with = "hex")]
444    pub cofactor: Vec<u8>,
445}
446
447#[derive(Debug, Clone, Serialize, Deserialize)]
448#[serde(rename_all = "camelCase")]
449pub struct NamedCurveParams {
450    pub named_curve: NamedU16,
451}
452
453#[derive(Debug, Clone, Serialize, Deserialize)]
454#[serde(rename_all = "camelCase")]
455pub struct EcCurve {
456    #[serde(with = "hex")]
457    pub a: Vec<u8>,
458    #[serde(with = "hex")]
459    pub b: Vec<u8>,
460}
461
462#[derive(Debug, Clone, Serialize, Deserialize)]
463#[serde(tag = "type", rename_all = "snake_case", content = "content")]
464pub enum Char2Basis {
465    Trinomial(TrinomialBasis),
466    Pentanomial(PentanomialBasis),
467}
468
469#[derive(Debug, Clone, Serialize, Deserialize)]
470#[serde(rename_all = "camelCase")]
471pub struct TrinomialBasis {
472    #[serde(with = "hex")]
473    pub k: Vec<u8>,
474}
475
476#[derive(Debug, Clone, Serialize, Deserialize)]
477#[serde(rename_all = "camelCase")]
478pub struct PentanomialBasis {
479    #[serde(with = "hex")]
480    pub k1: Vec<u8>,
481    #[serde(with = "hex")]
482    pub k2: Vec<u8>,
483    #[serde(with = "hex")]
484    pub k3: Vec<u8>,
485}
486
487/// TLS ClientKeyExchange for DH, ECDH or RSA key exchange.
488#[derive(Debug, Clone, Serialize, Deserialize)]
489#[serde(tag = "type", rename_all = "snake_case", content = "content")]
490pub enum ClientKeyExchange {
491    Dh(DhClientKeyExchange),
492    Ecdh(EcdhClientKeyExchange),
493    Rsa(RsaClientKeyExchange),
494}
495
496#[derive(Debug, Clone, Serialize, Deserialize)]
497#[serde(rename_all = "camelCase")]
498pub struct DhClientKeyExchange {
499    #[serde(with = "hex")]
500    pub yc: Vec<u8>,
501}
502
503#[derive(Debug, Clone, Serialize, Deserialize)]
504#[serde(rename_all = "camelCase")]
505pub struct EcdhClientKeyExchange {
506    #[serde(with = "hex")]
507    pub yc: Vec<u8>,
508}
509
510#[derive(Debug, Clone, Serialize, Deserialize)]
511#[serde(rename_all = "camelCase")]
512pub struct RsaClientKeyExchange {
513    #[serde(with = "hex")]
514    pub encrypted_pre_master_secret: Vec<u8>,
515}
516
517#[derive(Debug, Clone, Serialize, Deserialize)]
518#[serde(tag = "type", rename_all = "snake_case", content = "content")]
519pub enum CertificateRequest {
520    Tls13(Tls13CertificateRequest),
521}
522
523#[derive(Debug, Clone, Serialize, Deserialize)]
524#[serde(rename_all = "camelCase")]
525pub struct Tls13CertificateRequest {
526    #[serde(with = "hex")]
527    pub certificate_request_context: Vec<u8>,
528    pub extensions: Vec<ServerExtension>,
529}
530
531#[derive(Debug, Clone, Serialize, Deserialize)]
532#[serde(rename_all = "camelCase")]
533pub struct CertificateVerify {
534    pub algorithm: NamedU16,
535    #[serde(with = "hex")]
536    pub signature: Vec<u8>,
537}
538
539#[derive(Debug, Clone, Serialize, Deserialize)]
540#[serde(rename_all = "camelCase")]
541pub struct Finished {
542    #[serde(with = "hex")]
543    pub verify_data: Vec<u8>,
544}
545
546#[derive(Debug, Clone, Serialize, Deserialize)]
547#[serde(rename_all = "camelCase")]
548pub struct CompressedCertificate {
549    pub algorithm: NamedU16,
550    pub uncompressed_len: usize,
551    #[serde(with = "hex")]
552    pub compressed_certificate_message: Vec<u8>,
553}