1use super::dtls::{
19 noxtls_apply_dtls13_ack_ranges, noxtls_encode_dtls12_handshake_fragments,
20 noxtls_encode_dtls13_ack, noxtls_encode_dtls_record_packet,
21 noxtls_open_dtls13_aes128gcm_record, noxtls_open_dtls13_unified_aes128gcm_record_with_cid,
22 noxtls_parse_dtls13_ack, noxtls_parse_dtls13_record_packet_with_cid_len,
23 noxtls_parse_dtls_record_packet, noxtls_reassemble_dtls12_handshake_fragments,
24 noxtls_seal_dtls13_aes128gcm_record, noxtls_seal_dtls13_unified_aes128gcm_record_with_cid,
25 Dtls13AckRange, Dtls13RecordHeader, Dtls13TransportEvent, DtlsEpochReplayTracker,
26 DtlsFlightRetransmitTracker, DtlsRecordHeader, DtlsReplayWindow, DtlsReplayWindowSnapshot,
27 DTLS13_HANDSHAKE_ACK,
28};
29use super::handshake::{noxtls_encode_handshake_message, noxtls_parse_handshake_message};
30use super::kdf::{
31 noxtls_finished_hmac_for_hash, noxtls_hash_bytes_for_algorithm, noxtls_hkdf_expand_for_hash,
32 noxtls_hkdf_extract_for_hash, noxtls_hkdf_extract_with_salt_for_hash,
33 noxtls_tls13_expand_label_for_hash, HashAlgorithm,
34};
35use super::keyshare::{
36 noxtls_derive_deterministic_brainpoolp256r1_private,
37 noxtls_derive_deterministic_brainpoolp384r1_private,
38 noxtls_derive_deterministic_brainpoolp512r1_private,
39 noxtls_derive_deterministic_mlkem768_keypair, noxtls_derive_deterministic_p256_private,
40 noxtls_derive_deterministic_p384_private, noxtls_derive_deterministic_p521_private,
41 noxtls_derive_deterministic_x25519_private, noxtls_derive_tls13_mlkem768_shared_secret,
42 noxtls_derive_tls13_named_ec_shared_secret, noxtls_derive_tls13_p256_shared_secret,
43 noxtls_derive_tls13_p384_shared_secret, noxtls_derive_tls13_p521_shared_secret,
44 noxtls_derive_tls13_x25519_shared_secret,
45 noxtls_tls13_client_hello_offers_supported_key_exchange,
46};
47#[cfg(feature = "hazardous-legacy-crypto")]
48use super::keyshare::{
49 noxtls_derive_deterministic_x448_private, noxtls_derive_tls13_x448_shared_secret,
50};
51use super::psk::{
52 noxtls_ticket_age_matches_policy, ResumptionTicket, TicketStore, TicketUsagePolicy,
53};
54use super::record::{
55 noxtls_build_record_nonce, noxtls_decode_tls12_ciphertext_record,
56 noxtls_decode_tls13_ciphertext_record, noxtls_decode_tls13_inner_plaintext,
57 noxtls_encode_tls12_ciphertext_record, noxtls_encode_tls13_ciphertext_record,
58 noxtls_encode_tls13_inner_plaintext,
59};
60use super::state::{
61 AlertDescription, AlertLevel, CipherSuite, HandshakeState, RecordContentType, TlsRole,
62 TlsVersion,
63};
64use super::tls_wire::split_tls13_handshake_payload;
65#[cfg(not(feature = "std"))]
66use crate::internal_alloc::ToOwned;
67use crate::internal_alloc::{String, Vec};
68use noxtls_core::{Error, Result};
69use noxtls_crypto::{
70 noxtls_aes_cbc_decrypt, noxtls_aes_cbc_encrypt, noxtls_aes_ccm_decrypt_with_tag_len,
71 noxtls_aes_ccm_encrypt_with_tag_len, noxtls_aes_gcm_decrypt, noxtls_aes_gcm_encrypt,
72 noxtls_chacha20_poly1305_decrypt, noxtls_chacha20_poly1305_encrypt,
73 noxtls_ed25519_public_key_from_subject_public_key_info, noxtls_ed25519_verify,
74 noxtls_ffdhe_shared_secret, noxtls_hkdf_extract_sha256, noxtls_hmac_sha1, noxtls_mldsa_verify,
75 noxtls_mlkem_encapsulate_auto, noxtls_p256_ecdsa_sign_sha256, noxtls_p256_ecdsa_verify_sha256,
76 noxtls_p384_ecdsa_sign_sha384, noxtls_p384_ecdsa_verify_sha384, noxtls_rsaes_pkcs1_v15_decrypt,
77 noxtls_rsassa_pss_sha256_sign_auto, noxtls_rsassa_pss_sha256_verify,
78 noxtls_rsassa_pss_sha384_sign_auto, noxtls_rsassa_pss_sha384_verify, noxtls_rsassa_pss_sign,
79 noxtls_rsassa_pss_verify, noxtls_secp521r1_ecdsa_sign_sha512, noxtls_tls12_prf_sha256,
80 noxtls_tls12_prf_sha384, AesCipher, HmacDrbgSha256, MlDsaPublicKey, MlKemParameterSet,
81 MlKemPrivateKey, MlKemPublicKey, NamedCurve, NamedEcPrivateKey, NamedEcPublicKey,
82 P256PrivateKey, P256PublicKey, P384PrivateKey, P384PublicKey, RsaPrivateKey,
83 RsaPssHashAlgorithm, RsaPublicKey, TlsTranscriptSha256, TlsTranscriptSha384, X25519PrivateKey,
84 MLKEM1024_CIPHERTEXT_LEN, MLKEM1024_PUBLIC_KEY_LEN, MLKEM_CIPHERTEXT_LEN, MLKEM_PUBLIC_KEY_LEN,
85};
86use noxtls_x509::{
87 noxtls_certificate_matches_hostname, noxtls_p256_private_key_from_pkcs8_der,
88 noxtls_p384_private_key_from_pkcs8_der, noxtls_p521_private_key_from_pkcs8_der,
89 noxtls_parse_certificate, noxtls_parse_der_node, noxtls_parse_ecdsa_p384_signature_der,
90 noxtls_parse_ecdsa_signature_der, noxtls_parse_spki_public_key_info_der,
91 noxtls_rsa_private_key_from_pkcs8_der, noxtls_rsa_pss_private_key_from_pkcs8_der,
92 noxtls_validate_certificate_chain, noxtls_write_der_integer, noxtls_write_der_sequence,
93 ValidationError,
94};
95
96#[derive(Debug, Clone)]
98pub enum Tls13ServerIdentityKey {
99 P256(P256PrivateKey),
101 P384(P384PrivateKey),
103 P521(NamedEcPrivateKey),
105 Rsa(RsaPrivateKey),
107 RsaPss(RsaPrivateKey),
109}
110
111#[derive(Debug, Clone)]
113pub struct Tls13ServerIdentity {
114 pub certificate_chain_der: Vec<Vec<u8>>,
116 pub signing_key: Tls13ServerIdentityKey,
118}
119
120impl Tls13ServerIdentity {
121 pub fn noxtls_from_pkcs8_der(
123 certificate_chain_der: &[Vec<u8>],
124 private_key_pkcs8_der: &[u8],
125 ) -> Result<Self> {
126 if certificate_chain_der.is_empty() {
127 return Err(Error::InvalidLength(
128 "server certificate chain must contain at least one certificate",
129 ));
130 }
131 let signing_key =
132 Connection::noxtls_tls13_server_identity_key_from_pkcs8_der(private_key_pkcs8_der)?;
133 Ok(Self {
134 certificate_chain_der: certificate_chain_der.to_vec(),
135 signing_key,
136 })
137 }
138}
139
140#[derive(Debug, Clone)]
142pub struct Connection {
143 pub version: TlsVersion,
144 pub tls_role: TlsRole,
145 pub state: HandshakeState,
146 noxtls_selected_cipher_suite: Option<CipherSuite>,
147 client_offered_cipher_suites: Vec<CipherSuite>,
148 client_offered_tls_fallback_scsv: bool,
149 tls13_client_cipher_suites: Option<Vec<CipherSuite>>,
150 transcript: Vec<u8>,
151 noxtls_transcript_hash: TranscriptHashState,
152 handshake_secret: Option<Vec<u8>>,
153 tls13_master_secret: Option<Vec<u8>>,
154 tls13_client_handshake_traffic_secret: Option<Vec<u8>>,
155 tls13_server_handshake_traffic_secret: Option<Vec<u8>>,
156 tls13_client_application_traffic_secret: Option<Vec<u8>>,
157 tls13_server_application_traffic_secret: Option<Vec<u8>>,
158 tls13_exporter_master_secret: Option<Vec<u8>>,
159 noxtls_tls13_resumption_master_secret: Option<Vec<u8>>,
160 tls13_client_x25519_private: Option<X25519PrivateKey>,
161 tls13_client_p256_private: Option<P256PrivateKey>,
162 tls13_client_mlkem768_private: Option<MlKemPrivateKey>,
163 tls13_shared_secret: Option<Vec<u8>>,
164 tls13_hrr_requested_group: Option<u16>,
165 tls13_hrr_client_hello_extension_order: Option<Vec<u16>>,
166 tls13_hrr_seen: bool,
167 tls13_negotiated_key_exchange_group: Option<u16>,
168 tls13_negotiated_certificate_verify_signature_scheme: Option<u16>,
169 client_write_key: Option<[u8; 32]>,
171 server_write_key: Option<[u8; 32]>,
172 tls12_client_write_mac_key: Option<[u8; 20]>,
173 tls12_server_write_mac_key: Option<[u8; 20]>,
174 client_write_iv: Option<[u8; 12]>,
175 server_write_iv: Option<[u8; 12]>,
176 client_sequence: u64,
177 server_sequence: u64,
178 noxtls_tls13_peer_close_notify_received: bool,
179 noxtls_tls13_local_close_notify_sent: bool,
180 tls13_require_certificate_auth: bool,
181 tls13_server_trust_anchors_der: Vec<Vec<u8>>,
182 tls13_server_intermediates_der: Vec<Vec<u8>>,
183 tls13_server_validation_time: Option<String>,
184 tls13_server_expected_hostname: Option<String>,
185 tls13_client_server_name: Option<String>,
186 tls13_request_ocsp_stapling: bool,
187 tls13_require_ocsp_staple: bool,
188 tls13_ocsp_staple_verifier: Option<Tls13OcspStapleVerifier>,
189 noxtls_tls13_server_ocsp_staple: Option<Vec<u8>>,
190 noxtls_tls13_server_ocsp_staple_verified: bool,
191 tls13_require_server_name_ack: bool,
192 noxtls_tls13_server_name_acknowledged: bool,
193 tls13_client_alpn_protocols: Vec<Vec<u8>>,
194 noxtls_tls13_selected_alpn_protocol: Option<Vec<u8>>,
195 tls13_client_signature_algorithms: Vec<u16>,
196 tls13_client_certificate_compression_algorithms: Vec<u16>,
197 tls13_application_traffic_transcript_hash: Option<Vec<u8>>,
198 tls13_client_offer_pq_key_shares: bool,
199 tls13_client_offer_mldsa_signature: bool,
200 tls13_server_leaf_public_key_der: Option<Vec<u8>>,
201 tls13_client_identity_certificate_chain_der: Vec<Vec<u8>>,
202 tls13_client_signing_key: Option<Tls13ServerIdentityKey>,
203 tls13_client_trust_anchors_der: Vec<Vec<u8>>,
204 tls13_client_intermediates_der: Vec<Vec<u8>>,
205 tls13_client_validation_time: Option<String>,
206 tls13_client_leaf_public_key_der: Option<Vec<u8>>,
207 tls13_client_certificate_chain_validated: bool,
208 tls13_require_client_certificate_auth: bool,
209 tls13_server_requested_client_certificate: bool,
210 tls13_server_certificate_chain_validated: bool,
211 tls13_server_certificate_chain_der: Vec<Vec<u8>>,
212 tls13_client_raw_public_keys_enabled: bool,
213 tls13_expected_server_raw_public_key_der: Option<Vec<u8>>,
214 tls13_server_identity_certificate_type: u8,
215 tls13_negotiated_server_certificate_type: u8,
216 tls13_client_offered_server_certificate_types: Vec<u8>,
217 tls13_server_signing_key: Option<Tls13ServerIdentityKey>,
218 tls13_server_preferred_cipher_suites: Vec<CipherSuite>,
219 tls13_server_preferred_key_exchange_groups: Vec<u16>,
220 tls13_server_alpn_protocols: Vec<Vec<u8>>,
221 tls13_server_x25519_private: Option<X25519PrivateKey>,
222 tls13_server_p256_private: Option<P256PrivateKey>,
223 tls13_early_data_require_acceptance: bool,
224 tls13_early_data_accepted_psk: Option<Vec<u8>>,
225 tls13_early_data_max_bytes: Option<u32>,
226 tls13_early_data_opened_bytes: u64,
227 tls13_early_data_offered_in_client_hello: bool,
228 tls13_early_data_accepted_in_encrypted_extensions: bool,
229 tls13_end_of_early_data_seen: bool,
230 tls13_early_data_anti_replay_enabled: bool,
231 tls13_early_data_replay_window: DtlsReplayWindow,
232 noxtls_tls13_early_data_telemetry: Tls13EarlyDataTelemetry,
233 tls12_change_cipher_spec_seen: bool,
234 tls12_secure_renegotiation_enabled: bool,
235 tls12_secure_renegotiation_offered: bool,
236 tls12_secure_renegotiation_negotiated: bool,
237 tls12_secure_renegotiation_renegotiating: bool,
238 tls12_secure_renegotiation_client_verify_data: Vec<u8>,
239 tls12_secure_renegotiation_server_verify_data: Vec<u8>,
240 noxtls_tls12_session_id: Option<Vec<u8>>,
241 tls12_allow_legacy_record_versions: bool,
242 tls12_client_random: Option<[u8; 32]>,
243 tls12_server_random: Option<[u8; 32]>,
244 tls12_pre_master_secret: Option<Vec<u8>>,
245 tls12_rsa_encrypted_pre_master_secret: Option<Vec<u8>>,
246 tls12_dhe_prime: Option<Vec<u8>>,
247 tls12_dhe_server_public_key: Option<Vec<u8>>,
248 tls12_dhe_client_public_key: Option<Vec<u8>>,
249 tls12_master_secret: Option<[u8; 48]>,
250 tls12_extended_master_secret_session_hash: Option<Vec<u8>>,
251 dtls13_client_write_key: Option<[u8; 16]>,
252 dtls13_client_write_iv: Option<[u8; 12]>,
253 dtls13_server_write_key: Option<[u8; 16]>,
254 dtls13_server_write_iv: Option<[u8; 12]>,
255 dtls13_outbound_epoch: u16,
256 dtls13_outbound_sequence: u64,
257 dtls13_outbound_connection_id: Vec<u8>,
258 dtls13_inbound_connection_id: Vec<u8>,
259 dtls13_inbound_replay_tracker: DtlsEpochReplayTracker,
260 dtls13_client_inbound_replay_tracker: DtlsEpochReplayTracker,
261 dtls13_active_flight: Vec<(u16, u64)>,
262 dtls13_pending_ack_ranges: Vec<Dtls13AckRange>,
263 dtls13_active_flight_started_at_ms: Option<u64>,
264 dtls13_active_flight_timeout_ms: u64,
265 noxtls_dtls13_active_flight_failed: bool,
266 dtls_retransmit_tracker: DtlsFlightRetransmitTracker,
267 dtls_retransmit_initial_timeout_ms: u64,
268 dtls_max_retransmit_attempts: u8,
269 noxtls_dtls12_handshake_phase: Dtls12HandshakePhase,
270 dtls12_expected_cookie: Option<Vec<u8>>,
271 dtls12_anti_amplification_enforced: bool,
272 dtls12_inbound_bytes: u64,
273 dtls12_outbound_bytes: u64,
274 max_record_plaintext_len: usize,
275}
276
277#[derive(Debug, Clone)]
279pub struct ProtectedRecord {
280 pub sequence: u64,
281 pub ciphertext: Vec<u8>,
282 pub tag: [u8; 16],
283}
284
285#[derive(Debug, Copy, Clone, Eq, PartialEq)]
287pub struct DtlsOperationalPolicy {
288 pub retransmit_initial_timeout_ms: u64,
289 pub max_retransmit_attempts: u8,
290 pub active_flight_timeout_ms: u64,
291}
292
293#[derive(Debug, Copy, Clone, Eq, PartialEq)]
295pub enum DtlsOperationalProfile {
296 Conservative,
297 LanLowLatency,
298 LossyNetwork,
299}
300
301#[derive(Debug, Copy, Clone, Eq, PartialEq)]
303pub struct Tls13EarlyDataOperationalPolicy {
304 pub require_acceptance: bool,
305 pub anti_replay_enabled: bool,
306}
307
308#[derive(Debug, Copy, Clone, Eq, PartialEq)]
310pub enum Tls13EarlyDataOperationalProfile {
311 Compatibility,
312 Strict,
313}
314
315#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
317pub struct Tls13EarlyDataTelemetry {
318 pub accepted_records: u64,
319 pub rejected_missing_acceptance: u64,
320 pub rejected_psk_mismatch: u64,
321 pub rejected_replay_or_too_old: u64,
322 pub rejected_invalid_input: u64,
323 pub rejected_decrypt_or_policy: u64,
324}
325
326#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
328pub struct Tls13EarlyDataReplayState {
329 pub latest_sequence: u64,
330 pub bitmap: u64,
331 pub initialized: bool,
332}
333
334#[derive(Debug, Clone, Eq, PartialEq)]
336pub struct Tls13QuicInitialSecrets {
337 pub initial_secret: Vec<u8>,
338 pub client_initial_secret: Vec<u8>,
339 pub server_initial_secret: Vec<u8>,
340}
341
342#[derive(Debug, Clone, Eq, PartialEq)]
344pub struct Tls13QuicPacketProtectionKeys {
345 pub key: Vec<u8>,
346 pub iv: Vec<u8>,
347 pub header_protection_key: Vec<u8>,
348}
349
350#[derive(Debug, Clone, Eq, PartialEq)]
352pub struct Tls13QuicTrafficSecretSnapshot {
353 pub client_handshake_secret: Vec<u8>,
354 pub server_handshake_secret: Vec<u8>,
355 pub client_application_secret: Vec<u8>,
356 pub server_application_secret: Vec<u8>,
357}
358
359#[derive(Debug, Clone, Eq, PartialEq)]
361pub struct Tls13QuicNextTrafficSecrets {
362 pub client_next_application_secret: Vec<u8>,
363 pub server_next_application_secret: Vec<u8>,
364}
365
366pub const TLS13_QUIC_EXPORTER_LABEL_CLIENT_1RTT: &[u8] = b"EXPORTER-QUIC client 1rtt";
368pub const TLS13_QUIC_EXPORTER_LABEL_SERVER_1RTT: &[u8] = b"EXPORTER-QUIC server 1rtt";
370
371const TLS13_QUIC_V1_INITIAL_SALT: [u8; 20] = [
372 0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3, 0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad,
373 0xcc, 0xbb, 0x7f, 0x0a,
374];
375
376const HANDSHAKE_CLIENT_HELLO: u8 = 0x01;
377const HANDSHAKE_SERVER_HELLO: u8 = 0x02;
378const HANDSHAKE_HELLO_VERIFY_REQUEST: u8 = 0x03;
379const HANDSHAKE_NEW_SESSION_TICKET: u8 = 0x04;
380const HANDSHAKE_END_OF_EARLY_DATA: u8 = 0x05;
381const HANDSHAKE_ENCRYPTED_EXTENSIONS: u8 = 0x08;
382const HANDSHAKE_CERTIFICATE: u8 = 0x0B;
383const HANDSHAKE_SERVER_KEY_EXCHANGE: u8 = 0x0C;
384const HANDSHAKE_CERTIFICATE_REQUEST: u8 = 0x0D;
385const HANDSHAKE_SERVER_HELLO_DONE: u8 = 0x0E;
386const HANDSHAKE_CLIENT_KEY_EXCHANGE: u8 = 0x10;
387const HANDSHAKE_CERTIFICATE_VERIFY: u8 = 0x0F;
388const HANDSHAKE_FINISHED: u8 = 0x14;
389#[allow(dead_code)]
390const HANDSHAKE_COMPRESSED_CERTIFICATE: u8 = 0x19;
391const HANDSHAKE_KEY_UPDATE: u8 = 0x18;
392const EXT_SERVER_NAME: u16 = 0x0000;
393const EXT_STATUS_REQUEST: u16 = 0x0005;
394const EXT_SUPPORTED_GROUPS: u16 = 0x000A;
395const EXT_ALPN: u16 = 0x0010;
396const EXT_CLIENT_CERTIFICATE_TYPE: u16 = 0x0013;
397const EXT_SERVER_CERTIFICATE_TYPE: u16 = 0x0014;
398const EXT_COMPRESS_CERTIFICATE: u16 = 0x001B;
399const EXT_RENEGOTIATION_INFO: u16 = 0xFF01;
400const TLS_EMPTY_RENEGOTIATION_INFO_SCSV: u16 = 0x00FF;
401const TLS_FALLBACK_SCSV: u16 = 0x5600;
402const EXT_SUPPORTED_VERSIONS: u16 = 0x002B;
403const EXT_SIGNATURE_ALGORITHMS: u16 = 0x000D;
404const EXT_KEY_SHARE: u16 = 0x0033;
405const EXT_PSK_KEY_EXCHANGE_MODES: u16 = 0x002D;
406const EXT_PRE_SHARED_KEY: u16 = 0x0029;
407const EXT_EARLY_DATA: u16 = 0x002A;
408const TLS_CERTIFICATE_TYPE_X509: u8 = 0x00;
409const TLS_CERTIFICATE_TYPE_RAW_PUBLIC_KEY: u8 = 0x02;
410const TLS13_KEY_SHARE_GROUP_SECP256R1: u16 = 0x0017;
411const TLS13_KEY_SHARE_GROUP_SECP384R1: u16 = 0x0018;
412const TLS13_KEY_SHARE_GROUP_SECP521R1: u16 = 0x0019;
413const TLS13_KEY_SHARE_GROUP_BRAINPOOLP256R1TLS13: u16 = 0x001F;
414const TLS13_KEY_SHARE_GROUP_BRAINPOOLP384R1TLS13: u16 = 0x0020;
415const TLS13_KEY_SHARE_GROUP_BRAINPOOLP512R1TLS13: u16 = 0x0021;
416const TLS13_KEY_SHARE_GROUP_X25519: u16 = 0x001D;
417const TLS13_KEY_SHARE_GROUP_X448: u16 = 0x001E;
418const TLS13_KEY_SHARE_GROUP_MLKEM768: u16 = 0x0201;
419const TLS13_KEY_SHARE_GROUP_SECP256R1_MLKEM768_HYBRID: u16 = 0x11EB;
420const TLS13_KEY_SHARE_GROUP_X25519_MLKEM768_HYBRID: u16 = 0x11EC;
421const TLS13_KEY_SHARE_GROUP_SECP384R1_MLKEM1024_HYBRID: u16 = 0x11ED;
422const TLS13_PSK_KEY_EXCHANGE_MODE_PSK_DHE_KE: u8 = 0x01;
423const TLS13_CERT_COMPRESSION_ZLIB: u16 = 0x0001;
424const TLS13_SIGALG_ECDSA_SECP256R1_SHA256: u16 = 0x0403;
425const TLS13_SIGALG_ECDSA_SECP384R1_SHA384: u16 = 0x0503;
426const TLS13_SIGALG_ECDSA_SECP521R1_SHA512: u16 = 0x0603;
427const TLS13_SIGALG_RSA_PSS_RSAE_SHA256: u16 = 0x0804;
428const TLS13_SIGALG_RSA_PSS_RSAE_SHA384: u16 = 0x0805;
429const TLS13_SIGALG_RSA_PSS_RSAE_SHA512: u16 = 0x0806;
430const TLS13_SIGALG_ED25519: u16 = 0x0807;
431const TLS13_SIGALG_RSA_PSS_PSS_SHA256: u16 = 0x0809;
432const TLS13_SIGALG_RSA_PSS_PSS_SHA384: u16 = 0x080A;
433const TLS13_SIGALG_RSA_PSS_PSS_SHA512: u16 = 0x080B;
434const TLS13_SIGALG_MLDSA65: u16 = 0x0905;
435const TLS13_MAX_EXTENSION_VALUE_BYTES: usize = 16_384;
436const TLS_MAX_RECORD_PLAINTEXT_LEN: usize = 16_384;
437const DTLS_RETRANSMIT_TRACKER_MAX_RECORDS: usize = 256;
438const DTLS_RETRANSMIT_INITIAL_TIMEOUT_MS: u64 = 1_000;
439const DTLS_MAX_RETRANSMIT_ATTEMPTS: u8 = 4;
440const DTLS13_ACTIVE_FLIGHT_TIMEOUT_MS: u64 = 10_000;
441const DTLS13_MAX_SEQUENCE: u64 = (1_u64 << 48) - 1;
442const DTLS12_MAX_COOKIE_LEN: usize = 255;
443const DTLS12_ANTI_AMPLIFICATION_FACTOR: u64 = 3;
444const TLS13_HRR_RANDOM: [u8; 32] = [
445 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
446 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C,
447];
448
449#[derive(Debug, Clone, Eq, PartialEq, Default)]
451pub struct ClientHelloExtensions {
452 pub supported_versions: Vec<u16>,
453 pub supported_groups: Vec<u16>,
454 pub signature_algorithms: Vec<u16>,
455 pub certificate_compression_algorithms: Vec<u16>,
456 pub key_share_groups: Vec<u16>,
457 pub key_share_offered: bool,
458 pub sni_server_name: Option<String>,
459 pub alpn_protocols: Vec<Vec<u8>>,
460 pub status_request_ocsp: bool,
461 pub psk_key_exchange_modes: Vec<u8>,
462 pub psk_identity_count: usize,
463 pub psk_identities: Vec<Vec<u8>>,
464 pub psk_obfuscated_ticket_ages: Vec<u32>,
465 pub psk_binders: Vec<Vec<u8>>,
466 pub early_data_offered: bool,
467 pub secure_renegotiation_info: Option<Vec<u8>>,
468 pub secure_renegotiation_scsv: bool,
469 pub client_certificate_types: Vec<u8>,
470 pub server_certificate_types: Vec<u8>,
471}
472
473#[derive(Debug, Clone, Eq, PartialEq, Default)]
475pub struct ClientHelloInfo {
476 pub legacy_version: u16,
477 pub offered_cipher_suites: Vec<CipherSuite>,
478 pub offered_tls_fallback_scsv: bool,
479 pub extensions: ClientHelloExtensions,
480}
481
482struct PskIdentityOffer<'a> {
484 identity: &'a [u8],
485 obfuscated_ticket_age: u32,
486}
487
488struct PskClientOffer<'a> {
490 identities: Vec<PskIdentityOffer<'a>>,
491 binders: Vec<&'a [u8]>,
492}
493
494#[derive(Debug, Clone, Eq, PartialEq, Default)]
496struct Tls13ClientPublicKeyShares {
497 x25519: Option<[u8; 32]>,
498 secp256r1_uncompressed: Option<[u8; 65]>,
499 mlkem768: Option<Vec<u8>>,
500 x25519_mlkem768_hybrid: Option<Vec<u8>>,
501}
502
503#[derive(Debug, Clone, Eq, PartialEq)]
505enum Tls13ServerKeyShareParsed {
506 X25519([u8; 32]),
507 Secp256r1([u8; 65]),
508 MlKem768(Vec<u8>),
509 X25519MlKem768Hybrid { x25519: [u8; 32], mlkem768: Vec<u8> },
510}
511
512struct ParsedServerHello {
514 suite: CipherSuite,
515 random: Option<[u8; 32]>,
516 key_share: Option<Tls13ServerKeyShareParsed>,
517 hello_retry_request: bool,
518 requested_group: Option<u16>,
519 secure_renegotiation_info: Option<Vec<u8>>,
520}
521
522struct ParsedEncryptedExtensions {
524 selected_alpn_protocol: Option<Vec<u8>>,
525 server_name_acknowledged: bool,
526 early_data_accepted: bool,
527 server_certificate_type: Option<u8>,
528}
529
530struct ParsedTls13CertificateBody {
532 certificate_type: u8,
533 certificates: Vec<Vec<u8>>,
534 leaf_ocsp_staple: Option<Vec<u8>>,
535}
536
537#[derive(Debug, Copy, Clone, Eq, PartialEq)]
539pub enum Tls13OcspStapleVerification {
540 Good,
541 Expired,
542 Revoked,
543}
544
545pub type Tls13OcspStapleVerifier = fn(&[u8]) -> Result<Tls13OcspStapleVerification>;
547
548#[derive(Debug, Clone, Eq, PartialEq)]
550pub struct Tls13OcspStapleInfo {
551 pub produced_at: String,
552 pub this_update: String,
553 pub next_update: Option<String>,
554 pub status: Tls13OcspStapleVerification,
555}
556
557#[derive(Debug, Copy, Clone, Eq, PartialEq)]
559enum Dtls12HandshakePhase {
560 AwaitingClientHello,
561 AwaitingClientHelloWithCookie,
562 AwaitingClientKeyExchange,
563 AwaitingFinished,
564 Connected,
565}
566
567#[derive(Debug, Clone)]
569enum TranscriptHashState {
570 Sha256(TlsTranscriptSha256),
571 Sha384(TlsTranscriptSha384),
572}
573
574impl TranscriptHashState {
575 fn noxtls_for_version(version: TlsVersion) -> Self {
590 match version {
591 TlsVersion::Tls13 | TlsVersion::Dtls13 => {
592 Self::Sha384(TlsTranscriptSha384::noxtls_new())
593 }
594 TlsVersion::Tls10 | TlsVersion::Tls11 | TlsVersion::Tls12 | TlsVersion::Dtls12 => {
595 Self::Sha256(TlsTranscriptSha256::noxtls_new())
596 }
597 }
598 }
599
600 fn noxtls_update(&mut self, message: &[u8]) {
612 match self {
613 Self::Sha256(hasher) => hasher.noxtls_update(message),
614 Self::Sha384(hasher) => hasher.noxtls_update(message),
615 }
616 }
617
618 fn noxtls_snapshot_hash(&self) -> Vec<u8> {
633 match self {
634 Self::Sha256(hasher) => hasher.noxtls_snapshot_hash().to_vec(),
635 Self::Sha384(hasher) => hasher.noxtls_snapshot_hash().to_vec(),
636 }
637 }
638
639 fn noxtls_algorithm(&self) -> HashAlgorithm {
654 match self {
655 Self::Sha256(_) => HashAlgorithm::Sha256,
656 Self::Sha384(_) => HashAlgorithm::Sha384,
657 }
658 }
659}
660
661impl CipherSuite {
662 fn noxtls_from_u16(codepoint: u16) -> Option<Self> {
663 match codepoint {
664 0x1301 => Some(Self::TlsAes128GcmSha256),
665 0x1302 => Some(Self::TlsAes256GcmSha384),
666 0x1303 => Some(Self::TlsChacha20Poly1305Sha256),
667 0xC02B => Some(Self::TlsEcdheEcdsaWithAes128GcmSha256),
668 0xC02C => Some(Self::TlsEcdheEcdsaWithAes256GcmSha384),
669 0xCCA9 => Some(Self::TlsEcdheEcdsaWithChacha20Poly1305Sha256),
670 0xC02F => Some(Self::TlsEcdheRsaWithAes128GcmSha256),
671 0xC030 => Some(Self::TlsEcdheRsaWithAes256GcmSha384),
672 0xCCA8 => Some(Self::TlsEcdheRsaWithChacha20Poly1305Sha256),
673 0xCCAA => Some(Self::TlsDheRsaWithChacha20Poly1305Sha256),
674 0x009E => Some(Self::TlsDheRsaWithAes128GcmSha256),
675 0x009F => Some(Self::TlsDheRsaWithAes256GcmSha384),
676 0x009C => Some(Self::TlsRsaWithAes128GcmSha256),
677 0x009D => Some(Self::TlsRsaWithAes256GcmSha384),
678 0xC013 => Some(Self::TlsEcdheRsaWithAes128CbcSha),
679 0x002F => Some(Self::TlsRsaWithAes128CbcSha),
680 0xC0AC => Some(Self::TlsEcdheEcdsaWithAes128CcmSha256),
681 0xC0AD => Some(Self::TlsEcdheEcdsaWithAes256CcmSha256),
682 0xC0AE => Some(Self::TlsEcdheEcdsaWithAes128Ccm8Sha256),
683 0xC0AF => Some(Self::TlsEcdheEcdsaWithAes256Ccm8Sha256),
684 0xC09C => Some(Self::TlsRsaWithAes128CcmSha256),
685 0xC09D => Some(Self::TlsRsaWithAes256CcmSha256),
686 0xC0A0 => Some(Self::TlsRsaWithAes128Ccm8Sha256),
687 0xC0A1 => Some(Self::TlsRsaWithAes256Ccm8Sha256),
688 0xC09E => Some(Self::TlsDheRsaWithAes128CcmSha256),
689 0xC09F => Some(Self::TlsDheRsaWithAes256CcmSha256),
690 0xC0A2 => Some(Self::TlsDheRsaWithAes128Ccm8Sha256),
691 0xC0A3 => Some(Self::TlsDheRsaWithAes256Ccm8Sha256),
692 0xC0A4 => Some(Self::TlsPskWithAes128Ccm8Sha256),
693 0xC0FF => Some(Self::TlsEcjpakeWithAes128Ccm8Sha256),
694 _ => None,
695 }
696 }
697
698 fn noxtls_transcript_hash_state(self) -> TranscriptHashState {
699 match self.noxtls_hash_algorithm() {
700 HashAlgorithm::Sha256 => TranscriptHashState::Sha256(TlsTranscriptSha256::noxtls_new()),
701 HashAlgorithm::Sha384 => TranscriptHashState::Sha384(TlsTranscriptSha384::noxtls_new()),
702 }
703 }
704
705 fn noxtls_hash_algorithm(self) -> HashAlgorithm {
706 match self {
707 Self::TlsAes256GcmSha384
708 | Self::TlsEcdheRsaWithAes256GcmSha384
709 | Self::TlsEcdheEcdsaWithAes256GcmSha384
710 | Self::TlsDheRsaWithAes256GcmSha384
711 | Self::TlsRsaWithAes256GcmSha384 => HashAlgorithm::Sha384,
712 _ => HashAlgorithm::Sha256,
713 }
714 }
715
716 fn noxtls_tls13_traffic_key_len(self) -> Option<usize> {
717 match self {
718 Self::TlsAes128GcmSha256 => Some(16),
719 Self::TlsAes256GcmSha384 | Self::TlsChacha20Poly1305Sha256 => Some(32),
720 _ => None,
721 }
722 }
723
724 fn noxtls_tls12_aead_key_len(self) -> Option<usize> {
725 match self {
726 Self::TlsEcdheRsaWithAes128GcmSha256
727 | Self::TlsEcdheEcdsaWithAes128GcmSha256
728 | Self::TlsDheRsaWithAes128GcmSha256
729 | Self::TlsRsaWithAes128GcmSha256
730 | Self::TlsEcdheEcdsaWithAes128CcmSha256
731 | Self::TlsEcdheEcdsaWithAes128Ccm8Sha256
732 | Self::TlsRsaWithAes128CcmSha256
733 | Self::TlsRsaWithAes128Ccm8Sha256
734 | Self::TlsDheRsaWithAes128CcmSha256
735 | Self::TlsDheRsaWithAes128Ccm8Sha256
736 | Self::TlsPskWithAes128Ccm8Sha256
737 | Self::TlsEcjpakeWithAes128Ccm8Sha256 => Some(16),
738 Self::TlsEcdheRsaWithAes256GcmSha384
739 | Self::TlsEcdheEcdsaWithAes256GcmSha384
740 | Self::TlsDheRsaWithAes256GcmSha384
741 | Self::TlsRsaWithAes256GcmSha384
742 | Self::TlsEcdheEcdsaWithAes256CcmSha256
743 | Self::TlsEcdheEcdsaWithAes256Ccm8Sha256
744 | Self::TlsRsaWithAes256CcmSha256
745 | Self::TlsRsaWithAes256Ccm8Sha256
746 | Self::TlsDheRsaWithAes256CcmSha256
747 | Self::TlsDheRsaWithAes256Ccm8Sha256 => Some(32),
748 _ => None,
749 }
750 }
751
752 fn noxtls_tls12_cbc_key_len(self) -> Option<usize> {
753 match self {
754 Self::TlsEcdheRsaWithAes128CbcSha | Self::TlsRsaWithAes128CbcSha => Some(16),
755 _ => None,
756 }
757 }
758
759 fn noxtls_tls12_chacha20_poly1305_key_len(self) -> Option<usize> {
760 match self {
761 Self::TlsEcdheRsaWithChacha20Poly1305Sha256
762 | Self::TlsEcdheEcdsaWithChacha20Poly1305Sha256
763 | Self::TlsDheRsaWithChacha20Poly1305Sha256 => Some(32),
764 _ => None,
765 }
766 }
767
768 fn noxtls_tls12_aead_tag_len(self) -> Option<usize> {
769 match self {
770 Self::TlsEcdheEcdsaWithAes128Ccm8Sha256
771 | Self::TlsEcdheEcdsaWithAes256Ccm8Sha256
772 | Self::TlsRsaWithAes128Ccm8Sha256
773 | Self::TlsRsaWithAes256Ccm8Sha256
774 | Self::TlsDheRsaWithAes128Ccm8Sha256
775 | Self::TlsDheRsaWithAes256Ccm8Sha256
776 | Self::TlsPskWithAes128Ccm8Sha256
777 | Self::TlsEcjpakeWithAes128Ccm8Sha256 => Some(8),
778 Self::TlsEcdheRsaWithAes128GcmSha256
779 | Self::TlsEcdheRsaWithAes256GcmSha384
780 | Self::TlsEcdheEcdsaWithAes128GcmSha256
781 | Self::TlsEcdheEcdsaWithAes256GcmSha384
782 | Self::TlsDheRsaWithAes128GcmSha256
783 | Self::TlsDheRsaWithAes256GcmSha384
784 | Self::TlsRsaWithAes128GcmSha256
785 | Self::TlsRsaWithAes256GcmSha384
786 | Self::TlsEcdheEcdsaWithAes128CcmSha256
787 | Self::TlsEcdheEcdsaWithAes256CcmSha256
788 | Self::TlsRsaWithAes128CcmSha256
789 | Self::TlsRsaWithAes256CcmSha256
790 | Self::TlsDheRsaWithAes128CcmSha256
791 | Self::TlsDheRsaWithAes256CcmSha256 => Some(16),
792 _ => None,
793 }
794 }
795
796 fn noxtls_to_u16(self) -> u16 {
797 match self {
798 Self::TlsAes128GcmSha256 => 0x1301,
799 Self::TlsAes256GcmSha384 => 0x1302,
800 Self::TlsChacha20Poly1305Sha256 => 0x1303,
801 Self::TlsEcdheEcdsaWithAes128GcmSha256 => 0xC02B,
802 Self::TlsEcdheEcdsaWithAes256GcmSha384 => 0xC02C,
803 Self::TlsEcdheEcdsaWithChacha20Poly1305Sha256 => 0xCCA9,
804 Self::TlsEcdheRsaWithAes128GcmSha256 => 0xC02F,
805 Self::TlsEcdheRsaWithAes256GcmSha384 => 0xC030,
806 Self::TlsEcdheRsaWithChacha20Poly1305Sha256 => 0xCCA8,
807 Self::TlsDheRsaWithChacha20Poly1305Sha256 => 0xCCAA,
808 Self::TlsDheRsaWithAes128GcmSha256 => 0x009E,
809 Self::TlsDheRsaWithAes256GcmSha384 => 0x009F,
810 Self::TlsRsaWithAes128GcmSha256 => 0x009C,
811 Self::TlsRsaWithAes256GcmSha384 => 0x009D,
812 Self::TlsEcdheRsaWithAes128CbcSha => 0xC013,
813 Self::TlsRsaWithAes128CbcSha => 0x002F,
814 Self::TlsEcdheEcdsaWithAes128CcmSha256 => 0xC0AC,
815 Self::TlsEcdheEcdsaWithAes256CcmSha256 => 0xC0AD,
816 Self::TlsEcdheEcdsaWithAes128Ccm8Sha256 => 0xC0AE,
817 Self::TlsEcdheEcdsaWithAes256Ccm8Sha256 => 0xC0AF,
818 Self::TlsRsaWithAes128CcmSha256 => 0xC09C,
819 Self::TlsRsaWithAes256CcmSha256 => 0xC09D,
820 Self::TlsRsaWithAes128Ccm8Sha256 => 0xC0A0,
821 Self::TlsRsaWithAes256Ccm8Sha256 => 0xC0A1,
822 Self::TlsDheRsaWithAes128CcmSha256 => 0xC09E,
823 Self::TlsDheRsaWithAes256CcmSha256 => 0xC09F,
824 Self::TlsDheRsaWithAes128Ccm8Sha256 => 0xC0A2,
825 Self::TlsDheRsaWithAes256Ccm8Sha256 => 0xC0A3,
826 Self::TlsPskWithAes128Ccm8Sha256 => 0xC0A4,
827 Self::TlsEcjpakeWithAes128Ccm8Sha256 => 0xC0FF,
828 }
829 }
830}
831
832mod client_hello;
833mod common;
834mod dtls12;
835mod dtls13;
836mod quic;
837mod record_common;
838mod record_server;
839mod tls12_handshake;
840mod tls12_security;
841mod tls13_client;
842mod tls13_handshake;
843mod tls13_server;
844mod tls13_server_role;
845mod tls_kdf;
846mod tls_key_exchange;
847
848use self::common::noxtls_constant_time_eq;
849use self::tls12_security::noxtls_parse_tls12_signature_fields;
850use self::tls_kdf::{noxtls_derive_tls13_handshake_secret, noxtls_tls12_prf_for_hash};
851use self::tls_key_exchange::noxtls_combine_tls13_hybrid_shared_secret;
852
853impl Connection {
854 pub fn noxtls_new(version: TlsVersion) -> Self {
866 Self {
867 version,
868 tls_role: TlsRole::Client,
869 state: HandshakeState::Idle,
870 noxtls_selected_cipher_suite: None,
871 client_offered_cipher_suites: Vec::new(),
872 client_offered_tls_fallback_scsv: false,
873 tls13_client_cipher_suites: None,
874 transcript: Vec::new(),
875 noxtls_transcript_hash: TranscriptHashState::noxtls_for_version(version),
876 handshake_secret: None,
877 tls13_master_secret: None,
878 tls13_client_handshake_traffic_secret: None,
879 tls13_server_handshake_traffic_secret: None,
880 tls13_client_application_traffic_secret: None,
881 tls13_server_application_traffic_secret: None,
882 tls13_exporter_master_secret: None,
883 noxtls_tls13_resumption_master_secret: None,
884 tls13_client_x25519_private: None,
885 tls13_client_p256_private: None,
886 tls13_client_mlkem768_private: None,
887 tls13_shared_secret: None,
888 tls13_hrr_requested_group: None,
889 tls13_hrr_client_hello_extension_order: None,
890 tls13_hrr_seen: false,
891 tls13_negotiated_key_exchange_group: None,
892 tls13_negotiated_certificate_verify_signature_scheme: None,
893 client_write_key: None,
894 server_write_key: None,
895 tls12_client_write_mac_key: None,
896 tls12_server_write_mac_key: None,
897 client_write_iv: None,
898 server_write_iv: None,
899 client_sequence: 0,
900 server_sequence: 0,
901 noxtls_tls13_peer_close_notify_received: false,
902 noxtls_tls13_local_close_notify_sent: false,
903 tls13_require_certificate_auth: false,
904 tls13_server_trust_anchors_der: Vec::new(),
905 tls13_server_intermediates_der: Vec::new(),
906 tls13_server_validation_time: None,
907 tls13_server_expected_hostname: None,
908 tls13_client_server_name: None,
909 tls13_request_ocsp_stapling: false,
910 tls13_require_ocsp_staple: false,
911 tls13_ocsp_staple_verifier: None,
912 noxtls_tls13_server_ocsp_staple: None,
913 noxtls_tls13_server_ocsp_staple_verified: false,
914 tls13_require_server_name_ack: false,
915 noxtls_tls13_server_name_acknowledged: false,
916 tls13_client_alpn_protocols: Vec::new(),
917 noxtls_tls13_selected_alpn_protocol: None,
918 tls13_client_signature_algorithms: Vec::new(),
919 tls13_client_certificate_compression_algorithms: Vec::new(),
920 tls13_application_traffic_transcript_hash: None,
921 tls13_client_offer_pq_key_shares: true,
922 tls13_client_offer_mldsa_signature: true,
923 tls13_server_leaf_public_key_der: None,
924 tls13_client_identity_certificate_chain_der: Vec::new(),
925 tls13_client_signing_key: None,
926 tls13_client_trust_anchors_der: Vec::new(),
927 tls13_client_intermediates_der: Vec::new(),
928 tls13_client_validation_time: None,
929 tls13_client_leaf_public_key_der: None,
930 tls13_client_certificate_chain_validated: false,
931 tls13_require_client_certificate_auth: false,
932 tls13_server_requested_client_certificate: false,
933 tls13_server_certificate_chain_validated: false,
934 tls13_server_certificate_chain_der: Vec::new(),
935 tls13_client_raw_public_keys_enabled: false,
936 tls13_expected_server_raw_public_key_der: None,
937 tls13_server_identity_certificate_type: TLS_CERTIFICATE_TYPE_X509,
938 tls13_negotiated_server_certificate_type: TLS_CERTIFICATE_TYPE_X509,
939 tls13_client_offered_server_certificate_types: Vec::new(),
940 tls13_server_signing_key: None,
941 tls13_server_preferred_cipher_suites: Vec::new(),
942 tls13_server_preferred_key_exchange_groups: Vec::new(),
943 tls13_server_alpn_protocols: Vec::new(),
944 tls13_server_x25519_private: None,
945 tls13_server_p256_private: None,
946 tls13_early_data_require_acceptance: false,
947 tls13_early_data_accepted_psk: None,
948 tls13_early_data_max_bytes: None,
949 tls13_early_data_opened_bytes: 0,
950 tls13_early_data_offered_in_client_hello: false,
951 tls13_early_data_accepted_in_encrypted_extensions: false,
952 tls13_end_of_early_data_seen: false,
953 tls13_early_data_anti_replay_enabled: true,
954 tls13_early_data_replay_window: DtlsReplayWindow::noxtls_new(),
955 noxtls_tls13_early_data_telemetry: Tls13EarlyDataTelemetry::default(),
956 tls12_change_cipher_spec_seen: false,
957 tls12_secure_renegotiation_enabled: true,
958 tls12_secure_renegotiation_offered: false,
959 tls12_secure_renegotiation_negotiated: false,
960 tls12_secure_renegotiation_renegotiating: false,
961 tls12_secure_renegotiation_client_verify_data: Vec::new(),
962 tls12_secure_renegotiation_server_verify_data: Vec::new(),
963 noxtls_tls12_session_id: None,
964 tls12_allow_legacy_record_versions: false,
965 tls12_client_random: None,
966 tls12_server_random: None,
967 tls12_pre_master_secret: None,
968 tls12_rsa_encrypted_pre_master_secret: None,
969 tls12_dhe_prime: None,
970 tls12_dhe_server_public_key: None,
971 tls12_dhe_client_public_key: None,
972 tls12_master_secret: None,
973 tls12_extended_master_secret_session_hash: None,
974 dtls13_client_write_key: None,
975 dtls13_client_write_iv: None,
976 dtls13_server_write_key: None,
977 dtls13_server_write_iv: None,
978 dtls13_outbound_epoch: 0,
979 dtls13_outbound_sequence: 0,
980 dtls13_outbound_connection_id: Vec::new(),
981 dtls13_inbound_connection_id: Vec::new(),
982 dtls13_inbound_replay_tracker: DtlsEpochReplayTracker::noxtls_new(),
983 dtls13_client_inbound_replay_tracker: DtlsEpochReplayTracker::noxtls_new(),
984 dtls13_active_flight: Vec::new(),
985 dtls13_pending_ack_ranges: Vec::new(),
986 dtls13_active_flight_started_at_ms: None,
987 dtls13_active_flight_timeout_ms: DTLS13_ACTIVE_FLIGHT_TIMEOUT_MS,
988 noxtls_dtls13_active_flight_failed: false,
989 dtls_retransmit_tracker: DtlsFlightRetransmitTracker::noxtls_new(
990 DTLS_RETRANSMIT_TRACKER_MAX_RECORDS,
991 ),
992 dtls_retransmit_initial_timeout_ms: DTLS_RETRANSMIT_INITIAL_TIMEOUT_MS,
993 dtls_max_retransmit_attempts: DTLS_MAX_RETRANSMIT_ATTEMPTS,
994 noxtls_dtls12_handshake_phase: Dtls12HandshakePhase::AwaitingClientHello,
995 dtls12_expected_cookie: None,
996 dtls12_anti_amplification_enforced: true,
997 dtls12_inbound_bytes: 0,
998 dtls12_outbound_bytes: 0,
999 max_record_plaintext_len: TLS_MAX_RECORD_PLAINTEXT_LEN,
1000 }
1001 }
1002
1003 #[must_use]
1008 pub fn noxtls_dtls_operational_policy(&self) -> Option<DtlsOperationalPolicy> {
1021 if !self.version.is_dtls() {
1022 return None;
1023 }
1024 Some(DtlsOperationalPolicy {
1025 retransmit_initial_timeout_ms: self.dtls_retransmit_initial_timeout_ms,
1026 max_retransmit_attempts: self.dtls_max_retransmit_attempts,
1027 active_flight_timeout_ms: self.dtls13_active_flight_timeout_ms,
1028 })
1029 }
1030
1031 pub fn noxtls_set_dtls_operational_policy(
1047 &mut self,
1048 policy: DtlsOperationalPolicy,
1049 ) -> Result<DtlsOperationalPolicy> {
1050 self.noxtls_ensure_dtls12_mode()?;
1051 let effective = DtlsOperationalPolicy {
1052 retransmit_initial_timeout_ms: policy.retransmit_initial_timeout_ms.max(1),
1053 max_retransmit_attempts: policy.max_retransmit_attempts.max(1),
1054 active_flight_timeout_ms: policy.active_flight_timeout_ms.max(1),
1055 };
1056 self.dtls_retransmit_initial_timeout_ms = effective.retransmit_initial_timeout_ms;
1057 self.dtls_max_retransmit_attempts = effective.max_retransmit_attempts;
1058 self.dtls13_active_flight_timeout_ms = effective.active_flight_timeout_ms;
1059 Ok(effective)
1060 }
1061
1062 pub fn noxtls_apply_dtls_operational_profile(
1079 &mut self,
1080 profile: DtlsOperationalProfile,
1081 ) -> Result<DtlsOperationalPolicy> {
1082 let policy = match profile {
1083 DtlsOperationalProfile::Conservative => DtlsOperationalPolicy {
1084 retransmit_initial_timeout_ms: DTLS_RETRANSMIT_INITIAL_TIMEOUT_MS,
1085 max_retransmit_attempts: DTLS_MAX_RETRANSMIT_ATTEMPTS,
1086 active_flight_timeout_ms: DTLS13_ACTIVE_FLIGHT_TIMEOUT_MS,
1087 },
1088 DtlsOperationalProfile::LanLowLatency => DtlsOperationalPolicy {
1089 retransmit_initial_timeout_ms: 250,
1090 max_retransmit_attempts: 3,
1091 active_flight_timeout_ms: 3_000,
1092 },
1093 DtlsOperationalProfile::LossyNetwork => DtlsOperationalPolicy {
1094 retransmit_initial_timeout_ms: 1_500,
1095 max_retransmit_attempts: 6,
1096 active_flight_timeout_ms: 20_000,
1097 },
1098 };
1099 self.noxtls_set_dtls_operational_policy(policy)
1100 }
1101
1102 pub fn noxtls_set_tls13_require_certificate_auth(&mut self, required: bool) {
1111 self.tls13_require_certificate_auth = required;
1112 }
1113
1114 pub fn noxtls_set_tls13_require_client_auth(&mut self, required: bool) {
1116 self.tls13_require_client_certificate_auth = required;
1117 }
1118
1119 pub fn noxtls_configure_tls13_client_auth(
1121 &mut self,
1122 trust_anchors_der: &[Vec<u8>],
1123 intermediates_der: &[Vec<u8>],
1124 validation_time: &str,
1125 ) -> Result<()> {
1126 if trust_anchors_der.is_empty() {
1127 return Err(Error::InvalidLength(
1128 "tls13 client trust anchor list must not be empty",
1129 ));
1130 }
1131 if validation_time.is_empty() {
1132 return Err(Error::InvalidLength(
1133 "tls13 client validation time must not be empty",
1134 ));
1135 }
1136 self.tls13_client_trust_anchors_der = trust_anchors_der.to_vec();
1137 self.tls13_client_intermediates_der = intermediates_der.to_vec();
1138 self.tls13_client_validation_time = Some(validation_time.to_owned());
1139 Ok(())
1140 }
1141
1142 pub fn noxtls_configure_tls13_server_auth(
1160 &mut self,
1161 trust_anchors_der: &[Vec<u8>],
1162 intermediates_der: &[Vec<u8>],
1163 validation_time: &str,
1164 ) -> Result<()> {
1165 if trust_anchors_der.is_empty() {
1166 return Err(Error::InvalidLength(
1167 "tls13 trust anchor list must not be empty",
1168 ));
1169 }
1170 if validation_time.is_empty() {
1171 return Err(Error::InvalidLength(
1172 "tls13 validation time must not be empty",
1173 ));
1174 }
1175 self.tls13_server_trust_anchors_der = trust_anchors_der.to_vec();
1176 self.tls13_server_intermediates_der = intermediates_der.to_vec();
1177 self.tls13_server_validation_time = Some(validation_time.to_owned());
1178 Ok(())
1179 }
1180
1181 pub fn noxtls_set_tls13_server_expected_hostname(
1197 &mut self,
1198 hostname: Option<&str>,
1199 ) -> Result<()> {
1200 match hostname {
1201 Some(value) if value.is_empty() => Err(Error::InvalidLength(
1202 "tls13 expected hostname must not be empty",
1203 )),
1204 Some(value) => {
1205 self.tls13_server_expected_hostname = Some(value.to_owned());
1206 Ok(())
1207 }
1208 None => {
1209 self.tls13_server_expected_hostname = None;
1210 Ok(())
1211 }
1212 }
1213 }
1214
1215 pub fn noxtls_set_tls12_session_id(&mut self, session_id: Option<&[u8]>) -> Result<()> {
1230 match session_id {
1231 Some(value) if value.is_empty() => Err(Error::InvalidLength(
1232 "tls12 session id must not be empty when present",
1233 )),
1234 Some(value) if value.len() > 32 => Err(Error::InvalidLength(
1235 "tls12 session id must not exceed 32 bytes",
1236 )),
1237 Some(value) => {
1238 self.noxtls_tls12_session_id = Some(value.to_vec());
1239 Ok(())
1240 }
1241 None => {
1242 self.noxtls_tls12_session_id = None;
1243 Ok(())
1244 }
1245 }
1246 }
1247
1248 #[must_use]
1262 pub fn noxtls_tls12_session_id(&self) -> Option<&[u8]> {
1263 self.noxtls_tls12_session_id.as_deref()
1264 }
1265
1266 pub fn noxtls_set_tls12_allow_legacy_record_versions(&mut self, allow: bool) {
1276 self.tls12_allow_legacy_record_versions = allow;
1277 }
1278
1279 pub fn noxtls_set_tls12_secure_renegotiation_enabled(&mut self, enabled: bool) {
1280 self.tls12_secure_renegotiation_enabled = enabled;
1281 if !enabled {
1282 self.tls12_secure_renegotiation_offered = false;
1283 self.tls12_secure_renegotiation_negotiated = false;
1284 self.tls12_secure_renegotiation_renegotiating = false;
1285 }
1286 }
1287
1288 #[must_use]
1289 pub fn noxtls_tls12_secure_renegotiation_negotiated(&self) -> bool {
1290 self.tls12_secure_renegotiation_negotiated
1291 }
1292
1293 #[must_use]
1294 pub fn noxtls_tls12_secure_renegotiation_verify_data(&self) -> (&[u8], &[u8]) {
1295 (
1296 self.tls12_secure_renegotiation_client_verify_data
1297 .as_slice(),
1298 self.tls12_secure_renegotiation_server_verify_data
1299 .as_slice(),
1300 )
1301 }
1302
1303 pub fn noxtls_set_tls12_secure_renegotiation_verify_data_for_test(
1304 &mut self,
1305 client_verify_data: &[u8],
1306 server_verify_data: &[u8],
1307 ) -> Result<()> {
1308 if client_verify_data.len() > u8::MAX as usize
1309 || server_verify_data.len() > u8::MAX as usize
1310 || client_verify_data
1311 .len()
1312 .saturating_add(server_verify_data.len())
1313 > u8::MAX as usize
1314 {
1315 return Err(Error::InvalidLength(
1316 "tls12 secure renegotiation verify data is too large",
1317 ));
1318 }
1319 self.tls12_secure_renegotiation_client_verify_data = client_verify_data.to_vec();
1320 self.tls12_secure_renegotiation_server_verify_data = server_verify_data.to_vec();
1321 self.tls12_secure_renegotiation_negotiated = true;
1322 Ok(())
1323 }
1324
1325 fn noxtls_validate_tls12_secure_renegotiation_server_hello(
1326 &mut self,
1327 renegotiation_info: Option<&[u8]>,
1328 ) -> Result<()> {
1329 if self.version != TlsVersion::Tls12 || !self.tls12_secure_renegotiation_enabled {
1330 return Ok(());
1331 }
1332 if !self.tls12_secure_renegotiation_offered {
1333 return Err(Error::StateError(
1334 "tls12 secure renegotiation was not offered in ClientHello",
1335 ));
1336 }
1337 let actual = renegotiation_info.ok_or(Error::ParseFailure(
1338 "tls12 server hello missing renegotiation_info extension",
1339 ))?;
1340 let mut expected = Vec::new();
1341 if self.tls12_secure_renegotiation_renegotiating {
1342 expected.extend_from_slice(&self.tls12_secure_renegotiation_client_verify_data);
1343 expected.extend_from_slice(&self.tls12_secure_renegotiation_server_verify_data);
1344 }
1345 if actual != expected.as_slice() {
1346 return Err(Error::ParseFailure(
1347 "tls12 server hello renegotiation_info verify_data mismatch",
1348 ));
1349 }
1350 self.tls12_secure_renegotiation_negotiated = true;
1351 Ok(())
1352 }
1353
1354 pub fn noxtls_build_server_hello(
1372 version: TlsVersion,
1373 suite: CipherSuite,
1374 random: &[u8],
1375 ) -> Result<Vec<u8>> {
1376 if random.len() != 32 {
1377 return Err(Error::InvalidLength("server hello random must be 32 bytes"));
1378 }
1379 let body = noxtls_encode_server_hello_body(version, suite, random)?;
1380 Ok(noxtls_encode_handshake_message(
1381 HANDSHAKE_SERVER_HELLO,
1382 &body,
1383 ))
1384 }
1385
1386 pub fn noxtls_build_server_hello_auto(
1404 version: TlsVersion,
1405 suite: CipherSuite,
1406 drbg: &mut HmacDrbgSha256,
1407 ) -> Result<Vec<u8>> {
1408 let random = drbg.generate(32, b"server_hello_random")?;
1409 Self::noxtls_build_server_hello(version, suite, &random)
1410 }
1411
1412 pub fn noxtls_build_tls12_server_hello_with_secure_renegotiation(
1413 suite: CipherSuite,
1414 random: &[u8],
1415 client_verify_data: &[u8],
1416 server_verify_data: &[u8],
1417 ) -> Result<Vec<u8>> {
1418 let total_len = client_verify_data
1419 .len()
1420 .saturating_add(server_verify_data.len());
1421 if total_len > u8::MAX as usize {
1422 return Err(Error::InvalidLength(
1423 "tls12 secure renegotiation info is too large",
1424 ));
1425 }
1426 let mut renegotiation_info = Vec::with_capacity(total_len);
1427 renegotiation_info.extend_from_slice(client_verify_data);
1428 renegotiation_info.extend_from_slice(server_verify_data);
1429 let body = noxtls_encode_server_hello_body_with_key_share(
1430 TlsVersion::Tls12,
1431 suite,
1432 random,
1433 None,
1434 None,
1435 Some(&renegotiation_info),
1436 )?;
1437 Ok(noxtls_encode_handshake_message(
1438 HANDSHAKE_SERVER_HELLO,
1439 &body,
1440 ))
1441 }
1442
1443 pub fn noxtls_parse_client_hello_cipher_suites(msg: &[u8]) -> Result<Vec<CipherSuite>> {
1459 noxtls_parse_client_hello_info(msg).map(|hello| hello.offered_cipher_suites)
1460 }
1461
1462 pub fn noxtls_parse_client_hello_info(msg: &[u8]) -> Result<ClientHelloInfo> {
1478 noxtls_parse_client_hello_info(msg)
1479 }
1480
1481 #[must_use]
1483 pub fn noxtls_selected_alpn_protocol(&self) -> Option<&[u8]> {
1484 self.noxtls_tls13_selected_alpn_protocol.as_deref()
1485 }
1486
1487 #[must_use]
1489 pub fn noxtls_tls13_selected_alpn_protocol(&self) -> Option<&[u8]> {
1490 self.noxtls_selected_alpn_protocol()
1491 }
1492
1493 #[must_use]
1495 pub fn noxtls_negotiated_key_exchange_group(&self) -> Option<u16> {
1496 self.tls13_negotiated_key_exchange_group
1497 }
1498
1499 #[must_use]
1501 pub fn noxtls_tls13_negotiated_key_exchange_group(&self) -> Option<u16> {
1502 self.noxtls_negotiated_key_exchange_group()
1503 }
1504
1505 #[must_use]
1507 pub fn noxtls_negotiated_certificate_verify_signature_scheme(&self) -> Option<u16> {
1508 self.tls13_negotiated_certificate_verify_signature_scheme
1509 }
1510
1511 #[must_use]
1513 pub fn noxtls_tls13_negotiated_certificate_verify_signature_scheme(&self) -> Option<u16> {
1514 self.noxtls_negotiated_certificate_verify_signature_scheme()
1515 }
1516
1517 pub fn noxtls_select_tls13_server_alpn_protocol(
1519 client_hello: &[u8],
1520 server_preferred: &[&[u8]],
1521 ) -> Result<Option<Vec<u8>>> {
1522 let hello = Self::noxtls_parse_client_hello_info(client_hello)?;
1523 Self::noxtls_select_server_alpn_protocol_from_offers(
1524 &hello.extensions.alpn_protocols,
1525 server_preferred,
1526 )
1527 }
1528
1529 pub fn noxtls_tls13_server_identity_key_from_pkcs8_der(
1531 private_key_pkcs8_der: &[u8],
1532 ) -> Result<Tls13ServerIdentityKey> {
1533 if let Ok(private_key) = noxtls_p256_private_key_from_pkcs8_der(private_key_pkcs8_der) {
1534 return Ok(Tls13ServerIdentityKey::P256(private_key));
1535 }
1536 if let Ok(private_key) = noxtls_p384_private_key_from_pkcs8_der(private_key_pkcs8_der) {
1537 return Ok(Tls13ServerIdentityKey::P384(private_key));
1538 }
1539 if let Ok(private_key) = noxtls_p521_private_key_from_pkcs8_der(private_key_pkcs8_der) {
1540 return Ok(Tls13ServerIdentityKey::P521(private_key));
1541 }
1542 if let Ok(private_key) = noxtls_rsa_pss_private_key_from_pkcs8_der(private_key_pkcs8_der) {
1543 return Ok(Tls13ServerIdentityKey::RsaPss(private_key));
1544 }
1545 if let Ok(private_key) = noxtls_rsa_private_key_from_pkcs8_der(private_key_pkcs8_der) {
1546 return Ok(Tls13ServerIdentityKey::Rsa(private_key));
1547 }
1548 Err(Error::UnsupportedFeature(
1549 "unsupported pkcs8 private key algorithm for tls13 server identity",
1550 ))
1551 }
1552
1553 fn noxtls_select_server_alpn_protocol_from_offers(
1554 client_offered: &[Vec<u8>],
1555 server_preferred: &[&[u8]],
1556 ) -> Result<Option<Vec<u8>>> {
1557 for protocol in server_preferred {
1558 if protocol.is_empty() {
1559 return Err(Error::InvalidLength("alpn protocol must not be empty"));
1560 }
1561 if protocol.len() > u8::MAX as usize {
1562 return Err(Error::InvalidLength(
1563 "alpn protocol length must not exceed 255 bytes",
1564 ));
1565 }
1566 if client_offered
1567 .iter()
1568 .any(|offered| offered.as_slice() == *protocol)
1569 {
1570 return Ok(Some(protocol.to_vec()));
1571 }
1572 }
1573 Ok(None)
1574 }
1575
1576 #[must_use]
1584 pub fn noxtls_tls13_server_certificate_verify_content(
1597 noxtls_transcript_hash: &[u8],
1598 ) -> Vec<u8> {
1599 noxtls_build_tls13_server_certificate_verify_message(noxtls_transcript_hash)
1600 }
1601
1602 pub fn noxtls_select_cipher_suite_from_client_hello(
1620 client_hello: &[u8],
1621 server_preferred: &[CipherSuite],
1622 version: TlsVersion,
1623 ) -> Result<CipherSuite> {
1624 let hello = noxtls_parse_client_hello_info(client_hello)?;
1625 Self::noxtls_select_cipher_suite_from_client_hello_info(&hello, server_preferred, version)
1626 }
1627
1628 pub(crate) fn noxtls_select_cipher_suite_from_client_hello_info(
1629 hello: &ClientHelloInfo,
1630 server_preferred: &[CipherSuite],
1631 version: TlsVersion,
1632 ) -> Result<CipherSuite> {
1633 noxtls_pick_intersection_suite(&hello, server_preferred, version)
1634 }
1635
1636 pub fn noxtls_build_server_hello_for_client(
1655 version: TlsVersion,
1656 client_hello: &[u8],
1657 server_random: &[u8],
1658 server_preferred: &[CipherSuite],
1659 ) -> Result<Vec<u8>> {
1660 let selected = Self::noxtls_select_cipher_suite_from_client_hello(
1661 client_hello,
1662 server_preferred,
1663 version,
1664 )?;
1665 Self::noxtls_build_server_hello(version, selected, server_random)
1666 }
1667
1668 pub fn noxtls_build_server_hello_for_client_auto(
1687 version: TlsVersion,
1688 client_hello: &[u8],
1689 server_preferred: &[CipherSuite],
1690 drbg: &mut HmacDrbgSha256,
1691 ) -> Result<Vec<u8>> {
1692 let random = drbg.generate(32, b"server_hello_random")?;
1693 Self::noxtls_build_server_hello_for_client(version, client_hello, &random, server_preferred)
1694 }
1695
1696 pub fn noxtls_export_keying_material(
1714 &self,
1715 label: &[u8],
1716 context: &[u8],
1717 len: usize,
1718 ) -> Result<Vec<u8>> {
1719 if !self.version.uses_tls13_handshake_semantics() {
1720 return Err(Error::StateError(
1721 "key exporter is currently only modeled for TLS 1.3",
1722 ));
1723 }
1724 if self.state != HandshakeState::Finished {
1725 return Err(Error::StateError(
1726 "key exporter requires finished handshake state",
1727 ));
1728 }
1729 let noxtls_hash_algorithm = self.noxtls_negotiated_hash_algorithm();
1730 let hash_len = noxtls_hash_algorithm.output_len();
1731 let exporter_master =
1732 self.tls13_exporter_master_secret
1733 .as_ref()
1734 .ok_or(Error::StateError(
1735 "tls13 exporter master secret is not installed",
1736 ))?;
1737 let context_hash = noxtls_hash_bytes_for_algorithm(noxtls_hash_algorithm, context);
1738 let exporter_secret = noxtls_tls13_expand_label_for_hash(
1739 noxtls_hash_algorithm,
1740 exporter_master,
1741 b"exporter",
1742 &context_hash,
1743 hash_len,
1744 )?;
1745 noxtls_tls13_expand_label_for_hash(
1746 noxtls_hash_algorithm,
1747 &exporter_secret,
1748 label,
1749 &context_hash,
1750 len,
1751 )
1752 }
1753
1754 pub fn noxtls_issue_tls13_resumption_ticket(
1771 &self,
1772 drbg: &mut HmacDrbgSha256,
1773 age_add: u32,
1774 ) -> Result<ResumptionTicket> {
1775 self.noxtls_issue_tls13_resumption_ticket_with_time(drbg, age_add, 0, u64::MAX)
1776 }
1777
1778 pub fn noxtls_issue_tls13_resumption_ticket_into_store(
1796 &self,
1797 drbg: &mut HmacDrbgSha256,
1798 age_add: u32,
1799 ticket_store: &mut TicketStore,
1800 ) -> Result<ResumptionTicket> {
1801 let ticket = self.noxtls_issue_tls13_resumption_ticket(drbg, age_add)?;
1802 ticket_store.insert(ticket.clone());
1803 Ok(ticket)
1804 }
1805
1806 pub fn noxtls_issue_tls13_resumption_ticket_with_time(
1825 &self,
1826 drbg: &mut HmacDrbgSha256,
1827 age_add: u32,
1828 issued_at_ms: u64,
1829 lifetime_ms: u64,
1830 ) -> Result<ResumptionTicket> {
1831 if !self.version.uses_tls13_handshake_semantics() {
1832 return Err(Error::StateError(
1833 "resumption ticket issuance is only defined for TLS 1.3",
1834 ));
1835 }
1836 if self.state != HandshakeState::Finished {
1837 return Err(Error::StateError(
1838 "resumption ticket issuance requires finished handshake state",
1839 ));
1840 }
1841 let nonce = drbg.generate(16, b"tls13_ticket_nonce")?;
1842 let noxtls_hash_algorithm = self.noxtls_negotiated_hash_algorithm();
1843 let identity = noxtls_tls13_expand_label_for_hash(
1844 noxtls_hash_algorithm,
1845 &self.noxtls_tls13_resumption_master_secret()?,
1846 b"ticket",
1847 &nonce,
1848 16,
1849 )?;
1850 Ok(ResumptionTicket {
1851 identity,
1852 ticket_nonce: nonce,
1853 obfuscated_ticket_age: age_add,
1854 age_add,
1855 issued_at_ms,
1856 lifetime_ms,
1857 max_early_data_size: TLS_MAX_RECORD_PLAINTEXT_LEN as u32,
1858 consumed: false,
1859 })
1860 }
1861
1862 pub fn noxtls_issue_tls13_resumption_ticket_with_time_and_early_data(
1881 &self,
1882 drbg: &mut HmacDrbgSha256,
1883 age_add: u32,
1884 issued_at_ms: u64,
1885 lifetime_ms: u64,
1886 max_early_data_size: u32,
1887 ) -> Result<ResumptionTicket> {
1888 let mut ticket = self.noxtls_issue_tls13_resumption_ticket_with_time(
1889 drbg,
1890 age_add,
1891 issued_at_ms,
1892 lifetime_ms,
1893 )?;
1894 ticket.max_early_data_size = max_early_data_size;
1895 Ok(ticket)
1896 }
1897
1898 pub fn noxtls_issue_tls13_resumption_ticket_with_time_into_store(
1918 &self,
1919 drbg: &mut HmacDrbgSha256,
1920 age_add: u32,
1921 issued_at_ms: u64,
1922 lifetime_ms: u64,
1923 ticket_store: &mut TicketStore,
1924 ) -> Result<ResumptionTicket> {
1925 let ticket = self.noxtls_issue_tls13_resumption_ticket_with_time(
1926 drbg,
1927 age_add,
1928 issued_at_ms,
1929 lifetime_ms,
1930 )?;
1931 ticket_store.insert(ticket.clone());
1932 Ok(ticket)
1933 }
1934
1935 pub fn noxtls_issue_tls13_resumption_ticket_with_time_and_early_data_into_store(
1955 &self,
1956 drbg: &mut HmacDrbgSha256,
1957 age_add: u32,
1958 issued_at_ms: u64,
1959 lifetime_ms: u64,
1960 max_early_data_size: u32,
1961 ticket_store: &mut TicketStore,
1962 ) -> Result<ResumptionTicket> {
1963 let ticket = self.noxtls_issue_tls13_resumption_ticket_with_time_and_early_data(
1964 drbg,
1965 age_add,
1966 issued_at_ms,
1967 lifetime_ms,
1968 max_early_data_size,
1969 )?;
1970 ticket_store.insert(ticket.clone());
1971 Ok(ticket)
1972 }
1973
1974 pub fn noxtls_seal_record(&mut self, plaintext: &[u8], aad: &[u8]) -> Result<ProtectedRecord> {
1991 if self.state != HandshakeState::Finished {
1992 return Err(Error::StateError(
1993 "cannot seal record before handshake noxtls_finish",
1994 ));
1995 }
1996 let plaintext_limit = if self.version.uses_tls13_handshake_semantics() {
1997 self.max_record_plaintext_len.saturating_add(1)
1998 } else {
1999 self.max_record_plaintext_len
2000 };
2001 if plaintext.len() > plaintext_limit {
2002 return Err(Error::InvalidLength(
2003 "record plaintext exceeds configured limit",
2004 ));
2005 }
2006 if self.client_sequence == u64::MAX {
2007 return Err(Error::StateError("client record sequence exhausted"));
2008 }
2009 let suite = self.noxtls_selected_cipher_suite.ok_or(Error::StateError(
2010 "cipher suite must be selected before sealing records",
2011 ))?;
2012 let key = self
2013 .client_write_key
2014 .ok_or(Error::StateError("client write key is not installed"))?;
2015 let iv = self
2016 .client_write_iv
2017 .ok_or(Error::StateError("client write iv is not installed"))?;
2018 let nonce = noxtls_build_record_nonce(&iv, self.client_sequence);
2019 let (ciphertext, tag) = match suite {
2020 CipherSuite::TlsChacha20Poly1305Sha256 => {
2021 noxtls_chacha20_poly1305_encrypt(&key, &nonce, aad, plaintext)?
2022 }
2023 CipherSuite::TlsAes128GcmSha256 | CipherSuite::TlsAes256GcmSha384 => {
2024 let key_len = suite
2025 .noxtls_tls13_traffic_key_len()
2026 .ok_or(Error::StateError(
2027 "tls 1.3 aes suites must define traffic key length",
2028 ))?;
2029 let cipher = AesCipher::noxtls_new(&key[..key_len])?;
2030 noxtls_aes_gcm_encrypt(&cipher, &nonce, aad, plaintext)?
2031 }
2032 CipherSuite::TlsEcdheRsaWithAes128GcmSha256
2033 | CipherSuite::TlsEcdheRsaWithAes256GcmSha384
2034 | CipherSuite::TlsEcdheEcdsaWithAes128GcmSha256
2035 | CipherSuite::TlsEcdheEcdsaWithAes256GcmSha384
2036 | CipherSuite::TlsDheRsaWithAes128GcmSha256
2037 | CipherSuite::TlsDheRsaWithAes256GcmSha384
2038 | CipherSuite::TlsRsaWithAes128GcmSha256
2039 | CipherSuite::TlsRsaWithAes256GcmSha384 => {
2040 let key_len = suite.noxtls_tls12_aead_key_len().ok_or(Error::StateError(
2041 "tls 1.2 aes-gcm suites must define traffic key length",
2042 ))?;
2043 let cipher = AesCipher::noxtls_new(&key[..key_len])?;
2044 noxtls_aes_gcm_encrypt(&cipher, &nonce, aad, plaintext)?
2045 }
2046 CipherSuite::TlsEcdheEcdsaWithAes128CcmSha256
2047 | CipherSuite::TlsEcdheEcdsaWithAes256CcmSha256
2048 | CipherSuite::TlsEcdheEcdsaWithAes128Ccm8Sha256
2049 | CipherSuite::TlsEcdheEcdsaWithAes256Ccm8Sha256
2050 | CipherSuite::TlsRsaWithAes128CcmSha256
2051 | CipherSuite::TlsRsaWithAes256CcmSha256
2052 | CipherSuite::TlsRsaWithAes128Ccm8Sha256
2053 | CipherSuite::TlsRsaWithAes256Ccm8Sha256
2054 | CipherSuite::TlsDheRsaWithAes128CcmSha256
2055 | CipherSuite::TlsDheRsaWithAes256CcmSha256
2056 | CipherSuite::TlsDheRsaWithAes128Ccm8Sha256
2057 | CipherSuite::TlsDheRsaWithAes256Ccm8Sha256
2058 | CipherSuite::TlsPskWithAes128Ccm8Sha256
2059 | CipherSuite::TlsEcjpakeWithAes128Ccm8Sha256 => {
2060 let key_len = suite.noxtls_tls12_aead_key_len().ok_or(Error::StateError(
2061 "tls 1.2 aes-ccm suites must define traffic key length",
2062 ))?;
2063 let tag_len = suite.noxtls_tls12_aead_tag_len().ok_or(Error::StateError(
2064 "tls 1.2 aes-ccm suites must define tag length",
2065 ))?;
2066 let cipher = AesCipher::noxtls_new(&key[..key_len])?;
2067 noxtls_aes_ccm_encrypt_with_tag_len(&cipher, &nonce, aad, plaintext, tag_len)?
2068 }
2069 CipherSuite::TlsEcdheRsaWithAes128CbcSha | CipherSuite::TlsRsaWithAes128CbcSha => {
2070 return Err(Error::UnsupportedFeature(
2071 "tls 1.2 cbc uses block record protection",
2072 ));
2073 }
2074 CipherSuite::TlsEcdheRsaWithChacha20Poly1305Sha256
2075 | CipherSuite::TlsEcdheEcdsaWithChacha20Poly1305Sha256
2076 | CipherSuite::TlsDheRsaWithChacha20Poly1305Sha256 => {
2077 return Err(Error::UnsupportedFeature(
2078 "tls 1.2 chacha20-poly1305 uses tls12 nonce record protection",
2079 ));
2080 }
2081 };
2082 let record = ProtectedRecord {
2083 sequence: self.client_sequence,
2084 ciphertext,
2085 tag,
2086 };
2087 self.client_sequence = self.client_sequence.wrapping_add(1);
2088 Ok(record)
2089 }
2090
2091 pub fn noxtls_open_record(&mut self, record: &ProtectedRecord, aad: &[u8]) -> Result<Vec<u8>> {
2108 let tls13_handshake_open_allowed = self.version.uses_tls13_handshake_semantics()
2109 && matches!(
2110 self.state,
2111 HandshakeState::KeysDerived
2112 | HandshakeState::ServerEncryptedExtensionsReceived
2113 | HandshakeState::ServerCertificateRequestReceived
2114 | HandshakeState::ServerCertificateReceived
2115 | HandshakeState::ServerCertificateVerified
2116 );
2117 if self.state != HandshakeState::Finished && !tls13_handshake_open_allowed {
2118 return Err(Error::StateError(
2119 "cannot open record before handshake noxtls_finish",
2120 ));
2121 }
2122 if self.server_sequence == u64::MAX {
2123 return Err(Error::StateError("server record sequence exhausted"));
2124 }
2125 if record.sequence != self.server_sequence {
2126 return Err(Error::StateError(
2127 "unexpected server record sequence number",
2128 ));
2129 }
2130 let suite = self.noxtls_selected_cipher_suite.ok_or(Error::StateError(
2131 "cipher suite must be selected before opening records",
2132 ))?;
2133 let key = self
2134 .server_write_key
2135 .ok_or(Error::StateError("server write key is not installed"))?;
2136 let iv = self
2137 .server_write_iv
2138 .ok_or(Error::StateError("server write iv is not installed"))?;
2139 let nonce = noxtls_build_record_nonce(&iv, record.sequence);
2140 let plaintext = match suite {
2141 CipherSuite::TlsChacha20Poly1305Sha256 => noxtls_chacha20_poly1305_decrypt(
2142 &key,
2143 &nonce,
2144 aad,
2145 &record.ciphertext,
2146 &record.tag,
2147 )?,
2148 CipherSuite::TlsAes128GcmSha256 | CipherSuite::TlsAes256GcmSha384 => {
2149 let key_len = suite
2150 .noxtls_tls13_traffic_key_len()
2151 .ok_or(Error::StateError(
2152 "tls 1.3 aes suites must define traffic key length",
2153 ))?;
2154 let cipher = AesCipher::noxtls_new(&key[..key_len])?;
2155 noxtls_aes_gcm_decrypt(&cipher, &nonce, aad, &record.ciphertext, &record.tag)?
2156 }
2157 CipherSuite::TlsEcdheRsaWithAes128GcmSha256
2158 | CipherSuite::TlsEcdheRsaWithAes256GcmSha384
2159 | CipherSuite::TlsEcdheEcdsaWithAes128GcmSha256
2160 | CipherSuite::TlsEcdheEcdsaWithAes256GcmSha384
2161 | CipherSuite::TlsDheRsaWithAes128GcmSha256
2162 | CipherSuite::TlsDheRsaWithAes256GcmSha384
2163 | CipherSuite::TlsRsaWithAes128GcmSha256
2164 | CipherSuite::TlsRsaWithAes256GcmSha384 => {
2165 let key_len = suite.noxtls_tls12_aead_key_len().ok_or(Error::StateError(
2166 "tls 1.2 aes-gcm suites must define traffic key length",
2167 ))?;
2168 let cipher = AesCipher::noxtls_new(&key[..key_len])?;
2169 noxtls_aes_gcm_decrypt(&cipher, &nonce, aad, &record.ciphertext, &record.tag)?
2170 }
2171 CipherSuite::TlsEcdheEcdsaWithAes128CcmSha256
2172 | CipherSuite::TlsEcdheEcdsaWithAes256CcmSha256
2173 | CipherSuite::TlsEcdheEcdsaWithAes128Ccm8Sha256
2174 | CipherSuite::TlsEcdheEcdsaWithAes256Ccm8Sha256
2175 | CipherSuite::TlsRsaWithAes128CcmSha256
2176 | CipherSuite::TlsRsaWithAes256CcmSha256
2177 | CipherSuite::TlsRsaWithAes128Ccm8Sha256
2178 | CipherSuite::TlsRsaWithAes256Ccm8Sha256
2179 | CipherSuite::TlsDheRsaWithAes128CcmSha256
2180 | CipherSuite::TlsDheRsaWithAes256CcmSha256
2181 | CipherSuite::TlsDheRsaWithAes128Ccm8Sha256
2182 | CipherSuite::TlsDheRsaWithAes256Ccm8Sha256
2183 | CipherSuite::TlsPskWithAes128Ccm8Sha256
2184 | CipherSuite::TlsEcjpakeWithAes128Ccm8Sha256 => {
2185 let key_len = suite.noxtls_tls12_aead_key_len().ok_or(Error::StateError(
2186 "tls 1.2 aes-ccm suites must define traffic key length",
2187 ))?;
2188 let tag_len = suite.noxtls_tls12_aead_tag_len().ok_or(Error::StateError(
2189 "tls 1.2 aes-ccm suites must define tag length",
2190 ))?;
2191 let cipher = AesCipher::noxtls_new(&key[..key_len])?;
2192 noxtls_aes_ccm_decrypt_with_tag_len(
2193 &cipher,
2194 &nonce,
2195 aad,
2196 &record.ciphertext,
2197 &record.tag,
2198 tag_len,
2199 )?
2200 }
2201 CipherSuite::TlsEcdheRsaWithAes128CbcSha | CipherSuite::TlsRsaWithAes128CbcSha => {
2202 return Err(Error::UnsupportedFeature(
2203 "tls 1.2 cbc uses block record protection",
2204 ));
2205 }
2206 CipherSuite::TlsEcdheRsaWithChacha20Poly1305Sha256
2207 | CipherSuite::TlsEcdheEcdsaWithChacha20Poly1305Sha256
2208 | CipherSuite::TlsDheRsaWithChacha20Poly1305Sha256 => {
2209 return Err(Error::UnsupportedFeature(
2210 "tls 1.2 chacha20-poly1305 uses tls12 nonce record protection",
2211 ));
2212 }
2213 };
2214 let plaintext_limit = if self.version.uses_tls13_handshake_semantics() {
2215 self.max_record_plaintext_len.saturating_add(1)
2216 } else {
2217 self.max_record_plaintext_len
2218 };
2219 if plaintext.len() > plaintext_limit {
2220 return Err(Error::InvalidLength(
2221 "record plaintext exceeds configured limit",
2222 ));
2223 }
2224 self.server_sequence = self.server_sequence.wrapping_add(1);
2225 Ok(plaintext)
2226 }
2227
2228 pub fn noxtls_open_own_record(&self, record: &ProtectedRecord, aad: &[u8]) -> Result<Vec<u8>> {
2245 let suite = self.noxtls_selected_cipher_suite.ok_or(Error::StateError(
2246 "cipher suite must be selected before opening own records",
2247 ))?;
2248 let key = self
2249 .client_write_key
2250 .ok_or(Error::StateError("client write key is not installed"))?;
2251 let iv = self
2252 .client_write_iv
2253 .ok_or(Error::StateError("client write iv is not installed"))?;
2254 let nonce = noxtls_build_record_nonce(&iv, record.sequence);
2255 let plaintext = match suite {
2256 CipherSuite::TlsChacha20Poly1305Sha256 => noxtls_chacha20_poly1305_decrypt(
2257 &key,
2258 &nonce,
2259 aad,
2260 &record.ciphertext,
2261 &record.tag,
2262 )?,
2263 CipherSuite::TlsAes128GcmSha256 | CipherSuite::TlsAes256GcmSha384 => {
2264 let key_len = suite
2265 .noxtls_tls13_traffic_key_len()
2266 .ok_or(Error::StateError(
2267 "tls 1.3 aes suites must define traffic key length",
2268 ))?;
2269 let cipher = AesCipher::noxtls_new(&key[..key_len])?;
2270 noxtls_aes_gcm_decrypt(&cipher, &nonce, aad, &record.ciphertext, &record.tag)?
2271 }
2272 CipherSuite::TlsEcdheRsaWithAes128GcmSha256
2273 | CipherSuite::TlsEcdheRsaWithAes256GcmSha384
2274 | CipherSuite::TlsEcdheEcdsaWithAes128GcmSha256
2275 | CipherSuite::TlsEcdheEcdsaWithAes256GcmSha384
2276 | CipherSuite::TlsDheRsaWithAes128GcmSha256
2277 | CipherSuite::TlsDheRsaWithAes256GcmSha384
2278 | CipherSuite::TlsRsaWithAes128GcmSha256
2279 | CipherSuite::TlsRsaWithAes256GcmSha384 => {
2280 let key_len = suite.noxtls_tls12_aead_key_len().ok_or(Error::StateError(
2281 "tls 1.2 aes-gcm suites must define traffic key length",
2282 ))?;
2283 let cipher = AesCipher::noxtls_new(&key[..key_len])?;
2284 noxtls_aes_gcm_decrypt(&cipher, &nonce, aad, &record.ciphertext, &record.tag)?
2285 }
2286 CipherSuite::TlsEcdheEcdsaWithAes128CcmSha256
2287 | CipherSuite::TlsEcdheEcdsaWithAes256CcmSha256
2288 | CipherSuite::TlsEcdheEcdsaWithAes128Ccm8Sha256
2289 | CipherSuite::TlsEcdheEcdsaWithAes256Ccm8Sha256
2290 | CipherSuite::TlsRsaWithAes128CcmSha256
2291 | CipherSuite::TlsRsaWithAes256CcmSha256
2292 | CipherSuite::TlsRsaWithAes128Ccm8Sha256
2293 | CipherSuite::TlsRsaWithAes256Ccm8Sha256
2294 | CipherSuite::TlsDheRsaWithAes128CcmSha256
2295 | CipherSuite::TlsDheRsaWithAes256CcmSha256
2296 | CipherSuite::TlsDheRsaWithAes128Ccm8Sha256
2297 | CipherSuite::TlsDheRsaWithAes256Ccm8Sha256
2298 | CipherSuite::TlsPskWithAes128Ccm8Sha256
2299 | CipherSuite::TlsEcjpakeWithAes128Ccm8Sha256 => {
2300 let key_len = suite.noxtls_tls12_aead_key_len().ok_or(Error::StateError(
2301 "tls 1.2 aes-ccm suites must define traffic key length",
2302 ))?;
2303 let tag_len = suite.noxtls_tls12_aead_tag_len().ok_or(Error::StateError(
2304 "tls 1.2 aes-ccm suites must define tag length",
2305 ))?;
2306 let cipher = AesCipher::noxtls_new(&key[..key_len])?;
2307 noxtls_aes_ccm_decrypt_with_tag_len(
2308 &cipher,
2309 &nonce,
2310 aad,
2311 &record.ciphertext,
2312 &record.tag,
2313 tag_len,
2314 )?
2315 }
2316 CipherSuite::TlsEcdheRsaWithAes128CbcSha | CipherSuite::TlsRsaWithAes128CbcSha => {
2317 return Err(Error::UnsupportedFeature(
2318 "tls 1.2 cbc uses block record protection",
2319 ));
2320 }
2321 CipherSuite::TlsEcdheRsaWithChacha20Poly1305Sha256
2322 | CipherSuite::TlsEcdheEcdsaWithChacha20Poly1305Sha256
2323 | CipherSuite::TlsDheRsaWithChacha20Poly1305Sha256 => {
2324 return Err(Error::UnsupportedFeature(
2325 "tls 1.2 chacha20-poly1305 uses tls12 nonce record protection",
2326 ));
2327 }
2328 };
2329 if plaintext.len() > self.max_record_plaintext_len {
2330 return Err(Error::InvalidLength(
2331 "record plaintext exceeds configured limit",
2332 ));
2333 }
2334 Ok(plaintext)
2335 }
2336
2337 pub fn noxtls_seal_tls12_record_packet(
2354 &mut self,
2355 plaintext: &[u8],
2356 content_type: RecordContentType,
2357 ) -> Result<Vec<u8>> {
2358 self.noxtls_ensure_tls12_wire_mode()?;
2359 if self.state != HandshakeState::Finished {
2360 return Err(Error::StateError(
2361 "cannot seal tls12 record packet before handshake completion",
2362 ));
2363 }
2364 if plaintext.len() > self.max_record_plaintext_len {
2365 return Err(Error::InvalidLength(
2366 "record plaintext exceeds configured limit",
2367 ));
2368 }
2369 if self.client_sequence == u64::MAX {
2370 return Err(Error::StateError("client record sequence exhausted"));
2371 }
2372 let sequence = self.client_sequence;
2373 let suite = self.noxtls_selected_cipher_suite.ok_or(Error::StateError(
2374 "cipher suite must be selected before sealing tls12 record packet",
2375 ))?;
2376 if suite.noxtls_tls12_chacha20_poly1305_key_len().is_some() {
2377 let key = self
2378 .client_write_key
2379 .ok_or(Error::StateError("client write key is not installed"))?;
2380 let iv = self
2381 .client_write_iv
2382 .ok_or(Error::StateError("client write iv is not installed"))?;
2383 let nonce = Self::noxtls_build_tls12_chacha20_poly1305_nonce(&iv, sequence);
2384 let aad =
2385 self.noxtls_build_tls12_record_aad(sequence, content_type, plaintext.len())?;
2386 let (ciphertext, tag) =
2387 noxtls_chacha20_poly1305_encrypt(&key, &nonce, &aad, plaintext)?;
2388 let mut payload = Vec::with_capacity(ciphertext.len() + tag.len());
2389 payload.extend_from_slice(&ciphertext);
2390 payload.extend_from_slice(&tag);
2391 self.client_sequence = self.client_sequence.wrapping_add(1);
2392 return noxtls_encode_tls12_ciphertext_record(
2393 content_type.to_u8(),
2394 noxtls_legacy_wire_version(self.version),
2395 &payload,
2396 );
2397 }
2398 let key = self
2399 .client_write_key
2400 .ok_or(Error::StateError("client write key is not installed"))?;
2401 let iv = self
2402 .client_write_iv
2403 .ok_or(Error::StateError("client write iv is not installed"))?;
2404 let explicit_nonce = sequence.to_be_bytes();
2405 let nonce = Self::noxtls_build_tls12_aead_nonce(&iv, &explicit_nonce);
2406 let aad = self.noxtls_build_tls12_record_aad(sequence, content_type, plaintext.len())?;
2407 let (ciphertext, tag) =
2408 Self::noxtls_aead_encrypt_for_suite(suite, &key, &nonce, &aad, plaintext)?;
2409 let record = ProtectedRecord {
2410 sequence,
2411 ciphertext,
2412 tag,
2413 };
2414 self.client_sequence = self.client_sequence.wrapping_add(1);
2415 self.noxtls_encode_tls12_record_packet(&record, content_type, &explicit_nonce)
2416 }
2417
2418 pub fn noxtls_open_tls12_record_packet(
2434 &mut self,
2435 packet: &[u8],
2436 ) -> Result<(RecordContentType, Vec<u8>)> {
2437 self.noxtls_ensure_tls12_wire_mode()?;
2438 if self.state != HandshakeState::Finished {
2439 return Err(Error::StateError(
2440 "cannot open tls12 record packet before handshake completion",
2441 ));
2442 }
2443 let sequence = self.server_sequence;
2444 let suite = self.noxtls_selected_cipher_suite.ok_or(Error::StateError(
2445 "cipher suite must be selected before opening tls12 record packet",
2446 ))?;
2447 if suite.noxtls_tls12_chacha20_poly1305_key_len().is_some() {
2448 let (content_type_u8, version, payload) =
2449 noxtls_decode_tls12_ciphertext_record(packet)?;
2450 let strict_version = noxtls_legacy_wire_version(self.version);
2451 let legacy_compat_ok = self.tls12_allow_legacy_record_versions
2452 && (version == [0x03, 0x01] || version == [0x03, 0x02]);
2453 if version != strict_version && !legacy_compat_ok {
2454 return Err(Error::ParseFailure(
2455 "tls12 record has invalid legacy version",
2456 ));
2457 }
2458 let content_type = RecordContentType::from_u8(content_type_u8)
2459 .ok_or(Error::ParseFailure("unknown tls12 record content type"))?;
2460 if payload.len() < 16 {
2461 return Err(Error::ParseFailure(
2462 "tls12 chacha20-poly1305 record payload too short",
2463 ));
2464 }
2465 let tag_offset = payload.len() - 16;
2466 let ciphertext = &payload[..tag_offset];
2467 let mut tag = [0_u8; 16];
2468 tag.copy_from_slice(&payload[tag_offset..]);
2469 let key = self
2470 .server_write_key
2471 .ok_or(Error::StateError("server write key is not installed"))?;
2472 let iv = self
2473 .server_write_iv
2474 .ok_or(Error::StateError("server write iv is not installed"))?;
2475 let nonce = Self::noxtls_build_tls12_chacha20_poly1305_nonce(&iv, sequence);
2476 let aad =
2477 self.noxtls_build_tls12_record_aad(sequence, content_type, ciphertext.len())?;
2478 let plaintext = noxtls_chacha20_poly1305_decrypt(&key, &nonce, &aad, ciphertext, &tag)?;
2479 if plaintext.len() > self.max_record_plaintext_len {
2480 return Err(Error::InvalidLength(
2481 "record plaintext exceeds configured limit",
2482 ));
2483 }
2484 self.server_sequence = self.server_sequence.wrapping_add(1);
2485 return Ok((content_type, plaintext));
2486 }
2487 let (record, content_type, explicit_nonce) =
2488 self.noxtls_decode_tls12_record_packet(packet, sequence)?;
2489 let suite = self.noxtls_selected_cipher_suite.ok_or(Error::StateError(
2490 "cipher suite must be selected before opening tls12 record packet",
2491 ))?;
2492 let key = self
2493 .server_write_key
2494 .ok_or(Error::StateError("server write key is not installed"))?;
2495 let iv = self
2496 .server_write_iv
2497 .ok_or(Error::StateError("server write iv is not installed"))?;
2498 let nonce = Self::noxtls_build_tls12_aead_nonce(&iv, &explicit_nonce);
2499 let aad =
2500 self.noxtls_build_tls12_record_aad(sequence, content_type, record.ciphertext.len())?;
2501 let plaintext = Self::noxtls_aead_decrypt_for_suite(
2502 suite,
2503 &key,
2504 &nonce,
2505 &aad,
2506 &record.ciphertext,
2507 &record.tag,
2508 )?;
2509 if plaintext.len() > self.max_record_plaintext_len {
2510 return Err(Error::InvalidLength(
2511 "record plaintext exceeds configured limit",
2512 ));
2513 }
2514 self.server_sequence = self.server_sequence.wrapping_add(1);
2515 Ok((content_type, plaintext))
2516 }
2517
2518 pub fn noxtls_open_own_tls12_record_packet(
2535 &self,
2536 packet: &[u8],
2537 sequence: u64,
2538 ) -> Result<(RecordContentType, Vec<u8>)> {
2539 self.noxtls_ensure_tls12_wire_mode()?;
2540 let suite = self.noxtls_selected_cipher_suite.ok_or(Error::StateError(
2541 "cipher suite must be selected before opening own tls12 record packet",
2542 ))?;
2543 if suite.noxtls_tls12_chacha20_poly1305_key_len().is_some() {
2544 let (content_type_u8, version, payload) =
2545 noxtls_decode_tls12_ciphertext_record(packet)?;
2546 let strict_version = noxtls_legacy_wire_version(self.version);
2547 let legacy_compat_ok = self.tls12_allow_legacy_record_versions
2548 && (version == [0x03, 0x01] || version == [0x03, 0x02]);
2549 if version != strict_version && !legacy_compat_ok {
2550 return Err(Error::ParseFailure(
2551 "tls12 record has invalid legacy version",
2552 ));
2553 }
2554 let content_type = RecordContentType::from_u8(content_type_u8)
2555 .ok_or(Error::ParseFailure("unknown tls12 record content type"))?;
2556 if payload.len() < 16 {
2557 return Err(Error::ParseFailure(
2558 "tls12 chacha20-poly1305 record payload too short",
2559 ));
2560 }
2561 let tag_offset = payload.len() - 16;
2562 let ciphertext = &payload[..tag_offset];
2563 let mut tag = [0_u8; 16];
2564 tag.copy_from_slice(&payload[tag_offset..]);
2565 let key = self
2566 .client_write_key
2567 .ok_or(Error::StateError("client write key is not installed"))?;
2568 let iv = self
2569 .client_write_iv
2570 .ok_or(Error::StateError("client write iv is not installed"))?;
2571 let nonce = Self::noxtls_build_tls12_chacha20_poly1305_nonce(&iv, sequence);
2572 let aad =
2573 self.noxtls_build_tls12_record_aad(sequence, content_type, ciphertext.len())?;
2574 let plaintext = noxtls_chacha20_poly1305_decrypt(&key, &nonce, &aad, ciphertext, &tag)?;
2575 if plaintext.len() > self.max_record_plaintext_len {
2576 return Err(Error::InvalidLength(
2577 "record plaintext exceeds configured limit",
2578 ));
2579 }
2580 return Ok((content_type, plaintext));
2581 }
2582 let (record, content_type, explicit_nonce) =
2583 self.noxtls_decode_tls12_record_packet(packet, sequence)?;
2584 let key = self
2585 .client_write_key
2586 .ok_or(Error::StateError("client write key is not installed"))?;
2587 let iv = self
2588 .client_write_iv
2589 .ok_or(Error::StateError("client write iv is not installed"))?;
2590 let nonce = Self::noxtls_build_tls12_aead_nonce(&iv, &explicit_nonce);
2591 let aad =
2592 self.noxtls_build_tls12_record_aad(sequence, content_type, record.ciphertext.len())?;
2593 let plaintext = Self::noxtls_aead_decrypt_for_suite(
2594 suite,
2595 &key,
2596 &nonce,
2597 &aad,
2598 &record.ciphertext,
2599 &record.tag,
2600 )?;
2601 if plaintext.len() > self.max_record_plaintext_len {
2602 return Err(Error::InvalidLength(
2603 "record plaintext exceeds configured limit",
2604 ));
2605 }
2606 Ok((content_type, plaintext))
2607 }
2608
2609 pub fn noxtls_send_tls12_alert_packet(
2626 &mut self,
2627 level: AlertLevel,
2628 description: AlertDescription,
2629 ) -> Result<Vec<u8>> {
2630 if self.version != TlsVersion::Tls12 {
2631 return Err(Error::StateError(
2632 "tls12 alert records require TLS 1.2 connection",
2633 ));
2634 }
2635 self.noxtls_seal_tls12_record_packet(
2636 &[level.to_u8(), description.to_u8()],
2637 RecordContentType::Alert,
2638 )
2639 }
2640
2641 pub fn noxtls_send_tls12_alert_for_handshake_error(
2657 &mut self,
2658 error: &Error,
2659 ) -> Result<Vec<u8>> {
2660 let (level, description) = Self::noxtls_tls12_alert_for_handshake_error(error);
2661 self.noxtls_send_tls12_alert_packet(level, description)
2662 }
2663
2664 pub fn noxtls_recv_tls12_alert_packet(
2680 &mut self,
2681 packet: &[u8],
2682 ) -> Result<(AlertLevel, AlertDescription)> {
2683 let (content_type, payload) = self.noxtls_open_tls12_record_packet(packet)?;
2684 self.noxtls_parse_tls12_alert_payload(content_type, &payload)
2685 }
2686
2687 pub fn noxtls_recv_own_tls12_alert_packet(
2704 &self,
2705 packet: &[u8],
2706 sequence: u64,
2707 ) -> Result<(AlertLevel, AlertDescription)> {
2708 let (content_type, payload) = self.noxtls_open_own_tls12_record_packet(packet, sequence)?;
2709 self.noxtls_parse_tls12_alert_payload(content_type, &payload)
2710 }
2711
2712 pub fn noxtls_seal_record_fragments(
2730 &mut self,
2731 plaintext: &[u8],
2732 aad: &[u8],
2733 fragment_len: usize,
2734 ) -> Result<Vec<ProtectedRecord>> {
2735 if fragment_len == 0 {
2736 return Err(Error::InvalidLength(
2737 "fragment length must be greater than zero",
2738 ));
2739 }
2740 if fragment_len > self.max_record_plaintext_len {
2741 return Err(Error::InvalidLength(
2742 "fragment length exceeds configured record plaintext limit",
2743 ));
2744 }
2745 if plaintext.is_empty() {
2746 return Ok(Vec::new());
2747 }
2748 let fragment_count = plaintext.len().div_ceil(fragment_len);
2749 let required_sequences = u64::try_from(fragment_count)
2750 .map_err(|_| Error::InvalidLength("too many record fragments requested"))?;
2751 let highest_sequence = self
2752 .client_sequence
2753 .checked_add(required_sequences.saturating_sub(1));
2754 if highest_sequence.is_none() {
2755 return Err(Error::StateError(
2756 "insufficient record sequence space for all fragments",
2757 ));
2758 }
2759
2760 let mut out = Vec::with_capacity(fragment_count);
2761 let mut offset = 0_usize;
2762 while offset < plaintext.len() {
2763 let end = (offset + fragment_len).min(plaintext.len());
2764 out.push(self.noxtls_seal_record(&plaintext[offset..end], aad)?);
2765 offset = end;
2766 }
2767 Ok(out)
2768 }
2769
2770 pub fn noxtls_open_record_fragments(
2787 &mut self,
2788 records: &[ProtectedRecord],
2789 aad: &[u8],
2790 ) -> Result<Vec<u8>> {
2791 if records.is_empty() {
2792 return Ok(Vec::new());
2793 }
2794 let base_sequence = self.server_sequence;
2795 for (index, record) in records.iter().enumerate() {
2796 let expected_sequence = base_sequence
2797 .checked_add(index as u64)
2798 .ok_or(Error::ParseFailure("record fragment sequence overflow"))?;
2799 if record.sequence != expected_sequence {
2800 return Err(Error::ParseFailure(
2801 "record fragments must be contiguous sequences",
2802 ));
2803 }
2804 }
2805 let mut out = Vec::new();
2806 for record in records {
2807 out.extend_from_slice(&self.noxtls_open_record(record, aad)?);
2808 }
2809 Ok(out)
2810 }
2811
2812 pub fn noxtls_open_own_record_fragments(
2829 &self,
2830 records: &[ProtectedRecord],
2831 aad: &[u8],
2832 ) -> Result<Vec<u8>> {
2833 if records.is_empty() {
2834 return Ok(Vec::new());
2835 }
2836 let base_sequence = records[0].sequence;
2837 for (index, record) in records.iter().enumerate() {
2838 let expected_sequence = base_sequence
2839 .checked_add(index as u64)
2840 .ok_or(Error::ParseFailure("record fragment sequence overflow"))?;
2841 if record.sequence != expected_sequence {
2842 return Err(Error::ParseFailure(
2843 "record fragments must be contiguous sequences",
2844 ));
2845 }
2846 }
2847 let mut out = Vec::new();
2848 for record in records {
2849 out.extend_from_slice(&self.noxtls_open_own_record(record, aad)?);
2850 }
2851 Ok(out)
2852 }
2853
2854 pub fn noxtls_seal_tls13_inner_record(
2873 &mut self,
2874 content: &[u8],
2875 content_type: u8,
2876 aad: &[u8],
2877 padding_len: usize,
2878 ) -> Result<ProtectedRecord> {
2879 if !self.version.uses_tls13_handshake_semantics() {
2880 return Err(Error::StateError(
2881 "tls13 inner plaintext records require TLS 1.3 connection",
2882 ));
2883 }
2884 let inner = noxtls_encode_tls13_inner_plaintext(content, content_type, padding_len);
2885 self.noxtls_seal_record(&inner, aad)
2886 }
2887
2888 pub fn noxtls_open_tls13_inner_record(
2905 &mut self,
2906 record: &ProtectedRecord,
2907 aad: &[u8],
2908 ) -> Result<(Vec<u8>, u8)> {
2909 if !self.version.uses_tls13_handshake_semantics() {
2910 return Err(Error::StateError(
2911 "tls13 inner plaintext records require TLS 1.3 connection",
2912 ));
2913 }
2914 let inner = self.noxtls_open_record(record, aad)?;
2915 noxtls_decode_tls13_inner_plaintext(&inner)
2916 }
2917
2918 pub fn noxtls_open_own_tls13_inner_record(
2935 &self,
2936 record: &ProtectedRecord,
2937 aad: &[u8],
2938 ) -> Result<(Vec<u8>, u8)> {
2939 if !self.version.uses_tls13_handshake_semantics() {
2940 return Err(Error::StateError(
2941 "tls13 inner plaintext records require TLS 1.3 connection",
2942 ));
2943 }
2944 let inner = self.noxtls_open_own_record(record, aad)?;
2945 noxtls_decode_tls13_inner_plaintext(&inner)
2946 }
2947
2948 pub fn noxtls_seal_tls13_record_packet(
2967 &mut self,
2968 content: &[u8],
2969 content_type: u8,
2970 aad: &[u8],
2971 padding_len: usize,
2972 ) -> Result<Vec<u8>> {
2973 if !self.version.uses_tls13_handshake_semantics() {
2974 return Err(Error::StateError(
2975 "tls13 record packets require TLS 1.3 connection",
2976 ));
2977 }
2978 let record =
2979 self.noxtls_seal_tls13_inner_record(content, content_type, aad, padding_len)?;
2980 self.noxtls_encode_tls13_record_packet(&record)
2981 }
2982
2983 pub fn noxtls_open_tls13_record_packet(
3000 &mut self,
3001 packet: &[u8],
3002 aad: &[u8],
3003 ) -> Result<(Vec<u8>, u8)> {
3004 if !self.version.uses_tls13_handshake_semantics() {
3005 return Err(Error::StateError(
3006 "tls13 record packets require TLS 1.3 connection",
3007 ));
3008 }
3009 let record = self.noxtls_decode_tls13_record_packet(packet, self.server_sequence)?;
3010 match self.noxtls_open_tls13_inner_record(&record, aad) {
3011 Ok(inner) => Ok(inner),
3012 Err(error) => {
3013 noxtls_tls13_debug_log("tls13.open_record.error", "failed to decrypt record");
3014 noxtls_tls13_debug_log_bytes("tls13.open_record.aad", aad);
3015 noxtls_tls13_debug_log_bytes("tls13.open_record.ciphertext", &record.ciphertext);
3016 noxtls_tls13_debug_log_bytes("tls13.open_record.tag", &record.tag);
3017 if let Some(key) = self.server_write_key.as_ref() {
3018 noxtls_tls13_debug_log_bytes("tls13.open_record.server_write_key", key);
3019 }
3020 if let Some(iv) = self.server_write_iv.as_ref() {
3021 noxtls_tls13_debug_log_bytes("tls13.open_record.server_write_iv", iv);
3022 }
3023 self.noxtls_debug_probe_tls13_open_record_failure(&record, aad);
3024 Err(error)
3025 }
3026 }
3027 }
3028
3029 pub fn noxtls_open_own_tls13_record_packet(
3047 &self,
3048 packet: &[u8],
3049 sequence: u64,
3050 aad: &[u8],
3051 ) -> Result<(Vec<u8>, u8)> {
3052 if !self.version.uses_tls13_handshake_semantics() {
3053 return Err(Error::StateError(
3054 "tls13 record packets require TLS 1.3 connection",
3055 ));
3056 }
3057 let record = self.noxtls_decode_tls13_record_packet(packet, sequence)?;
3058 self.noxtls_open_own_tls13_inner_record(&record, aad)
3059 }
3060
3061 pub fn noxtls_send_tls13_alert(
3079 &mut self,
3080 level: AlertLevel,
3081 description: AlertDescription,
3082 aad: &[u8],
3083 ) -> Result<ProtectedRecord> {
3084 if !self.version.uses_tls13_handshake_semantics() {
3085 return Err(Error::StateError(
3086 "tls13 alert records require TLS 1.3 connection",
3087 ));
3088 }
3089 let payload = [level.to_u8(), description.to_u8()];
3090 let record = self.noxtls_seal_tls13_inner_record(
3091 &payload,
3092 RecordContentType::Alert.to_u8(),
3093 aad,
3094 0,
3095 )?;
3096 self.noxtls_apply_tls13_alert_effects(level, description, true);
3097 Ok(record)
3098 }
3099
3100 pub fn noxtls_send_tls13_alert_packet(
3118 &mut self,
3119 level: AlertLevel,
3120 description: AlertDescription,
3121 aad: &[u8],
3122 ) -> Result<Vec<u8>> {
3123 if !self.version.uses_tls13_handshake_semantics() {
3124 return Err(Error::StateError(
3125 "tls13 alert records require TLS 1.3 connection",
3126 ));
3127 }
3128 let record = self.noxtls_send_tls13_alert(level, description, aad)?;
3129 self.noxtls_encode_tls13_record_packet(&record)
3130 }
3131
3132 pub fn noxtls_recv_tls13_alert(
3149 &mut self,
3150 record: &ProtectedRecord,
3151 aad: &[u8],
3152 ) -> Result<(AlertLevel, AlertDescription)> {
3153 if !self.version.uses_tls13_handshake_semantics() {
3154 return Err(Error::StateError(
3155 "tls13 alert records require TLS 1.3 connection",
3156 ));
3157 }
3158 let (payload, content_type) = self.noxtls_open_tls13_inner_record(record, aad)?;
3159 self.noxtls_process_parsed_tls13_alert(payload, content_type)
3160 }
3161
3162 pub fn noxtls_recv_own_tls13_alert(
3179 &mut self,
3180 record: &ProtectedRecord,
3181 aad: &[u8],
3182 ) -> Result<(AlertLevel, AlertDescription)> {
3183 if !self.version.uses_tls13_handshake_semantics() {
3184 return Err(Error::StateError(
3185 "tls13 alert records require TLS 1.3 connection",
3186 ));
3187 }
3188 let (payload, content_type) = self.noxtls_open_own_tls13_inner_record(record, aad)?;
3189 self.noxtls_process_parsed_tls13_alert(payload, content_type)
3190 }
3191
3192 pub fn noxtls_recv_tls13_alert_packet(
3209 &mut self,
3210 packet: &[u8],
3211 aad: &[u8],
3212 ) -> Result<(AlertLevel, AlertDescription)> {
3213 if !self.version.uses_tls13_handshake_semantics() {
3214 return Err(Error::StateError(
3215 "tls13 alert records require TLS 1.3 connection",
3216 ));
3217 }
3218 let (payload, content_type) = self.noxtls_open_tls13_record_packet(packet, aad)?;
3219 self.noxtls_process_parsed_tls13_alert(payload, content_type)
3220 }
3221
3222 pub fn noxtls_recv_own_tls13_alert_packet(
3240 &mut self,
3241 packet: &[u8],
3242 sequence: u64,
3243 aad: &[u8],
3244 ) -> Result<(AlertLevel, AlertDescription)> {
3245 if !self.version.uses_tls13_handshake_semantics() {
3246 return Err(Error::StateError(
3247 "tls13 alert records require TLS 1.3 connection",
3248 ));
3249 }
3250 let (payload, content_type) =
3251 self.noxtls_open_own_tls13_record_packet(packet, sequence, aad)?;
3252 self.noxtls_process_parsed_tls13_alert(payload, content_type)
3253 }
3254
3255 fn noxtls_process_parsed_tls13_alert(
3276 &mut self,
3277 payload: Vec<u8>,
3278 content_type: u8,
3279 ) -> Result<(AlertLevel, AlertDescription)> {
3280 if RecordContentType::from_u8(content_type) != Some(RecordContentType::Alert) {
3281 return Err(Error::ParseFailure("record is not an alert content type"));
3282 }
3283 if payload.len() != 2 {
3284 return Err(Error::ParseFailure("tls13 alert payload must be two bytes"));
3285 }
3286 let level =
3287 AlertLevel::from_u8(payload[0]).ok_or(Error::ParseFailure("unknown alert level"))?;
3288 let description = AlertDescription::from_u8(payload[1])
3289 .ok_or(Error::ParseFailure("unknown alert description"))?;
3290 self.noxtls_apply_tls13_alert_effects(level, description, false);
3291 Ok((level, description))
3292 }
3293
3294 fn noxtls_apply_tls13_alert_effects(
3308 &mut self,
3309 level: AlertLevel,
3310 description: AlertDescription,
3311 from_local_send: bool,
3312 ) {
3313 if description == AlertDescription::CloseNotify {
3314 if from_local_send {
3315 self.noxtls_tls13_local_close_notify_sent = true;
3316 } else {
3317 self.noxtls_tls13_peer_close_notify_received = true;
3318 }
3319 }
3320 if level == AlertLevel::Fatal {
3321 self.state = HandshakeState::Idle;
3322 }
3323 }
3324
3325 #[must_use]
3327 pub fn noxtls_tls13_peer_close_notify_received(&self) -> bool {
3340 self.noxtls_tls13_peer_close_notify_received
3341 }
3342
3343 #[must_use]
3345 pub fn noxtls_tls13_local_close_notify_sent(&self) -> bool {
3358 self.noxtls_tls13_local_close_notify_sent
3359 }
3360
3361 fn noxtls_reset_tls13_certificate_auth_state(&mut self) {
3372 self.tls13_server_leaf_public_key_der = None;
3373 self.tls13_server_certificate_chain_validated = false;
3374 self.tls13_negotiated_server_certificate_type = TLS_CERTIFICATE_TYPE_X509;
3375 self.noxtls_tls13_server_name_acknowledged = false;
3376 self.noxtls_tls13_selected_alpn_protocol = None;
3377 self.noxtls_tls13_server_ocsp_staple = None;
3378 self.noxtls_tls13_server_ocsp_staple_verified = false;
3379 }
3380
3381 fn noxtls_validate_tls13_server_raw_public_key(&mut self, spki_der: &[u8]) -> Result<()> {
3401 let expected = self
3402 .tls13_expected_server_raw_public_key_der
3403 .as_deref()
3404 .ok_or(Error::StateError(
3405 "expected tls13 server raw public key is not configured",
3406 ))?;
3407 if expected != spki_der {
3408 return Err(Error::CryptoFailure(
3409 "server raw public key validation failed",
3410 ));
3411 }
3412 let spki = noxtls_parse_spki_public_key_info_der(spki_der)?;
3413 self.tls13_server_leaf_public_key_der = Some(spki.subject_public_key);
3414 self.tls13_server_certificate_chain_validated = true;
3415 Ok(())
3416 }
3417
3418 fn noxtls_validate_tls13_server_certificate_chain(
3419 &mut self,
3420 certificates: &[Vec<u8>],
3421 ) -> Result<()> {
3422 if certificates.is_empty() {
3423 return Err(Error::ParseFailure(
3424 "certificate list must include leaf certificate",
3425 ));
3426 }
3427 if self.tls13_server_trust_anchors_der.is_empty() {
3428 return Err(Error::StateError(
3429 "tls13 server trust anchors are not configured",
3430 ));
3431 }
3432 let validation_time =
3433 self.tls13_server_validation_time
3434 .as_deref()
3435 .ok_or(Error::StateError(
3436 "tls13 server validation time is not configured",
3437 ))?;
3438 let leaf = noxtls_parse_certificate(&certificates[0])?;
3439 if let Some(expected_hostname) = self.tls13_server_expected_hostname.as_deref() {
3440 if !noxtls_certificate_matches_hostname(&leaf, expected_hostname) {
3441 return Err(Error::CryptoFailure(
3442 "server certificate hostname validation failed",
3443 ));
3444 }
3445 }
3446
3447 let mut parsed_intermediates = Vec::new();
3448 for der in &certificates[1..] {
3449 let parsed = noxtls_parse_certificate(der)?;
3450 parsed_intermediates.push(parsed);
3451 }
3452 for der in &self.tls13_server_intermediates_der {
3453 let parsed = noxtls_parse_certificate(der)?;
3454 parsed_intermediates.push(parsed);
3455 }
3456
3457 let mut parsed_anchors = Vec::new();
3458 for der in &self.tls13_server_trust_anchors_der {
3459 let parsed = noxtls_parse_certificate(der)?;
3460 parsed_anchors.push(parsed);
3461 }
3462
3463 noxtls_validate_certificate_chain(
3464 &leaf,
3465 &parsed_intermediates,
3466 &parsed_anchors,
3467 validation_time,
3468 )
3469 .map_err(noxtls_map_certificate_validation_error)?;
3470 self.tls13_server_leaf_public_key_der = Some(leaf.subject_public_key.clone());
3471 self.tls13_server_certificate_chain_validated = true;
3472 Ok(())
3473 }
3474
3475 fn noxtls_verify_tls13_server_certificate_verify_signature(
3496 &self,
3497 signature_scheme: u16,
3498 signature: &[u8],
3499 ) -> Result<()> {
3500 let leaf_spki =
3501 self.tls13_server_leaf_public_key_der
3502 .as_deref()
3503 .ok_or(Error::StateError(
3504 "server leaf public key is unavailable for certificate verify",
3505 ))?;
3506 let signed_message =
3507 noxtls_build_tls13_server_certificate_verify_message(&self.noxtls_transcript_hash());
3508 match signature_scheme {
3509 TLS13_SIGALG_ECDSA_SECP256R1_SHA256 => {
3510 let public_key = P256PublicKey::from_uncompressed(leaf_spki)?;
3511 let (r, s) = if signature.len() == 64 {
3512 let mut r = [0_u8; 32];
3513 let mut s = [0_u8; 32];
3514 r.copy_from_slice(&signature[..32]);
3515 s.copy_from_slice(&signature[32..]);
3516 (r, s)
3517 } else {
3518 noxtls_parse_ecdsa_signature_der(signature)?
3519 };
3520 noxtls_p256_ecdsa_verify_sha256(&public_key, &signed_message, &r, &s).map_err(
3521 |_| {
3522 Error::CryptoFailure("tls13 certificate verify signature validation failed")
3523 },
3524 )
3525 }
3526 TLS13_SIGALG_ECDSA_SECP384R1_SHA384 => {
3527 let public_key = P384PublicKey::from_uncompressed(leaf_spki)
3528 .map_err(|_| Error::ParseFailure("failed to parse p384 server public key"))?;
3529 let (r, s) = noxtls_parse_ecdsa_p384_signature_der(signature)
3530 .map_err(|_| Error::ParseFailure("failed to parse p384 ecdsa signature"))?;
3531 noxtls_p384_ecdsa_verify_sha384(&public_key, &signed_message, &r, &s).map_err(
3532 |_| {
3533 Error::CryptoFailure("tls13 certificate verify signature validation failed")
3534 },
3535 )
3536 }
3537 TLS13_SIGALG_RSA_PSS_RSAE_SHA256 | TLS13_SIGALG_RSA_PSS_PSS_SHA256 => {
3538 let public_key = noxtls_parse_rsa_public_key_der(leaf_spki)?;
3539 noxtls_rsassa_pss_sha256_verify(&public_key, &signed_message, signature, 32)
3540 .map_err(|_| {
3541 Error::CryptoFailure("tls13 certificate verify signature validation failed")
3542 })
3543 }
3544 TLS13_SIGALG_RSA_PSS_RSAE_SHA384 | TLS13_SIGALG_RSA_PSS_PSS_SHA384 => {
3545 let public_key = noxtls_parse_rsa_public_key_der(leaf_spki)?;
3546 noxtls_rsassa_pss_sha384_verify(&public_key, &signed_message, signature, 48)
3547 .map_err(|_| {
3548 Error::CryptoFailure("tls13 certificate verify signature validation failed")
3549 })
3550 }
3551 TLS13_SIGALG_RSA_PSS_RSAE_SHA512 | TLS13_SIGALG_RSA_PSS_PSS_SHA512 => {
3552 let public_key = noxtls_parse_rsa_public_key_der(leaf_spki)?;
3553 noxtls_rsassa_pss_verify(
3554 &public_key,
3555 &signed_message,
3556 signature,
3557 RsaPssHashAlgorithm::Sha512,
3558 RsaPssHashAlgorithm::Sha512,
3559 64,
3560 )
3561 .map_err(|_| {
3562 Error::CryptoFailure("tls13 certificate verify signature validation failed")
3563 })
3564 }
3565 TLS13_SIGALG_ED25519 => {
3566 let public_key = noxtls_ed25519_public_key_from_subject_public_key_info(leaf_spki)?;
3567 noxtls_ed25519_verify(&public_key, &signed_message, signature).map_err(|_| {
3568 Error::CryptoFailure("tls13 certificate verify signature validation failed")
3569 })
3570 }
3571 TLS13_SIGALG_MLDSA65 => {
3572 let public_key = MlDsaPublicKey::from_bytes(leaf_spki).map_err(|_| {
3573 Error::ParseFailure("failed to parse mldsa server public key bytes")
3574 })?;
3575 noxtls_mldsa_verify(&public_key, &signed_message, signature).map_err(|_| {
3576 Error::CryptoFailure("tls13 certificate verify signature validation failed")
3577 })
3578 }
3579 _ => Err(Error::UnsupportedFeature(
3580 "unsupported tls13 certificate verify signature scheme",
3581 )),
3582 }
3583 }
3584
3585 pub fn noxtls_set_record_sequences_for_test(
3597 &mut self,
3598 client_sequence: u64,
3599 server_sequence: u64,
3600 ) {
3601 self.client_sequence = client_sequence;
3602 self.server_sequence = server_sequence;
3603 }
3604
3605 pub fn noxtls_set_tls13_certificate_verify_material_for_test(
3616 &mut self,
3617 leaf_spki_der: Vec<u8>,
3618 ) {
3619 self.tls13_server_leaf_public_key_der = Some(leaf_spki_der);
3620 self.tls13_server_certificate_chain_validated = true;
3621 }
3622
3623 pub fn noxtls_tls13_server_certificate_verify_message_for_test(&self) -> Vec<u8> {
3637 noxtls_build_tls13_server_certificate_verify_message(&self.noxtls_transcript_hash())
3638 }
3639
3640 fn noxtls_debug_probe_tls13_open_record_failure(&self, record: &ProtectedRecord, aad: &[u8]) {
3655 if !noxtls_tls13_debug_enabled() {
3656 return;
3657 }
3658 let Some(suite) = self.noxtls_selected_cipher_suite else {
3659 return;
3660 };
3661 let Some(key_len) = suite.noxtls_tls13_traffic_key_len() else {
3662 return;
3663 };
3664 let probe_key = |label: &str, key: &[u8; 32], iv: &[u8; 12], seq: u64| {
3665 let nonce = noxtls_build_record_nonce(iv, seq);
3666 let status = match AesCipher::noxtls_new(&key[..key_len]) {
3667 Ok(cipher) => {
3668 noxtls_aes_gcm_decrypt(&cipher, &nonce, aad, &record.ciphertext, &record.tag)
3669 .is_ok()
3670 }
3671 Err(_) => false,
3672 };
3673 if status {
3674 noxtls_tls13_debug_log(label, "success");
3675 } else {
3676 noxtls_tls13_debug_log(label, "fail");
3677 }
3678 };
3679 if let (Some(key), Some(iv)) = (
3680 self.server_write_key.as_ref(),
3681 self.server_write_iv.as_ref(),
3682 ) {
3683 probe_key(
3684 "tls13.open_record.probe.server_seq+1",
3685 key,
3686 iv,
3687 record.sequence.saturating_add(1),
3688 );
3689 probe_key(
3690 "tls13.open_record.probe.server_seq+2",
3691 key,
3692 iv,
3693 record.sequence.saturating_add(2),
3694 );
3695 let mut nonce_first8_be = *iv;
3696 for (idx, byte) in record.sequence.to_be_bytes().iter().enumerate() {
3697 nonce_first8_be[idx] ^= *byte;
3698 }
3699 let first8_be_ok = match AesCipher::noxtls_new(&key[..key_len]) {
3700 Ok(cipher) => noxtls_aes_gcm_decrypt(
3701 &cipher,
3702 &nonce_first8_be,
3703 aad,
3704 &record.ciphertext,
3705 &record.tag,
3706 )
3707 .is_ok(),
3708 Err(_) => false,
3709 };
3710 noxtls_tls13_debug_log(
3711 "tls13.open_record.probe.server_nonce_first8_be",
3712 if first8_be_ok { "success" } else { "fail" },
3713 );
3714 let mut nonce_last8_le = *iv;
3715 for (idx, byte) in record.sequence.to_le_bytes().iter().enumerate() {
3716 nonce_last8_le[4 + idx] ^= *byte;
3717 }
3718 let last8_le_ok = match AesCipher::noxtls_new(&key[..key_len]) {
3719 Ok(cipher) => noxtls_aes_gcm_decrypt(
3720 &cipher,
3721 &nonce_last8_le,
3722 aad,
3723 &record.ciphertext,
3724 &record.tag,
3725 )
3726 .is_ok(),
3727 Err(_) => false,
3728 };
3729 noxtls_tls13_debug_log(
3730 "tls13.open_record.probe.server_nonce_last8_le",
3731 if last8_le_ok { "success" } else { "fail" },
3732 );
3733 let mut nonce_first8_le = *iv;
3734 for (idx, byte) in record.sequence.to_le_bytes().iter().enumerate() {
3735 nonce_first8_le[idx] ^= *byte;
3736 }
3737 let first8_le_ok = match AesCipher::noxtls_new(&key[..key_len]) {
3738 Ok(cipher) => noxtls_aes_gcm_decrypt(
3739 &cipher,
3740 &nonce_first8_le,
3741 aad,
3742 &record.ciphertext,
3743 &record.tag,
3744 )
3745 .is_ok(),
3746 Err(_) => false,
3747 };
3748 noxtls_tls13_debug_log(
3749 "tls13.open_record.probe.server_nonce_first8_le",
3750 if first8_le_ok { "success" } else { "fail" },
3751 );
3752 }
3753 if let (Some(key), Some(iv)) = (
3754 self.client_write_key.as_ref(),
3755 self.client_write_iv.as_ref(),
3756 ) {
3757 probe_key(
3758 "tls13.open_record.probe.client_seq+0",
3759 key,
3760 iv,
3761 record.sequence,
3762 );
3763 }
3764 }
3765}
3766
3767fn noxtls_extract_first_psk_binder_from_client_hello(client_hello: &[u8]) -> Result<Vec<u8>> {
3786 let info = noxtls_parse_client_hello_info(client_hello)?;
3787 info.extensions
3788 .psk_binders
3789 .first()
3790 .cloned()
3791 .ok_or(Error::ParseFailure(
3792 "client hello missing pre_shared_key binder",
3793 ))
3794}
3795
3796fn noxtls_zero_client_hello_psk_binders(client_hello: &[u8]) -> Result<Vec<u8>> {
3815 let (handshake_type, body) = noxtls_parse_handshake_message(client_hello)?;
3816 if handshake_type != HANDSHAKE_CLIENT_HELLO {
3817 return Err(Error::ParseFailure("invalid client hello type"));
3818 }
3819 if body.len() < 39 {
3820 return Err(Error::ParseFailure("client hello body too short"));
3821 }
3822 let mut out = client_hello.to_vec();
3823 let session_id_len = body[34] as usize;
3824 let suites_len_offset = 35 + session_id_len;
3825 if body.len() < suites_len_offset + 2 {
3826 return Err(Error::ParseFailure(
3827 "client hello missing cipher suites length",
3828 ));
3829 }
3830 let suites_len =
3831 u16::from_be_bytes([body[suites_len_offset], body[suites_len_offset + 1]]) as usize;
3832 let suites_end = suites_len_offset + 2 + suites_len;
3833 if body.len() < suites_end + 3 {
3834 return Err(Error::ParseFailure(
3835 "client hello missing compression methods",
3836 ));
3837 }
3838 let compression_methods_len = body[suites_end] as usize;
3839 let compression_methods_end = suites_end + 1 + compression_methods_len;
3840 if body.len() < compression_methods_end + 2 {
3841 return Err(Error::ParseFailure("client hello missing extension length"));
3842 }
3843 let extensions_len = u16::from_be_bytes([
3844 body[compression_methods_end],
3845 body[compression_methods_end + 1],
3846 ]) as usize;
3847 let extensions_start_in_body = compression_methods_end + 2;
3848 let extensions_end_in_body = extensions_start_in_body + extensions_len;
3849 if body.len() < extensions_end_in_body {
3850 return Err(Error::ParseFailure("client hello extensions truncated"));
3851 }
3852
3853 let body_offset = 4; let mut ext_cursor = extensions_start_in_body;
3855 while ext_cursor < extensions_end_in_body {
3856 if extensions_end_in_body - ext_cursor < 4 {
3857 return Err(Error::ParseFailure(
3858 "client hello extension header truncated",
3859 ));
3860 }
3861 let ext_type = u16::from_be_bytes([body[ext_cursor], body[ext_cursor + 1]]);
3862 let ext_len = u16::from_be_bytes([body[ext_cursor + 2], body[ext_cursor + 3]]) as usize;
3863 let ext_data_start = ext_cursor + 4;
3864 let ext_data_end = ext_data_start + ext_len;
3865 if ext_data_end > extensions_end_in_body {
3866 return Err(Error::ParseFailure("client hello extension truncated"));
3867 }
3868 if ext_type == EXT_PRE_SHARED_KEY {
3869 if ext_len < 4 {
3870 return Err(Error::ParseFailure("pre_shared_key extension too short"));
3871 }
3872 let identities_len =
3873 u16::from_be_bytes([body[ext_data_start], body[ext_data_start + 1]]) as usize;
3874 if ext_len < 2 + identities_len + 2 {
3875 return Err(Error::ParseFailure("pre_shared_key identities truncated"));
3876 }
3877 let binders_len_offset = ext_data_start + 2 + identities_len;
3878 let binders_len =
3879 u16::from_be_bytes([body[binders_len_offset], body[binders_len_offset + 1]])
3880 as usize;
3881 let mut binder_cursor = binders_len_offset + 2;
3882 let binders_end = binder_cursor + binders_len;
3883 if binders_end != ext_data_end {
3884 return Err(Error::ParseFailure(
3885 "invalid pre_shared_key binder vector length",
3886 ));
3887 }
3888 while binder_cursor < binders_end {
3889 let binder_len = body[binder_cursor] as usize;
3890 binder_cursor += 1;
3891 if binder_cursor + binder_len > binders_end {
3892 return Err(Error::ParseFailure("pre_shared_key binder bytes truncated"));
3893 }
3894 let start = body_offset + binder_cursor;
3895 let end = start + binder_len;
3896 out[start..end].fill(0);
3897 binder_cursor += binder_len;
3898 }
3899 return Ok(out);
3900 }
3901 ext_cursor = ext_data_end;
3902 }
3903
3904 Err(Error::ParseFailure(
3905 "client hello missing pre_shared_key extension",
3906 ))
3907}
3908
3909fn noxtls_default_client_cipher_suites(version: TlsVersion) -> Vec<CipherSuite> {
3924 match version {
3925 TlsVersion::Tls13 | TlsVersion::Dtls13 => vec![
3926 CipherSuite::TlsAes256GcmSha384,
3927 CipherSuite::TlsAes128GcmSha256,
3928 CipherSuite::TlsChacha20Poly1305Sha256,
3929 ],
3930 TlsVersion::Tls10 | TlsVersion::Tls11 | TlsVersion::Tls12 | TlsVersion::Dtls12 => {
3931 vec![
3932 CipherSuite::TlsEcdheEcdsaWithAes128GcmSha256,
3933 CipherSuite::TlsEcdheEcdsaWithAes256GcmSha384,
3934 CipherSuite::TlsEcdheEcdsaWithChacha20Poly1305Sha256,
3935 CipherSuite::TlsEcdheRsaWithAes128GcmSha256,
3936 CipherSuite::TlsEcdheRsaWithAes256GcmSha384,
3937 CipherSuite::TlsEcdheRsaWithChacha20Poly1305Sha256,
3938 CipherSuite::TlsDheRsaWithChacha20Poly1305Sha256,
3939 CipherSuite::TlsDheRsaWithAes128GcmSha256,
3940 CipherSuite::TlsDheRsaWithAes256GcmSha384,
3941 CipherSuite::TlsEcdheEcdsaWithAes128CcmSha256,
3942 CipherSuite::TlsEcdheEcdsaWithAes256CcmSha256,
3943 CipherSuite::TlsEcdheEcdsaWithAes128Ccm8Sha256,
3944 CipherSuite::TlsEcdheEcdsaWithAes256Ccm8Sha256,
3945 CipherSuite::TlsRsaWithAes128CcmSha256,
3946 CipherSuite::TlsRsaWithAes256CcmSha256,
3947 CipherSuite::TlsRsaWithAes128Ccm8Sha256,
3948 CipherSuite::TlsRsaWithAes256Ccm8Sha256,
3949 CipherSuite::TlsDheRsaWithAes128CcmSha256,
3950 CipherSuite::TlsDheRsaWithAes256CcmSha256,
3951 CipherSuite::TlsDheRsaWithAes128Ccm8Sha256,
3952 CipherSuite::TlsDheRsaWithAes256Ccm8Sha256,
3953 ]
3954 }
3955 }
3956}
3957
3958#[allow(clippy::too_many_arguments)]
3983fn noxtls_encode_client_hello_body(
3984 version: TlsVersion,
3985 random: &[u8],
3986 suites: &[CipherSuite],
3987 key_shares: &Tls13ClientPublicKeyShares,
3988 sni_server_name: Option<&str>,
3989 alpn_protocols: &[Vec<u8>],
3990 request_ocsp_stapling: bool,
3991 offer_mldsa_signature: bool,
3992 offer_early_data: bool,
3993 psk_offer: Option<&PskClientOffer<'_>>,
3994 offer_raw_public_key: bool,
3995 noxtls_tls12_session_id: Option<&[u8]>,
3996 secure_renegotiation_info: Option<&[u8]>,
3997) -> Result<Vec<u8>> {
3998 if random.len() != 32 {
3999 return Err(Error::InvalidLength("client hello random must be 32 bytes"));
4000 }
4001 if suites.is_empty() {
4002 return Err(Error::InvalidLength(
4003 "client hello suite list must not be empty",
4004 ));
4005 }
4006 let mut body = Vec::new();
4007 body.extend_from_slice(&noxtls_legacy_wire_version(version));
4008 body.extend_from_slice(random);
4009 if version == TlsVersion::Tls12 {
4010 let session_id = noxtls_tls12_session_id.unwrap_or(&[]);
4011 if session_id.len() > 32 {
4012 return Err(Error::InvalidLength(
4013 "tls12 session id must not exceed 32 bytes",
4014 ));
4015 }
4016 body.push(session_id.len() as u8);
4017 body.extend_from_slice(session_id);
4018 } else {
4019 body.push(0x00); }
4021 body.extend_from_slice(&((suites.len() * 2) as u16).to_be_bytes());
4022 for suite in suites {
4023 body.extend_from_slice(&suite.noxtls_to_u16().to_be_bytes());
4024 }
4025 body.extend_from_slice(&[0x01, 0x00]); let extensions = noxtls_build_client_hello_extensions(
4027 version,
4028 key_shares,
4029 sni_server_name,
4030 alpn_protocols,
4031 request_ocsp_stapling,
4032 offer_mldsa_signature,
4033 offer_early_data,
4034 psk_offer,
4035 offer_raw_public_key,
4036 secure_renegotiation_info,
4037 )?;
4038 body.extend_from_slice(&(extensions.len() as u16).to_be_bytes());
4039 body.extend_from_slice(&extensions);
4040 Ok(body)
4041}
4042
4043fn noxtls_encode_server_hello_body(
4064 version: TlsVersion,
4065 suite: CipherSuite,
4066 random: &[u8],
4067) -> Result<Vec<u8>> {
4068 noxtls_encode_server_hello_body_with_key_share(version, suite, random, None, None, None)
4069}
4070
4071fn noxtls_encode_server_hello_body_with_key_share(
4093 version: TlsVersion,
4094 suite: CipherSuite,
4095 random: &[u8],
4096 key_share_override: Option<(u16, &[u8])>,
4097 legacy_session_id_echo: Option<&[u8]>,
4098 secure_renegotiation_info: Option<&[u8]>,
4099) -> Result<Vec<u8>> {
4100 if random.len() != 32 {
4101 return Err(Error::InvalidLength("server hello random must be 32 bytes"));
4102 }
4103 let mut body = Vec::new();
4104 body.extend_from_slice(&noxtls_legacy_wire_version(version));
4105 body.extend_from_slice(random);
4106 let session_id = legacy_session_id_echo.unwrap_or(&[]);
4107 if session_id.len() > 32 {
4108 return Err(Error::InvalidLength(
4109 "server hello session_id echo must not exceed 32 bytes",
4110 ));
4111 }
4112 body.push(session_id.len() as u8);
4113 body.extend_from_slice(session_id);
4114 body.extend_from_slice(&suite.noxtls_to_u16().to_be_bytes());
4115 body.push(0x00); let mut extensions = Vec::new();
4117 if version == TlsVersion::Tls12 {
4118 let renegotiation_info = secure_renegotiation_info.unwrap_or(&[]);
4119 if renegotiation_info.len() > u8::MAX as usize {
4120 return Err(Error::InvalidLength(
4121 "renegotiation_info length must not exceed 255 bytes",
4122 ));
4123 }
4124 let mut extension_data = Vec::with_capacity(1 + renegotiation_info.len());
4125 extension_data.push(renegotiation_info.len() as u8);
4126 extension_data.extend_from_slice(renegotiation_info);
4127 noxtls_push_extension(&mut extensions, EXT_RENEGOTIATION_INFO, &extension_data);
4128 }
4129 if version.uses_tls13_handshake_semantics() {
4130 noxtls_push_extension(
4131 &mut extensions,
4132 EXT_SUPPORTED_VERSIONS,
4133 &0x0304_u16.to_be_bytes(),
4134 );
4135 let mut key_share = Vec::new();
4136 if let Some((g, bytes)) = key_share_override {
4137 if g == TLS13_KEY_SHARE_GROUP_X25519 && bytes.len() != 32 {
4138 return Err(Error::ParseFailure(
4139 "invalid x25519 server key_share key_exchange length",
4140 ));
4141 }
4142 if g == TLS13_KEY_SHARE_GROUP_SECP256R1 && bytes.len() != 65 {
4143 return Err(Error::ParseFailure(
4144 "invalid secp256r1 server key_share key_exchange length",
4145 ));
4146 }
4147 if g == TLS13_KEY_SHARE_GROUP_SECP384R1 && bytes.len() != 97 {
4148 return Err(Error::ParseFailure(
4149 "invalid secp384r1 server key_share key_exchange length",
4150 ));
4151 }
4152 if g == TLS13_KEY_SHARE_GROUP_SECP521R1 && bytes.len() != 133 {
4153 return Err(Error::ParseFailure(
4154 "invalid secp521r1 server key_share key_exchange length",
4155 ));
4156 }
4157 if g == TLS13_KEY_SHARE_GROUP_BRAINPOOLP256R1TLS13 && bytes.len() != 65 {
4158 return Err(Error::ParseFailure(
4159 "invalid brainpoolP256r1tls13 server key_share key_exchange length",
4160 ));
4161 }
4162 if g == TLS13_KEY_SHARE_GROUP_BRAINPOOLP384R1TLS13 && bytes.len() != 97 {
4163 return Err(Error::ParseFailure(
4164 "invalid brainpoolP384r1tls13 server key_share key_exchange length",
4165 ));
4166 }
4167 if g == TLS13_KEY_SHARE_GROUP_BRAINPOOLP512R1TLS13 && bytes.len() != 129 {
4168 return Err(Error::ParseFailure(
4169 "invalid brainpoolP512r1tls13 server key_share key_exchange length",
4170 ));
4171 }
4172 if g == TLS13_KEY_SHARE_GROUP_X448 && bytes.len() != 56 {
4173 return Err(Error::ParseFailure(
4174 "invalid x448 server key_share key_exchange length",
4175 ));
4176 }
4177 if g == TLS13_KEY_SHARE_GROUP_MLKEM768 && bytes.len() != MLKEM_CIPHERTEXT_LEN {
4178 return Err(Error::ParseFailure(
4179 "invalid mlkem768 server key_share key_exchange length",
4180 ));
4181 }
4182 if g == TLS13_KEY_SHARE_GROUP_SECP256R1_MLKEM768_HYBRID
4183 && bytes.len() != (65 + MLKEM_CIPHERTEXT_LEN)
4184 {
4185 return Err(Error::ParseFailure(
4186 "invalid secp256r1mlkem768 hybrid server key_share key_exchange length",
4187 ));
4188 }
4189 if g == TLS13_KEY_SHARE_GROUP_X25519_MLKEM768_HYBRID
4190 && bytes.len() != (32 + MLKEM_CIPHERTEXT_LEN)
4191 {
4192 return Err(Error::ParseFailure(
4193 "invalid x25519_mlkem768 hybrid server key_share key_exchange length",
4194 ));
4195 }
4196 if g == TLS13_KEY_SHARE_GROUP_SECP384R1_MLKEM1024_HYBRID
4197 && bytes.len() != (97 + MLKEM1024_CIPHERTEXT_LEN)
4198 {
4199 return Err(Error::ParseFailure(
4200 "invalid secp384r1mlkem1024 hybrid server key_share key_exchange length",
4201 ));
4202 }
4203 if g != TLS13_KEY_SHARE_GROUP_X25519
4204 && g != TLS13_KEY_SHARE_GROUP_SECP256R1
4205 && g != TLS13_KEY_SHARE_GROUP_SECP384R1
4206 && g != TLS13_KEY_SHARE_GROUP_SECP521R1
4207 && g != TLS13_KEY_SHARE_GROUP_BRAINPOOLP256R1TLS13
4208 && g != TLS13_KEY_SHARE_GROUP_BRAINPOOLP384R1TLS13
4209 && g != TLS13_KEY_SHARE_GROUP_BRAINPOOLP512R1TLS13
4210 && (g != TLS13_KEY_SHARE_GROUP_X448 || !cfg!(feature = "hazardous-legacy-crypto"))
4211 && g != TLS13_KEY_SHARE_GROUP_MLKEM768
4212 && g != TLS13_KEY_SHARE_GROUP_SECP256R1_MLKEM768_HYBRID
4213 && g != TLS13_KEY_SHARE_GROUP_X25519_MLKEM768_HYBRID
4214 && g != TLS13_KEY_SHARE_GROUP_SECP384R1_MLKEM1024_HYBRID
4215 {
4216 return Err(Error::ParseFailure("unsupported server key_share group"));
4217 }
4218 key_share.extend_from_slice(&g.to_be_bytes());
4219 key_share.extend_from_slice(&(bytes.len() as u16).to_be_bytes());
4220 key_share.extend_from_slice(bytes);
4221 } else {
4222 let private =
4223 noxtls_derive_deterministic_x25519_private(random, b"tls13 server x25519");
4224 let public = private.public_key().bytes;
4225 key_share.extend_from_slice(&TLS13_KEY_SHARE_GROUP_X25519.to_be_bytes());
4226 key_share.extend_from_slice(&32_u16.to_be_bytes());
4227 key_share.extend_from_slice(&public);
4228 }
4229 noxtls_push_extension(&mut extensions, EXT_KEY_SHARE, &key_share);
4230 }
4231 body.extend_from_slice(&(extensions.len() as u16).to_be_bytes());
4232 body.extend_from_slice(&extensions);
4233 Ok(body)
4234}
4235
4236fn noxtls_extract_client_hello_legacy_session_id(body: &[u8]) -> Result<&[u8]> {
4254 if body.len() < 35 {
4255 return Err(Error::ParseFailure(
4256 "client hello body too short for session_id",
4257 ));
4258 }
4259 let session_id_len = body[34] as usize;
4260 if session_id_len > 32 {
4261 return Err(Error::ParseFailure(
4262 "client hello legacy session_id exceeds 32 bytes",
4263 ));
4264 }
4265 let end = 35_usize.saturating_add(session_id_len);
4266 if body.len() < end {
4267 return Err(Error::ParseFailure(
4268 "client hello legacy session_id bytes truncated",
4269 ));
4270 }
4271 Ok(&body[35..end])
4272}
4273
4274fn noxtls_parse_server_hello(msg: &[u8]) -> Result<ParsedServerHello> {
4293 if msg.len() == 3 && msg.first().copied() == Some(HANDSHAKE_SERVER_HELLO) {
4294 let suite_id = u16::from_be_bytes([msg[1], msg[2]]);
4295 let suite = CipherSuite::noxtls_from_u16(suite_id)
4296 .ok_or(Error::ParseFailure("unsupported cipher suite"))?;
4297 return Ok(ParsedServerHello {
4298 suite,
4299 random: None,
4300 key_share: None,
4301 hello_retry_request: false,
4302 requested_group: None,
4303 secure_renegotiation_info: None,
4304 });
4305 }
4306
4307 let (handshake_type, body) = noxtls_parse_handshake_message(msg)?;
4308 if handshake_type != HANDSHAKE_SERVER_HELLO {
4309 return Err(Error::ParseFailure("invalid server hello type"));
4310 }
4311 if body.len() < 40 {
4312 return Err(Error::ParseFailure("server hello body too short"));
4313 }
4314 let session_id_len = body[34] as usize;
4315 let suite_start = 35 + session_id_len;
4316 let suite_end = suite_start + 2;
4317 if body.len() < suite_end + 3 {
4318 return Err(Error::ParseFailure("server hello missing cipher suite"));
4319 }
4320 let suite_id = u16::from_be_bytes([body[suite_start], body[suite_start + 1]]);
4321 let suite = CipherSuite::noxtls_from_u16(suite_id)
4322 .ok_or(Error::ParseFailure("unsupported cipher suite"))?;
4323 let legacy_version = u16::from_be_bytes([body[0], body[1]]);
4324 if noxtls_is_tls13_suite(suite) && legacy_version != 0x0303 && legacy_version != 0xFEFD {
4325 return Err(Error::ParseFailure(
4326 "invalid tls13 server hello legacy_version",
4327 ));
4328 }
4329 let compression_method = body[suite_end];
4330 if compression_method != 0x00 {
4331 return Err(Error::ParseFailure(
4332 "invalid server hello compression method",
4333 ));
4334 }
4335 let mut random_bytes = [0_u8; 32];
4336 random_bytes.copy_from_slice(&body[2..34]);
4337 let random = &random_bytes;
4338 let hello_retry_request = random == &TLS13_HRR_RANDOM;
4339 let mut key_share_parsed = None;
4340 let mut requested_group = None;
4341 let mut seen_key_share_extension = false;
4342 let mut seen_supported_versions_extension = false;
4343 let mut secure_renegotiation_info = None;
4344 let mut supports_tls13 = false;
4345 let mut seen_extension_types = Vec::new();
4346 let ext_len_offset = suite_end + 1;
4347 let ext_len = u16::from_be_bytes([body[ext_len_offset], body[ext_len_offset + 1]]) as usize;
4348 let ext_start = ext_len_offset + 2;
4349 let ext_end = ext_start + ext_len;
4350 if ext_end > body.len() {
4351 return Err(Error::ParseFailure("server hello extensions truncated"));
4352 }
4353 let mut cursor = &body[ext_start..ext_end];
4354 while !cursor.is_empty() {
4355 if cursor.len() < 4 {
4356 return Err(Error::ParseFailure(
4357 "server hello extension header truncated",
4358 ));
4359 }
4360 let ext_type = u16::from_be_bytes([cursor[0], cursor[1]]);
4361 let ext_data_len = u16::from_be_bytes([cursor[2], cursor[3]]) as usize;
4362 cursor = &cursor[4..];
4363 if cursor.len() < ext_data_len {
4364 return Err(Error::ParseFailure("server hello extension truncated"));
4365 }
4366 if seen_extension_types.contains(&ext_type) {
4367 return Err(Error::ParseFailure("duplicate server hello extension type"));
4368 }
4369 seen_extension_types.push(ext_type);
4370 let ext_data = &cursor[..ext_data_len];
4371 match ext_type {
4372 EXT_SIGNATURE_ALGORITHMS | EXT_PSK_KEY_EXCHANGE_MODES | EXT_SERVER_NAME => {
4373 return Err(Error::ParseFailure(
4374 "server hello contains forbidden extension type",
4375 ));
4376 }
4377 EXT_SUPPORTED_VERSIONS => {
4378 if ext_data_len != 2 {
4379 return Err(Error::ParseFailure(
4380 "invalid server hello supported_versions length",
4381 ));
4382 }
4383 seen_supported_versions_extension = true;
4384 let selected_version = u16::from_be_bytes([ext_data[0], ext_data[1]]);
4385 if selected_version != 0x0304 {
4386 return Err(Error::ParseFailure(
4387 "invalid tls13 server hello supported_versions value",
4388 ));
4389 }
4390 supports_tls13 = true;
4391 }
4392 EXT_RENEGOTIATION_INFO => {
4393 if ext_data.is_empty() {
4394 return Err(Error::ParseFailure(
4395 "server hello renegotiation_info extension missing length",
4396 ));
4397 }
4398 let renegotiated_len = ext_data[0] as usize;
4399 if ext_data.len() != 1 + renegotiated_len {
4400 return Err(Error::ParseFailure(
4401 "server hello renegotiation_info extension length mismatch",
4402 ));
4403 }
4404 secure_renegotiation_info = Some(ext_data[1..].to_vec());
4405 }
4406 EXT_KEY_SHARE => {
4407 seen_key_share_extension = true;
4408 if hello_retry_request {
4409 if ext_data_len != 2 {
4410 return Err(Error::ParseFailure("invalid hrr key_share length"));
4411 }
4412 requested_group = Some(u16::from_be_bytes([ext_data[0], ext_data[1]]));
4413 } else {
4414 if ext_data_len < 4 {
4415 return Err(Error::ParseFailure("invalid server key_share length"));
4416 }
4417 let group = u16::from_be_bytes([ext_data[0], ext_data[1]]);
4418 let key_len = u16::from_be_bytes([ext_data[2], ext_data[3]]) as usize;
4419 if ext_data_len != 4 + key_len {
4420 return Err(Error::ParseFailure("invalid server key_share length"));
4421 }
4422 key_share_parsed = Some(match group {
4423 TLS13_KEY_SHARE_GROUP_X25519 => {
4424 if key_len != 32 {
4425 return Err(Error::ParseFailure(
4426 "invalid x25519 server key_share key_exchange length",
4427 ));
4428 }
4429 let mut key = [0_u8; 32];
4430 key.copy_from_slice(&ext_data[4..36]);
4431 Tls13ServerKeyShareParsed::X25519(key)
4432 }
4433 TLS13_KEY_SHARE_GROUP_SECP256R1 => {
4434 if key_len != 65 {
4435 return Err(Error::ParseFailure(
4436 "invalid secp256r1 server key_share key_exchange length",
4437 ));
4438 }
4439 let mut key = [0_u8; 65];
4440 key.copy_from_slice(&ext_data[4..69]);
4441 Tls13ServerKeyShareParsed::Secp256r1(key)
4442 }
4443 TLS13_KEY_SHARE_GROUP_MLKEM768 => {
4444 if key_len != MLKEM_CIPHERTEXT_LEN {
4445 return Err(Error::ParseFailure(
4446 "invalid mlkem768 server key_share key_exchange length",
4447 ));
4448 }
4449 Tls13ServerKeyShareParsed::MlKem768(ext_data[4..].to_vec())
4450 }
4451 TLS13_KEY_SHARE_GROUP_X25519_MLKEM768_HYBRID => {
4452 if key_len != (32 + MLKEM_CIPHERTEXT_LEN) {
4453 return Err(Error::ParseFailure(
4454 "invalid x25519_mlkem768 hybrid server key_share key_exchange length",
4455 ));
4456 }
4457 let mlkem768 = ext_data[4..(4 + MLKEM_CIPHERTEXT_LEN)].to_vec();
4458 let mut x25519 = [0_u8; 32];
4459 x25519.copy_from_slice(&ext_data[(4 + MLKEM_CIPHERTEXT_LEN)..]);
4460 Tls13ServerKeyShareParsed::X25519MlKem768Hybrid { x25519, mlkem768 }
4461 }
4462 _ => {
4463 return Err(Error::ParseFailure("unsupported server key_share"));
4464 }
4465 });
4466 }
4467 }
4468 _ => {}
4469 }
4470 cursor = &cursor[ext_data_len..];
4471 }
4472 if hello_retry_request && !seen_key_share_extension {
4473 return Err(Error::ParseFailure("hrr missing key_share extension"));
4474 }
4475 if !hello_retry_request
4476 && noxtls_is_tls13_suite(suite)
4477 && legacy_version == 0x0303
4478 && !seen_supported_versions_extension
4479 {
4480 return Err(Error::ParseFailure(
4481 "tls13 server hello missing supported_versions extension",
4482 ));
4483 }
4484 if !hello_retry_request
4485 && noxtls_is_tls13_suite(suite)
4486 && legacy_version == 0x0303
4487 && !supports_tls13
4488 {
4489 return Err(Error::ParseFailure(
4490 "invalid tls13 server hello supported_versions value",
4491 ));
4492 }
4493 if !hello_retry_request
4494 && noxtls_is_tls13_suite(suite)
4495 && legacy_version == 0x0303
4496 && !seen_key_share_extension
4497 {
4498 return Err(Error::ParseFailure(
4499 "tls13 server hello missing key_share extension",
4500 ));
4501 }
4502 Ok(ParsedServerHello {
4503 suite,
4504 random: Some(random_bytes),
4505 key_share: key_share_parsed,
4506 hello_retry_request,
4507 requested_group,
4508 secure_renegotiation_info,
4509 })
4510}
4511
4512fn noxtls_is_tls13_suite(suite: CipherSuite) -> bool {
4527 matches!(
4528 suite,
4529 CipherSuite::TlsAes128GcmSha256
4530 | CipherSuite::TlsAes256GcmSha384
4531 | CipherSuite::TlsChacha20Poly1305Sha256
4532 )
4533}
4534
4535fn noxtls_parse_client_hello_info(msg: &[u8]) -> Result<ClientHelloInfo> {
4554 let (handshake_type, body) = noxtls_parse_handshake_message(msg)?;
4555 if handshake_type != HANDSHAKE_CLIENT_HELLO {
4556 return Err(Error::ParseFailure("invalid client hello type"));
4557 }
4558 if body.len() < 39 {
4559 return Err(Error::ParseFailure("client hello body too short"));
4560 }
4561 let legacy_version = u16::from_be_bytes([body[0], body[1]]);
4562 let session_id_len = body[34] as usize;
4563 let suites_len_offset = 35 + session_id_len;
4564 if body.len() < suites_len_offset + 2 {
4565 return Err(Error::ParseFailure(
4566 "client hello missing cipher suites length",
4567 ));
4568 }
4569 let suites_len =
4570 u16::from_be_bytes([body[suites_len_offset], body[suites_len_offset + 1]]) as usize;
4571 if suites_len == 0 || suites_len % 2 != 0 {
4572 return Err(Error::ParseFailure(
4573 "invalid client hello cipher suites length",
4574 ));
4575 }
4576 let suites_start = suites_len_offset + 2;
4577 let suites_end = suites_start + suites_len;
4578 if body.len() < suites_end + 3 {
4579 return Err(Error::ParseFailure("client hello cipher suites truncated"));
4580 }
4581
4582 let mut suites = Vec::new();
4583 let mut secure_renegotiation_scsv = false;
4584 let mut offered_tls_fallback_scsv = false;
4585 for chunk in body[suites_start..suites_end].chunks_exact(2) {
4586 let codepoint = u16::from_be_bytes([chunk[0], chunk[1]]);
4587 if codepoint == TLS_EMPTY_RENEGOTIATION_INFO_SCSV {
4588 secure_renegotiation_scsv = true;
4589 continue;
4590 }
4591 if codepoint == TLS_FALLBACK_SCSV {
4592 offered_tls_fallback_scsv = true;
4593 continue;
4594 }
4595 if let Some(suite) = CipherSuite::noxtls_from_u16(codepoint) {
4596 suites.push(suite);
4597 }
4598 }
4599 if suites.is_empty() {
4600 return Err(Error::ParseFailure(
4601 "client hello has no supported cipher suite",
4602 ));
4603 }
4604
4605 let compression_methods_len = body[suites_end] as usize;
4606 let compression_methods_start = suites_end + 1;
4607 let compression_methods_end = compression_methods_start + compression_methods_len;
4608 if body.len() < compression_methods_end + 2 {
4609 return Err(Error::ParseFailure(
4610 "client hello missing compression methods",
4611 ));
4612 }
4613 let extensions_len = u16::from_be_bytes([
4614 body[compression_methods_end],
4615 body[compression_methods_end + 1],
4616 ]) as usize;
4617 let extensions_start = compression_methods_end + 2;
4618 let extensions_end = extensions_start + extensions_len;
4619 if body.len() < extensions_end {
4620 return Err(Error::ParseFailure("client hello extensions truncated"));
4621 }
4622 if body.len() != extensions_end {
4623 return Err(Error::ParseFailure("client hello has trailing bytes"));
4624 }
4625 let mut extensions =
4626 noxtls_parse_client_hello_extensions(&body[extensions_start..extensions_end])?;
4627 extensions.secure_renegotiation_scsv = secure_renegotiation_scsv;
4628
4629 Ok(ClientHelloInfo {
4630 legacy_version,
4631 offered_cipher_suites: suites,
4632 offered_tls_fallback_scsv,
4633 extensions,
4634 })
4635}
4636
4637fn noxtls_pick_intersection_suite(
4658 hello: &ClientHelloInfo,
4659 preferred: &[CipherSuite],
4660 version: TlsVersion,
4661) -> Result<CipherSuite> {
4662 for suite in preferred {
4663 if !hello.offered_cipher_suites.contains(suite) {
4664 continue;
4665 }
4666 if !noxtls_suite_supported_by_version(*suite, version) {
4667 continue;
4668 }
4669 if noxtls_suite_allowed_by_extensions(*suite, version, &hello.extensions) {
4670 return Ok(*suite);
4671 }
4672 }
4673 Err(Error::ParseFailure("no mutually supported cipher suite"))
4674}
4675
4676fn noxtls_suite_supported_by_version(suite: CipherSuite, version: TlsVersion) -> bool {
4692 match version {
4693 TlsVersion::Tls13 | TlsVersion::Dtls13 => matches!(
4694 suite,
4695 CipherSuite::TlsAes128GcmSha256
4696 | CipherSuite::TlsAes256GcmSha384
4697 | CipherSuite::TlsChacha20Poly1305Sha256
4698 ),
4699 TlsVersion::Tls10 | TlsVersion::Tls11 | TlsVersion::Tls12 | TlsVersion::Dtls12 => {
4700 !noxtls_is_tls13_suite(suite)
4701 }
4702 }
4703}
4704
4705fn noxtls_suite_allowed_by_extensions(
4722 suite: CipherSuite,
4723 version: TlsVersion,
4724 extensions: &ClientHelloExtensions,
4725) -> bool {
4726 match version {
4727 TlsVersion::Tls13 | TlsVersion::Dtls13 => {
4728 if matches!(
4729 suite,
4730 CipherSuite::TlsAes128GcmSha256
4731 | CipherSuite::TlsAes256GcmSha384
4732 | CipherSuite::TlsChacha20Poly1305Sha256
4733 ) {
4734 return noxtls_tls13_client_hello_offers_supported_key_exchange(
4735 &extensions.supported_versions,
4736 &extensions.key_share_groups,
4737 &extensions.signature_algorithms,
4738 );
4739 }
4740 true
4741 }
4742 TlsVersion::Tls10 | TlsVersion::Tls11 | TlsVersion::Tls12 | TlsVersion::Dtls12 => true,
4743 }
4744}
4745
4746fn noxtls_tls13_debug_enabled() -> bool {
4760 #[cfg(feature = "std")]
4761 {
4762 std::env::var_os("NOXTLS_TLS13_DEBUG").is_some()
4763 }
4764 #[cfg(not(feature = "std"))]
4765 {
4766 false
4767 }
4768}
4769
4770fn noxtls_tls13_debug_log(_label: &str, _value: &str) {
4785 if !noxtls_tls13_debug_enabled() {
4786 return;
4787 }
4788 #[cfg(feature = "std")]
4789 {
4790 eprintln!("tls13_debug::{_label}={_value}");
4791 }
4792 #[cfg(not(feature = "std"))]
4793 {
4794 let _ = (_label, _value);
4795 }
4796}
4797
4798fn noxtls_tls13_debug_log_bytes(label: &str, bytes: &[u8]) {
4813 if !noxtls_tls13_debug_enabled() {
4814 return;
4815 }
4816 noxtls_tls13_debug_log(label, &noxtls_encode_hex(bytes));
4817}
4818
4819fn noxtls_encode_hex(bytes: &[u8]) -> String {
4833 const HEX: &[u8; 16] = b"0123456789abcdef";
4834 let mut out = String::with_capacity(bytes.len() * 2);
4835 for byte in bytes {
4836 out.push(HEX[(byte >> 4) as usize] as char);
4837 out.push(HEX[(byte & 0x0f) as usize] as char);
4838 }
4839 out
4840}
4841
4842fn noxtls_hash_algorithm_name(noxtls_hash_algorithm: HashAlgorithm) -> &'static str {
4856 match noxtls_hash_algorithm {
4857 HashAlgorithm::Sha256 => "sha256",
4858 HashAlgorithm::Sha384 => "sha384",
4859 }
4860}
4861
4862fn noxtls_extract_tls13_client_hello_x25519_key_share(message: &[u8]) -> Result<Option<[u8; 32]>> {
4880 let (handshake_type, body) = noxtls_parse_handshake_message(message)?;
4881 if handshake_type != HANDSHAKE_CLIENT_HELLO {
4882 return Err(Error::ParseFailure(
4883 "expected client hello while extracting x25519 key share",
4884 ));
4885 }
4886 if body.len() < 39 {
4887 return Err(Error::ParseFailure("client hello body too short"));
4888 }
4889 let mut offset = 0_usize;
4890 offset = offset.saturating_add(2); offset = offset.saturating_add(32); let session_id_len = body.get(offset).copied().ok_or(Error::ParseFailure(
4893 "client hello missing session_id length",
4894 ))? as usize;
4895 offset = offset.saturating_add(1 + session_id_len);
4896 if body.len().saturating_sub(offset) < 2 {
4897 return Err(Error::ParseFailure(
4898 "client hello missing cipher_suites length",
4899 ));
4900 }
4901 let suites_len = u16::from_be_bytes([body[offset], body[offset + 1]]) as usize;
4902 offset = offset.saturating_add(2 + suites_len);
4903 if body.len().saturating_sub(offset) < 1 {
4904 return Err(Error::ParseFailure(
4905 "client hello missing compression_methods length",
4906 ));
4907 }
4908 let compression_len = body[offset] as usize;
4909 offset = offset.saturating_add(1 + compression_len);
4910 if body.len().saturating_sub(offset) < 2 {
4911 return Err(Error::ParseFailure(
4912 "client hello missing extensions length",
4913 ));
4914 }
4915 let extensions_len = u16::from_be_bytes([body[offset], body[offset + 1]]) as usize;
4916 offset = offset.saturating_add(2);
4917 if body.len().saturating_sub(offset) < extensions_len {
4918 return Err(Error::ParseFailure("client hello extensions truncated"));
4919 }
4920 let mut cursor = &body[offset..offset + extensions_len];
4921 while !cursor.is_empty() {
4922 if cursor.len() < 4 {
4923 return Err(Error::ParseFailure(
4924 "client hello extension header truncated",
4925 ));
4926 }
4927 let extension_type = u16::from_be_bytes([cursor[0], cursor[1]]);
4928 let extension_len = u16::from_be_bytes([cursor[2], cursor[3]]) as usize;
4929 cursor = &cursor[4..];
4930 if cursor.len() < extension_len {
4931 return Err(Error::ParseFailure("client hello extension truncated"));
4932 }
4933 let extension_data = &cursor[..extension_len];
4934 if extension_type == EXT_KEY_SHARE {
4935 if extension_data.len() < 2 {
4936 return Err(Error::ParseFailure(
4937 "client hello key_share extension missing vector length",
4938 ));
4939 }
4940 let key_share_list_len =
4941 u16::from_be_bytes([extension_data[0], extension_data[1]]) as usize;
4942 if extension_data.len() != key_share_list_len + 2 {
4943 return Err(Error::ParseFailure(
4944 "client hello key_share extension length mismatch",
4945 ));
4946 }
4947 let mut shares = &extension_data[2..];
4948 while !shares.is_empty() {
4949 if shares.len() < 4 {
4950 return Err(Error::ParseFailure(
4951 "client hello key_share entry truncated",
4952 ));
4953 }
4954 let group = u16::from_be_bytes([shares[0], shares[1]]);
4955 let key_exchange_len = u16::from_be_bytes([shares[2], shares[3]]) as usize;
4956 shares = &shares[4..];
4957 if shares.len() < key_exchange_len {
4958 return Err(Error::ParseFailure(
4959 "client hello key_share key_exchange truncated",
4960 ));
4961 }
4962 if group == TLS13_KEY_SHARE_GROUP_X25519 {
4963 if key_exchange_len != 32 {
4964 return Err(Error::ParseFailure(
4965 "client hello x25519 key_share length must be 32",
4966 ));
4967 }
4968 let mut key_exchange = [0_u8; 32];
4969 key_exchange.copy_from_slice(&shares[..32]);
4970 return Ok(Some(key_exchange));
4971 }
4972 shares = &shares[key_exchange_len..];
4973 }
4974 return Ok(None);
4975 }
4976 cursor = &cursor[extension_len..];
4977 }
4978 Ok(None)
4979}
4980
4981#[allow(clippy::too_many_arguments)]
5005fn noxtls_build_client_hello_extensions(
5006 version: TlsVersion,
5007 key_shares: &Tls13ClientPublicKeyShares,
5008 sni_server_name: Option<&str>,
5009 alpn_protocols: &[Vec<u8>],
5010 request_ocsp_stapling: bool,
5011 offer_mldsa_signature: bool,
5012 offer_early_data: bool,
5013 psk_offer: Option<&PskClientOffer<'_>>,
5014 offer_raw_public_key: bool,
5015 secure_renegotiation_info: Option<&[u8]>,
5016) -> Result<Vec<u8>> {
5017 let mut extensions = Vec::new();
5018 match version {
5019 TlsVersion::Tls13 | TlsVersion::Dtls13 => {
5020 let mut supported_versions = Vec::new();
5022 supported_versions.push(4_u8);
5023 supported_versions.extend_from_slice(&0x0304_u16.to_be_bytes());
5024 supported_versions.extend_from_slice(&0x0303_u16.to_be_bytes());
5025 noxtls_push_extension(&mut extensions, EXT_SUPPORTED_VERSIONS, &supported_versions);
5026
5027 let mut sigalgs = Vec::new();
5029 let mut supported_sigalgs = vec![
5030 TLS13_SIGALG_ECDSA_SECP256R1_SHA256,
5031 TLS13_SIGALG_ECDSA_SECP384R1_SHA384,
5032 TLS13_SIGALG_ECDSA_SECP521R1_SHA512,
5033 TLS13_SIGALG_RSA_PSS_RSAE_SHA256,
5034 TLS13_SIGALG_RSA_PSS_RSAE_SHA384,
5035 TLS13_SIGALG_RSA_PSS_RSAE_SHA512,
5036 TLS13_SIGALG_RSA_PSS_PSS_SHA256,
5037 TLS13_SIGALG_RSA_PSS_PSS_SHA384,
5038 TLS13_SIGALG_RSA_PSS_PSS_SHA512,
5039 TLS13_SIGALG_ED25519,
5040 ];
5041 if offer_mldsa_signature {
5042 supported_sigalgs.push(TLS13_SIGALG_MLDSA65);
5043 }
5044 sigalgs.extend_from_slice(&((supported_sigalgs.len() * 2) as u16).to_be_bytes());
5045 for sigalg in supported_sigalgs {
5046 sigalgs.extend_from_slice(&sigalg.to_be_bytes());
5047 }
5048 noxtls_push_extension(&mut extensions, EXT_SIGNATURE_ALGORITHMS, &sigalgs);
5049
5050 let mut supported_groups = Vec::new();
5052 let mut supported_group_ids = Vec::new();
5053 if key_shares.x25519.is_some() {
5054 supported_group_ids.push(TLS13_KEY_SHARE_GROUP_X25519);
5055 }
5056 if key_shares.secp256r1_uncompressed.is_some() {
5057 supported_group_ids.push(TLS13_KEY_SHARE_GROUP_SECP256R1);
5058 }
5059 if key_shares.mlkem768.is_some() {
5060 supported_group_ids.push(TLS13_KEY_SHARE_GROUP_MLKEM768);
5061 }
5062 if key_shares.x25519_mlkem768_hybrid.is_some() {
5063 supported_group_ids.push(TLS13_KEY_SHARE_GROUP_X25519_MLKEM768_HYBRID);
5064 }
5065 if supported_group_ids.is_empty() {
5066 return Err(Error::InvalidLength(
5067 "tls13 client hello supported_groups extension must not be empty",
5068 ));
5069 }
5070 supported_groups
5071 .extend_from_slice(&((supported_group_ids.len() * 2) as u16).to_be_bytes());
5072 for group in supported_group_ids {
5073 supported_groups.extend_from_slice(&group.to_be_bytes());
5074 }
5075 noxtls_push_extension(&mut extensions, EXT_SUPPORTED_GROUPS, &supported_groups);
5076
5077 let mut key_share_list = Vec::new();
5079 if let Some(public) = key_shares.x25519 {
5080 key_share_list.extend_from_slice(&TLS13_KEY_SHARE_GROUP_X25519.to_be_bytes());
5081 key_share_list.extend_from_slice(&32_u16.to_be_bytes());
5082 key_share_list.extend_from_slice(&public);
5083 }
5084 if let Some(public) = key_shares.secp256r1_uncompressed {
5085 key_share_list.extend_from_slice(&TLS13_KEY_SHARE_GROUP_SECP256R1.to_be_bytes());
5086 key_share_list.extend_from_slice(&65_u16.to_be_bytes());
5087 key_share_list.extend_from_slice(&public);
5088 }
5089 if let Some(public) = key_shares.mlkem768.as_ref() {
5090 key_share_list.extend_from_slice(&TLS13_KEY_SHARE_GROUP_MLKEM768.to_be_bytes());
5091 key_share_list.extend_from_slice(&(public.len() as u16).to_be_bytes());
5092 key_share_list.extend_from_slice(public);
5093 }
5094 if let Some(public) = key_shares.x25519_mlkem768_hybrid.as_ref() {
5095 key_share_list
5096 .extend_from_slice(&TLS13_KEY_SHARE_GROUP_X25519_MLKEM768_HYBRID.to_be_bytes());
5097 key_share_list.extend_from_slice(&(public.len() as u16).to_be_bytes());
5098 key_share_list.extend_from_slice(public);
5099 }
5100 if key_share_list.is_empty() {
5101 return Err(Error::InvalidLength(
5102 "tls13 client hello key_share extension must not be empty",
5103 ));
5104 }
5105 let mut key_share_ext = Vec::new();
5106 key_share_ext.extend_from_slice(&(key_share_list.len() as u16).to_be_bytes());
5107 key_share_ext.extend_from_slice(&key_share_list);
5108 noxtls_push_extension(&mut extensions, EXT_KEY_SHARE, &key_share_ext);
5109 if let Some(server_name) = sni_server_name {
5110 let server_name_extension_data =
5111 noxtls_encode_server_name_extension_data(server_name)?;
5112 noxtls_push_extension(
5113 &mut extensions,
5114 EXT_SERVER_NAME,
5115 &server_name_extension_data,
5116 );
5117 }
5118 if request_ocsp_stapling {
5119 let status_request_data = noxtls_encode_status_request_ocsp_extension_data()?;
5120 noxtls_push_extension(&mut extensions, EXT_STATUS_REQUEST, &status_request_data);
5121 }
5122 if !alpn_protocols.is_empty() {
5123 let alpn_extension_data = noxtls_encode_alpn_extension_data(alpn_protocols)?;
5124 noxtls_push_extension(&mut extensions, EXT_ALPN, &alpn_extension_data);
5125 }
5126 if let Some(renegotiation_info) = secure_renegotiation_info {
5127 if renegotiation_info.len() > u8::MAX as usize {
5128 return Err(Error::InvalidLength(
5129 "renegotiation_info length must not exceed 255 bytes",
5130 ));
5131 }
5132 let mut extension_data = Vec::with_capacity(1 + renegotiation_info.len());
5133 extension_data.push(renegotiation_info.len() as u8);
5134 extension_data.extend_from_slice(renegotiation_info);
5135 noxtls_push_extension(&mut extensions, EXT_RENEGOTIATION_INFO, &extension_data);
5136 }
5137 if offer_raw_public_key {
5138 noxtls_push_extension(
5139 &mut extensions,
5140 EXT_CLIENT_CERTIFICATE_TYPE,
5141 &[1, TLS_CERTIFICATE_TYPE_RAW_PUBLIC_KEY],
5142 );
5143 noxtls_push_extension(
5144 &mut extensions,
5145 EXT_SERVER_CERTIFICATE_TYPE,
5146 &[
5147 2,
5148 TLS_CERTIFICATE_TYPE_RAW_PUBLIC_KEY,
5149 TLS_CERTIFICATE_TYPE_X509,
5150 ],
5151 );
5152 }
5153 if offer_early_data {
5154 if psk_offer.is_none() {
5155 return Err(Error::StateError(
5156 "tls13 early_data extension requires pre_shared_key offer",
5157 ));
5158 }
5159 noxtls_push_extension(&mut extensions, EXT_EARLY_DATA, &[]);
5160 }
5161 if let Some(psk) = psk_offer {
5162 let psk_key_exchange_modes = [1_u8, TLS13_PSK_KEY_EXCHANGE_MODE_PSK_DHE_KE];
5163 noxtls_push_extension(
5164 &mut extensions,
5165 EXT_PSK_KEY_EXCHANGE_MODES,
5166 &psk_key_exchange_modes,
5167 );
5168 let psk_extension = noxtls_encode_pre_shared_key_extension(psk)?;
5169 noxtls_push_extension(&mut extensions, EXT_PRE_SHARED_KEY, &psk_extension);
5170 }
5171 }
5172 TlsVersion::Tls10 | TlsVersion::Tls11 | TlsVersion::Tls12 | TlsVersion::Dtls12 => {
5173 let mut sigalgs = Vec::new();
5175 sigalgs.extend_from_slice(&2_u16.to_be_bytes());
5176 sigalgs.extend_from_slice(&0x0401_u16.to_be_bytes());
5177 noxtls_push_extension(&mut extensions, EXT_SIGNATURE_ALGORITHMS, &sigalgs);
5178 if let Some(renegotiation_info) = secure_renegotiation_info {
5179 if renegotiation_info.len() > u8::MAX as usize {
5180 return Err(Error::InvalidLength(
5181 "renegotiation_info length must not exceed 255 bytes",
5182 ));
5183 }
5184 let mut extension_data = Vec::with_capacity(1 + renegotiation_info.len());
5185 extension_data.push(renegotiation_info.len() as u8);
5186 extension_data.extend_from_slice(renegotiation_info);
5187 noxtls_push_extension(&mut extensions, EXT_RENEGOTIATION_INFO, &extension_data);
5188 }
5189 if offer_raw_public_key {
5190 noxtls_push_extension(
5191 &mut extensions,
5192 EXT_CLIENT_CERTIFICATE_TYPE,
5193 &[1, TLS_CERTIFICATE_TYPE_RAW_PUBLIC_KEY],
5194 );
5195 noxtls_push_extension(
5196 &mut extensions,
5197 EXT_SERVER_CERTIFICATE_TYPE,
5198 &[
5199 2,
5200 TLS_CERTIFICATE_TYPE_RAW_PUBLIC_KEY,
5201 TLS_CERTIFICATE_TYPE_X509,
5202 ],
5203 );
5204 }
5205 }
5206 }
5207 Ok(extensions)
5208}
5209
5210fn noxtls_push_extension(out: &mut Vec<u8>, ext_type: u16, ext_data: &[u8]) {
5223 out.extend_from_slice(&ext_type.to_be_bytes());
5224 out.extend_from_slice(&(ext_data.len() as u16).to_be_bytes());
5225 out.extend_from_slice(ext_data);
5226}
5227
5228fn noxtls_parse_client_hello_extensions(input: &[u8]) -> Result<ClientHelloExtensions> {
5247 let mut out = ClientHelloExtensions::default();
5248 let mut cursor = input;
5249 let mut seen_supported_versions = false;
5250 let mut seen_signature_algorithms = false;
5251 let mut seen_key_share = false;
5252 let mut seen_psk_key_exchange_modes = false;
5253 let mut seen_pre_shared_key = false;
5254 let mut seen_early_data = false;
5255 let mut seen_extension_types = Vec::new();
5256 while !cursor.is_empty() {
5257 if cursor.len() < 4 {
5258 return Err(Error::ParseFailure(
5259 "client hello extension header truncated",
5260 ));
5261 }
5262 let ext_type = u16::from_be_bytes([cursor[0], cursor[1]]);
5263 let ext_len = u16::from_be_bytes([cursor[2], cursor[3]]) as usize;
5264 cursor = &cursor[4..];
5265 if cursor.len() < ext_len {
5266 return Err(Error::ParseFailure("client hello extension truncated"));
5267 }
5268 let ext_data = &cursor[..ext_len];
5269 if seen_extension_types.contains(&ext_type) {
5270 return Err(Error::ParseFailure("duplicate client hello extension type"));
5271 }
5272 seen_extension_types.push(ext_type);
5273 if seen_pre_shared_key {
5274 return Err(Error::ParseFailure(
5275 "pre_shared_key extension must be the last extension",
5276 ));
5277 }
5278 match ext_type {
5279 EXT_SUPPORTED_VERSIONS => {
5280 if seen_supported_versions {
5281 return Err(Error::ParseFailure(
5282 "duplicate supported_versions extension",
5283 ));
5284 }
5285 out.supported_versions = noxtls_parse_supported_versions_extension(ext_data)?;
5286 seen_supported_versions = true;
5287 }
5288 EXT_SIGNATURE_ALGORITHMS => {
5289 if seen_signature_algorithms {
5290 return Err(Error::ParseFailure(
5291 "duplicate signature_algorithms extension",
5292 ));
5293 }
5294 out.signature_algorithms = noxtls_parse_u16_vector_with_len(ext_data)?;
5295 if out.signature_algorithms.is_empty() {
5296 return Err(Error::ParseFailure(
5297 "signature_algorithms extension must not be empty",
5298 ));
5299 }
5300 seen_signature_algorithms = true;
5301 }
5302 EXT_SUPPORTED_GROUPS => {
5303 out.supported_groups = noxtls_parse_u16_vector_with_len(ext_data)?;
5304 }
5305 EXT_KEY_SHARE => {
5306 if seen_key_share {
5307 return Err(Error::ParseFailure("duplicate key_share extension"));
5308 }
5309 out.key_share_groups = noxtls_parse_key_share_groups_extension(ext_data)?;
5310 out.key_share_offered = true;
5311 seen_key_share = true;
5312 }
5313 EXT_SERVER_NAME => {
5314 out.sni_server_name = Some(noxtls_parse_server_name_extension(ext_data)?);
5315 }
5316 EXT_ALPN => {
5317 out.alpn_protocols = noxtls_parse_alpn_protocol_name_list(ext_data)?;
5318 }
5319 EXT_STATUS_REQUEST => {
5320 out.status_request_ocsp = noxtls_parse_status_request_ocsp_extension(ext_data)?;
5321 }
5322 EXT_COMPRESS_CERTIFICATE => {
5323 out.certificate_compression_algorithms =
5324 noxtls_parse_compress_certificate_extension(ext_data)?;
5325 }
5326 EXT_CLIENT_CERTIFICATE_TYPE => {
5327 out.client_certificate_types = noxtls_parse_u8_vector_with_len(ext_data)?;
5328 if out.client_certificate_types.is_empty() {
5329 return Err(Error::ParseFailure(
5330 "client_certificate_type extension must not be empty",
5331 ));
5332 }
5333 }
5334 EXT_SERVER_CERTIFICATE_TYPE => {
5335 out.server_certificate_types = noxtls_parse_u8_vector_with_len(ext_data)?;
5336 if out.server_certificate_types.is_empty() {
5337 return Err(Error::ParseFailure(
5338 "server_certificate_type extension must not be empty",
5339 ));
5340 }
5341 }
5342 EXT_PSK_KEY_EXCHANGE_MODES => {
5343 if seen_psk_key_exchange_modes {
5344 return Err(Error::ParseFailure(
5345 "duplicate psk_key_exchange_modes extension",
5346 ));
5347 }
5348 out.psk_key_exchange_modes = noxtls_parse_u8_vector_with_len(ext_data)?;
5349 if !out
5350 .psk_key_exchange_modes
5351 .contains(&TLS13_PSK_KEY_EXCHANGE_MODE_PSK_DHE_KE)
5352 {
5353 return Err(Error::ParseFailure(
5354 "psk_key_exchange_modes must include psk_dhe_ke",
5355 ));
5356 }
5357 seen_psk_key_exchange_modes = true;
5358 }
5359 EXT_PRE_SHARED_KEY => {
5360 if seen_pre_shared_key {
5361 return Err(Error::ParseFailure("duplicate pre_shared_key extension"));
5362 }
5363 let (identity_count, identities, obfuscated_ages, binders) =
5364 noxtls_parse_pre_shared_key_extension(ext_data)?;
5365 out.psk_identity_count = identity_count;
5366 out.psk_identities = identities;
5367 out.psk_obfuscated_ticket_ages = obfuscated_ages;
5368 out.psk_binders = binders;
5369 seen_pre_shared_key = true;
5370 }
5371 EXT_RENEGOTIATION_INFO => {
5372 if ext_data.is_empty() {
5373 return Err(Error::ParseFailure(
5374 "renegotiation_info extension missing length",
5375 ));
5376 }
5377 let renegotiated_len = ext_data[0] as usize;
5378 if ext_data.len() != 1 + renegotiated_len {
5379 return Err(Error::ParseFailure(
5380 "renegotiation_info extension length mismatch",
5381 ));
5382 }
5383 out.secure_renegotiation_info = Some(ext_data[1..].to_vec());
5384 }
5385 EXT_EARLY_DATA => {
5386 if seen_early_data {
5387 return Err(Error::ParseFailure("duplicate early_data extension"));
5388 }
5389 if !ext_data.is_empty() {
5390 return Err(Error::ParseFailure(
5391 "client hello early_data extension must be empty",
5392 ));
5393 }
5394 out.early_data_offered = true;
5395 seen_early_data = true;
5396 }
5397 _ => {}
5398 }
5399 cursor = &cursor[ext_len..];
5400 }
5401 if seen_pre_shared_key && !seen_psk_key_exchange_modes {
5402 return Err(Error::ParseFailure(
5403 "pre_shared_key extension requires psk_key_exchange_modes extension",
5404 ));
5405 }
5406 if seen_early_data && !seen_pre_shared_key {
5407 return Err(Error::ParseFailure(
5408 "early_data extension requires pre_shared_key extension",
5409 ));
5410 }
5411 let advertises_tls13 = out.supported_versions.contains(&0x0304);
5412 if seen_pre_shared_key && !advertises_tls13 {
5413 return Err(Error::ParseFailure(
5414 "pre_shared_key extension requires tls13 supported_versions entry",
5415 ));
5416 }
5417 if seen_key_share && !advertises_tls13 {
5418 return Err(Error::ParseFailure(
5419 "key_share extension requires tls13 supported_versions entry",
5420 ));
5421 }
5422 if advertises_tls13 && !seen_signature_algorithms {
5423 return Err(Error::ParseFailure(
5424 "tls13 supported_versions requires signature_algorithms extension",
5425 ));
5426 }
5427 if advertises_tls13 && !seen_key_share {
5428 return Err(Error::ParseFailure(
5429 "tls13 supported_versions requires key_share extension",
5430 ));
5431 }
5432 if advertises_tls13
5433 && noxtls_tls13_supported_groups_has_explicit_obsolete_offer(&out.supported_groups)
5434 {
5435 return Err(Error::ParseFailure(
5436 "tls13 client hello offered obsolete supported_group",
5437 ));
5438 }
5439 if advertises_tls13
5440 && out
5441 .key_share_groups
5442 .iter()
5443 .copied()
5444 .any(noxtls_tls13_named_group_is_obsolete)
5445 {
5446 return Err(Error::ParseFailure(
5447 "tls13 client hello offered obsolete key_share group",
5448 ));
5449 }
5450 if seen_pre_shared_key && !seen_key_share {
5451 return Err(Error::ParseFailure(
5452 "pre_shared_key with psk_dhe_ke requires key_share extension",
5453 ));
5454 }
5455 Ok(out)
5456}
5457
5458fn noxtls_tls13_named_group_is_obsolete(group: u16) -> bool {
5459 (0x0001..=0x0016).contains(&group)
5460 || (0x001A..=0x001C).contains(&group)
5461 || (0xFF01..=0xFF02).contains(&group)
5462}
5463
5464fn noxtls_tls13_supported_groups_has_explicit_obsolete_offer(groups: &[u16]) -> bool {
5465 groups.len() <= 2
5466 && groups
5467 .iter()
5468 .copied()
5469 .any(noxtls_tls13_named_group_is_obsolete)
5470}
5471
5472fn noxtls_parse_supported_versions_extension(input: &[u8]) -> Result<Vec<u16>> {
5491 if input.is_empty() {
5492 return Err(Error::ParseFailure("supported_versions extension is empty"));
5493 }
5494 let declared = input[0] as usize;
5495 if input.len() != declared + 1 || declared % 2 != 0 {
5496 return Err(Error::ParseFailure(
5497 "invalid supported_versions extension length",
5498 ));
5499 }
5500 let mut versions = Vec::new();
5501 for chunk in input[1..].chunks_exact(2) {
5502 let version = u16::from_be_bytes([chunk[0], chunk[1]]);
5503 if versions.contains(&version) {
5504 return Err(Error::ParseFailure(
5505 "duplicate supported_versions entry in extension body",
5506 ));
5507 }
5508 versions.push(version);
5509 }
5510 Ok(versions)
5511}
5512
5513fn noxtls_is_valid_sni_dns_name(name: &str) -> bool {
5528 if name.is_empty() || !name.is_ascii() {
5529 return false;
5530 }
5531 let trimmed = if let Some(stripped) = name.strip_suffix('.') {
5532 stripped
5533 } else {
5534 name
5535 };
5536 if trimmed.is_empty() || trimmed.len() > u16::MAX as usize {
5537 return false;
5538 }
5539 if trimmed
5540 .as_bytes()
5541 .iter()
5542 .any(|byte| *byte <= 0x20 || *byte >= 0x7f)
5543 {
5544 return false;
5545 }
5546 for label in trimmed.split('.') {
5547 if label.is_empty() || label.len() > 63 {
5548 return false;
5549 }
5550 let bytes = label.as_bytes();
5551 if bytes.first() == Some(&b'-') || bytes.last() == Some(&b'-') {
5552 return false;
5553 }
5554 if !bytes
5555 .iter()
5556 .all(|byte| byte.is_ascii_alphanumeric() || *byte == b'-')
5557 {
5558 return false;
5559 }
5560 }
5561 true
5562}
5563
5564fn noxtls_parse_server_name_extension(input: &[u8]) -> Result<String> {
5583 if input.len() < 5 {
5584 return Err(Error::ParseFailure("server_name extension too short"));
5585 }
5586 let list_len = u16::from_be_bytes([input[0], input[1]]) as usize;
5587 if list_len == 0 || input.len() != list_len + 2 {
5588 return Err(Error::ParseFailure("invalid server_name extension length"));
5589 }
5590 if input[2] != 0x00 {
5591 return Err(Error::ParseFailure("unsupported server_name type"));
5592 }
5593 let name_len = u16::from_be_bytes([input[3], input[4]]) as usize;
5594 if name_len == 0 || input.len() != 5 + name_len {
5595 return Err(Error::ParseFailure("invalid server_name host_name length"));
5596 }
5597 let name = core::str::from_utf8(&input[5..])
5598 .map_err(|_| Error::ParseFailure("invalid sni server_name"))?;
5599 if !noxtls_is_valid_sni_dns_name(name) {
5600 return Err(Error::ParseFailure("invalid sni server_name"));
5601 }
5602 Ok(name.to_owned())
5603}
5604
5605fn noxtls_encode_server_name_extension_data(server_name: &str) -> Result<Vec<u8>> {
5624 if !noxtls_is_valid_sni_dns_name(server_name) {
5625 return Err(Error::ParseFailure("invalid sni server_name"));
5626 }
5627 let name_bytes = server_name.as_bytes();
5628 let mut entry = Vec::new();
5629 entry.push(0x00); entry.extend_from_slice(&(name_bytes.len() as u16).to_be_bytes());
5631 entry.extend_from_slice(name_bytes);
5632 let mut out = Vec::new();
5633 out.extend_from_slice(&(entry.len() as u16).to_be_bytes());
5634 out.extend_from_slice(&entry);
5635 Ok(out)
5636}
5637
5638fn noxtls_encode_status_request_ocsp_extension_data() -> Result<Vec<u8>> {
5640 let mut out = Vec::new();
5641 out.push(0x01); out.extend_from_slice(&0_u16.to_be_bytes()); out.extend_from_slice(&0_u16.to_be_bytes()); Ok(out)
5645}
5646
5647fn noxtls_parse_status_request_ocsp_extension(input: &[u8]) -> Result<bool> {
5649 if input.len() != 5 {
5650 return Err(Error::ParseFailure(
5651 "invalid status_request extension length",
5652 ));
5653 }
5654 if input[0] != 0x01 {
5655 return Err(Error::ParseFailure(
5656 "status_request extension must use ocsp status type",
5657 ));
5658 }
5659 let responder_id_list_len = u16::from_be_bytes([input[1], input[2]]) as usize;
5660 let request_extensions_len = u16::from_be_bytes([input[3], input[4]]) as usize;
5661 if responder_id_list_len != 0 || request_extensions_len != 0 {
5662 return Err(Error::ParseFailure(
5663 "status_request extension non-empty responder/request vectors are unsupported",
5664 ));
5665 }
5666 Ok(true)
5667}
5668
5669fn noxtls_parse_alpn_protocol_name_list(input: &[u8]) -> Result<Vec<Vec<u8>>> {
5688 if input.len() < 2 {
5689 return Err(Error::ParseFailure(
5690 "alpn extension missing protocol_name_list",
5691 ));
5692 }
5693 let declared_len = u16::from_be_bytes([input[0], input[1]]) as usize;
5694 if declared_len == 0 || input.len() != declared_len + 2 {
5695 return Err(Error::ParseFailure("invalid alpn extension length"));
5696 }
5697 let mut cursor = &input[2..];
5698 let mut protocols = Vec::new();
5699 while !cursor.is_empty() {
5700 let protocol_len = cursor[0] as usize;
5701 cursor = &cursor[1..];
5702 if protocol_len == 0 {
5703 return Err(Error::ParseFailure("alpn protocol must not be empty"));
5704 }
5705 if cursor.len() < protocol_len {
5706 return Err(Error::ParseFailure("alpn protocol truncated"));
5707 }
5708 let protocol = cursor[..protocol_len].to_vec();
5709 if protocols.contains(&protocol) {
5710 return Err(Error::ParseFailure("duplicate alpn protocol"));
5711 }
5712 protocols.push(protocol);
5713 cursor = &cursor[protocol_len..];
5714 }
5715 Ok(protocols)
5716}
5717
5718fn noxtls_encode_alpn_extension_data(protocols: &[Vec<u8>]) -> Result<Vec<u8>> {
5737 if protocols.is_empty() {
5738 return Err(Error::InvalidLength(
5739 "alpn extension must include at least one protocol",
5740 ));
5741 }
5742 let mut protocol_name_list = Vec::new();
5743 let mut seen_protocols = Vec::new();
5744 for protocol in protocols {
5745 if protocol.is_empty() {
5746 return Err(Error::InvalidLength("alpn protocol must not be empty"));
5747 }
5748 if protocol.len() > u8::MAX as usize {
5749 return Err(Error::InvalidLength(
5750 "alpn protocol length must not exceed 255 bytes",
5751 ));
5752 }
5753 if seen_protocols.contains(protocol) {
5754 return Err(Error::ParseFailure("duplicate alpn protocol"));
5755 }
5756 seen_protocols.push(protocol.clone());
5757 protocol_name_list.push(protocol.len() as u8);
5758 protocol_name_list.extend_from_slice(protocol);
5759 }
5760 let mut extension_data = Vec::new();
5761 extension_data.extend_from_slice(&(protocol_name_list.len() as u16).to_be_bytes());
5762 extension_data.extend_from_slice(&protocol_name_list);
5763 Ok(extension_data)
5764}
5765
5766fn noxtls_parse_u16_vector_with_len(input: &[u8]) -> Result<Vec<u16>> {
5785 if input.len() < 2 {
5786 return Err(Error::ParseFailure("u16 vector missing length prefix"));
5787 }
5788 let len = u16::from_be_bytes([input[0], input[1]]) as usize;
5789 if input.len() != len + 2 || len % 2 != 0 {
5790 return Err(Error::ParseFailure("invalid u16 vector length"));
5791 }
5792 let mut out = Vec::with_capacity(len / 2);
5793 for chunk in input[2..].chunks_exact(2) {
5794 let value = u16::from_be_bytes([chunk[0], chunk[1]]);
5795 if !out.contains(&value) {
5796 out.push(value);
5797 }
5798 }
5799 Ok(out)
5800}
5801
5802fn noxtls_parse_compress_certificate_extension(input: &[u8]) -> Result<Vec<u16>> {
5803 if input.is_empty() {
5804 return Err(Error::ParseFailure(
5805 "certificate compression extension missing length prefix",
5806 ));
5807 }
5808 let len = input[0] as usize;
5809 if len == 0 {
5810 return Err(Error::ParseFailure(
5811 "certificate compression extension algorithm list must not be empty",
5812 ));
5813 }
5814 if input.len() != len + 1 || len % 2 != 0 {
5815 return Err(Error::ParseFailure(
5816 "invalid certificate compression extension length",
5817 ));
5818 }
5819 let mut algorithms = Vec::with_capacity(len / 2);
5820 for chunk in input[1..].chunks_exact(2) {
5821 let algorithm = u16::from_be_bytes([chunk[0], chunk[1]]);
5822 if !algorithms.contains(&algorithm) {
5823 algorithms.push(algorithm);
5824 }
5825 }
5826 Ok(algorithms)
5827}
5828
5829fn noxtls_parse_u8_vector_with_len(input: &[u8]) -> Result<Vec<u8>> {
5848 if input.is_empty() {
5849 return Err(Error::ParseFailure("u8 vector missing length prefix"));
5850 }
5851 let len = input[0] as usize;
5852 if input.len() != len + 1 {
5853 return Err(Error::ParseFailure("invalid u8 vector length"));
5854 }
5855 if len == 0 {
5856 return Err(Error::ParseFailure("u8 vector must not be empty"));
5857 }
5858 let mut out = Vec::new();
5859 for value in &input[1..] {
5860 if out.contains(value) {
5861 return Err(Error::ParseFailure("duplicate u8 vector entry"));
5862 }
5863 out.push(*value);
5864 }
5865 Ok(out)
5866}
5867
5868fn noxtls_parse_certificate_request_body(body: &[u8]) -> Result<()> {
5887 if body.len() < 3 {
5888 return Err(Error::ParseFailure("certificate request body too short"));
5889 }
5890 let context_len = body[0] as usize;
5891 let ext_len_offset = 1 + context_len;
5892 if body.len() < ext_len_offset + 2 {
5893 return Err(Error::ParseFailure("certificate request context truncated"));
5894 }
5895 let ext_len = u16::from_be_bytes([body[ext_len_offset], body[ext_len_offset + 1]]) as usize;
5896 let ext_start = ext_len_offset + 2;
5897 if body.len() != ext_start + ext_len {
5898 return Err(Error::ParseFailure(
5899 "certificate request extensions truncated",
5900 ));
5901 }
5902 noxtls_parse_certificate_request_extensions(&body[ext_start..])?;
5903 Ok(())
5904}
5905
5906fn noxtls_parse_certificate_request_extensions(input: &[u8]) -> Result<()> {
5925 let mut cursor = input;
5926 let mut seen_extension_types = Vec::new();
5927 let mut seen_signature_algorithms = false;
5928 while !cursor.is_empty() {
5929 if cursor.len() < 4 {
5930 return Err(Error::ParseFailure(
5931 "certificate request extension header truncated",
5932 ));
5933 }
5934 let ext_type = u16::from_be_bytes([cursor[0], cursor[1]]);
5935 let ext_len = u16::from_be_bytes([cursor[2], cursor[3]]) as usize;
5936 if seen_extension_types.contains(&ext_type) {
5937 return Err(Error::ParseFailure(
5938 "duplicate certificate request extension type",
5939 ));
5940 }
5941 if matches!(
5942 ext_type,
5943 EXT_SUPPORTED_VERSIONS
5944 | EXT_KEY_SHARE
5945 | EXT_PRE_SHARED_KEY
5946 | EXT_PSK_KEY_EXCHANGE_MODES
5947 | EXT_SERVER_NAME
5948 ) {
5949 return Err(Error::ParseFailure(
5950 "certificate request contains forbidden extension type",
5951 ));
5952 }
5953 seen_extension_types.push(ext_type);
5954 cursor = &cursor[4..];
5955 if cursor.len() < ext_len {
5956 return Err(Error::ParseFailure(
5957 "certificate request extension truncated",
5958 ));
5959 }
5960 if ext_type == EXT_SIGNATURE_ALGORITHMS {
5961 let signature_algorithms = noxtls_parse_u16_vector_with_len(&cursor[..ext_len])?;
5962 if signature_algorithms.is_empty() {
5963 return Err(Error::ParseFailure(
5964 "certificate request signature_algorithms must not be empty",
5965 ));
5966 }
5967 seen_signature_algorithms = true;
5968 }
5969 cursor = &cursor[ext_len..];
5970 }
5971 if !seen_signature_algorithms {
5972 return Err(Error::ParseFailure(
5973 "certificate request missing signature_algorithms extension",
5974 ));
5975 }
5976 Ok(())
5977}
5978
5979fn noxtls_parse_encrypted_extensions_body(body: &[u8]) -> Result<ParsedEncryptedExtensions> {
5998 if body.len() < 2 {
5999 return Err(Error::ParseFailure("encrypted extensions body too short"));
6000 }
6001 let extensions_len = u16::from_be_bytes([body[0], body[1]]) as usize;
6002 if body.len() != 2 + extensions_len {
6003 return Err(Error::ParseFailure("encrypted extensions malformed length"));
6004 }
6005 let mut cursor = &body[2..];
6006 let mut seen_extension_types = Vec::new();
6007 let mut selected_alpn_protocol = None;
6008 let mut server_name_acknowledged = false;
6009 let mut early_data_accepted = false;
6010 let mut server_certificate_type = None;
6011 while !cursor.is_empty() {
6012 if cursor.len() < 4 {
6013 return Err(Error::ParseFailure(
6014 "encrypted extensions entry header truncated",
6015 ));
6016 }
6017 let ext_type = u16::from_be_bytes([cursor[0], cursor[1]]);
6018 let ext_len = u16::from_be_bytes([cursor[2], cursor[3]]) as usize;
6019 if ext_len > TLS13_MAX_EXTENSION_VALUE_BYTES {
6020 return Err(Error::ParseFailure(
6021 "encrypted extensions extension value exceeds modeled maximum",
6022 ));
6023 }
6024 if seen_extension_types.contains(&ext_type) {
6025 return Err(Error::ParseFailure("duplicate encrypted extensions type"));
6026 }
6027 seen_extension_types.push(ext_type);
6028 cursor = &cursor[4..];
6029 if cursor.len() < ext_len {
6030 return Err(Error::ParseFailure("encrypted extensions entry truncated"));
6031 }
6032 let ext_data = &cursor[..ext_len];
6033 match ext_type {
6034 EXT_SERVER_NAME => {
6035 if !ext_data.is_empty() {
6036 return Err(Error::ParseFailure(
6037 "encrypted extensions server_name must be empty",
6038 ));
6039 }
6040 server_name_acknowledged = true;
6041 }
6042 EXT_ALPN => {
6043 let protocols = noxtls_parse_alpn_protocol_name_list(ext_data)?;
6044 if protocols.len() != 1 {
6045 return Err(Error::ParseFailure(
6046 "encrypted extensions alpn must select exactly one protocol",
6047 ));
6048 }
6049 selected_alpn_protocol = protocols.first().cloned();
6050 }
6051 EXT_EARLY_DATA => {
6052 if !ext_data.is_empty() {
6053 return Err(Error::ParseFailure(
6054 "encrypted extensions early_data must be empty",
6055 ));
6056 }
6057 early_data_accepted = true;
6058 }
6059 EXT_SERVER_CERTIFICATE_TYPE => {
6060 if ext_data.len() != 1 {
6061 return Err(Error::ParseFailure(
6062 "encrypted extensions server_certificate_type must be one byte",
6063 ));
6064 }
6065 match ext_data[0] {
6066 TLS_CERTIFICATE_TYPE_X509 | TLS_CERTIFICATE_TYPE_RAW_PUBLIC_KEY => {
6067 server_certificate_type = Some(ext_data[0]);
6068 }
6069 _ => {
6070 return Err(Error::UnsupportedFeature(
6071 "unsupported server_certificate_type selected",
6072 ));
6073 }
6074 }
6075 }
6076 EXT_SUPPORTED_VERSIONS
6077 | EXT_KEY_SHARE
6078 | EXT_PRE_SHARED_KEY
6079 | EXT_PSK_KEY_EXCHANGE_MODES => {
6080 return Err(Error::ParseFailure(
6081 "encrypted extensions contains forbidden extension type",
6082 ));
6083 }
6084 _ => {}
6085 }
6086 cursor = &cursor[ext_len..];
6087 }
6088 Ok(ParsedEncryptedExtensions {
6089 selected_alpn_protocol,
6090 server_name_acknowledged,
6091 early_data_accepted,
6092 server_certificate_type,
6093 })
6094}
6095
6096fn noxtls_map_certificate_validation_error(err: ValidationError) -> Error {
6128 let message = match err {
6129 ValidationError::InvalidNowTimeFormat => "server certificate validation time is invalid",
6130 ValidationError::CertificateNotYetValid => "server certificate is not yet valid",
6131 ValidationError::CertificateExpired => "server certificate is expired",
6132 ValidationError::IssuerNotFound => "server certificate issuer not found",
6133 ValidationError::IssuerNotCa => "server certificate issuer is not a CA",
6134 ValidationError::IssuerMissingKeyCertSign => {
6135 "server certificate issuer missing keyCertSign usage"
6136 }
6137 ValidationError::PathLenExceeded => "server certificate path length exceeded",
6138 ValidationError::UntrustedRoot => {
6139 "server certificate chain does not terminate at trust anchor"
6140 }
6141 ValidationError::ChainLoopDetected => "server certificate chain loop detected",
6142 ValidationError::MaxChainDepthExceeded => "server certificate chain depth exceeded",
6143 ValidationError::SignatureAlgorithmMismatch => {
6144 "server certificate signature algorithm mismatch"
6145 }
6146 ValidationError::UnsupportedSignatureAlgorithm => {
6147 "server certificate signature algorithm unsupported"
6148 }
6149 ValidationError::UnsupportedPublicKeyAlgorithm => {
6150 "server certificate issuer public key algorithm unsupported"
6151 }
6152 ValidationError::PublicKeyDecodeFailed => {
6153 "server certificate issuer public key decode failed"
6154 }
6155 ValidationError::SignatureVerificationFailed => {
6156 "server certificate signature verification failed"
6157 }
6158 ValidationError::MissingRequiredPolicy => "server certificate missing required policy OID",
6159 ValidationError::MissingRequiredExtendedKeyUsage => {
6160 "server certificate missing required extended key usage"
6161 }
6162 ValidationError::ExplicitPolicyRequired => {
6163 "server certificate policy set is empty under explicit policy mode"
6164 }
6165 ValidationError::PolicyMappingInhibited => {
6166 "server certificate policy mappings are inhibited"
6167 }
6168 ValidationError::NameConstraintsViolation => {
6169 "server certificate violates issuer name constraints"
6170 }
6171 ValidationError::MissingRevocationInfo => {
6172 "server certificate missing revocation distribution info"
6173 }
6174 ValidationError::MissingRevocationLocator => {
6175 "server certificate missing revocation locator"
6176 }
6177 };
6178 Error::CryptoFailure(message)
6179}
6180
6181fn noxtls_parse_certificate_body(
6182 body: &[u8],
6183 certificate_type: u8,
6184) -> Result<ParsedTls13CertificateBody> {
6185 if body.len() < 4 {
6186 return Err(Error::ParseFailure("certificate body too short"));
6187 }
6188 match certificate_type {
6189 TLS_CERTIFICATE_TYPE_X509 | TLS_CERTIFICATE_TYPE_RAW_PUBLIC_KEY => {}
6190 _ => {
6191 return Err(Error::UnsupportedFeature(
6192 "unsupported certificate message type",
6193 ));
6194 }
6195 }
6196 let context_len = body[0] as usize;
6197 let list_len_offset = 1 + context_len;
6198 if body.len() < list_len_offset + 3 {
6199 return Err(Error::ParseFailure("certificate list length missing"));
6200 }
6201 let cert_list_len = u32::from_be_bytes([
6202 0x00,
6203 body[list_len_offset],
6204 body[list_len_offset + 1],
6205 body[list_len_offset + 2],
6206 ]) as usize;
6207 let cert_list_start = list_len_offset + 3;
6208 let cert_list_end = cert_list_start + cert_list_len;
6209 if cert_list_end > body.len() {
6210 return Err(Error::ParseFailure("certificate list truncated"));
6211 }
6212 let mut certificates = Vec::new();
6213 let mut cursor = &body[cert_list_start..cert_list_end];
6214 let mut leaf_ocsp_staple = None;
6215 while !cursor.is_empty() {
6216 if cursor.len() < 5 {
6217 return Err(Error::ParseFailure("certificate entry truncated"));
6218 }
6219 let cert_len = u32::from_be_bytes([0x00, cursor[0], cursor[1], cursor[2]]) as usize;
6220 let cert_end = 3 + cert_len;
6221 if cursor.len() < cert_end + 2 {
6222 return Err(Error::ParseFailure("certificate bytes truncated"));
6223 }
6224 certificates.push(cursor[3..cert_end].to_vec());
6225 let ext_len = u16::from_be_bytes([cursor[cert_end], cursor[cert_end + 1]]) as usize;
6226 let ext_end = cert_end + 2 + ext_len;
6227 if cursor.len() < ext_end {
6228 return Err(Error::ParseFailure(
6229 "certificate entry extensions truncated",
6230 ));
6231 }
6232 let parsed_staple =
6233 noxtls_parse_certificate_entry_extensions(&cursor[cert_end + 2..ext_end])?;
6234 if certificates.len() == 1 {
6235 leaf_ocsp_staple = parsed_staple;
6236 }
6237 cursor = &cursor[ext_end..];
6238 }
6239 if certificates.is_empty() {
6240 return Err(Error::ParseFailure("certificate list must not be empty"));
6241 }
6242 if certificate_type == TLS_CERTIFICATE_TYPE_RAW_PUBLIC_KEY {
6243 if certificates.len() != 1 {
6244 return Err(Error::ParseFailure(
6245 "raw public key certificate list must contain exactly one entry",
6246 ));
6247 }
6248 noxtls_parse_spki_public_key_info_der(&certificates[0])?;
6249 }
6250 if cert_list_end != body.len() {
6251 return Err(Error::ParseFailure("certificate body trailing bytes"));
6252 }
6253 Ok(ParsedTls13CertificateBody {
6254 certificate_type,
6255 certificates,
6256 leaf_ocsp_staple,
6257 })
6258}
6259
6260fn noxtls_parse_tls12_certificate_list(body: &[u8]) -> Result<Vec<Vec<u8>>> {
6278 if body.len() < 3 {
6279 return Err(Error::ParseFailure(
6280 "tls12 certificate message is malformed",
6281 ));
6282 }
6283 let list_len = ((body[0] as usize) << 16) | ((body[1] as usize) << 8) | body[2] as usize;
6284 if list_len == 0 || list_len != body.len() - 3 {
6285 return Err(Error::ParseFailure(
6286 "tls12 certificate list length is malformed",
6287 ));
6288 }
6289 let mut certificates = Vec::new();
6290 let mut cursor = &body[3..];
6291 while !cursor.is_empty() {
6292 if cursor.len() < 3 {
6293 return Err(Error::ParseFailure(
6294 "tls12 certificate entry length is truncated",
6295 ));
6296 }
6297 let cert_len =
6298 ((cursor[0] as usize) << 16) | ((cursor[1] as usize) << 8) | cursor[2] as usize;
6299 if cert_len == 0 {
6300 return Err(Error::ParseFailure(
6301 "tls12 certificate entry must not be empty",
6302 ));
6303 }
6304 if cursor.len() < 3 + cert_len {
6305 return Err(Error::ParseFailure("tls12 certificate entry is truncated"));
6306 }
6307 certificates.push(cursor[3..3 + cert_len].to_vec());
6308 cursor = &cursor[3 + cert_len..];
6309 }
6310 if certificates.is_empty() {
6311 return Err(Error::ParseFailure(
6312 "tls12 certificate list must not be empty",
6313 ));
6314 }
6315 Ok(certificates)
6316}
6317
6318#[derive(Clone, Copy, Debug, Eq, PartialEq)]
6319enum Tls12KeyExchangeKind {
6320 EcdheSigned,
6321 DheSigned,
6322 StaticRsa,
6323 Psk,
6324 Ecjpake,
6325}
6326
6327fn noxtls_tls12_key_exchange_kind(suite: CipherSuite) -> Result<Tls12KeyExchangeKind> {
6328 match suite {
6329 CipherSuite::TlsEcdheRsaWithAes128GcmSha256
6330 | CipherSuite::TlsEcdheRsaWithAes256GcmSha384
6331 | CipherSuite::TlsEcdheRsaWithAes128CbcSha
6332 | CipherSuite::TlsEcdheRsaWithChacha20Poly1305Sha256
6333 | CipherSuite::TlsEcdheEcdsaWithAes128GcmSha256
6334 | CipherSuite::TlsEcdheEcdsaWithAes256GcmSha384
6335 | CipherSuite::TlsEcdheEcdsaWithChacha20Poly1305Sha256
6336 | CipherSuite::TlsEcdheEcdsaWithAes128CcmSha256
6337 | CipherSuite::TlsEcdheEcdsaWithAes256CcmSha256
6338 | CipherSuite::TlsEcdheEcdsaWithAes128Ccm8Sha256
6339 | CipherSuite::TlsEcdheEcdsaWithAes256Ccm8Sha256 => Ok(Tls12KeyExchangeKind::EcdheSigned),
6340 CipherSuite::TlsDheRsaWithChacha20Poly1305Sha256
6341 | CipherSuite::TlsDheRsaWithAes128GcmSha256
6342 | CipherSuite::TlsDheRsaWithAes256GcmSha384
6343 | CipherSuite::TlsDheRsaWithAes128CcmSha256
6344 | CipherSuite::TlsDheRsaWithAes256CcmSha256
6345 | CipherSuite::TlsDheRsaWithAes128Ccm8Sha256
6346 | CipherSuite::TlsDheRsaWithAes256Ccm8Sha256 => Ok(Tls12KeyExchangeKind::DheSigned),
6347 CipherSuite::TlsRsaWithAes128CbcSha
6348 | CipherSuite::TlsRsaWithAes128GcmSha256
6349 | CipherSuite::TlsRsaWithAes256GcmSha384
6350 | CipherSuite::TlsRsaWithAes128CcmSha256
6351 | CipherSuite::TlsRsaWithAes256CcmSha256
6352 | CipherSuite::TlsRsaWithAes128Ccm8Sha256
6353 | CipherSuite::TlsRsaWithAes256Ccm8Sha256 => Ok(Tls12KeyExchangeKind::StaticRsa),
6354 CipherSuite::TlsPskWithAes128Ccm8Sha256 => Ok(Tls12KeyExchangeKind::Psk),
6355 CipherSuite::TlsEcjpakeWithAes128Ccm8Sha256 => Ok(Tls12KeyExchangeKind::Ecjpake),
6356 _ => Err(Error::UnsupportedFeature(
6357 "tls12 handshake key exchange requires a tls 1.2 cipher suite",
6358 )),
6359 }
6360}
6361
6362fn noxtls_parse_tls12_server_key_exchange_body(suite: CipherSuite, body: &[u8]) -> Result<()> {
6363 match noxtls_tls12_key_exchange_kind(suite)? {
6364 Tls12KeyExchangeKind::StaticRsa => {
6365 if body.is_empty() {
6366 Ok(())
6367 } else {
6368 Err(Error::ParseFailure(
6369 "tls12 rsa key transport must omit server key exchange",
6370 ))
6371 }
6372 }
6373 Tls12KeyExchangeKind::Psk => noxtls_parse_tls12_psk_server_key_exchange_body(body),
6374 Tls12KeyExchangeKind::Ecjpake => noxtls_parse_tls12_ecjpake_key_exchange_body(
6375 body,
6376 "tls12 ecjpake server key exchange body must not be empty",
6377 ),
6378 Tls12KeyExchangeKind::EcdheSigned => {
6379 noxtls_parse_tls12_ecdhe_server_key_exchange_body(body)
6380 }
6381 Tls12KeyExchangeKind::DheSigned => noxtls_parse_tls12_dhe_server_key_exchange_body(body),
6382 }
6383}
6384
6385fn noxtls_parse_tls12_client_key_exchange_body(suite: CipherSuite, body: &[u8]) -> Result<()> {
6386 match noxtls_tls12_key_exchange_kind(suite)? {
6387 Tls12KeyExchangeKind::StaticRsa => {
6388 noxtls_parse_tls12_u16_opaque(body, "tls12 rsa encrypted pre-master secret")
6389 }
6390 Tls12KeyExchangeKind::EcdheSigned => {
6391 noxtls_parse_tls12_u8_opaque(body, "tls12 ecdhe client key exchange public key")
6392 }
6393 Tls12KeyExchangeKind::DheSigned => {
6394 noxtls_parse_tls12_u16_opaque(body, "tls12 dhe client public key")
6395 }
6396 Tls12KeyExchangeKind::Psk => noxtls_parse_tls12_u16_opaque(body, "tls12 psk identity"),
6397 Tls12KeyExchangeKind::Ecjpake => noxtls_parse_tls12_ecjpake_key_exchange_body(
6398 body,
6399 "tls12 ecjpake client key exchange body must not be empty",
6400 ),
6401 }
6402}
6403
6404fn noxtls_parse_tls12_ecdhe_server_key_exchange_body(body: &[u8]) -> Result<()> {
6405 if body.len() < 8 {
6406 return Err(Error::ParseFailure(
6407 "tls12 ecdhe server key exchange body must include key share and signature fields",
6408 ));
6409 }
6410 if body[0] != 0x03 {
6411 return Err(Error::ParseFailure(
6412 "tls12 ecdhe server key exchange requires named_curve parameters",
6413 ));
6414 }
6415 let public_len = body[3] as usize;
6416 if public_len == 0 {
6417 return Err(Error::ParseFailure(
6418 "tls12 ecdhe server key exchange public key must not be empty",
6419 ));
6420 }
6421 let signature_header_offset = 4 + public_len;
6422 noxtls_parse_tls12_signature_tail(body, signature_header_offset)
6423}
6424
6425fn noxtls_parse_tls12_dhe_server_key_exchange_body(body: &[u8]) -> Result<()> {
6426 let _ = noxtls_tls12_dhe_server_key_exchange_values(body)?;
6427 Ok(())
6428}
6429
6430fn noxtls_tls12_dhe_server_key_exchange_values(body: &[u8]) -> Result<(Vec<u8>, Vec<u8>, Vec<u8>)> {
6431 let (prime, cursor) = noxtls_parse_tls12_u16_opaque_value(body, "tls12 dhe prime")?;
6432 let (generator, cursor) = noxtls_parse_tls12_u16_opaque_value(cursor, "tls12 dhe generator")?;
6433 let (server_public, cursor) =
6434 noxtls_parse_tls12_u16_opaque_value(cursor, "tls12 dhe server public key")?;
6435 let signature_header_offset = body.len() - cursor.len();
6436 noxtls_parse_tls12_signature_tail(body, signature_header_offset)?;
6437 Ok((prime.to_vec(), generator.to_vec(), server_public.to_vec()))
6438}
6439
6440fn noxtls_parse_tls12_psk_server_key_exchange_body(body: &[u8]) -> Result<()> {
6441 if body.len() < 2 {
6442 return Err(Error::ParseFailure(
6443 "tls12 psk server key exchange missing identity hint length",
6444 ));
6445 }
6446 let hint_len = u16::from_be_bytes([body[0], body[1]]) as usize;
6447 if body.len() != 2 + hint_len {
6448 return Err(Error::ParseFailure(
6449 "tls12 psk server key exchange identity hint length is malformed",
6450 ));
6451 }
6452 Ok(())
6453}
6454
6455fn noxtls_parse_tls12_ecjpake_key_exchange_body(body: &[u8], message: &'static str) -> Result<()> {
6456 if body.is_empty() {
6457 Err(Error::ParseFailure(message))
6458 } else {
6459 Ok(())
6460 }
6461}
6462
6463fn noxtls_parse_tls12_u8_opaque(body: &[u8], _label: &'static str) -> Result<()> {
6464 if body.is_empty() {
6465 return Err(Error::ParseFailure(
6466 "tls12 client key exchange body must not be empty",
6467 ));
6468 }
6469 let len = body[0] as usize;
6470 if len == 0 {
6471 return Err(Error::ParseFailure(
6472 "tls12 client key exchange value must not be empty",
6473 ));
6474 }
6475 if body.len() != 1 + len {
6476 return Err(Error::ParseFailure(
6477 "tls12 client key exchange length is malformed",
6478 ));
6479 }
6480 Ok(())
6481}
6482
6483fn noxtls_parse_tls12_u16_opaque(body: &[u8], label: &'static str) -> Result<()> {
6484 let (_value, remaining) = noxtls_parse_tls12_u16_opaque_value(body, label)?;
6485 if remaining.is_empty() {
6486 Ok(())
6487 } else {
6488 Err(Error::ParseFailure(
6489 "tls12 client key exchange has trailing bytes",
6490 ))
6491 }
6492}
6493
6494fn noxtls_tls12_u16_opaque_value(body: &[u8], label: &'static str) -> Result<Vec<u8>> {
6495 let (value, remaining) = noxtls_parse_tls12_u16_opaque_value(body, label)?;
6496 if !remaining.is_empty() {
6497 return Err(Error::ParseFailure(
6498 "tls12 client key exchange has trailing bytes",
6499 ));
6500 }
6501 Ok(value.to_vec())
6502}
6503
6504fn noxtls_parse_tls12_u16_opaque_value<'a>(
6505 body: &'a [u8],
6506 _label: &'static str,
6507) -> Result<(&'a [u8], &'a [u8])> {
6508 if body.len() < 2 {
6509 return Err(Error::ParseFailure("tls12 opaque vector missing length"));
6510 }
6511 let len = u16::from_be_bytes([body[0], body[1]]) as usize;
6512 if len == 0 {
6513 return Err(Error::ParseFailure("tls12 opaque vector must not be empty"));
6514 }
6515 if body.len() < 2 + len {
6516 return Err(Error::ParseFailure("tls12 opaque vector is truncated"));
6517 }
6518 Ok((&body[2..2 + len], &body[2 + len..]))
6519}
6520
6521fn noxtls_parse_tls12_signature_tail(body: &[u8], offset: usize) -> Result<()> {
6522 noxtls_parse_tls12_signature_fields(body, offset).map(|_| ())
6523}
6524
6525fn noxtls_parse_tls12_certificate_verify_body(body: &[u8]) -> Result<()> {
6526 if body.len() < 4 {
6527 return Err(Error::ParseFailure(
6528 "tls12 client certificate verify body must include signature scheme and length",
6529 ));
6530 }
6531 let signature_scheme = u16::from_be_bytes([body[0], body[1]]);
6532 if !noxtls_tls12_signature_scheme_is_modern(signature_scheme) {
6533 return Err(Error::ParseFailure(
6534 "tls12 client certificate verify uses unsupported signature scheme",
6535 ));
6536 }
6537 let signature_len = u16::from_be_bytes([body[2], body[3]]) as usize;
6538 if signature_len == 0 {
6539 return Err(Error::ParseFailure(
6540 "tls12 client certificate verify signature must not be empty",
6541 ));
6542 }
6543 if body.len() != 4 + signature_len {
6544 return Err(Error::ParseFailure(
6545 "tls12 client certificate verify signature length is malformed",
6546 ));
6547 }
6548 Ok(())
6549}
6550
6551fn noxtls_tls12_signature_scheme_is_modern(signature_scheme: u16) -> bool {
6565 matches!(
6566 signature_scheme,
6567 TLS13_SIGALG_ECDSA_SECP256R1_SHA256
6568 | TLS13_SIGALG_ECDSA_SECP384R1_SHA384
6569 | TLS13_SIGALG_ECDSA_SECP521R1_SHA512
6570 | TLS13_SIGALG_RSA_PSS_RSAE_SHA256
6571 | TLS13_SIGALG_RSA_PSS_RSAE_SHA384
6572 | TLS13_SIGALG_RSA_PSS_RSAE_SHA512
6573 | TLS13_SIGALG_RSA_PSS_PSS_SHA256
6574 | TLS13_SIGALG_RSA_PSS_PSS_SHA384
6575 | TLS13_SIGALG_RSA_PSS_PSS_SHA512
6576 | TLS13_SIGALG_ED25519
6577 | TLS13_SIGALG_MLDSA65
6578 )
6579}
6580
6581fn noxtls_parse_certificate_entry_extensions(input: &[u8]) -> Result<Option<Vec<u8>>> {
6600 let mut cursor = input;
6601 let mut seen_extension_types = Vec::new();
6602 let mut status_request_ocsp = None;
6603 while !cursor.is_empty() {
6604 if cursor.len() < 4 {
6605 return Err(Error::ParseFailure(
6606 "certificate entry extension header truncated",
6607 ));
6608 }
6609 let ext_type = u16::from_be_bytes([cursor[0], cursor[1]]);
6610 let ext_len = u16::from_be_bytes([cursor[2], cursor[3]]) as usize;
6611 if seen_extension_types.contains(&ext_type) {
6612 return Err(Error::ParseFailure(
6613 "duplicate certificate entry extension type",
6614 ));
6615 }
6616 seen_extension_types.push(ext_type);
6617 cursor = &cursor[4..];
6618 if cursor.len() < ext_len {
6619 return Err(Error::ParseFailure("certificate entry extension truncated"));
6620 }
6621 let ext_data = &cursor[..ext_len];
6622 if ext_type == EXT_STATUS_REQUEST {
6623 if status_request_ocsp.is_some() {
6624 return Err(Error::ParseFailure(
6625 "duplicate certificate entry status_request extension",
6626 ));
6627 }
6628 status_request_ocsp = Some(noxtls_parse_certificate_entry_status_request_extension(
6629 ext_data,
6630 )?);
6631 }
6632 cursor = &cursor[ext_len..];
6633 }
6634 Ok(status_request_ocsp)
6635}
6636
6637fn noxtls_encode_certificate_entry_status_request_extension(ocsp_staple: &[u8]) -> Result<Vec<u8>> {
6639 if ocsp_staple.is_empty() {
6640 return Err(Error::InvalidLength("ocsp staple must not be empty"));
6641 }
6642 if ocsp_staple.len() > 0x00FF_FFFF {
6643 return Err(Error::InvalidLength("ocsp staple is too large"));
6644 }
6645 let mut status_request_payload = Vec::new();
6646 status_request_payload.push(0x01); let staple_len = ocsp_staple.len() as u32;
6648 status_request_payload.extend_from_slice(&staple_len.to_be_bytes()[1..4]);
6649 status_request_payload.extend_from_slice(ocsp_staple);
6650
6651 let mut extension = Vec::new();
6652 extension.extend_from_slice(&EXT_STATUS_REQUEST.to_be_bytes());
6653 extension.extend_from_slice(&(status_request_payload.len() as u16).to_be_bytes());
6654 extension.extend_from_slice(&status_request_payload);
6655 Ok(extension)
6656}
6657
6658pub fn noxtls_parse_tls13_ocsp_staple_info(
6660 ocsp_response_der: &[u8],
6661 validation_time: &str,
6662) -> Result<Tls13OcspStapleInfo> {
6663 let now = noxtls_canonical_ocsp_time(validation_time)
6664 .ok_or(Error::ParseFailure("invalid ocsp validation time"))?;
6665 let (outer, rest) = noxtls_parse_der_node(ocsp_response_der)?;
6666 if outer.tag != 0x30 || !rest.is_empty() {
6667 return Err(Error::ParseFailure("ocsp response must be a DER sequence"));
6668 }
6669 let (status, cursor) = noxtls_parse_der_node(outer.body)?;
6670 if status.tag != 0x0A || status.body.len() != 1 {
6671 return Err(Error::ParseFailure("ocsp response status is malformed"));
6672 }
6673 if status.body[0] != 0 {
6674 return Err(Error::ParseFailure(
6675 "ocsp response status is not successful",
6676 ));
6677 }
6678 if cursor.is_empty() {
6679 return Err(Error::ParseFailure(
6680 "successful ocsp response missing responseBytes",
6681 ));
6682 }
6683 let (response_bytes_explicit, after_response_bytes) = noxtls_parse_der_node(cursor)?;
6684 if response_bytes_explicit.tag != 0xA0 || !after_response_bytes.is_empty() {
6685 return Err(Error::ParseFailure("ocsp responseBytes is malformed"));
6686 }
6687 let (response_bytes, response_bytes_rest) =
6688 noxtls_parse_der_node(response_bytes_explicit.body)?;
6689 if response_bytes.tag != 0x30 || !response_bytes_rest.is_empty() {
6690 return Err(Error::ParseFailure("ocsp ResponseBytes must be a sequence"));
6691 }
6692 let (response_type, response_payload_cursor) = noxtls_parse_der_node(response_bytes.body)?;
6693 if response_type.tag != 0x06 || response_type.body != OCSP_BASIC_RESPONSE_OID_DER {
6694 return Err(Error::UnsupportedFeature("unsupported ocsp response type"));
6695 }
6696 let (response_octets, response_payload_rest) = noxtls_parse_der_node(response_payload_cursor)?;
6697 if response_octets.tag != 0x04 || !response_payload_rest.is_empty() {
6698 return Err(Error::ParseFailure(
6699 "ocsp basic response octets are malformed",
6700 ));
6701 }
6702 noxtls_parse_tls13_basic_ocsp_response(response_octets.body, &now)
6703}
6704
6705pub fn noxtls_verify_tls13_ocsp_staple(
6707 ocsp_response_der: &[u8],
6708 validation_time: &str,
6709) -> Result<Tls13OcspStapleVerification> {
6710 Ok(noxtls_parse_tls13_ocsp_staple_info(ocsp_response_der, validation_time)?.status)
6711}
6712
6713const OCSP_BASIC_RESPONSE_OID_DER: &[u8] = &[0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01];
6714
6715fn noxtls_parse_tls13_basic_ocsp_response(
6716 basic_response_der: &[u8],
6717 now: &str,
6718) -> Result<Tls13OcspStapleInfo> {
6719 let (basic_response, rest) = noxtls_parse_der_node(basic_response_der)?;
6720 if basic_response.tag != 0x30 || !rest.is_empty() {
6721 return Err(Error::ParseFailure(
6722 "ocsp BasicOCSPResponse must be a sequence",
6723 ));
6724 }
6725 let (response_data, _) = noxtls_parse_der_node(basic_response.body)?;
6726 if response_data.tag != 0x30 {
6727 return Err(Error::ParseFailure("ocsp ResponseData must be a sequence"));
6728 }
6729 noxtls_parse_tls13_ocsp_response_data(response_data.body, now)
6730}
6731
6732fn noxtls_parse_tls13_ocsp_response_data(
6733 mut cursor: &[u8],
6734 now: &str,
6735) -> Result<Tls13OcspStapleInfo> {
6736 if cursor.is_empty() {
6737 return Err(Error::ParseFailure("ocsp ResponseData is empty"));
6738 }
6739 let (first, rest_after_first) = noxtls_parse_der_node(cursor)?;
6740 cursor = if first.tag == 0xA0 {
6741 rest_after_first
6742 } else {
6743 cursor
6744 };
6745 let (_responder_id, after_responder_id) = noxtls_parse_der_node(cursor)?;
6746 let (produced_at_node, after_produced_at) = noxtls_parse_der_node(after_responder_id)?;
6747 let produced_at = noxtls_ocsp_time_from_node(&produced_at_node)?;
6748 if produced_at.as_str() > now {
6749 return Err(Error::ParseFailure(
6750 "ocsp response producedAt is in the future",
6751 ));
6752 }
6753 let (responses, _after_responses) = noxtls_parse_der_node(after_produced_at)?;
6754 if responses.tag != 0x30 {
6755 return Err(Error::ParseFailure("ocsp responses must be a sequence"));
6756 }
6757 let mut response_cursor = responses.body;
6758 let mut first_info: Option<Tls13OcspStapleInfo> = None;
6759 while !response_cursor.is_empty() {
6760 let (single_response, rest) = noxtls_parse_der_node(response_cursor)?;
6761 if single_response.tag != 0x30 {
6762 return Err(Error::ParseFailure(
6763 "ocsp SingleResponse must be a sequence",
6764 ));
6765 }
6766 let info =
6767 noxtls_parse_tls13_ocsp_single_response(single_response.body, now, &produced_at)?;
6768 if info.status == Tls13OcspStapleVerification::Revoked {
6769 return Ok(info);
6770 }
6771 if first_info.is_none() {
6772 first_info = Some(info);
6773 }
6774 response_cursor = rest;
6775 }
6776 first_info.ok_or(Error::ParseFailure(
6777 "ocsp response contains no SingleResponse",
6778 ))
6779}
6780
6781fn noxtls_parse_tls13_ocsp_single_response(
6782 mut cursor: &[u8],
6783 now: &str,
6784 produced_at: &str,
6785) -> Result<Tls13OcspStapleInfo> {
6786 let (_cert_id, after_cert_id) = noxtls_parse_der_node(cursor)?;
6787 cursor = after_cert_id;
6788 let (cert_status, after_status) = noxtls_parse_der_node(cursor)?;
6789 cursor = after_status;
6790 let status = match cert_status.tag {
6791 0x80 => Tls13OcspStapleVerification::Good,
6792 0xA1 | 0x81 => Tls13OcspStapleVerification::Revoked,
6793 0x82 | 0xA2 => return Err(Error::ParseFailure("ocsp certificate status is unknown")),
6794 _ => return Err(Error::ParseFailure("ocsp certificate status is malformed")),
6795 };
6796 let (this_update_node, after_this_update) = noxtls_parse_der_node(cursor)?;
6797 let this_update = noxtls_ocsp_time_from_node(&this_update_node)?;
6798 let mut next_update = None;
6799 cursor = after_this_update;
6800 if !cursor.is_empty() {
6801 let (maybe_next_update, _after_next_update) = noxtls_parse_der_node(cursor)?;
6802 if maybe_next_update.tag == 0xA0 {
6803 let (time_node, time_rest) = noxtls_parse_der_node(maybe_next_update.body)?;
6804 if !time_rest.is_empty() {
6805 return Err(Error::ParseFailure("ocsp nextUpdate has trailing bytes"));
6806 }
6807 next_update = Some(noxtls_ocsp_time_from_node(&time_node)?);
6808 }
6809 }
6810 if status == Tls13OcspStapleVerification::Revoked {
6811 return Ok(Tls13OcspStapleInfo {
6812 produced_at: produced_at.to_owned(),
6813 this_update,
6814 next_update,
6815 status,
6816 });
6817 }
6818 let is_fresh = this_update.as_str() <= now
6819 && next_update
6820 .as_deref()
6821 .map(|value| now <= value)
6822 .unwrap_or(true);
6823 Ok(Tls13OcspStapleInfo {
6824 produced_at: produced_at.to_owned(),
6825 this_update,
6826 next_update,
6827 status: if is_fresh {
6828 Tls13OcspStapleVerification::Good
6829 } else {
6830 Tls13OcspStapleVerification::Expired
6831 },
6832 })
6833}
6834
6835fn noxtls_ocsp_time_from_node(node: &noxtls_x509::DerNode) -> Result<String> {
6836 if node.tag != 0x17 && node.tag != 0x18 {
6837 return Err(Error::ParseFailure(
6838 "ocsp time must be UTCTime or GeneralizedTime",
6839 ));
6840 }
6841 let text = core::str::from_utf8(node.body)
6842 .map_err(|_| Error::ParseFailure("ocsp time is not valid utf-8"))?;
6843 noxtls_canonical_ocsp_time(text).ok_or(Error::ParseFailure("invalid ocsp time"))
6844}
6845
6846fn noxtls_canonical_ocsp_time(input: &str) -> Option<String> {
6847 if input.len() == 15 && input.ends_with("Z") {
6848 let body = &input[..14];
6849 if body.chars().all(|c| c.is_ascii_digit()) {
6850 return Some(input.to_owned());
6851 }
6852 return None;
6853 }
6854 if input.len() == 13 && input.ends_with("Z") {
6855 let yy = &input[..2];
6856 let rest = &input[2..12];
6857 if !yy.chars().all(|c| c.is_ascii_digit()) || !rest.chars().all(|c| c.is_ascii_digit()) {
6858 return None;
6859 }
6860 let yy_value = yy.parse::<u32>().ok()?;
6861 let century = if yy_value >= 50 { "19" } else { "20" };
6862 return Some(format!("{century}{yy}{rest}Z"));
6863 }
6864 None
6865}
6866
6867fn noxtls_parse_certificate_entry_status_request_extension(input: &[u8]) -> Result<Vec<u8>> {
6869 if input.len() < 4 {
6870 return Err(Error::ParseFailure(
6871 "certificate entry status_request extension is truncated",
6872 ));
6873 }
6874 if input[0] != 0x01 {
6875 return Err(Error::ParseFailure(
6876 "certificate entry status_request must use ocsp status type",
6877 ));
6878 }
6879 let ocsp_len = ((input[1] as usize) << 16) | ((input[2] as usize) << 8) | input[3] as usize;
6880 if ocsp_len == 0 {
6881 return Err(Error::ParseFailure(
6882 "certificate entry status_request ocsp response must not be empty",
6883 ));
6884 }
6885 if input.len() != 4 + ocsp_len {
6886 return Err(Error::ParseFailure(
6887 "certificate entry status_request ocsp response is truncated",
6888 ));
6889 }
6890 Ok(input[4..].to_vec())
6891}
6892
6893fn noxtls_parse_certificate_verify_fields(body: &[u8]) -> Result<(u16, &[u8])> {
6912 if body.len() < 4 {
6913 return Err(Error::ParseFailure("certificate verify body too short"));
6914 }
6915 let signature_scheme = u16::from_be_bytes([body[0], body[1]]);
6916 let sig_len = u16::from_be_bytes([body[2], body[3]]) as usize;
6917 if body.len() != 4 + sig_len {
6918 return Err(Error::ParseFailure(
6919 "certificate verify signature truncated",
6920 ));
6921 }
6922 Ok((signature_scheme, &body[4..]))
6923}
6924
6925fn noxtls_tls13_supported_certificate_verify_signature_scheme(signature_scheme: u16) -> bool {
6940 matches!(
6941 signature_scheme,
6942 TLS13_SIGALG_ECDSA_SECP256R1_SHA256
6943 | TLS13_SIGALG_ECDSA_SECP384R1_SHA384
6944 | TLS13_SIGALG_ECDSA_SECP521R1_SHA512
6945 | TLS13_SIGALG_RSA_PSS_RSAE_SHA256
6946 | TLS13_SIGALG_RSA_PSS_RSAE_SHA384
6947 | TLS13_SIGALG_RSA_PSS_RSAE_SHA512
6948 | TLS13_SIGALG_RSA_PSS_PSS_SHA256
6949 | TLS13_SIGALG_RSA_PSS_PSS_SHA384
6950 | TLS13_SIGALG_RSA_PSS_PSS_SHA512
6951 | TLS13_SIGALG_ED25519
6952 | TLS13_SIGALG_MLDSA65
6953 )
6954}
6955
6956fn noxtls_parse_new_session_ticket_body(body: &[u8]) -> Result<()> {
6975 if body.len() < 11 {
6976 return Err(Error::ParseFailure(
6977 "noxtls_new session ticket body too short",
6978 ));
6979 }
6980 let nonce_len = body[8] as usize;
6981 let ticket_len_offset = 9 + nonce_len;
6982 if body.len() < ticket_len_offset + 2 {
6983 return Err(Error::ParseFailure(
6984 "noxtls_new session ticket nonce truncated",
6985 ));
6986 }
6987 let ticket_len =
6988 u16::from_be_bytes([body[ticket_len_offset], body[ticket_len_offset + 1]]) as usize;
6989 let ext_len_offset = ticket_len_offset + 2 + ticket_len;
6990 if body.len() < ext_len_offset + 2 {
6991 return Err(Error::ParseFailure(
6992 "noxtls_new session ticket bytes truncated",
6993 ));
6994 }
6995 let ext_len = u16::from_be_bytes([body[ext_len_offset], body[ext_len_offset + 1]]) as usize;
6996 if body.len() != ext_len_offset + 2 + ext_len {
6997 return Err(Error::ParseFailure(
6998 "noxtls_new session ticket extensions truncated",
6999 ));
7000 }
7001 Ok(())
7002}
7003
7004fn noxtls_build_tls13_server_certificate_verify_message(noxtls_transcript_hash: &[u8]) -> Vec<u8> {
7019 const PREFIX_LEN: usize = 64;
7020 const CONTEXT: &[u8] = b"TLS 1.3, server CertificateVerify";
7021 let mut out = Vec::with_capacity(PREFIX_LEN + CONTEXT.len() + 1 + noxtls_transcript_hash.len());
7022 out.extend(core::iter::repeat(0x20_u8).take(PREFIX_LEN));
7023 out.extend_from_slice(CONTEXT);
7024 out.push(0x00);
7025 out.extend_from_slice(noxtls_transcript_hash);
7026 out
7027}
7028
7029fn noxtls_build_tls13_client_certificate_verify_message(noxtls_transcript_hash: &[u8]) -> Vec<u8> {
7030 const PREFIX_LEN: usize = 64;
7031 const CONTEXT: &[u8] = b"TLS 1.3, client CertificateVerify";
7032 let mut out = Vec::with_capacity(PREFIX_LEN + CONTEXT.len() + 1 + noxtls_transcript_hash.len());
7033 out.extend(core::iter::repeat(0x20_u8).take(PREFIX_LEN));
7034 out.extend_from_slice(CONTEXT);
7035 out.push(0x00);
7036 out.extend_from_slice(noxtls_transcript_hash);
7037 out
7038}
7039
7040fn noxtls_encode_ecdsa_signature_der(r: &[u8], s: &[u8]) -> Result<Vec<u8>> {
7041 let r_der = noxtls_write_der_integer(r)?;
7042 let s_der = noxtls_write_der_integer(s)?;
7043 let mut body = Vec::with_capacity(r_der.len() + s_der.len());
7044 body.extend_from_slice(&r_der);
7045 body.extend_from_slice(&s_der);
7046 noxtls_write_der_sequence(&body)
7047}
7048
7049fn noxtls_parse_rsa_public_key_der(public_key_der: &[u8]) -> Result<RsaPublicKey> {
7068 let (rsa_seq, rem) = noxtls_parse_der_node(public_key_der)
7069 .map_err(|_| Error::ParseFailure("failed to parse server RSA public key"))?;
7070 if rsa_seq.tag != 0x30 || !rem.is_empty() {
7071 return Err(Error::ParseFailure(
7072 "invalid server RSA public key sequence",
7073 ));
7074 }
7075 let (modulus_node, rest) = noxtls_parse_der_node(rsa_seq.body)
7076 .map_err(|_| Error::ParseFailure("failed to parse server RSA modulus"))?;
7077 let (exponent_node, tail) = noxtls_parse_der_node(rest)
7078 .map_err(|_| Error::ParseFailure("failed to parse server RSA exponent"))?;
7079 if modulus_node.tag != 0x02 || exponent_node.tag != 0x02 || !tail.is_empty() {
7080 return Err(Error::ParseFailure(
7081 "invalid server RSA public key integer fields",
7082 ));
7083 }
7084 RsaPublicKey::from_be_bytes(modulus_node.body, exponent_node.body)
7085 .map_err(|_| Error::CryptoFailure("failed to construct server RSA public key"))
7086}
7087
7088fn noxtls_parse_key_share_groups_extension(input: &[u8]) -> Result<Vec<u16>> {
7107 if input.len() < 2 {
7108 return Err(Error::ParseFailure(
7109 "key_share extension missing list length",
7110 ));
7111 }
7112 let list_len = u16::from_be_bytes([input[0], input[1]]) as usize;
7113 if input.len() != list_len + 2 {
7114 return Err(Error::ParseFailure("invalid key_share extension length"));
7115 }
7116 let mut cursor = &input[2..];
7117 let mut groups = Vec::new();
7118 while !cursor.is_empty() {
7119 if cursor.len() < 4 {
7120 return Err(Error::ParseFailure("key_share entry truncated"));
7121 }
7122 let group = u16::from_be_bytes([cursor[0], cursor[1]]);
7123 let key_len = u16::from_be_bytes([cursor[2], cursor[3]]) as usize;
7124 if groups.contains(&group) {
7125 return Err(Error::ParseFailure("duplicate key_share group"));
7126 }
7127 if key_len == 0 {
7128 return Err(Error::ParseFailure(
7129 "key_share key_exchange must not be empty",
7130 ));
7131 }
7132 cursor = &cursor[4..];
7133 if cursor.len() < key_len {
7134 return Err(Error::ParseFailure("key_share key_exchange truncated"));
7135 }
7136 groups.push(group);
7137 cursor = &cursor[key_len..];
7138 }
7139 Ok(groups)
7140}
7141
7142fn noxtls_validate_tls13_key_share_entry(group: u16, key_exchange: &[u8]) -> Result<()> {
7143 match group {
7144 TLS13_KEY_SHARE_GROUP_SECP256R1 => {
7145 P256PublicKey::from_uncompressed(key_exchange)?;
7146 }
7147 TLS13_KEY_SHARE_GROUP_SECP384R1 => {
7148 P384PublicKey::from_uncompressed(key_exchange)?;
7149 }
7150 TLS13_KEY_SHARE_GROUP_SECP521R1 => {
7151 NamedEcPublicKey::from_uncompressed(NamedCurve::Secp521R1, key_exchange)?;
7152 }
7153 TLS13_KEY_SHARE_GROUP_BRAINPOOLP256R1TLS13 => {
7154 NamedEcPublicKey::from_uncompressed(NamedCurve::BrainpoolP256R1, key_exchange)?;
7155 }
7156 TLS13_KEY_SHARE_GROUP_BRAINPOOLP384R1TLS13 => {
7157 NamedEcPublicKey::from_uncompressed(NamedCurve::BrainpoolP384R1, key_exchange)?;
7158 }
7159 TLS13_KEY_SHARE_GROUP_BRAINPOOLP512R1TLS13 => {
7160 NamedEcPublicKey::from_uncompressed(NamedCurve::BrainpoolP512R1, key_exchange)?;
7161 }
7162 TLS13_KEY_SHARE_GROUP_X25519 if key_exchange.len() != 32 => {
7163 return Err(Error::ParseFailure(
7164 "tls13 key_share entry must contain 32-byte x25519 key_exchange",
7165 ));
7166 }
7167 TLS13_KEY_SHARE_GROUP_X25519 => {}
7168 TLS13_KEY_SHARE_GROUP_X448 => {
7169 if key_exchange.len() != 56 {
7170 return Err(Error::ParseFailure(
7171 "tls13 key_share entry must contain 56-byte x448 key_exchange",
7172 ));
7173 }
7174 let is_zero = key_exchange.iter().all(|byte| *byte == 0);
7175 let is_one = key_exchange[0] == 1 && key_exchange[1..].iter().all(|byte| *byte == 0);
7176 if is_zero || is_one {
7177 return Err(Error::ParseFailure(
7178 "noxtls_x448 peer public key is low-order",
7179 ));
7180 }
7181 }
7182 _ => {}
7183 }
7184 Ok(())
7185}
7186
7187fn noxtls_encode_pre_shared_key_extension(offer: &PskClientOffer<'_>) -> Result<Vec<u8>> {
7206 if offer.identities.is_empty() || offer.binders.is_empty() {
7207 return Err(Error::InvalidLength(
7208 "psk identity/binder list must not be empty",
7209 ));
7210 }
7211 if offer.identities.len() != offer.binders.len() {
7212 return Err(Error::InvalidLength(
7213 "psk identity and binder list lengths must match",
7214 ));
7215 }
7216 let mut identities = Vec::new();
7217 let mut binders = Vec::new();
7218 for (identity, binder) in offer.identities.iter().zip(offer.binders.iter()) {
7219 if identity.identity.is_empty() || binder.is_empty() {
7220 return Err(Error::InvalidLength(
7221 "psk identity and binder must not be empty",
7222 ));
7223 }
7224 if identity.identity.len() > u16::MAX as usize || binder.len() > u8::MAX as usize {
7225 return Err(Error::InvalidLength("psk identity or binder too long"));
7226 }
7227 identities.extend_from_slice(&(identity.identity.len() as u16).to_be_bytes());
7228 identities.extend_from_slice(identity.identity);
7229 identities.extend_from_slice(&identity.obfuscated_ticket_age.to_be_bytes());
7230 binders.push(binder.len() as u8);
7231 binders.extend_from_slice(binder);
7232 }
7233
7234 let mut out = Vec::new();
7235 out.extend_from_slice(&(identities.len() as u16).to_be_bytes());
7236 out.extend_from_slice(&identities);
7237 out.extend_from_slice(&(binders.len() as u16).to_be_bytes());
7238 out.extend_from_slice(&binders);
7239 Ok(out)
7240}
7241
7242fn noxtls_parse_pre_shared_key_extension(
7261 input: &[u8],
7262) -> Result<(usize, Vec<Vec<u8>>, Vec<u32>, Vec<Vec<u8>>)> {
7263 if input.len() < 4 {
7264 return Err(Error::ParseFailure("pre_shared_key extension too short"));
7265 }
7266 let identities_len = u16::from_be_bytes([input[0], input[1]]) as usize;
7267 if input.len() < 2 + identities_len + 2 {
7268 return Err(Error::ParseFailure("pre_shared_key identities truncated"));
7269 }
7270 let identities_end = 2 + identities_len;
7271 let mut id_cursor = &input[2..identities_end];
7272 let mut identity_count = 0_usize;
7273 let mut identities = Vec::new();
7274 let mut obfuscated_ages = Vec::new();
7275 while !id_cursor.is_empty() {
7276 if id_cursor.len() < 6 {
7277 return Err(Error::ParseFailure(
7278 "pre_shared_key identity entry truncated",
7279 ));
7280 }
7281 let id_len = u16::from_be_bytes([id_cursor[0], id_cursor[1]]) as usize;
7282 if id_len == 0 {
7283 return Err(Error::ParseFailure(
7284 "pre_shared_key identity must not be empty",
7285 ));
7286 }
7287 if id_cursor.len() < 2 + id_len + 4 {
7288 return Err(Error::ParseFailure(
7289 "pre_shared_key identity bytes truncated",
7290 ));
7291 }
7292 let identity = id_cursor[2..2 + id_len].to_vec();
7293 if identities.iter().any(|existing| existing == &identity) {
7294 return Err(Error::ParseFailure("duplicate pre_shared_key identity"));
7295 }
7296 identities.push(identity);
7297 obfuscated_ages.push(u32::from_be_bytes([
7298 id_cursor[2 + id_len],
7299 id_cursor[3 + id_len],
7300 id_cursor[4 + id_len],
7301 id_cursor[5 + id_len],
7302 ]));
7303 identity_count = identity_count.saturating_add(1);
7304 id_cursor = &id_cursor[2 + id_len + 4..];
7305 }
7306
7307 let binders_len =
7308 u16::from_be_bytes([input[identities_end], input[identities_end + 1]]) as usize;
7309 let binders_start = identities_end + 2;
7310 let binders_end = binders_start + binders_len;
7311 if input.len() != binders_end {
7312 return Err(Error::ParseFailure(
7313 "invalid pre_shared_key binder vector length",
7314 ));
7315 }
7316 let mut binders = Vec::new();
7317 let mut binder_cursor = &input[binders_start..binders_end];
7318 while !binder_cursor.is_empty() {
7319 let binder_len = binder_cursor[0] as usize;
7320 if binder_len == 0 {
7321 return Err(Error::ParseFailure(
7322 "pre_shared_key binder must not be empty",
7323 ));
7324 }
7325 binder_cursor = &binder_cursor[1..];
7326 if binder_cursor.len() < binder_len {
7327 return Err(Error::ParseFailure("pre_shared_key binder bytes truncated"));
7328 }
7329 binders.push(binder_cursor[..binder_len].to_vec());
7330 binder_cursor = &binder_cursor[binder_len..];
7331 }
7332 if identity_count != binders.len() {
7333 return Err(Error::ParseFailure(
7334 "pre_shared_key identity and binder counts differ",
7335 ));
7336 }
7337 if identity_count == 0 {
7338 return Err(Error::ParseFailure(
7339 "pre_shared_key extension must include at least one identity",
7340 ));
7341 }
7342 Ok((identity_count, identities, obfuscated_ages, binders))
7343}
7344
7345fn noxtls_legacy_wire_version(version: TlsVersion) -> [u8; 2] {
7360 match version {
7361 TlsVersion::Tls10 => [0x03, 0x01],
7362 TlsVersion::Tls11 => [0x03, 0x02],
7363 TlsVersion::Tls12 | TlsVersion::Tls13 => [0x03, 0x03],
7364 TlsVersion::Dtls12 | TlsVersion::Dtls13 => [0xFE, 0xFD],
7365 }
7366}