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
14pub trait Buffer: Deref<Target = [u8]> + DerefMut {}
20impl<T: Deref<Target = [u8]> + DerefMut> Buffer for T {}
21
22#[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 pub fn new(crypto_provider: C) -> Self {
42 Self {
43 crypto_provider,
44 supported_certificate_types: [CertType::X509].into(),
45 }
46 }
47 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
62pub 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 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 pub(crate) phase: Phase,
103 pub(crate) opened: bool,
104
105 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 pub(crate) key_exchange_group: KeyExchangeGroup,
112 pub(crate) key_exchange_pairs: heapless::Vec<KeyExchangeSecretKey, KEY_EXCHANGE_MAX_GROUPS>,
113
114 pub(crate) keys: KeySchedule<C>,
116
117 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#[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
177pub(crate) struct VerifyCertificateState {
179 frames: heapless::Vec<CertFrame, 8>,
181 cert_abs_start: usize,
183 cert_len: u16,
184 accepted: Option<Result<(), Error>>,
186}
187
188impl<B: Buffer, C: CryptoProvider> Client<B, C> {
191 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 #[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 #[inline]
250 pub fn commit_received(&mut self, n: usize) {
251 self.receive_pending += n;
252 }
253
254 #[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 #[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 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 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 self.send_buffer[0] = ContentType::Handshake as u8;
340 self.send_buffer[1] = 0x03;
341 self.send_buffer[2] = 0x03;
342 let offset = 5; 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 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 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 pub fn outgoing_data(&self) -> &[u8] {
490 &self.send_buffer[self.send_consumed..self.out_len]
491 }
492
493 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 #[inline]
516 fn clear_send_buffer(&mut self) {
517 self.send_consumed = 0;
518 self.out_len = 0;
519 }
520
521 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 pub fn decrypt(&mut self) -> Result<ClientApplicationDataEvent, Error> {
570 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(), 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 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 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 #[inline]
757 pub fn outgoing_key_update_data(&self) -> &[u8] {
758 &self.key_update_response[self.key_update_sent..]
759 }
760
761 #[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 pub fn received_ticket_data(&self) -> &[u8] {
784 &self.receive_buffer[self.ticket_offset..self.ticket_offset + self.ticket_len]
785 }
786
787 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 #[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 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 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 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 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 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 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 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
1437pub enum ClientHandshakeEvent<'a> {
1442 Send,
1446 Receive,
1451 VerifyServerCertificate,
1457 Done {
1459 ciphersuite: CipherSuite,
1460 tls_version: u16,
1462 key_exchange_group: KeyExchangeGroup,
1463 signature_scheme: SignatureScheme,
1465 alpn: &'a [u8],
1466 },
1467 Closed,
1469}
1470
1471pub enum ClientApplicationDataEvent {
1475 None,
1477 AppData,
1480 Ticket {
1484 psk: heapless::Vec<u8, PSK_MAX_SIZE>,
1485 lifetime_s: u32,
1486 age_add: u32,
1487 },
1488 KeyUpdate,
1492}
1493
1494fn 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}