tlspuffin/tls/
fn_messages.rs

1#![allow(clippy::ptr_arg)]
2#![allow(dead_code)]
3
4//! Extensions according to IANA:
5//! <https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-7>
6//!
7//! In the source code all IDs are available, but implementations are missing.
8//! Return type is `Message`
9
10use puffin::algebra::error::FnError;
11
12use crate::nyi_fn;
13use crate::tls::rustls::key;
14use crate::tls::rustls::msgs::alert::AlertMessagePayload;
15use crate::tls::rustls::msgs::base::{Payload, PayloadU16, PayloadU24, PayloadU8};
16use crate::tls::rustls::msgs::ccs::ChangeCipherSpecPayload;
17use crate::tls::rustls::msgs::enums::*;
18use crate::tls::rustls::msgs::handshake::{CertificateStatus, *};
19use crate::tls::rustls::msgs::heartbeat::HeartbeatPayload;
20use crate::tls::rustls::msgs::message::{Message, MessagePayload, OpaqueMessage};
21
22pub fn fn_empty_handshake_message() -> Result<OpaqueMessage, FnError> {
23    Ok(OpaqueMessage {
24        typ: ContentType::Handshake,
25        version: ProtocolVersion::TLSv1_2,
26        payload: Payload::empty(),
27    })
28}
29
30// ----
31// Alert Message constructors
32// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-6
33// ----
34
35pub fn fn_alert_close_notify() -> Result<Message, FnError> {
36    Ok(Message {
37        version: ProtocolVersion::TLSv1_2,
38        payload: MessagePayload::Alert(AlertMessagePayload {
39            level: AlertLevel::Warning,
40            description: AlertDescription::CloseNotify,
41        }),
42    })
43}
44
45// ----
46// CCS Message constructors
47// ----
48
49pub fn fn_change_cipher_spec() -> Result<Message, FnError> {
50    Ok(Message {
51        version: ProtocolVersion::TLSv1_2,
52        payload: MessagePayload::ChangeCipherSpec(ChangeCipherSpecPayload {}),
53    })
54}
55// ----
56// ApplicationData Message constructors
57// ----
58
59pub fn fn_application_data(data: &Vec<u8>) -> Result<Message, FnError> {
60    Ok(Message {
61        version: ProtocolVersion::TLSv1_2,
62        payload: MessagePayload::ApplicationData(Payload::new(data.clone())),
63    })
64}
65
66// ----
67// Heartbeats Message constructors
68// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#heartbeat-message-types
69// ----
70
71// Adapted from https://github.com/mpgn/heartbleed-PoC/blob/master/heartbleed-exploit.py
72// unused right now
73/*pub fn fn_heartbeat_ch() -> Result<Message, FnError> {
74    let hello_client_hex = "
75        16 03 03 00  dc 01 00 00 d8 03 03 53
76        43 5b 90 9d 9b 72 0b bc  0c bc 2b 92 a8 48 97 cf
77        bd 39 04 cc 16 0a 85 03  90 9f 77 04 33 d4 de 00
78        00 66 c0 14 c0 0a c0 22  c0 21 00 39 00 38 00 88
79        00 87 c0 0f c0 05 00 35  00 84 c0 12 c0 08 c0 1c
80        c0 1b 00 16 00 13 c0 0d  c0 03 00 0a c0 13 c0 09
81        c0 1f c0 1e 00 33 00 32  00 9a 00 99 00 45 00 44
82        c0 0e c0 04 00 2f 00 96  00 41 c0 11 c0 07 c0 0c
83        c0 02 00 05 00 04 00 15  00 12 00 09 00 14 00 11
84        00 08 00 06 00 03 00 ff  01 00 00 49 00 0b 00 04
85        03 00 01 02 00 0a 00 34  00 32 00 0e 00 0d 00 19
86        00 0b 00 0c 00 18 00 09  00 0a 00 16 00 17 00 08
87        00 06 00 07 00 14 00 15  00 04 00 05 00 12 00 13
88        00 01 00 02 00 03 00 0f  00 10 00 11 00 23 00 00
89        00 0f 00 01 01";
90
91    let hello_client = hex::decode(
92        hello_client_hex
93            .to_string()
94            .replace(" ", "")
95            .replace("\n", ""),
96    ).map_err(|err| err.to_string())?;
97
98    Ok(Message::try_from(OpaqueMessage::read(&mut Reader::init(
99        hello_client.as_slice(),
100    ))?)?)
101}*/
102
103// This is now subsumed by bit-level mutations
104// pub fn fn_heartbeat_fake_length(
105//     payload: &PayloadU16,
106//     fake_length: &u64,
107// ) -> Result<Message, FnError> {
108//     Ok(Message {
109//         version: ProtocolVersion::TLSv1_2,
110//         payload: MessagePayload::Heartbeat(HeartbeatPayload {
111//             typ: HeartbeatMessageType::Request,
112//             payload: payload.clone(),
113//             fake_length: Some(*fake_length as u16),
114//         }),
115//     })
116// }
117
118pub fn fn_heartbeat(payload: &PayloadU16) -> Result<Message, FnError> {
119    Ok(Message {
120        version: ProtocolVersion::TLSv1_2,
121        payload: MessagePayload::Heartbeat(HeartbeatPayload {
122            typ: HeartbeatMessageType::Request,
123            payload: payload.clone(),
124            fake_length: Some(payload.0.len() as u16),
125        }),
126    })
127}
128
129// ----
130// Handshake Message constructors
131// ----
132
133/// HelloRequest/hello_request_RESERVED => 0x00,
134pub fn fn_hello_request() -> Result<Message, FnError> {
135    Ok(Message {
136        version: ProtocolVersion::TLSv1_2,
137        payload: MessagePayload::Handshake(HandshakeMessagePayload {
138            typ: HandshakeType::HelloRequest,
139            payload: HandshakePayload::HelloRequest,
140        }),
141    })
142}
143/// ClientHello => 0x01,
144pub fn fn_client_hello(
145    client_version: &ProtocolVersion,
146    random: &Random,
147    session_id: &SessionID,
148    cipher_suites: &CipherSuites,
149    compression_methods: &Compressions,
150    extensions: &ClientExtensions,
151) -> Result<Message, FnError> {
152    Ok(Message {
153        version: ProtocolVersion::TLSv1_2,
154        payload: MessagePayload::Handshake(HandshakeMessagePayload {
155            typ: HandshakeType::ClientHello,
156            payload: HandshakePayload::ClientHello(ClientHelloPayload {
157                client_version: *client_version,
158                random: *random,
159                session_id: *session_id,
160                cipher_suites: cipher_suites.clone(),
161                compression_methods: compression_methods.clone(),
162                extensions: extensions.clone(),
163            }),
164        }),
165    })
166}
167/// ServerHello => 0x02,
168pub fn fn_server_hello(
169    legacy_version: &ProtocolVersion,
170    random: &Random,
171    session_id: &SessionID,
172    cipher_suite: &CipherSuite,
173    compression_method: &Compression,
174    extensions: &ServerExtensions,
175) -> Result<Message, FnError> {
176    Ok(Message {
177        version: ProtocolVersion::TLSv1_2,
178        payload: MessagePayload::Handshake(HandshakeMessagePayload {
179            typ: HandshakeType::ServerHello,
180            payload: HandshakePayload::ServerHello(ServerHelloPayload {
181                legacy_version: *legacy_version,
182                random: *random,
183                session_id: *session_id,
184                cipher_suite: *cipher_suite,
185                compression_method: *compression_method,
186                extensions: extensions.clone(),
187            }),
188        }),
189    })
190}
191nyi_fn! {
192    /// hello_verify_request_RESERVED => 0x03,
193}
194/// NewSessionTicket => 0x04,
195pub fn fn_new_session_ticket(lifetime_hint: &u32, ticket: &PayloadU16) -> Result<Message, FnError> {
196    // todo unclear where the arguments come from here, needs manual trace implementation
197    //      https://github.com/tlspuffin/tlspuffin/issues/155
198    Ok(Message {
199        version: ProtocolVersion::TLSv1_2,
200        payload: MessagePayload::Handshake(HandshakeMessagePayload {
201            typ: HandshakeType::NewSessionTicket,
202            payload: HandshakePayload::NewSessionTicket(NewSessionTicketPayload {
203                lifetime_hint: *lifetime_hint,
204                ticket: ticket.clone(),
205            }),
206        }),
207    })
208}
209
210pub fn fn_new_session_ticket_extensions(
211    extensions: &Vec<NewSessionTicketExtension>,
212) -> Result<NewSessionTicketExtensions, FnError> {
213    Ok(NewSessionTicketExtensions(extensions.clone()))
214}
215
216pub fn fn_new_session_ticket13(
217    nonce: &PayloadU8,
218    ticket: &PayloadU16,
219    extensions: &NewSessionTicketExtensions,
220) -> Result<Message, FnError> {
221    // todo unclear where the arguments come from here, needs manual trace implementation
222    //      https://github.com/tlspuffin/tlspuffin/issues/155
223    Ok(Message {
224        version: ProtocolVersion::TLSv1_2,
225        payload: MessagePayload::Handshake(HandshakeMessagePayload {
226            typ: HandshakeType::NewSessionTicket,
227            payload: HandshakePayload::NewSessionTicketTLS13(NewSessionTicketPayloadTLS13 {
228                lifetime: 10,
229                age_add: 12,
230                nonce: nonce.clone(),
231                ticket: ticket.clone(),
232                exts: extensions.clone(),
233            }),
234        }),
235    })
236}
237nyi_fn! {
238    /// EndOfEarlyData => 0x05,
239}
240
241/// Specific ClientHello Random recognized by the client as the one previously used for a
242/// HelloRetryRequest
243pub fn fn_hello_retry_request_random() -> Result<Random, FnError> {
244    Ok(Random([
245        0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, 0x02, 0x1e, 0x65, 0xb8,
246        0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, 0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8,
247        0x33, 0x9c,
248    ]))
249}
250
251/// HelloRetryRequest => 0x06,
252pub fn fn_hello_retry_request(
253    legacy_version: &ProtocolVersion,
254    random: &Random,
255    session_id: &SessionID,
256    cipher_suite: &CipherSuite,
257    compression_methods: &Compressions,
258    extensions: &HelloRetryExtensions,
259) -> Result<Message, FnError> {
260    Ok(Message {
261        version: ProtocolVersion::TLSv1_2,
262        payload: MessagePayload::Handshake(HandshakeMessagePayload {
263            typ: HandshakeType::HelloRetryRequest,
264            payload: HandshakePayload::HelloRetryRequest(HelloRetryRequest {
265                legacy_version: *legacy_version,
266                random: *random,
267                session_id: *session_id,
268                cipher_suite: *cipher_suite,
269                compression_methods: compression_methods.clone(),
270                extensions: extensions.clone(),
271            }),
272        }),
273    })
274}
275/// EncryptedExtensions => 0x08,
276pub fn fn_encrypted_extensions(
277    server_extensions: &Vec<ServerExtension>,
278) -> Result<Message, FnError> {
279    Ok(Message {
280        version: ProtocolVersion::TLSv1_2,
281        payload: MessagePayload::Handshake(HandshakeMessagePayload {
282            typ: HandshakeType::EncryptedExtensions,
283            payload: HandshakePayload::EncryptedExtensions(EncryptedExtensions(
284                server_extensions.clone(),
285            )),
286        }),
287    })
288}
289nyi_fn! {
290    /// RequestConnectionId => 0x09,
291}
292nyi_fn! {
293    /// NewConnectionId => 0x0a,
294}
295/// Certificate => 0x0b,
296pub fn fn_certificate(certs: &Vec<key::Certificate>) -> Result<Message, FnError> {
297    Ok(Message {
298        version: ProtocolVersion::TLSv1_2,
299        payload: MessagePayload::Handshake(HandshakeMessagePayload {
300            typ: HandshakeType::Certificate,
301            payload: HandshakePayload::Certificate(CertificatePayload(certs.clone())),
302        }),
303    })
304}
305pub fn fn_certificate13(
306    context: &PayloadU8,
307    entries: &CertificateEntries,
308) -> Result<Message, FnError> {
309    // todo unclear where the arguments come from here, needs manual trace implementation
310    //      Vec<CertificateEntry> is not possible to create
311    //      https://github.com/tlspuffin/tlspuffin/issues/155
312    Ok(Message {
313        version: ProtocolVersion::TLSv1_2,
314        payload: MessagePayload::Handshake(HandshakeMessagePayload {
315            typ: HandshakeType::Certificate,
316            payload: HandshakePayload::CertificateTLS13(CertificatePayloadTLS13 {
317                context: context.clone(),
318                entries: entries.clone(),
319            }),
320        }),
321    })
322}
323/// ServerKeyExchange => 0x0c,
324pub fn fn_server_key_exchange(data: &Vec<u8>) -> Result<Message, FnError> {
325    Ok(Message {
326        version: ProtocolVersion::TLSv1_2,
327        payload: MessagePayload::Handshake(HandshakeMessagePayload {
328            typ: HandshakeType::ServerKeyExchange,
329            payload: HandshakePayload::ServerKeyExchange(ServerKeyExchangePayload::Unknown(
330                Payload::new(data.clone()),
331            )),
332        }),
333    })
334}
335/// CertificateRequest => 0x0d,
336pub fn fn_certificate_request() -> Result<Message, FnError> {
337    // todo unclear where the arguments come from here, needs manual trace implementation
338    //      https://github.com/tlspuffin/tlspuffin/issues/155
339    Ok(Message {
340        version: ProtocolVersion::TLSv1_2,
341        payload: MessagePayload::Handshake(HandshakeMessagePayload {
342            typ: HandshakeType::CertificateRequest,
343            payload: HandshakePayload::CertificateRequest(CertificateRequestPayload {
344                certtypes: ClientCertificateTypes(vec![ClientCertificateType::RSASign]),
345                sigschemes: SupportedSignatureSchemes(vec![SignatureScheme::ED25519]), /* TODO-Mapper: could be extended to change this field */
346                canames: VecU16OfPayloadU16(vec![PayloadU16::new(
347                    "some ca name?".as_bytes().to_vec(),
348                )]),
349            }),
350        }),
351    })
352}
353pub fn fn_certificate_request13(
354    context: &PayloadU8,
355    extensions: &Vec<CertReqExtension>,
356) -> Result<Message, FnError> {
357    // todo unclear where the arguments come from here, needs manual trace implementation
358    //      Vec<CertReqExtension> is not possible to create
359    //      https://github.com/tlspuffin/tlspuffin/issues/155
360    Ok(Message {
361        version: ProtocolVersion::TLSv1_2,
362        payload: MessagePayload::Handshake(HandshakeMessagePayload {
363            typ: HandshakeType::CertificateRequest,
364            payload: HandshakePayload::CertificateRequestTLS13(CertificateRequestPayloadTLS13 {
365                context: context.clone(),
366                extensions: CertReqExtensions(extensions.clone()),
367            }),
368        }),
369    })
370}
371/// ServerHelloDone => 0x0e,
372pub fn fn_server_hello_done() -> Result<Message, FnError> {
373    Ok(Message {
374        version: ProtocolVersion::TLSv1_2,
375        payload: MessagePayload::Handshake(HandshakeMessagePayload {
376            typ: HandshakeType::ServerHelloDone,
377            payload: HandshakePayload::ServerHelloDone,
378        }),
379    })
380}
381
382pub fn fn_payload_u8(vec: &Vec<u8>) -> Result<PayloadU8, FnError> {
383    Ok(PayloadU8::new(vec.clone()))
384}
385
386pub fn fn_payload_u16(vec: &Vec<u8>) -> Result<PayloadU16, FnError> {
387    Ok(PayloadU16::new(vec.clone()))
388}
389
390pub fn fn_payload_u24(vec: &Vec<u8>) -> Result<PayloadU24, FnError> {
391    Ok(PayloadU24::new(vec.clone()))
392}
393
394pub fn fn_empty_payload_u16_vec() -> Result<Vec<PayloadU16>, FnError> {
395    Ok(vec![])
396}
397
398pub fn fn_append_payload_u16_vec(
399    vec: &Vec<PayloadU16>,
400    p: &PayloadU16,
401) -> Result<Vec<PayloadU16>, FnError> {
402    let mut res = vec.clone();
403    res.push(p.clone());
404    Ok(res)
405}
406
407pub fn fn_make_payload_u16_vec_u16(vec: &Vec<PayloadU16>) -> Result<VecU16OfPayloadU16, FnError> {
408    Ok(VecU16OfPayloadU16(vec.clone()))
409}
410
411pub fn fn_empty_payload_u8_vec() -> Result<Vec<PayloadU8>, FnError> {
412    Ok(vec![])
413}
414
415pub fn fn_append_payload_u8_vec(
416    vec: &Vec<PayloadU8>,
417    p: &PayloadU8,
418) -> Result<Vec<PayloadU8>, FnError> {
419    let mut res = vec.clone();
420    res.push(p.clone());
421    Ok(res)
422}
423
424pub fn fn_make_payload_u8_vec_u16(vec: &Vec<PayloadU8>) -> Result<VecU16OfPayloadU8, FnError> {
425    Ok(VecU16OfPayloadU8(vec.clone()))
426}
427
428/// CertificateVerify => 0x0f,
429pub fn fn_certificate_verify(
430    scheme: &SignatureScheme,
431    signature: &PayloadU16,
432) -> Result<Message, FnError> {
433    // todo unclear where the arguments come from here, needs manual trace implementation
434    //      https://github.com/tlspuffin/tlspuffin/issues/155
435    Ok(Message {
436        version: ProtocolVersion::TLSv1_2,
437        payload: MessagePayload::Handshake(HandshakeMessagePayload {
438            typ: HandshakeType::CertificateVerify,
439            payload: HandshakePayload::CertificateVerify(DigitallySignedStruct {
440                scheme: *scheme,
441                sig: signature.clone(),
442            }),
443        }),
444    })
445}
446/// ClientKeyExchange => 0x10,
447pub fn fn_client_key_exchange(encoded_pubkey_data: &Vec<u8>) -> Result<Message, FnError> {
448    Ok(Message {
449        version: ProtocolVersion::TLSv1_2,
450        payload: MessagePayload::Handshake(HandshakeMessagePayload {
451            typ: HandshakeType::ClientKeyExchange,
452            payload: HandshakePayload::ClientKeyExchange(Payload::new(encoded_pubkey_data.clone())),
453        }),
454    })
455}
456/// Finished => 0x14,
457pub fn fn_finished(verify_data: &Vec<u8>) -> Result<Message, FnError> {
458    Ok(Message {
459        version: ProtocolVersion::TLSv1_2,
460        payload: MessagePayload::Handshake(HandshakeMessagePayload {
461            typ: HandshakeType::Finished,
462            payload: HandshakePayload::Finished(Payload::new(verify_data.clone())),
463        }),
464    })
465}
466nyi_fn! {
467    /// CertificateURL => 0x15,
468}
469/// CertificateStatus => 0x16,
470pub fn fn_certificate_status(ocsp_response: &PayloadU24) -> Result<Message, FnError> {
471    Ok(Message {
472        version: ProtocolVersion::TLSv1_2,
473        payload: MessagePayload::Handshake(HandshakeMessagePayload {
474            typ: HandshakeType::CertificateStatus,
475            payload: HandshakePayload::CertificateStatus(CertificateStatus {
476                ocsp_response: ocsp_response.clone(),
477            }),
478        }),
479    })
480}
481/// KeyUpdate => 0x18,
482pub fn fn_key_update() -> Result<Message, FnError> {
483    Ok(Message {
484        version: ProtocolVersion::TLSv1_2,
485        payload: MessagePayload::Handshake(HandshakeMessagePayload {
486            typ: HandshakeType::KeyUpdate,
487            payload: HandshakePayload::KeyUpdate(KeyUpdateRequest::UpdateRequested),
488        }),
489    })
490}
491pub fn fn_key_update_not_requested() -> Result<Message, FnError> {
492    Ok(Message {
493        version: ProtocolVersion::TLSv1_2,
494        payload: MessagePayload::Handshake(HandshakeMessagePayload {
495            typ: HandshakeType::KeyUpdate,
496            payload: HandshakePayload::KeyUpdate(KeyUpdateRequest::UpdateNotRequested),
497        }),
498    })
499}
500nyi_fn! {
501    /// compressed_certificate => 0x019,
502}
503nyi_fn! {
504    /// ekt_key => 0x01A,
505}
506/// MessageHash => 0xfe
507pub fn fn_message_hash(hash: &Vec<u8>) -> Result<Message, FnError> {
508    // todo unclear where the arguments come from here, needs manual trace implementation
509    //      https://github.com/tlspuffin/tlspuffin/issues/155
510    Ok(Message {
511        version: ProtocolVersion::TLSv1_2,
512        payload: MessagePayload::Handshake(HandshakeMessagePayload {
513            typ: HandshakeType::MessageHash,
514            payload: HandshakePayload::MessageHash(Payload::new(hash.clone())),
515        }),
516    })
517}