Skip to main content

tls2/
client.rs

1use core::ops::{Deref, DerefMut};
2
3use heapless::Vec;
4
5use crate::{
6    ALPN_PROTOCOL_MAX_SIZE, CertType, CipherSuite, CryptoProvider, Hash, KEY_EXCHANGE_MAX_GROUPS, KeyExchangeGroup,
7    KeyExchangePublicKey, KeyExchangeSecretKey, PSK_MAX_SIZE, ReceivedCertificate, SIGNING_PUBLIC_KEY_MAX_SIZE,
8    SignatureScheme,
9    errors::Error,
10    key_schedule, message,
11    record::{self, ContentType, RecordHeader, decrypt_record, encrypt_record},
12};
13
14/// Trait for buffer types that can hold TLS record data.
15///
16/// Automatically implemented for any type that implements
17/// [`Deref<Target = [u8]>`] + [`DerefMut`], such as `Vec<u8>` (owned),
18/// `&mut [u8]` (borrowed), `Box<[u8]>`, and `bytes::BytesMut`.
19pub trait Buffer: Deref<Target = [u8]> + DerefMut {}
20impl<T: Deref<Target = [u8]> + DerefMut> Buffer for T {}
21
22/// Configuration for a TLS 1.3 client connection.
23///
24/// Created via [`ClientConfig::new`] with a [`CryptoProvider`]. The provider
25/// supplies all cryptographic primitives (AEAD, key exchange, signatures)
26/// and certificate validation.
27///
28/// By default only X.509 certificates are negotiated. Call
29/// [`with_certificate_types`][Self::with_certificate_types] to also accept
30/// RawPublicKey certificates (RFC 7250).
31#[derive(Clone)]
32pub struct ClientConfig<C: CryptoProvider> {
33    crypto_provider: C,
34    supported_certificate_types: heapless::Vec<CertType, 2>,
35}
36
37impl<C: CryptoProvider> ClientConfig<C> {
38    /// Create a new client configuration backed by the given crypto provider.
39    ///
40    /// The initial configuration accepts X.509 certificates only.
41    pub fn new(crypto_provider: C) -> Self {
42        Self {
43            crypto_provider,
44            supported_certificate_types: [CertType::X509].into(),
45        }
46    }
47    /// Set the set of acceptable certificate types.
48    ///
49    /// The default is `[CertType::X509]`. To also negotiate raw public keys
50    /// (RFC 7250), pass `&[CertType::X509, CertType::RawPublicKey]`.
51    ///
52    /// # Errors
53    ///
54    /// Returns [`Error::InvalidConfiguration`] when more than two types are
55    /// supplied.
56    pub fn with_certificate_types(mut self, types: &[CertType]) -> Result<Self, Error> {
57        self.supported_certificate_types = types.try_into().map_err(|_| Error::InvalidConfiguration)?;
58        Ok(self)
59    }
60}
61
62/// A sans-IO TLS 1.3 client state machine.
63///
64/// The client progresses through the handshake phases:
65///
66/// | Phase | What happens |
67/// |-------|-------------|
68/// | [`ClientHello`](Phase::ClientHello) | Waiting for [`start_handshake`](Self::start_handshake) to write the ClientHello |
69/// | [`ServerHello`](Phase::ServerHello) / [`ServerFlight`](Phase::ServerFlight) | Processing the server's response |
70/// | [`ClientFinished`](Phase::ClientFinished) | Sending the client Finished, then app keys are installed |
71/// | [`ApplicationData`](Phase::ApplicationData) | Connection is established; use [`encrypt`](Self::encrypt) / [`decrypt`](Self::decrypt) |
72/// | [`Closed`](Phase::Closed) | Connection has been terminated |
73///
74/// The caller is responsible for all network I/O. Use [`receive_buffer`](Self::receive_buffer)
75/// and [`commit_received`](Self::commit_received) to feed data in, and
76/// [`outgoing_data`](Self::outgoing_data) to extract data to send.
77///
78/// # Panics
79///
80/// Methods that dereference [`suite`](CipherSuite) (e.g. [`encrypt`](Self::encrypt),
81/// [`decrypt`](Self::decrypt)) will panic if called before the handshake completes.
82pub struct Client<B: Buffer, C: CryptoProvider> {
83    pub(crate) config: ClientConfig<C>,
84    pub(crate) receive_buffer: B,
85    pub(crate) send_buffer: B,
86
87    // ── Buffer tracking ──
88    pub(crate) receive_decoded: usize,
89    pub(crate) receive_pending: usize,
90    pub(crate) out_len: usize,
91    pub(crate) send_consumed: usize,
92
93    pub(crate) app_data_offset: usize,
94    pub(crate) app_data_decrypted_len: usize,
95    pub(crate) app_data_consumed: usize,
96    pub(crate) key_update_response: heapless::Vec<u8, 256>,
97    pub(crate) key_update_sent: usize,
98    pub(crate) ticket_offset: usize,
99    pub(crate) ticket_len: usize,
100
101    // ── Connection state ──
102    pub(crate) phase: Phase,
103    pub(crate) opened: bool,
104
105    // ── Negotiated ──
106    pub(crate) ciphersuite: Option<CipherSuite>,
107    pub(crate) alpn: Option<heapless::Vec<u8, ALPN_PROTOCOL_MAX_SIZE>>,
108    pub(crate) negotiated_cert_type: CertType,
109
110    // ── Key exchange ──
111    pub(crate) key_exchange_group: KeyExchangeGroup,
112    pub(crate) key_exchange_pairs: heapless::Vec<KeyExchangeSecretKey, KEY_EXCHANGE_MAX_GROUPS>,
113
114    // ── Key schedule ──
115    pub(crate) keys: KeySchedule<C>,
116
117    // ── Handshake-only (zeroed after Done) ──
118    pub(crate) handshake_client_finished_key: Hash,
119    pub(crate) handshake_server_finished_key: Hash,
120
121    pub(crate) server_public_key: heapless::Vec<u8, SIGNING_PUBLIC_KEY_MAX_SIZE>,
122    pub(crate) server_signature_scheme: Option<SignatureScheme>,
123    pub(crate) server_name: heapless::Vec<u8, 256>,
124    pub(crate) hash_state: Option<C::Hasher>,
125    pub(crate) resumption_secret: Hash,
126    pub(crate) cert_verify_state: Option<VerifyCertificateState>,
127}
128
129/// Handshake phases the TLS 1.3 client progresses through.
130///
131/// See the [`Client`] documentation for the phase transition diagram.
132#[derive(Debug, Clone, Copy, PartialEq, Eq)]
133pub(crate) enum Phase {
134    ClientHello,
135    ServerHello,
136    ServerFlight,
137    VerifyServerCertificate,
138    ClientFinished,
139    ApplicationData,
140    Closed,
141}
142
143pub(crate) struct KeySchedule<C: CryptoProvider + ?Sized> {
144    pub(crate) secret: Hash,
145    pub(crate) read_key: Option<C::AeadKey>,
146    pub(crate) read_iv: [u8; 12],
147    pub(crate) read_seq: u64,
148    pub(crate) read_traffic_secret: Hash,
149    pub(crate) write_key: Option<C::AeadKey>,
150    pub(crate) write_iv: [u8; 12],
151    pub(crate) write_seq: u64,
152    pub(crate) write_traffic_secret: Hash,
153}
154
155impl<C: CryptoProvider> KeySchedule<C> {
156    fn new() -> Self {
157        Self {
158            secret: Hash::new_zeroed(48),
159            read_key: None,
160            read_iv: [0u8; 12],
161            read_seq: 0,
162            read_traffic_secret: Hash::new_zeroed(48),
163            write_key: None,
164            write_iv: [0u8; 12],
165            write_seq: 0,
166            write_traffic_secret: Hash::new_zeroed(48),
167        }
168    }
169}
170
171pub(crate) struct CertFrame {
172    msg_type: message::HandshakeType,
173    abs_start: usize,
174    len: u16,
175}
176
177/// State saved when the handshake pauses for certificate verification.
178pub(crate) struct VerifyCertificateState {
179    /// Remaining handshake frames to process after acceptance
180    frames: heapless::Vec<CertFrame, 8>,
181    /// Absolute offset of the Certificate frame in receive_buffer
182    cert_abs_start: usize,
183    cert_len: u16,
184    /// Whether the caller has accepted or rejected the certificate
185    accepted: Option<Result<(), Error>>,
186}
187
188// ── Public API ──
189
190impl<B: Buffer, C: CryptoProvider> Client<B, C> {
191    /// Create a new TLS 1.3 client.
192    ///
193    /// `receive_buffer` and `send_buffer` are scratch buffers the client uses
194    /// to hold incoming and outgoing TLS records.  Each must be at least
195    /// [`MAX_RECORD_SIZE`] bytes long.
196    ///
197    /// Owned types such as `Vec<u8>` may be passed directly.  Borrowed
198    /// slices (`&mut [u8]`) are also accepted — they must outlive the
199    /// `Client`.
200    pub fn new(config: ClientConfig<C>, receive_buffer: B, send_buffer: B) -> Self {
201        Self {
202            config,
203            receive_buffer,
204            send_buffer,
205            receive_decoded: 0,
206            receive_pending: 0,
207            out_len: 0,
208            send_consumed: 0,
209            app_data_offset: 0,
210            app_data_decrypted_len: 0,
211            app_data_consumed: 0,
212            key_update_response: heapless::Vec::new(),
213            key_update_sent: 0,
214            ticket_offset: 0,
215            ticket_len: 0,
216            phase: Phase::ClientHello,
217            opened: false,
218            ciphersuite: None,
219            alpn: None,
220            negotiated_cert_type: CertType::X509,
221            key_exchange_group: C::key_exchange_groups()
222                .first()
223                .copied()
224                .unwrap_or(KeyExchangeGroup::X25519),
225            key_exchange_pairs: heapless::Vec::new(),
226            keys: KeySchedule::new(),
227            handshake_client_finished_key: Hash::new_zeroed(48),
228            handshake_server_finished_key: Hash::new_zeroed(48),
229            server_public_key: heapless::Vec::new(),
230            server_signature_scheme: None,
231            server_name: heapless::Vec::new(),
232            hash_state: None,
233            resumption_secret: Hash::new_zeroed(48),
234            cert_verify_state: None,
235        }
236    }
237
238    // ── I/O (buffer fill) ──
239    /// Return the tail of the receive buffer where the caller should write
240    /// incoming network data.
241    #[inline]
242    pub fn receive_buffer(&mut self) -> &mut [u8] {
243        let start = self.receive_decoded + self.receive_pending;
244        &mut self.receive_buffer[start..]
245    }
246
247    /// Inform the client that `n` bytes have been written into the buffer
248    /// returned by [`receive_buffer`](Self::receive_buffer).
249    #[inline]
250    pub fn commit_received(&mut self, n: usize) {
251        self.receive_pending += n;
252    }
253
254    /// Provide the result of certificate validation to the handshake.
255    ///
256    /// Must be called after receiving
257    /// [`VerifyServerCertificate`](ClientHandshakeEvent::VerifyServerCertificate).
258    /// The handshake will then proceed to verify the server's
259    /// CertificateVerify signature and Finished message.
260    ///
261    /// If `result` is `Err`, the handshake is aborted with that error when
262    /// [`continue_handshake`](Self::continue_handshake) is next called.
263    ///
264    /// This is a no-op if the handshake is not currently waiting for
265    /// certificate verification.
266    #[inline]
267    pub fn accept_certificate(&mut self, result: Result<(), Error>) {
268        if let Some(state) = self.cert_verify_state.as_mut() {
269            state.accepted = Some(result);
270        }
271    }
272
273    /// Return the server's certificate and server name for validation.
274    ///
275    /// Should be called after receiving
276    /// [`VerifyServerCertificate`](ClientHandshakeEvent::VerifyServerCertificate).
277    /// Returns `None` if the handshake is not in the certificate verification
278    /// phase.
279    #[inline]
280    pub fn server_certificate(&self) -> Option<(ReceivedCertificate<'_>, Option<&str>)> {
281        let state = self.cert_verify_state.as_ref()?;
282        let msg_body = &self.receive_buffer[state.cert_abs_start + 4..state.cert_abs_start + state.cert_len as usize];
283        let cert = message::decode_certificate(msg_body, self.negotiated_cert_type).ok()?;
284        let server_name = core::str::from_utf8(&self.server_name).ok();
285        Some((cert, server_name))
286    }
287
288    // ── Handshake ──
289    /// Begin the TLS 1.3 handshake by writing a ClientHello into the send
290    /// buffer.
291    ///
292    /// `server_name` is the SNI host name (optional).  `alpn_protocols`
293    /// lists application-layer protocol identifiers to negotiate (e.g.
294    /// `b"h2"`, `b"http/1.1"`).
295    ///
296    /// On success returns [`Send`](ClientHandshakeEvent::Send) — the caller
297    /// should transmit [`outgoing_data`](Self::outgoing_data)
298    /// over the network and then call [`continue_handshake`](Self::continue_handshake).
299    ///
300    /// # Errors
301    ///
302    /// Returns [`Error::CryptoError`] if key-pair generation fails, or
303    /// [`Error::EncodeError`] if the ClientHello cannot be encoded.
304    pub fn start_handshake(
305        &mut self,
306        server_name: Option<&str>,
307        alpn_protocols: &[&[u8]],
308    ) -> Result<ClientHandshakeEvent<'_>, Error> {
309        let crypto_provider = &self.config.crypto_provider;
310        let mut client_random = [0u8; 32];
311        crypto_provider.secure_random(&mut client_random);
312
313        // Generate key pairs for ALL supported groups; send all in key_share.
314        self.key_exchange_pairs.clear();
315        let mut key_exchange_public_keys: heapless::Vec<KeyExchangePublicKey, KEY_EXCHANGE_MAX_GROUPS> =
316            heapless::Vec::new();
317
318        let key_exchange_groups = C::key_exchange_groups();
319        for group in key_exchange_groups.iter().take(KEY_EXCHANGE_MAX_GROUPS) {
320            let (secret, public) = crypto_provider.key_exchange_generate_keypair(*group)?;
321            self.key_exchange_pairs
322                .push(secret)
323                .map_err(|_| Error::InvalidConfiguration)?;
324            key_exchange_public_keys
325                .push(public)
326                .map_err(|_| Error::InvalidConfiguration)?;
327        }
328
329        self.key_exchange_group = *key_exchange_groups.first().ok_or(Error::InvalidConfiguration)?;
330
331        self.server_name.clear();
332        if let Some(name) = server_name {
333            self.server_name
334                .extend_from_slice(name.as_bytes())
335                .map_err(|_| Error::InvalidConfiguration)?;
336        }
337
338        // Write TLS record header: placeholder (5 bytes), filled after encoding
339        self.send_buffer[0] = ContentType::Handshake as u8;
340        self.send_buffer[1] = 0x03;
341        self.send_buffer[2] = 0x03;
342        let offset = 5; // handshake message starts after record header
343
344        let mut extensions: Vec<message::ClientExtension, 7> = Vec::new();
345
346        if let Some(name) = server_name {
347            extensions
348                .push(message::ClientExtension::ServerName {
349                    host_name: name,
350                })
351                .unwrap();
352        }
353
354        if !key_exchange_public_keys.is_empty() {
355            extensions
356                .push(message::ClientExtension::SupportedGroups {
357                    key_share_entries: &key_exchange_public_keys,
358                })
359                .unwrap();
360        }
361
362        let signature_schemes = C::signature_schemes();
363        if !signature_schemes.is_empty() {
364            extensions
365                .push(message::ClientExtension::SignatureAlgorithms {
366                    schemes: signature_schemes,
367                })
368                .unwrap();
369        }
370
371        if !alpn_protocols.is_empty() {
372            extensions
373                .push(message::ClientExtension::ApplicationLayerProtocolNegotiation {
374                    protocols: alpn_protocols,
375                })
376                .unwrap();
377        }
378
379        if self.config.supported_certificate_types.len() > 1
380            || self
381                .config
382                .supported_certificate_types
383                .first()
384                .map_or(false, |t| *t != CertType::X509)
385        {
386            extensions
387                .push(message::ClientExtension::ServerCertificateType {
388                    types: &self.config.supported_certificate_types,
389                })
390                .unwrap();
391        }
392
393        extensions.push(message::ClientExtension::SupportedVersions).unwrap();
394        extensions
395            .push(message::ClientExtension::KeyShare {
396                entries: &key_exchange_public_keys,
397            })
398            .unwrap();
399
400        let written = message::encode_client_hello(
401            &mut self.send_buffer[offset..],
402            &client_random,
403            &[],
404            C::cipher_suites(),
405            &extensions,
406        )?;
407
408        // Fill record header length
409        self.send_buffer[3..5].copy_from_slice(&(written as u16).to_be_bytes());
410        self.out_len = offset + written;
411        self.phase = Phase::ServerHello;
412        Ok(ClientHandshakeEvent::Send)
413    }
414
415    /// Advance the handshake state machine.
416    ///
417    /// Must be called after each [`Send`](ClientHandshakeEvent::Send) or
418    /// [`Receive`](ClientHandshakeEvent::Receive) event produced by the
419    /// previous call.  The caller should:
420    ///
421    /// 1. Inspect the returned event.
422    /// 2. If [`Send`](ClientHandshakeEvent::Send): transmit
423    ///    [`outgoing_data`](Self::outgoing_data) over the network.
424    /// 3. If [`Receive`](ClientHandshakeEvent::Receive): read data from the
425    ///    network into [`receive_buffer`](Self::receive_buffer), then call
426    ///    [`commit_received`](Self::commit_received).
427    /// 4. Call `continue_handshake` again.
428    ///
429    /// When [`Done`](ClientHandshakeEvent::Done) is returned the connection
430    /// is established and application data may be exchanged with
431    /// [`encrypt`](Self::encrypt) / [`decrypt`](Self::decrypt).
432    ///
433    /// # Errors
434    ///
435    /// Returns an error if the server's messages are malformed, the
436    /// certificate chain is invalid, the signature verification fails, or
437    /// the transcript hash does not match the expected Finished verify_data.
438    pub fn continue_handshake(&mut self) -> Result<ClientHandshakeEvent<'_>, Error> {
439        match self.phase {
440            Phase::ClientHello | Phase::ServerHello => self.process_server_hello(),
441            Phase::ServerFlight => self.process_server_flight(),
442            Phase::VerifyServerCertificate => {
443                let state = self.cert_verify_state.as_ref().unwrap();
444                match state.accepted {
445                    None => Ok(ClientHandshakeEvent::VerifyServerCertificate),
446                    Some(Err(e)) => {
447                        self.cert_verify_state = None;
448                        Err(e)
449                    }
450                    Some(Ok(())) => {
451                        let state = self.cert_verify_state.take().unwrap();
452                        self.process_remaining_server_flight(state.frames)
453                    }
454                }
455            }
456            Phase::ClientFinished => {
457                self.keys.read_seq = 0;
458                self.keys.write_seq = 0;
459                self.phase = Phase::ApplicationData;
460                self.opened = true;
461                #[cfg(feature = "zeroize")]
462                {
463                    use zeroize::Zeroize;
464                    self.handshake_client_finished_key.zeroize();
465                    self.handshake_server_finished_key.zeroize();
466                }
467                self.hash_state = None;
468
469                self.clear_send_buffer();
470                Ok(ClientHandshakeEvent::Done {
471                    ciphersuite: self.ciphersuite.unwrap(),
472                    tls_version: 0x0304,
473                    key_exchange_group: self.key_exchange_group,
474                    signature_scheme: self.server_signature_scheme.unwrap(),
475                    alpn: &self.alpn.as_ref().unwrap(),
476                })
477            }
478            Phase::ApplicationData => Err(Error::HandshakeDone),
479            Phase::Closed => Ok(ClientHandshakeEvent::Closed),
480        }
481    }
482
483    /// Return the data that should be sent over the network.
484    ///
485    /// Used during both the handshake and application-data phases.  After
486    /// [`encrypt`](Self::encrypt) or after
487    /// [`Send`](ClientHandshakeEvent::Send) from the handshake, this returns
488    /// the contents of the send buffer.
489    pub fn outgoing_data(&self) -> &[u8] {
490        &self.send_buffer[self.send_consumed..self.out_len]
491    }
492
493    /// Advance the sent position within the send buffer.
494    ///
495    /// Call this after transmitting `n` bytes from the slice returned by
496    /// [`outgoing_data`](Self::outgoing_data).  The send buffer is reset
497    /// automatically once all bytes have been sent.
498    ///
499    /// # Panics
500    ///
501    /// Panics if `n` exceeds the remaining unsent length.
502    pub fn commit_sent(&mut self, n: usize) {
503        assert!(n <= self.out_len - self.send_consumed);
504        self.send_consumed += n;
505        if self.send_consumed == self.out_len {
506            self.send_consumed = 0;
507            self.out_len = 0;
508        }
509    }
510
511    /// Discard any data in the send buffer without sending it.
512    ///
513    /// Useful after the handshake to clear handshake messages from the
514    /// buffer without transmitting them again.
515    #[inline]
516    fn clear_send_buffer(&mut self) {
517        self.send_consumed = 0;
518        self.out_len = 0;
519    }
520
521    // ── Application data ──
522    /// Encrypt application data and write the resulting TLS record into the
523    /// send buffer.
524    ///
525    /// Returns the number of plaintext bytes written (always equal to
526    /// `data.len()`).  The encrypted record is available via
527    /// [`outgoing_data`](Self::outgoing_data).
528    ///
529    /// # Panics
530    ///
531    /// Panics if called before the handshake has completed (i.e. before
532    /// [`Done`](ClientHandshakeEvent::Done) is returned).
533    ///
534    /// # Errors
535    ///
536    /// Returns [`Error::InsufficientBuffer`] if the send buffer is too small
537    /// for the encrypted record.
538    pub fn encrypt(&mut self, data: &[u8]) -> Result<usize, Error> {
539        let crypto_provider = &self.config.crypto_provider;
540        let total = encrypt_record(
541            crypto_provider,
542            self.keys.write_key.as_ref().unwrap(),
543            &self.keys.write_iv,
544            self.keys.write_seq,
545            ContentType::ApplicationData,
546            data,
547            &mut *self.send_buffer,
548        )?;
549        self.keys.write_seq += 1;
550        self.out_len = total;
551        self.send_consumed = 0;
552        Ok(data.len())
553    }
554
555    /// Decrypt one or more TLS records from the receive buffer.
556    ///
557    /// Processes records in a loop until it runs out of complete records,
558    /// encounters application data, receives a NewSessionTicket, or
559    /// receives a close_notify alert.
560    ///
561    /// # Panics
562    ///
563    /// Panics if called before the handshake has completed.
564    ///
565    /// # Errors
566    ///
567    /// Returns [`Error::ConnectionClosed`] when the peer sends a close_notify
568    /// alert.  Returns [`Error::AeadError`] if record decryption fails.
569    pub fn decrypt(&mut self) -> Result<ClientApplicationDataEvent, Error> {
570        // Don't process new records while the caller still has unconsumed
571        // application data from the previous record.
572        if self.app_data_consumed < self.app_data_decrypted_len {
573            return Ok(ClientApplicationDataEvent::AppData);
574        }
575
576        self.compact_receive_buffer();
577
578        let suite = self.ciphersuite.unwrap();
579        let crypto_provider = &self.config.crypto_provider;
580        loop {
581            let buf_end = self.receive_decoded + self.receive_pending;
582            let buf = &self.receive_buffer[self.receive_decoded..buf_end];
583            if buf.len() < RecordHeader::SIZE {
584                return Ok(ClientApplicationDataEvent::None);
585            }
586            let Some((header, body)) = record::try_read_record(buf, buf.len())? else {
587                return Ok(ClientApplicationDataEvent::None);
588            };
589            let total = RecordHeader::SIZE + header.length as usize;
590
591            match header.content_type {
592                ContentType::ApplicationData => {
593                    let body_start = self.receive_decoded + RecordHeader::SIZE;
594                    let receive_base = self.receive_buffer.as_ptr() as usize;
595                    let (inner_type, payload) = decrypt_record(
596                        crypto_provider,
597                        self.keys.read_key.as_ref().unwrap(),
598                        &self.keys.read_iv,
599                        self.keys.read_seq,
600                        &header,
601                        &mut self.receive_buffer[body_start..body_start + header.length as usize],
602                    )?;
603                    self.keys.read_seq += 1;
604                    self.receive_decoded += total;
605                    self.receive_pending -= total;
606
607                    match inner_type {
608                        ContentType::ApplicationData => {
609                            let payload_offset = payload.as_ptr() as usize - receive_base;
610                            self.app_data_offset = payload_offset;
611                            self.app_data_decrypted_len = payload.len();
612                            self.app_data_consumed = 0;
613                            return Ok(ClientApplicationDataEvent::AppData);
614                        }
615                        ContentType::Alert => {
616                            if payload.len() >= 2 && payload[0] == 1 && payload[1] == 0 {
617                                self.phase = Phase::Closed;
618                                return Err(Error::ConnectionClosed);
619                            }
620                        }
621                        ContentType::Handshake => {
622                            if payload.len() < 4 {
623                                continue;
624                            }
625                            let (msg_type, msg_body) = message::decode_handshake_frame(payload, &mut 0)?;
626                            match msg_type {
627                                message::HandshakeType::NewSessionTicket => {
628                                    let ticket = message::decode_new_session_ticket(msg_body)?;
629                                    let psk = key_schedule::derive_ticket_psk(
630                                        crypto_provider,
631                                        suite,
632                                        &self.resumption_secret,
633                                        ticket.nonce,
634                                    )?;
635                                    self.ticket_offset = ticket.ticket.as_ptr() as usize - receive_base;
636                                    self.ticket_len = ticket.ticket.len();
637                                    return Ok(ClientApplicationDataEvent::Ticket {
638                                        psk: heapless::Vec::from_slice(&psk).unwrap(), // TODO: avoid copy
639                                        lifetime_s: ticket.lifetime_s,
640                                        age_add: ticket.age_add,
641                                    });
642                                }
643                                message::HandshakeType::KeyUpdate => {
644                                    let request_update = message::decode_key_update(msg_body)?;
645                                    let new_read_secret = key_schedule::key_update_secret(
646                                        crypto_provider,
647                                        suite,
648                                        &self.keys.read_traffic_secret,
649                                    )?;
650                                    self.keys.read_traffic_secret = new_read_secret;
651                                    let (read_key, read_iv) = key_schedule::derive_traffic_keys(
652                                        crypto_provider,
653                                        suite,
654                                        &self.keys.read_traffic_secret,
655                                    )?;
656                                    self.keys.read_iv = read_iv;
657                                    self.keys.read_key = Some(read_key);
658                                    self.keys.read_seq = 0;
659                                    if request_update == 1 {
660                                        let new_write_secret = key_schedule::key_update_secret(
661                                            crypto_provider,
662                                            suite,
663                                            &self.keys.write_traffic_secret,
664                                        )?;
665                                        self.keys.write_traffic_secret = new_write_secret;
666                                        let (write_key, write_iv) = key_schedule::derive_traffic_keys(
667                                            crypto_provider,
668                                            suite,
669                                            &self.keys.write_traffic_secret,
670                                        )?;
671                                        self.keys.write_iv = write_iv;
672                                        self.keys.write_key = Some(write_key);
673                                        self.keys.write_seq = 0;
674                                        let mut key_update_frame = [0u8; 8];
675                                        let mut frame_offset = 0;
676                                        key_update_frame[frame_offset] = message::HandshakeType::KeyUpdate as u8;
677                                        frame_offset += 1;
678                                        frame_offset += message::put_u24(&mut key_update_frame[frame_offset..], 1);
679                                        key_update_frame[frame_offset] = 0;
680                                        frame_offset += 1;
681                                        let mut resp_buf = [0u8; 256];
682                                        let total_encrypted = encrypt_record(
683                                            crypto_provider,
684                                            self.keys.write_key.as_ref().unwrap(),
685                                            &self.keys.write_iv,
686                                            self.keys.write_seq,
687                                            ContentType::Handshake,
688                                            &key_update_frame[..frame_offset],
689                                            &mut resp_buf,
690                                        )?;
691                                        self.keys.write_seq += 1;
692                                        self.key_update_response.clear();
693                                        self.key_update_response
694                                            .extend_from_slice(&resp_buf[..total_encrypted])
695                                            .map_err(|_| Error::InsufficientBuffer)?;
696                                    }
697                                    return Ok(ClientApplicationDataEvent::KeyUpdate);
698                                }
699                                _ => continue,
700                            }
701                        }
702                        _ => continue,
703                    }
704                }
705                ContentType::Alert => {
706                    if body.len() >= 2 && body[0] == 1 && body[1] == 0 {
707                        self.phase = Phase::Closed;
708                        self.receive_decoded += total;
709                        self.receive_pending -= total;
710                        return Err(Error::ConnectionClosed);
711                    }
712                    self.receive_decoded += total;
713                    self.receive_pending -= total;
714                }
715                _ => {
716                    self.receive_decoded += total;
717                    self.receive_pending -= total;
718                }
719            }
720        }
721    }
722
723    /// Get the last decrypted application data (after
724    /// [`decrypt`](Self::decrypt) returned
725    /// [`AppData`](ClientApplicationDataEvent::AppData)).
726    ///
727    /// Returns only the unconsumed portion of the data.  Advance the
728    /// consumed position with [`commit_app_data`](Self::commit_app_data)
729    /// so that subsequent calls return the remainder.
730    pub fn received_app_data(&self) -> &[u8] {
731        &self.receive_buffer
732            [self.app_data_offset + self.app_data_consumed..self.app_data_offset + self.app_data_decrypted_len]
733    }
734
735    /// Advance the consumed position within the last decrypted record.
736    ///
737    /// Call this after reading `n` bytes from the slice returned by
738    /// [`received_app_data`](Self::received_app_data).  The next call to
739    /// [`decrypt`](Self::decrypt) will not process new records until all
740    /// data from the current record has been consumed (i.e. the total
741    /// consumed equals the record length).
742    ///
743    /// # Panics
744    ///
745    /// Panics if `n` exceeds the remaining unconsumed length.
746    pub fn commit_app_data(&mut self, n: usize) {
747        assert!(n <= self.app_data_decrypted_len - self.app_data_consumed);
748        self.app_data_consumed += n;
749    }
750
751    /// Return the unsent portion of the pending KeyUpdate response, if any.
752    ///
753    /// The caller should transmit this data over the network and then call
754    /// [`commit_key_update_data`](Self::commit_key_update_data) with the
755    /// number of bytes successfully sent.
756    #[inline]
757    pub fn outgoing_key_update_data(&self) -> &[u8] {
758        &self.key_update_response[self.key_update_sent..]
759    }
760
761    /// Advance the sent position within the pending KeyUpdate response.
762    ///
763    /// Call this after transmitting `n` bytes from the slice returned by
764    /// [`outgoing_key_update_data`](Self::outgoing_key_update_data).  The
765    /// response is cleared automatically once all bytes have been sent.
766    ///
767    /// # Panics
768    ///
769    /// Panics if `n` exceeds the remaining unsent length.
770    #[inline]
771    pub fn commit_key_update_data(&mut self, n: usize) {
772        assert!(n <= self.key_update_response.len() - self.key_update_sent);
773        self.key_update_sent += n;
774        if self.key_update_sent == self.key_update_response.len() {
775            self.key_update_response.clear();
776            self.key_update_sent = 0;
777        }
778    }
779
780    /// Get the raw ticket bytes from the last NewSessionTicket (after
781    /// [`decrypt`](Self::decrypt) returned
782    /// [`Ticket`](ClientApplicationDataEvent::Ticket)).
783    pub fn received_ticket_data(&self) -> &[u8] {
784        &self.receive_buffer[self.ticket_offset..self.ticket_offset + self.ticket_len]
785    }
786
787    /// Send a close_notify alert to the peer.
788    ///
789    /// The encrypted alert is returned.
790    pub fn close(&mut self) -> Result<&[u8], Error> {
791        let crypto_provider = &self.config.crypto_provider;
792        let total = encrypt_record(
793            crypto_provider,
794            self.keys.write_key.as_ref().unwrap(),
795            &self.keys.write_iv,
796            self.keys.write_seq,
797            ContentType::Alert,
798            &[1u8, 0],
799            &mut *self.send_buffer,
800        )?;
801        self.keys.write_seq += 1;
802        self.out_len = total;
803        self.send_consumed = 0;
804        self.phase = Phase::Closed;
805        Ok(self.outgoing_data())
806    }
807
808    pub fn is_established(&self) -> bool {
809        self.opened
810    }
811
812    // ── Buffer management ──
813
814    #[inline]
815    fn compact_receive_buffer(&mut self) {
816        if self.receive_decoded > 0 {
817            let len = self.receive_pending;
818            if len > 0 {
819                self.receive_buffer
820                    .copy_within(self.receive_decoded..self.receive_decoded + len, 0);
821            }
822            self.receive_decoded = 0;
823        }
824    }
825
826    // ── Internal handshake processing ──
827
828    fn process_server_hello(&mut self) -> Result<ClientHandshakeEvent<'_>, Error> {
829        self.compact_receive_buffer();
830        let buf_end = self.receive_decoded + self.receive_pending;
831        let start = self.receive_decoded;
832        if buf_end - start < RecordHeader::SIZE {
833            return Ok(ClientHandshakeEvent::Receive);
834        }
835        // Read header directly to avoid borrowing the full buffer
836        let header_len = u16::from_be_bytes([self.receive_buffer[start + 3], self.receive_buffer[start + 4]]) as usize;
837        let total = RecordHeader::SIZE + header_len;
838        if buf_end - start < total {
839            return Ok(ClientHandshakeEvent::Receive);
840        }
841
842        self.receive_decoded += total;
843        self.receive_pending -= total;
844
845        let body_start = start + RecordHeader::SIZE;
846        let body = &self.receive_buffer[body_start..body_start + header_len];
847        let content_type = self.receive_buffer[start];
848
849        match content_type {
850            22 => {
851                // ContentType::Handshake
852                let (_msg_type, msg_body) = message::decode_handshake_frame(body, &mut 0)?;
853                let server_hello = message::decode_server_hello(msg_body)?;
854                self.ciphersuite = Some(server_hello.cipher_suite);
855                self.key_exchange_group = server_hello.key_share_group;
856                let suite = server_hello.cipher_suite;
857                let hash_size = suite.hash_size();
858                let crypto_provider = &self.config.crypto_provider;
859
860                let secret = self
861                    .key_exchange_pairs
862                    .iter()
863                    .find(|k| k.group() == server_hello.key_share_group)
864                    .ok_or(Error::UnsupportedKeyExchangeGroup)?;
865
866                let shared = crypto_provider.key_exchange(secret, server_hello.key_share_public)?;
867
868                let client_hello_len = self.out_len.checked_sub(5).unwrap_or(0);
869                if client_hello_len > 0 {
870                    let client_hello_message = &self.send_buffer[5..5 + client_hello_len];
871                    if let Some(ref mut state) = self.hash_state {
872                        crypto_provider.hash_update(state, client_hello_message);
873                    } else {
874                        let mut state = crypto_provider.new_hash(suite);
875                        crypto_provider.hash_update(&mut state, client_hello_message);
876                        self.hash_state = Some(state);
877                    }
878                }
879
880                if let Some(ref mut state) = self.hash_state {
881                    crypto_provider.hash_update(state, body);
882                } else {
883                    let mut state = crypto_provider.new_hash(suite);
884                    crypto_provider.hash_update(&mut state, body);
885                    self.hash_state = Some(state);
886                }
887
888                let transcript_hash = if let Some(ref state) = self.hash_state {
889                    let copy = state.clone();
890                    crypto_provider.hash_finalize(copy)?
891                } else {
892                    crypto_provider.hash(suite, &[])?
893                };
894
895                let early_secret =
896                    crypto_provider.hkdf_extract(suite, &Hash::new_zeroed(hash_size as u8), &[0u8; 48][..hash_size])?;
897                let empty_hash = crypto_provider.hash(suite, &[])?;
898                let derived_secret =
899                    key_schedule::derive_secret(crypto_provider, suite, &early_secret, b"derived", &empty_hash)?;
900                self.keys.secret = crypto_provider.hkdf_extract(suite, &derived_secret, &shared)?;
901
902                let client_handshake_traffic_secret = key_schedule::derive_secret(
903                    crypto_provider,
904                    suite,
905                    &self.keys.secret,
906                    b"c hs traffic",
907                    &transcript_hash,
908                )?;
909                let server_handshake_traffic_secret = key_schedule::derive_secret(
910                    crypto_provider,
911                    suite,
912                    &self.keys.secret,
913                    b"s hs traffic",
914                    &transcript_hash,
915                )?;
916
917                let (write_key, write_iv) =
918                    key_schedule::derive_traffic_keys(crypto_provider, suite, &client_handshake_traffic_secret)?;
919                self.keys.write_iv = write_iv;
920                self.keys.write_key = Some(write_key);
921
922                let (read_key, read_iv) =
923                    key_schedule::derive_traffic_keys(crypto_provider, suite, &server_handshake_traffic_secret)?;
924                self.keys.read_iv = read_iv;
925                self.keys.read_key = Some(read_key);
926
927                self.handshake_client_finished_key =
928                    key_schedule::derive_finished_key(crypto_provider, suite, &client_handshake_traffic_secret)?;
929                self.handshake_server_finished_key =
930                    key_schedule::derive_finished_key(crypto_provider, suite, &server_handshake_traffic_secret)?;
931
932                self.phase = Phase::ServerFlight;
933                if self.receive_pending > 0 {
934                    self.process_server_flight()
935                } else {
936                    Ok(ClientHandshakeEvent::Receive)
937                }
938            }
939            21 => {
940                if body.len() >= 2 {
941                    return Err(Error::HandshakeAborted {
942                        level: body[0],
943                        description: body[1],
944                    });
945                }
946                Err(Error::DecodeError)
947            }
948            _ => Err(Error::UnexpectedMessage),
949        }
950    }
951
952    /// Process the remaining flight after the ServerHello.
953    ///
954    /// This handles one or more encrypted records containing the server's
955    /// EncryptedExtensions, Certificate, CertificateVerify and Finished
956    /// messages.  Multiple handshake messages inside a single record are
957    /// processed in order.  Returns [`Send`](ClientHandshakeEvent::Send) once
958    /// the server's Finished has been verified and the client's own Finished
959    /// has been written to the send buffer.
960    ///
961    /// # Errors
962    ///
963    /// Returns [`Error::TranscriptMismatch`] if the server's Finished
964    /// verify_data does not match.  Returns [`Error::InvalidCertificate`]
965    /// or [`Error::InvalidSignature`] if the certificate chain or
966    /// CertificateVerify fails validation.
967    fn process_server_flight(&mut self) -> Result<ClientHandshakeEvent<'_>, Error> {
968        self.compact_receive_buffer();
969        let suite = self.ciphersuite.unwrap();
970        let hash_size = suite.hash_size();
971        let crypto_provider = &self.config.crypto_provider;
972
973        loop {
974            let len = self.receive_pending;
975            if len < RecordHeader::SIZE {
976                return Ok(ClientHandshakeEvent::Receive);
977            }
978            let start = self.receive_decoded;
979            let buf_slice = &self.receive_buffer[start..start + len];
980            let Some((header, _body)) = record::try_read_record(buf_slice, len)? else {
981                return Ok(ClientHandshakeEvent::Receive);
982            };
983            let total = RecordHeader::SIZE + header.length as usize;
984
985            match header.content_type {
986                ContentType::ChangeCipherSpec => {
987                    self.receive_decoded += total;
988                    self.receive_pending -= total;
989                    continue;
990                }
991                ContentType::ApplicationData => {
992                    let body_start = start + RecordHeader::SIZE;
993                    let body_len = header.length as usize;
994                    let body_base = start + RecordHeader::SIZE;
995
996                    let frames: heapless::Vec<CertFrame, 8> = {
997                        let (inner_type, payload) = decrypt_record(
998                            crypto_provider,
999                            self.keys.read_key.as_ref().unwrap(),
1000                            &self.keys.read_iv,
1001                            self.keys.read_seq,
1002                            &header,
1003                            &mut self.receive_buffer[body_start..body_start + body_len],
1004                        )?;
1005                        self.keys.read_seq += 1;
1006                        self.receive_decoded += total;
1007                        self.receive_pending -= total;
1008
1009                        match inner_type {
1010                            ContentType::Handshake => {
1011                                // Phase 1: decode frame boundaries (shared borrow on payload)
1012                                struct HandshakeFrame {
1013                                    msg_type: message::HandshakeType,
1014                                    start: u16,
1015                                    len: u16,
1016                                }
1017                                let mut raw_frames: heapless::Vec<HandshakeFrame, 8> = heapless::Vec::new();
1018                                let pl_len = payload.len();
1019                                let mut frame_off = 0;
1020                                while frame_off < pl_len {
1021                                    let frame_start = frame_off as u16;
1022                                    let (msg_type, _) = message::decode_handshake_frame(payload, &mut frame_off)?;
1023                                    raw_frames
1024                                        .push(HandshakeFrame {
1025                                            msg_type,
1026                                            start: frame_start,
1027                                            len: (frame_off as u16) - frame_start,
1028                                        })
1029                                        .map_err(|_| Error::DecodeError)?;
1030                                }
1031                                let _ = payload;
1032                                // Convert to CertFrame with absolute offsets; payload borrow ends here
1033                                raw_frames
1034                                    .iter()
1035                                    .map(|f| CertFrame {
1036                                        msg_type: f.msg_type,
1037                                        abs_start: body_base + f.start as usize,
1038                                        len: f.len,
1039                                    })
1040                                    .collect()
1041                            }
1042                            ContentType::Alert => {
1043                                return Err(Error::HandshakeAborted {
1044                                    level: payload[0],
1045                                    description: payload[1],
1046                                });
1047                            }
1048                            _ => return Err(Error::UnexpectedMessage),
1049                        }
1050                    };
1051                    // payload dropped, mutable borrow on receive_buffer released
1052
1053                    // Phase 2: process frames with full self access
1054                    for (frame_idx, frame) in frames.iter().enumerate() {
1055                        let f_start = frame.abs_start;
1056                        let frame_bytes = &self.receive_buffer[f_start..f_start + frame.len as usize];
1057                        let msg_body = &frame_bytes[4..];
1058
1059                        match frame.msg_type {
1060                            message::HandshakeType::EncryptedExtensions => {
1061                                if let Some(ref mut state) = self.hash_state {
1062                                    crypto_provider.hash_update(state, frame_bytes);
1063                                } else {
1064                                    let mut state = crypto_provider.new_hash(suite);
1065                                    crypto_provider.hash_update(&mut state, frame_bytes);
1066                                    self.hash_state = Some(state);
1067                                }
1068                                let dec_exts = message::decode_encrypted_extensions(msg_body)?;
1069                                for extension in &dec_exts {
1070                                    match extension {
1071                                        message::DecryptedExtension::ApplicationLayerProtocolNegotiation(proto) => {
1072                                            let mut alpn_buffer = heapless::Vec::new();
1073                                            let alpn_length = proto.len().min(ALPN_PROTOCOL_MAX_SIZE);
1074                                            let _ = alpn_buffer.extend_from_slice(&proto[..alpn_length]);
1075                                            self.alpn = Some(alpn_buffer);
1076                                        }
1077                                        message::DecryptedExtension::ServerCertificateType(ct) => {
1078                                            self.negotiated_cert_type = *ct;
1079                                        }
1080                                    }
1081                                }
1082                            }
1083                            message::HandshakeType::Certificate => {
1084                                if let Some(ref mut state) = self.hash_state {
1085                                    crypto_provider.hash_update(state, frame_bytes);
1086                                } else {
1087                                    let mut hasher = crypto_provider.new_hash(suite);
1088                                    crypto_provider.hash_update(&mut hasher, frame_bytes);
1089                                    self.hash_state = Some(hasher);
1090                                }
1091                                let cert = message::decode_certificate(msg_body, self.negotiated_cert_type)?;
1092                                let (scheme, pk_vec) = extract_ee_key(&cert)?;
1093                                self.server_public_key = pk_vec;
1094                                self.server_signature_scheme = Some(scheme);
1095
1096                                let remaining: heapless::Vec<CertFrame, 8> = frames
1097                                    .iter()
1098                                    .skip(frame_idx + 1)
1099                                    .map(|f| CertFrame {
1100                                        msg_type: f.msg_type,
1101                                        abs_start: f.abs_start,
1102                                        len: f.len,
1103                                    })
1104                                    .collect();
1105
1106                                self.cert_verify_state = Some(VerifyCertificateState {
1107                                    frames: remaining,
1108                                    cert_abs_start: frame.abs_start,
1109                                    cert_len: frame.len,
1110                                    accepted: None,
1111                                });
1112                                self.phase = Phase::VerifyServerCertificate;
1113                                return Ok(ClientHandshakeEvent::VerifyServerCertificate);
1114                            }
1115                            message::HandshakeType::CertificateVerify => {
1116                                let transcript_hash = if let Some(ref state) = self.hash_state {
1117                                    let copy = state.clone();
1118                                    crypto_provider.hash_finalize(copy)?
1119                                } else {
1120                                    crypto_provider.hash(suite, &[])?
1121                                };
1122                                let certificate_verify = message::decode_certificate_verify(msg_body)?;
1123                                let ctx = b"TLS 1.3, server CertificateVerify\x00";
1124                                let mut signed_content = [0u8; 200];
1125                                let mut signed_offset = 0;
1126                                signed_content[..64].fill(0x20);
1127                                signed_offset += 64;
1128                                signed_content[signed_offset..signed_offset + ctx.len()].copy_from_slice(ctx);
1129                                signed_offset += ctx.len();
1130                                signed_content[signed_offset..signed_offset + hash_size]
1131                                    .copy_from_slice(&transcript_hash);
1132                                signed_offset += hash_size;
1133                                crypto_provider.verify(
1134                                    certificate_verify.scheme,
1135                                    &self.server_public_key,
1136                                    &signed_content[..signed_offset],
1137                                    certificate_verify.signature,
1138                                )?;
1139                                if let Some(ref mut state) = self.hash_state {
1140                                    crypto_provider.hash_update(state, frame_bytes);
1141                                } else {
1142                                    let mut state = crypto_provider.new_hash(suite);
1143                                    crypto_provider.hash_update(&mut state, frame_bytes);
1144                                    self.hash_state = Some(state);
1145                                }
1146                            }
1147                            message::HandshakeType::Finished => {
1148                                let transcript_hash = if let Some(ref state) = self.hash_state {
1149                                    let copy = state.clone();
1150                                    crypto_provider.hash_finalize(copy)?
1151                                } else {
1152                                    crypto_provider.hash(suite, &[])?
1153                                };
1154                                let verify_data = message::decode_finished(msg_body)?;
1155                                let expected_verify_data = key_schedule::compute_finished(
1156                                    crypto_provider,
1157                                    suite,
1158                                    &self.handshake_server_finished_key,
1159                                    &transcript_hash,
1160                                )?;
1161                                if verify_data != &*expected_verify_data {
1162                                    return Err(Error::TranscriptMismatch);
1163                                }
1164
1165                                if let Some(ref mut state) = self.hash_state {
1166                                    crypto_provider.hash_update(state, frame_bytes);
1167                                } else {
1168                                    let mut state = crypto_provider.new_hash(suite);
1169                                    crypto_provider.hash_update(&mut state, frame_bytes);
1170                                    self.hash_state = Some(state);
1171                                }
1172
1173                                let final_transcript_hash = if let Some(ref state) = self.hash_state {
1174                                    let copy = state.clone();
1175                                    crypto_provider.hash_finalize(copy)?
1176                                } else {
1177                                    crypto_provider.hash(suite, &[])?
1178                                };
1179
1180                                let empty_hash = crypto_provider.hash(suite, &[])?;
1181                                let derived_secret = key_schedule::derive_secret(
1182                                    crypto_provider,
1183                                    suite,
1184                                    &self.keys.secret,
1185                                    b"derived",
1186                                    &empty_hash,
1187                                )?;
1188                                self.keys.secret =
1189                                    crypto_provider.hkdf_extract(suite, &derived_secret, &[0u8; 48][..hash_size])?;
1190
1191                                let client_application_secret = key_schedule::derive_secret(
1192                                    crypto_provider,
1193                                    suite,
1194                                    &self.keys.secret,
1195                                    b"c ap traffic",
1196                                    &final_transcript_hash,
1197                                )?;
1198                                let server_application_secret = key_schedule::derive_secret(
1199                                    crypto_provider,
1200                                    suite,
1201                                    &self.keys.secret,
1202                                    b"s ap traffic",
1203                                    &final_transcript_hash,
1204                                )?;
1205                                let (write_key, write_iv) = key_schedule::derive_traffic_keys(
1206                                    crypto_provider,
1207                                    suite,
1208                                    &client_application_secret,
1209                                )?;
1210                                let (read_key, read_iv) = key_schedule::derive_traffic_keys(
1211                                    crypto_provider,
1212                                    suite,
1213                                    &server_application_secret,
1214                                )?;
1215                                self.keys.write_traffic_secret = client_application_secret;
1216                                self.keys.read_traffic_secret = server_application_secret;
1217
1218                                let finished_verify_data = key_schedule::compute_finished(
1219                                    crypto_provider,
1220                                    suite,
1221                                    &self.handshake_client_finished_key,
1222                                    &final_transcript_hash,
1223                                )?;
1224                                let mut finished_frame = [0u8; 64];
1225                                let mut finished_frame_offset = 0;
1226                                finished_frame_offset += message::encode_handshake_frame(
1227                                    &mut finished_frame[finished_frame_offset..],
1228                                    message::HandshakeType::Finished,
1229                                    hash_size,
1230                                );
1231                                finished_frame[finished_frame_offset..finished_frame_offset + hash_size]
1232                                    .copy_from_slice(&finished_verify_data);
1233                                finished_frame_offset += hash_size;
1234                                let total_encrypted = encrypt_record(
1235                                    crypto_provider,
1236                                    self.keys.write_key.as_ref().unwrap(),
1237                                    &self.keys.write_iv,
1238                                    self.keys.write_seq,
1239                                    ContentType::Handshake,
1240                                    &finished_frame[..finished_frame_offset],
1241                                    &mut *self.send_buffer,
1242                                )?;
1243                                self.keys.write_seq += 1;
1244                                self.keys.write_key = Some(write_key);
1245                                self.keys.write_iv = write_iv;
1246                                self.keys.read_key = Some(read_key);
1247                                self.keys.read_iv = read_iv;
1248                                self.out_len = total_encrypted;
1249                                self.send_consumed = 0;
1250
1251                                let resumption_secret = key_schedule::derive_secret(
1252                                    crypto_provider,
1253                                    suite,
1254                                    &self.keys.secret,
1255                                    b"res master",
1256                                    &final_transcript_hash,
1257                                )?;
1258                                self.resumption_secret = resumption_secret;
1259                                self.phase = Phase::ClientFinished;
1260                                return Ok(ClientHandshakeEvent::Send);
1261                            }
1262                            _ => return Err(Error::UnexpectedMessage),
1263                        }
1264                    }
1265                }
1266                ContentType::Alert => {
1267                    return Err(Error::HandshakeAborted {
1268                        level: _body[0],
1269                        description: _body[1],
1270                    });
1271                }
1272                _ => return Err(Error::UnexpectedMessage),
1273            }
1274        }
1275    }
1276
1277    fn process_remaining_server_flight(
1278        &mut self,
1279        frames: heapless::Vec<CertFrame, 8>,
1280    ) -> Result<ClientHandshakeEvent<'_>, Error> {
1281        let suite = self.ciphersuite.unwrap();
1282        let hash_size = suite.hash_size();
1283        let crypto_provider = &self.config.crypto_provider;
1284
1285        for frame in &frames {
1286            let f_start = frame.abs_start;
1287            let frame_bytes = &self.receive_buffer[f_start..f_start + frame.len as usize];
1288            let msg_body = &frame_bytes[4..];
1289
1290            match frame.msg_type {
1291                message::HandshakeType::CertificateVerify => {
1292                    let transcript_hash = if let Some(ref state) = self.hash_state {
1293                        let copy = state.clone();
1294                        crypto_provider.hash_finalize(copy)?
1295                    } else {
1296                        crypto_provider.hash(suite, &[])?
1297                    };
1298                    let certificate_verify = message::decode_certificate_verify(msg_body)?;
1299                    let ctx = b"TLS 1.3, server CertificateVerify\x00";
1300                    let mut signed_content = [0u8; 200];
1301                    let mut signed_offset = 0;
1302                    signed_content[..64].fill(0x20);
1303                    signed_offset += 64;
1304                    signed_content[signed_offset..signed_offset + ctx.len()].copy_from_slice(ctx);
1305                    signed_offset += ctx.len();
1306                    signed_content[signed_offset..signed_offset + hash_size].copy_from_slice(&transcript_hash);
1307                    signed_offset += hash_size;
1308                    crypto_provider.verify(
1309                        certificate_verify.scheme,
1310                        &self.server_public_key,
1311                        &signed_content[..signed_offset],
1312                        certificate_verify.signature,
1313                    )?;
1314                    if let Some(ref mut state) = self.hash_state {
1315                        crypto_provider.hash_update(state, frame_bytes);
1316                    } else {
1317                        let mut state = crypto_provider.new_hash(suite);
1318                        crypto_provider.hash_update(&mut state, frame_bytes);
1319                        self.hash_state = Some(state);
1320                    }
1321                }
1322                message::HandshakeType::Finished => {
1323                    let transcript_hash = if let Some(ref state) = self.hash_state {
1324                        let copy = state.clone();
1325                        crypto_provider.hash_finalize(copy)?
1326                    } else {
1327                        crypto_provider.hash(suite, &[])?
1328                    };
1329                    let verify_data = message::decode_finished(msg_body)?;
1330                    let expected_verify_data = key_schedule::compute_finished(
1331                        crypto_provider,
1332                        suite,
1333                        &self.handshake_server_finished_key,
1334                        &transcript_hash,
1335                    )?;
1336                    if verify_data != &*expected_verify_data {
1337                        return Err(Error::TranscriptMismatch);
1338                    }
1339
1340                    if let Some(ref mut state) = self.hash_state {
1341                        crypto_provider.hash_update(state, frame_bytes);
1342                    } else {
1343                        let mut state = crypto_provider.new_hash(suite);
1344                        crypto_provider.hash_update(&mut state, frame_bytes);
1345                        self.hash_state = Some(state);
1346                    }
1347
1348                    let final_transcript_hash = if let Some(ref state) = self.hash_state {
1349                        let copy = state.clone();
1350                        crypto_provider.hash_finalize(copy)?
1351                    } else {
1352                        crypto_provider.hash(suite, &[])?
1353                    };
1354
1355                    let empty_hash = crypto_provider.hash(suite, &[])?;
1356                    let derived_secret = key_schedule::derive_secret(
1357                        crypto_provider,
1358                        suite,
1359                        &self.keys.secret,
1360                        b"derived",
1361                        &empty_hash,
1362                    )?;
1363                    self.keys.secret = crypto_provider.hkdf_extract(suite, &derived_secret, &[0u8; 48][..hash_size])?;
1364
1365                    let client_application_secret = key_schedule::derive_secret(
1366                        crypto_provider,
1367                        suite,
1368                        &self.keys.secret,
1369                        b"c ap traffic",
1370                        &final_transcript_hash,
1371                    )?;
1372                    let server_application_secret = key_schedule::derive_secret(
1373                        crypto_provider,
1374                        suite,
1375                        &self.keys.secret,
1376                        b"s ap traffic",
1377                        &final_transcript_hash,
1378                    )?;
1379                    let (write_key, write_iv) =
1380                        key_schedule::derive_traffic_keys(crypto_provider, suite, &client_application_secret)?;
1381                    let (read_key, read_iv) =
1382                        key_schedule::derive_traffic_keys(crypto_provider, suite, &server_application_secret)?;
1383                    self.keys.write_traffic_secret = client_application_secret;
1384                    self.keys.read_traffic_secret = server_application_secret;
1385
1386                    let finished_verify_data = key_schedule::compute_finished(
1387                        crypto_provider,
1388                        suite,
1389                        &self.handshake_client_finished_key,
1390                        &final_transcript_hash,
1391                    )?;
1392                    let mut finished_frame = [0u8; 64];
1393                    let mut finished_frame_offset = 0;
1394                    finished_frame_offset += message::encode_handshake_frame(
1395                        &mut finished_frame[finished_frame_offset..],
1396                        message::HandshakeType::Finished,
1397                        hash_size,
1398                    );
1399                    finished_frame[finished_frame_offset..finished_frame_offset + hash_size]
1400                        .copy_from_slice(&finished_verify_data);
1401                    finished_frame_offset += hash_size;
1402                    let total_encrypted = encrypt_record(
1403                        crypto_provider,
1404                        self.keys.write_key.as_ref().unwrap(),
1405                        &self.keys.write_iv,
1406                        self.keys.write_seq,
1407                        ContentType::Handshake,
1408                        &finished_frame[..finished_frame_offset],
1409                        &mut *self.send_buffer,
1410                    )?;
1411                    self.keys.write_seq += 1;
1412                    self.keys.write_key = Some(write_key);
1413                    self.keys.write_iv = write_iv;
1414                    self.keys.read_key = Some(read_key);
1415                    self.keys.read_iv = read_iv;
1416                    self.out_len = total_encrypted;
1417                    self.send_consumed = 0;
1418
1419                    let resumption_secret = key_schedule::derive_secret(
1420                        crypto_provider,
1421                        suite,
1422                        &self.keys.secret,
1423                        b"res master",
1424                        &final_transcript_hash,
1425                    )?;
1426                    self.resumption_secret = resumption_secret;
1427                    self.phase = Phase::ClientFinished;
1428                    return Ok(ClientHandshakeEvent::Send);
1429                }
1430                _ => return Err(Error::UnexpectedMessage),
1431            }
1432        }
1433        Err(Error::UnexpectedMessage)
1434    }
1435}
1436
1437/// Events produced by the handshake state machine.
1438///
1439/// Returned by [`start_handshake`](Client::start_handshake) and
1440/// [`continue_handshake`](Client::continue_handshake).
1441pub enum ClientHandshakeEvent<'a> {
1442    /// The caller should transmit
1443    /// [`outgoing_data`](Client::outgoing_data) over the
1444    /// network, then call [`continue_handshake`](Client::continue_handshake).
1445    Send,
1446    /// The caller should read data from the network into
1447    /// [`receive_buffer`](Client::receive_buffer), call
1448    /// [`commit_received`](Client::commit_received), then call
1449    /// [`continue_handshake`](Client::continue_handshake).
1450    Receive,
1451    /// The server's certificate has been received and must be validated
1452    /// by the caller.  Use [`server_certificate`](Client::server_certificate) to
1453    /// access the certificate and server name, then call
1454    /// [`accept_certificate`](Client::accept_certificate) with the result,
1455    /// then call [`continue_handshake`](Client::continue_handshake).
1456    VerifyServerCertificate,
1457    /// The handshake is complete.  The negotiated parameters are included.
1458    Done {
1459        ciphersuite: CipherSuite,
1460        /// Wire-encoded protocol version (`0x0304` for TLS 1.3).
1461        tls_version: u16,
1462        key_exchange_group: KeyExchangeGroup,
1463        /// The signature scheme used by the server's CertificateVerify.
1464        signature_scheme: SignatureScheme,
1465        alpn: &'a [u8],
1466    },
1467    /// The peer has closed the connection.
1468    Closed,
1469}
1470
1471/// Events produced when decrypting application data.
1472///
1473/// Returned by [`Client::decrypt`].
1474pub enum ClientApplicationDataEvent {
1475    /// No complete TLS record is available in the receive buffer.
1476    None,
1477    /// Decrypted application data is available via
1478    /// [`Client::received_app_data`].
1479    AppData,
1480    /// A NewSessionTicket was received from the server.  The pre-shared key
1481    /// (`psk`), lifetime (`lifetime_s`), and obfuscated ticket age addition
1482    /// (`age_add`) are provided for session resumption.
1483    Ticket {
1484        psk: heapless::Vec<u8, PSK_MAX_SIZE>,
1485        lifetime_s: u32,
1486        age_add: u32,
1487    },
1488    /// A KeyUpdate was processed.  The caller should flush
1489    /// [`outgoing_data`](Client::outgoing_data) before
1490    /// reading more data.
1491    KeyUpdate,
1492}
1493
1494/// Extract the EE public key from a [`ReceivedCertificate`] and determine
1495/// its [`SignatureScheme`] by probing the key length.
1496///
1497/// For `RawPublicKey` the scheme is taken directly from the enum.
1498/// For `X509` the public key is already parsed in the `ParsedCertificate`.
1499fn extract_ee_key(cert: &ReceivedCertificate) -> Result<(SignatureScheme, heapless::Vec<u8, 294>), Error> {
1500    match cert {
1501        ReceivedCertificate::RawPublicKey {
1502            public_key,
1503            scheme,
1504        } => {
1505            let mut public_key_vec = heapless::Vec::new();
1506            public_key_vec
1507                .extend_from_slice(public_key)
1508                .map_err(|_| Error::CertificateParseFailed)?;
1509            Ok((*scheme, public_key_vec))
1510        }
1511        ReceivedCertificate::X509 {
1512            chain,
1513        } => {
1514            let ee = chain.first().ok_or(Error::CertificateEmptyChain)?;
1515            detect_key_scheme(ee.public_key)
1516        }
1517    }
1518}
1519
1520fn detect_key_scheme(key: &[u8]) -> Result<(SignatureScheme, heapless::Vec<u8, 294>), Error> {
1521    let mut public_key_vec = heapless::Vec::new();
1522    public_key_vec
1523        .extend_from_slice(key)
1524        .map_err(|_| Error::CertificateParseFailed)?;
1525    let scheme = match key.len() {
1526        65 => SignatureScheme::EcdsaP256Sha256,
1527        97 => SignatureScheme::EcdsaP384Sha384,
1528        32 => SignatureScheme::Ed25519,
1529        _ if key.len() <= 294 => SignatureScheme::RsaPkcs1Sha256,
1530        _ => return Err(Error::CertificateParseFailed),
1531    };
1532    Ok((scheme, public_key_vec))
1533}