stackforge_core/layer/tls/
mod.rs1pub mod builder;
20pub mod cert;
21pub mod crypto;
22pub mod extensions;
23pub mod handshake;
24pub mod keyexchange;
25pub mod record;
26pub mod session;
27pub mod sslv2;
28pub mod types;
29
30pub use builder::{TlsAlertBuilder, TlsCcsBuilder, TlsRecordBuilder};
31pub use cert::TlsCertificate;
32pub use extensions::Extension;
33pub use handshake::{Certificate, ClientHello, Finished, Handshake, HandshakeBody, ServerHello};
34pub use record::{TLS_FIELDS, TLS_RECORD_HEADER_LEN, TlsLayer};
35pub use session::TlsSession;
36pub use sslv2::{Sslv2ClientHello, Sslv2ClientMasterKey, Sslv2ServerHello};
37pub use types::{
38 ExtensionType, HandshakeType, NamedGroup, SignatureScheme, TlsAlertDescription, TlsAlertLevel,
39 TlsContentType, TlsVersion,
40};
41
42pub const TLS_PORT: u16 = 443;
44
45pub const TLS_PORTS: &[u16] = &[443, 465, 636, 853, 993, 995, 8443];
47
48#[must_use]
55pub fn is_tls_payload(data: &[u8]) -> bool {
56 if data.len() < TLS_RECORD_HEADER_LEN {
57 return false;
58 }
59
60 let content_type = data[0];
62 if !(20..=24).contains(&content_type) {
63 if data.len() >= 2 && (data[0] & 0x80) != 0 {
65 return true;
67 }
68 return false;
69 }
70
71 let version = u16::from_be_bytes([data[1], data[2]]);
73 let valid_version = matches!(
74 version,
75 0x0300..=0x0304 | 0x7f00..=0x7fff
76 );
77 if !valid_version {
78 return false;
79 }
80
81 let length = u16::from_be_bytes([data[3], data[4]]) as usize;
83 length <= TLS_RECORD_HEADER_LEN + record::TLS_MAX_CIPHERTEXT_LEN
84}
85
86#[cfg(test)]
87mod tests {
88 use super::*;
89
90 #[test]
91 fn test_is_tls_payload_valid() {
92 let data = vec![0x16, 0x03, 0x03, 0x00, 0x05, 0x01, 0x00, 0x00, 0x01, 0x00];
94 assert!(is_tls_payload(&data));
95 }
96
97 #[test]
98 fn test_is_tls_payload_alert() {
99 let data = vec![0x15, 0x03, 0x03, 0x00, 0x02, 0x02, 0x28];
100 assert!(is_tls_payload(&data));
101 }
102
103 #[test]
104 fn test_is_tls_payload_ccs() {
105 let data = vec![0x14, 0x03, 0x03, 0x00, 0x01, 0x01];
106 assert!(is_tls_payload(&data));
107 }
108
109 #[test]
110 fn test_is_tls_payload_app_data() {
111 let data = vec![0x17, 0x03, 0x03, 0x00, 0x03, 0xaa, 0xbb, 0xcc];
112 assert!(is_tls_payload(&data));
113 }
114
115 #[test]
116 fn test_is_tls_payload_tls10() {
117 let data = vec![0x16, 0x03, 0x01, 0x00, 0x05, 0x01, 0x00, 0x00, 0x01, 0x00];
118 assert!(is_tls_payload(&data));
119 }
120
121 #[test]
122 fn test_is_tls_payload_invalid_type() {
123 let data = vec![0x19, 0x03, 0x03, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05];
124 assert!(!is_tls_payload(&data));
125 }
126
127 #[test]
128 fn test_is_tls_payload_invalid_version() {
129 let data = vec![0x16, 0x04, 0x00, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05];
130 assert!(!is_tls_payload(&data));
131 }
132
133 #[test]
134 fn test_is_tls_payload_too_short() {
135 let data = vec![0x16, 0x03, 0x03, 0x00];
136 assert!(!is_tls_payload(&data));
137 }
138
139 #[test]
140 fn test_is_tls_payload_http() {
141 assert!(!is_tls_payload(b"HTTP/1.1 200 OK\r\n"));
142 }
143
144 #[test]
145 fn test_is_tls_payload_sslv2() {
146 let data = vec![0x80, 0x2e, 0x01, 0x00, 0x02];
148 assert!(is_tls_payload(&data));
149 }
150}