rustls/client/
tls13.rs

1use alloc::boxed::Box;
2use alloc::vec;
3use alloc::vec::Vec;
4
5use pki_types::ServerName;
6use subtle::ConstantTimeEq;
7
8use super::client_conn::ClientConnectionData;
9use super::hs::{ClientContext, ClientHelloInput, ClientSessionValue};
10use crate::check::inappropriate_handshake_message;
11use crate::client::common::{ClientAuthDetails, ClientHelloDetails, ServerCertDetails};
12use crate::client::ech::{self, EchState, EchStatus};
13use crate::client::{ClientConfig, ClientSessionStore, hs};
14use crate::common_state::{
15    CommonState, HandshakeFlightTls13, HandshakeKind, KxState, Protocol, Side, State,
16};
17use crate::conn::ConnectionRandoms;
18use crate::conn::kernel::{Direction, KernelContext, KernelState};
19use crate::crypto::hash::Hash;
20use crate::crypto::{ActiveKeyExchange, SharedSecret};
21use crate::enums::{
22    AlertDescription, ContentType, HandshakeType, ProtocolVersion, SignatureScheme,
23};
24use crate::error::{Error, InvalidMessage, PeerIncompatible, PeerMisbehaved};
25use crate::hash_hs::{HandshakeHash, HandshakeHashBuffer};
26use crate::log::{debug, trace, warn};
27use crate::msgs::base::{Payload, PayloadU8};
28use crate::msgs::ccs::ChangeCipherSpecPayload;
29use crate::msgs::codec::{Codec, Reader};
30use crate::msgs::enums::{ExtensionType, KeyUpdateRequest};
31use crate::msgs::handshake::{
32    CERTIFICATE_MAX_SIZE_LIMIT, CertificatePayloadTls13, ClientExtensions, EchConfigPayload,
33    HandshakeMessagePayload, HandshakePayload, KeyShareEntry, NewSessionTicketPayloadTls13,
34    PresharedKeyBinder, PresharedKeyIdentity, PresharedKeyOffer, ServerExtensions,
35    ServerHelloPayload,
36};
37use crate::msgs::message::{Message, MessagePayload};
38use crate::msgs::persist::{self, Retrieved};
39use crate::sign::{CertifiedKey, Signer};
40use crate::suites::PartiallyExtractedSecrets;
41use crate::sync::Arc;
42use crate::tls13::key_schedule::{
43    KeyScheduleEarly, KeyScheduleHandshake, KeySchedulePreHandshake, KeyScheduleResumption,
44    KeyScheduleTraffic,
45};
46use crate::tls13::{
47    Tls13CipherSuite, construct_client_verify_message, construct_server_verify_message,
48};
49use crate::verify::{self, DigitallySignedStruct};
50use crate::{ConnectionTrafficSecrets, KeyLog, compress, crypto};
51
52// Extensions we expect in plaintext in the ServerHello.
53static ALLOWED_PLAINTEXT_EXTS: &[ExtensionType] = &[
54    ExtensionType::KeyShare,
55    ExtensionType::PreSharedKey,
56    ExtensionType::SupportedVersions,
57];
58
59// Only the intersection of things we offer, and those disallowed
60// in TLS1.3
61static DISALLOWED_TLS13_EXTS: &[ExtensionType] = &[
62    ExtensionType::ECPointFormats,
63    ExtensionType::SessionTicket,
64    ExtensionType::RenegotiationInfo,
65    ExtensionType::ExtendedMasterSecret,
66];
67
68/// `early_data_key_schedule` is `Some` if we sent the
69/// "early_data" extension to the server.
70pub(super) fn handle_server_hello(
71    cx: &mut ClientContext<'_>,
72    server_hello: &ServerHelloPayload,
73    mut randoms: ConnectionRandoms,
74    suite: &'static Tls13CipherSuite,
75    mut transcript: HandshakeHash,
76    early_data_key_schedule: Option<KeyScheduleEarly>,
77    our_key_share: Box<dyn ActiveKeyExchange>,
78    server_hello_msg: &Message<'_>,
79    ech_state: Option<EchState>,
80    input: ClientHelloInput,
81) -> hs::NextStateOrError<'static> {
82    validate_server_hello(cx.common, server_hello)?;
83
84    let their_key_share = server_hello
85        .key_share
86        .as_ref()
87        .ok_or_else(|| {
88            cx.common.send_fatal_alert(
89                AlertDescription::MissingExtension,
90                PeerMisbehaved::MissingKeyShare,
91            )
92        })?;
93
94    let ClientHelloInput {
95        config,
96        resuming,
97        mut sent_tls13_fake_ccs,
98        mut hello,
99        server_name,
100        ..
101    } = input;
102
103    let mut resuming_session = match resuming {
104        Some(Retrieved {
105            value: ClientSessionValue::Tls13(value),
106            ..
107        }) => Some(value),
108        _ => None,
109    };
110
111    let our_key_share = KeyExchangeChoice::new(&config, cx, our_key_share, their_key_share)
112        .map_err(|_| {
113            cx.common.send_fatal_alert(
114                AlertDescription::IllegalParameter,
115                PeerMisbehaved::WrongGroupForKeyShare,
116            )
117        })?;
118
119    let key_schedule_pre_handshake = match (server_hello.preshared_key, early_data_key_schedule) {
120        (Some(selected_psk), Some(early_key_schedule)) => {
121            match &resuming_session {
122                Some(resuming) => {
123                    let Some(resuming_suite) = suite.can_resume_from(resuming.suite()) else {
124                        return Err({
125                            cx.common.send_fatal_alert(
126                                AlertDescription::IllegalParameter,
127                                PeerMisbehaved::ResumptionOfferedWithIncompatibleCipherSuite,
128                            )
129                        });
130                    };
131
132                    // If the server varies the suite here, we will have encrypted early data with
133                    // the wrong suite.
134                    if cx.data.early_data.is_enabled() && resuming_suite != suite {
135                        return Err({
136                            cx.common.send_fatal_alert(
137                                AlertDescription::IllegalParameter,
138                                PeerMisbehaved::EarlyDataOfferedWithVariedCipherSuite,
139                            )
140                        });
141                    }
142
143                    if selected_psk != 0 {
144                        return Err({
145                            cx.common.send_fatal_alert(
146                                AlertDescription::IllegalParameter,
147                                PeerMisbehaved::SelectedInvalidPsk,
148                            )
149                        });
150                    }
151
152                    debug!("Resuming using PSK");
153                    // The key schedule has been initialized and set in fill_in_psk_binder()
154                }
155                _ => {
156                    return Err(PeerMisbehaved::SelectedUnofferedPsk.into());
157                }
158            }
159            KeySchedulePreHandshake::from(early_key_schedule)
160        }
161        _ => {
162            debug!("Not resuming");
163            // Discard the early data key schedule.
164            cx.data.early_data.rejected();
165            cx.common.early_traffic = false;
166            resuming_session.take();
167            KeySchedulePreHandshake::new(suite)
168        }
169    };
170
171    cx.common.kx_state.complete();
172    let shared_secret = our_key_share
173        .complete(&their_key_share.payload.0)
174        .map_err(|err| {
175            cx.common
176                .send_fatal_alert(AlertDescription::IllegalParameter, err)
177        })?;
178
179    let mut key_schedule = key_schedule_pre_handshake.into_handshake(shared_secret);
180
181    // If we have ECH state, check that the server accepted our offer.
182    if let Some(ech_state) = ech_state {
183        let Message {
184            payload:
185                MessagePayload::Handshake {
186                    encoded: server_hello_encoded,
187                    ..
188                },
189            ..
190        } = &server_hello_msg
191        else {
192            unreachable!("ServerHello is a handshake message");
193        };
194        cx.data.ech_status = match ech_state.confirm_acceptance(
195            &mut key_schedule,
196            server_hello,
197            server_hello_encoded,
198            suite.common.hash_provider,
199        )? {
200            // The server accepted our ECH offer, so complete the inner transcript with the
201            // server hello message, and switch the relevant state to the copies for the
202            // inner client hello.
203            Some(mut accepted) => {
204                accepted
205                    .transcript
206                    .add_message(server_hello_msg);
207                transcript = accepted.transcript;
208                randoms.client = accepted.random.0;
209                hello.sent_extensions = accepted.sent_extensions;
210                EchStatus::Accepted
211            }
212            // The server rejected our ECH offer.
213            None => EchStatus::Rejected,
214        };
215    }
216
217    // Remember what KX group the server liked for next time.
218    config
219        .resumption
220        .store
221        .set_kx_hint(server_name.clone(), their_key_share.group);
222
223    // If we change keying when a subsequent handshake message is being joined,
224    // the two halves will have different record layer protections.  Disallow this.
225    cx.common.check_aligned_handshake()?;
226
227    let hash_at_client_recvd_server_hello = transcript.current_hash();
228    let key_schedule = key_schedule.derive_client_handshake_secrets(
229        cx.data.early_data.is_enabled(),
230        hash_at_client_recvd_server_hello,
231        suite,
232        &*config.key_log,
233        &randoms.client,
234        cx.common,
235    );
236
237    emit_fake_ccs(&mut sent_tls13_fake_ccs, cx.common);
238
239    Ok(Box::new(ExpectEncryptedExtensions {
240        config,
241        resuming_session,
242        server_name,
243        randoms,
244        suite,
245        transcript,
246        key_schedule,
247        hello,
248    }))
249}
250
251enum KeyExchangeChoice {
252    Whole(Box<dyn ActiveKeyExchange>),
253    Component(Box<dyn ActiveKeyExchange>),
254}
255
256impl KeyExchangeChoice {
257    /// Decide between `our_key_share` or `our_key_share.hybrid_component()`
258    /// based on the selection of the server expressed in `their_key_share`.
259    fn new(
260        config: &Arc<ClientConfig>,
261        cx: &mut ClientContext<'_>,
262        our_key_share: Box<dyn ActiveKeyExchange>,
263        their_key_share: &KeyShareEntry,
264    ) -> Result<Self, ()> {
265        if our_key_share.group() == their_key_share.group {
266            return Ok(Self::Whole(our_key_share));
267        }
268
269        let (component_group, _) = our_key_share
270            .hybrid_component()
271            .ok_or(())?;
272
273        if component_group != their_key_share.group {
274            return Err(());
275        }
276
277        // correct the record for the benefit of accuracy of
278        // `negotiated_key_exchange_group()`
279        let actual_skxg = config
280            .find_kx_group(component_group, ProtocolVersion::TLSv1_3)
281            .ok_or(())?;
282        cx.common.kx_state = KxState::Start(actual_skxg);
283
284        Ok(Self::Component(our_key_share))
285    }
286
287    fn complete(self, peer_pub_key: &[u8]) -> Result<SharedSecret, Error> {
288        match self {
289            Self::Whole(akx) => akx.complete(peer_pub_key),
290            Self::Component(akx) => akx.complete_hybrid_component(peer_pub_key),
291        }
292    }
293}
294
295fn validate_server_hello(
296    common: &mut CommonState,
297    server_hello: &ServerHelloPayload,
298) -> Result<(), Error> {
299    if !server_hello.only_contains(ALLOWED_PLAINTEXT_EXTS) {
300        return Err(common.send_fatal_alert(
301            AlertDescription::UnsupportedExtension,
302            PeerMisbehaved::UnexpectedCleartextExtension,
303        ));
304    }
305
306    Ok(())
307}
308
309pub(super) fn initial_key_share(
310    config: &ClientConfig,
311    server_name: &ServerName<'_>,
312    kx_state: &mut KxState,
313) -> Result<Box<dyn ActiveKeyExchange>, Error> {
314    let group = config
315        .resumption
316        .store
317        .kx_hint(server_name)
318        .and_then(|group_name| config.find_kx_group(group_name, ProtocolVersion::TLSv1_3))
319        .unwrap_or_else(|| {
320            config
321                .provider
322                .kx_groups
323                .iter()
324                .copied()
325                .next()
326                .expect("No kx groups configured")
327        });
328
329    *kx_state = KxState::Start(group);
330    group.start()
331}
332
333/// This implements the horrifying TLS1.3 hack where PSK binders have a
334/// data dependency on the message they are contained within.
335pub(super) fn fill_in_psk_binder(
336    resuming: &persist::Tls13ClientSessionValue,
337    transcript: &HandshakeHashBuffer,
338    hmp: &mut HandshakeMessagePayload<'_>,
339) -> KeyScheduleEarly {
340    // We need to know the hash function of the suite we're trying to resume into.
341    let suite = resuming.suite();
342    let suite_hash = suite.common.hash_provider;
343
344    // The binder is calculated over the clienthello, but doesn't include itself or its
345    // length, or the length of its container.
346    let binder_plaintext = hmp.encoding_for_binder_signing();
347    let handshake_hash = transcript.hash_given(suite_hash, &binder_plaintext);
348
349    // Run a fake key_schedule to simulate what the server will do if it chooses
350    // to resume.
351    let key_schedule = KeyScheduleEarly::new(suite, resuming.secret());
352    let real_binder = key_schedule.resumption_psk_binder_key_and_sign_verify_data(&handshake_hash);
353
354    if let HandshakePayload::ClientHello(ch) = &mut hmp.0 {
355        if let Some(PresharedKeyOffer {
356            binders,
357            identities,
358        }) = &mut ch.preshared_key_offer
359        {
360            // the caller of this function must have set up the desired identity, and a
361            // matching (dummy) binder; or else the binder we compute here will be incorrect.
362            // See `prepare_resumption()`.
363            debug_assert_eq!(identities.len(), 1);
364            debug_assert_eq!(binders.len(), 1);
365            debug_assert_eq!(binders[0].as_ref().len(), real_binder.as_ref().len());
366            binders[0] = PresharedKeyBinder::from(real_binder.as_ref().to_vec());
367        }
368    };
369
370    key_schedule
371}
372
373pub(super) fn prepare_resumption(
374    config: &ClientConfig,
375    cx: &mut ClientContext<'_>,
376    resuming_session: &Retrieved<&persist::Tls13ClientSessionValue>,
377    exts: &mut ClientExtensions<'_>,
378    doing_retry: bool,
379) {
380    let resuming_suite = resuming_session.suite();
381    cx.common.suite = Some(resuming_suite.into());
382    // The EarlyData extension MUST be supplied together with the
383    // PreSharedKey extension.
384    let max_early_data_size = resuming_session.max_early_data_size();
385    if config.enable_early_data && max_early_data_size > 0 && !doing_retry {
386        cx.data
387            .early_data
388            .enable(max_early_data_size as usize);
389        exts.early_data_request = Some(());
390    }
391
392    // Finally, and only for TLS1.3 with a ticket resumption, include a binder
393    // for our ticket.  This must go last.
394    //
395    // Include an empty binder. It gets filled in below because it depends on
396    // the message it's contained in (!!!).
397    let obfuscated_ticket_age = resuming_session.obfuscated_ticket_age();
398
399    let binder_len = resuming_suite
400        .common
401        .hash_provider
402        .output_len();
403    let binder = vec![0u8; binder_len];
404
405    let psk_identity =
406        PresharedKeyIdentity::new(resuming_session.ticket().to_vec(), obfuscated_ticket_age);
407    let psk_offer = PresharedKeyOffer::new(psk_identity, binder);
408    exts.preshared_key_offer = Some(psk_offer);
409}
410
411pub(super) fn derive_early_traffic_secret(
412    key_log: &dyn KeyLog,
413    cx: &mut ClientContext<'_>,
414    hash_alg: &'static dyn Hash,
415    early_key_schedule: &KeyScheduleEarly,
416    sent_tls13_fake_ccs: &mut bool,
417    transcript_buffer: &HandshakeHashBuffer,
418    client_random: &[u8; 32],
419) {
420    // For middlebox compatibility
421    emit_fake_ccs(sent_tls13_fake_ccs, cx.common);
422
423    let client_hello_hash = transcript_buffer.hash_given(hash_alg, &[]);
424    early_key_schedule.client_early_traffic_secret(
425        &client_hello_hash,
426        key_log,
427        client_random,
428        cx.common,
429    );
430
431    // Now the client can send encrypted early data
432    cx.common.early_traffic = true;
433    trace!("Starting early data traffic");
434}
435
436pub(super) fn emit_fake_ccs(sent_tls13_fake_ccs: &mut bool, common: &mut CommonState) {
437    if common.is_quic() {
438        return;
439    }
440
441    if core::mem::replace(sent_tls13_fake_ccs, true) {
442        return;
443    }
444
445    let m = Message {
446        version: ProtocolVersion::TLSv1_2,
447        payload: MessagePayload::ChangeCipherSpec(ChangeCipherSpecPayload {}),
448    };
449    common.send_msg(m, false);
450}
451
452fn validate_encrypted_extensions(
453    common: &mut CommonState,
454    hello: &ClientHelloDetails,
455    exts: &ServerExtensions<'_>,
456) -> Result<(), Error> {
457    if hello.server_sent_unsolicited_extensions(exts, &[]) {
458        return Err(common.send_fatal_alert(
459            AlertDescription::UnsupportedExtension,
460            PeerMisbehaved::UnsolicitedEncryptedExtension,
461        ));
462    }
463
464    if exts.contains_any(ALLOWED_PLAINTEXT_EXTS) || exts.contains_any(DISALLOWED_TLS13_EXTS) {
465        return Err(common.send_fatal_alert(
466            AlertDescription::UnsupportedExtension,
467            PeerMisbehaved::DisallowedEncryptedExtension,
468        ));
469    }
470
471    Ok(())
472}
473
474struct ExpectEncryptedExtensions {
475    config: Arc<ClientConfig>,
476    resuming_session: Option<persist::Tls13ClientSessionValue>,
477    server_name: ServerName<'static>,
478    randoms: ConnectionRandoms,
479    suite: &'static Tls13CipherSuite,
480    transcript: HandshakeHash,
481    key_schedule: KeyScheduleHandshake,
482    hello: ClientHelloDetails,
483}
484
485impl State<ClientConnectionData> for ExpectEncryptedExtensions {
486    fn handle<'m>(
487        mut self: Box<Self>,
488        cx: &mut ClientContext<'_>,
489        m: Message<'m>,
490    ) -> hs::NextStateOrError<'m>
491    where
492        Self: 'm,
493    {
494        let exts = require_handshake_msg!(
495            m,
496            HandshakeType::EncryptedExtensions,
497            HandshakePayload::EncryptedExtensions
498        )?;
499        debug!("TLS1.3 encrypted extensions: {exts:?}");
500        self.transcript.add_message(&m);
501
502        validate_encrypted_extensions(cx.common, &self.hello, exts)?;
503        hs::process_alpn_protocol(
504            cx.common,
505            &self.hello.alpn_protocols,
506            exts.selected_protocol
507                .as_ref()
508                .map(|protocol| protocol.as_ref()),
509        )?;
510        hs::process_client_cert_type_extension(
511            cx.common,
512            &self.config,
513            exts.client_certificate_type.as_ref(),
514        )?;
515        hs::process_server_cert_type_extension(
516            cx.common,
517            &self.config,
518            exts.server_certificate_type.as_ref(),
519        )?;
520
521        let ech_retry_configs = match (cx.data.ech_status, &exts.encrypted_client_hello_ack) {
522            // If we didn't offer ECH, or ECH was accepted, but the server sent an ECH encrypted
523            // extension with retry configs, we must error.
524            (EchStatus::NotOffered | EchStatus::Accepted, Some(_)) => {
525                return Err(cx.common.send_fatal_alert(
526                    AlertDescription::UnsupportedExtension,
527                    PeerMisbehaved::UnsolicitedEchExtension,
528                ));
529            }
530            // If we offered ECH, and it was rejected, store the retry configs (if any) from
531            // the server's ECH extension. We will return them in an error produced at the end
532            // of the handshake.
533            (EchStatus::Rejected, ext) => ext
534                .as_ref()
535                .map(|ext| ext.retry_configs.to_vec()),
536            _ => None,
537        };
538
539        // QUIC transport parameters
540        if cx.common.is_quic() {
541            match exts
542                .transport_parameters
543                .as_ref()
544                .or(exts.transport_parameters_draft.as_ref())
545            {
546                Some(params) => cx.common.quic.params = Some(params.clone().into_vec()),
547                None => {
548                    return Err(cx
549                        .common
550                        .missing_extension(PeerMisbehaved::MissingQuicTransportParameters));
551                }
552            }
553        }
554
555        match self.resuming_session {
556            Some(resuming_session) => {
557                let was_early_traffic = cx.common.early_traffic;
558                if was_early_traffic {
559                    match exts.early_data_ack {
560                        Some(()) => cx.data.early_data.accepted(),
561                        None => {
562                            cx.data.early_data.rejected();
563                            cx.common.early_traffic = false;
564                        }
565                    }
566                }
567
568                if was_early_traffic && !cx.common.early_traffic {
569                    // If no early traffic, set the encryption key for handshakes
570                    self.key_schedule
571                        .set_handshake_encrypter(cx.common);
572                }
573
574                cx.common.peer_certificates = Some(
575                    resuming_session
576                        .server_cert_chain()
577                        .clone(),
578                );
579                cx.common.handshake_kind = Some(HandshakeKind::Resumed);
580
581                // We *don't* reverify the certificate chain here: resumption is a
582                // continuation of the previous session in terms of security policy.
583                let cert_verified = verify::ServerCertVerified::assertion();
584                let sig_verified = verify::HandshakeSignatureValid::assertion();
585                Ok(Box::new(ExpectFinished {
586                    config: self.config,
587                    server_name: self.server_name,
588                    randoms: self.randoms,
589                    suite: self.suite,
590                    transcript: self.transcript,
591                    key_schedule: self.key_schedule,
592                    client_auth: None,
593                    cert_verified,
594                    sig_verified,
595                    ech_retry_configs,
596                }))
597            }
598            _ => {
599                if exts.early_data_ack.is_some() {
600                    return Err(PeerMisbehaved::EarlyDataExtensionWithoutResumption.into());
601                }
602                cx.common
603                    .handshake_kind
604                    .get_or_insert(HandshakeKind::Full);
605
606                Ok(if self.hello.offered_cert_compression {
607                    Box::new(ExpectCertificateOrCompressedCertificateOrCertReq {
608                        config: self.config,
609                        server_name: self.server_name,
610                        randoms: self.randoms,
611                        suite: self.suite,
612                        transcript: self.transcript,
613                        key_schedule: self.key_schedule,
614                        ech_retry_configs,
615                    })
616                } else {
617                    Box::new(ExpectCertificateOrCertReq {
618                        config: self.config,
619                        server_name: self.server_name,
620                        randoms: self.randoms,
621                        suite: self.suite,
622                        transcript: self.transcript,
623                        key_schedule: self.key_schedule,
624                        ech_retry_configs,
625                    })
626                })
627            }
628        }
629    }
630
631    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
632        self
633    }
634}
635
636struct ExpectCertificateOrCompressedCertificateOrCertReq {
637    config: Arc<ClientConfig>,
638    server_name: ServerName<'static>,
639    randoms: ConnectionRandoms,
640    suite: &'static Tls13CipherSuite,
641    transcript: HandshakeHash,
642    key_schedule: KeyScheduleHandshake,
643    ech_retry_configs: Option<Vec<EchConfigPayload>>,
644}
645
646impl State<ClientConnectionData> for ExpectCertificateOrCompressedCertificateOrCertReq {
647    fn handle<'m>(
648        self: Box<Self>,
649        cx: &mut ClientContext<'_>,
650        m: Message<'m>,
651    ) -> hs::NextStateOrError<'m>
652    where
653        Self: 'm,
654    {
655        match m.payload {
656            MessagePayload::Handshake {
657                parsed: HandshakeMessagePayload(HandshakePayload::CertificateTls13(..)),
658                ..
659            } => Box::new(ExpectCertificate {
660                config: self.config,
661                server_name: self.server_name,
662                randoms: self.randoms,
663                suite: self.suite,
664                transcript: self.transcript,
665                key_schedule: self.key_schedule,
666                client_auth: None,
667                message_already_in_transcript: false,
668                ech_retry_configs: self.ech_retry_configs,
669            })
670            .handle(cx, m),
671            MessagePayload::Handshake {
672                parsed: HandshakeMessagePayload(HandshakePayload::CompressedCertificate(..)),
673                ..
674            } => Box::new(ExpectCompressedCertificate {
675                config: self.config,
676                server_name: self.server_name,
677                randoms: self.randoms,
678                suite: self.suite,
679                transcript: self.transcript,
680                key_schedule: self.key_schedule,
681                client_auth: None,
682                ech_retry_configs: self.ech_retry_configs,
683            })
684            .handle(cx, m),
685            MessagePayload::Handshake {
686                parsed: HandshakeMessagePayload(HandshakePayload::CertificateRequestTls13(..)),
687                ..
688            } => Box::new(ExpectCertificateRequest {
689                config: self.config,
690                server_name: self.server_name,
691                randoms: self.randoms,
692                suite: self.suite,
693                transcript: self.transcript,
694                key_schedule: self.key_schedule,
695                offered_cert_compression: true,
696                ech_retry_configs: self.ech_retry_configs,
697            })
698            .handle(cx, m),
699            payload => Err(inappropriate_handshake_message(
700                &payload,
701                &[ContentType::Handshake],
702                &[
703                    HandshakeType::Certificate,
704                    HandshakeType::CertificateRequest,
705                    HandshakeType::CompressedCertificate,
706                ],
707            )),
708        }
709    }
710
711    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
712        self
713    }
714}
715
716struct ExpectCertificateOrCompressedCertificate {
717    config: Arc<ClientConfig>,
718    server_name: ServerName<'static>,
719    randoms: ConnectionRandoms,
720    suite: &'static Tls13CipherSuite,
721    transcript: HandshakeHash,
722    key_schedule: KeyScheduleHandshake,
723    client_auth: Option<ClientAuthDetails>,
724    ech_retry_configs: Option<Vec<EchConfigPayload>>,
725}
726
727impl State<ClientConnectionData> for ExpectCertificateOrCompressedCertificate {
728    fn handle<'m>(
729        self: Box<Self>,
730        cx: &mut ClientContext<'_>,
731        m: Message<'m>,
732    ) -> hs::NextStateOrError<'m>
733    where
734        Self: 'm,
735    {
736        match m.payload {
737            MessagePayload::Handshake {
738                parsed: HandshakeMessagePayload(HandshakePayload::CertificateTls13(..)),
739                ..
740            } => Box::new(ExpectCertificate {
741                config: self.config,
742                server_name: self.server_name,
743                randoms: self.randoms,
744                suite: self.suite,
745                transcript: self.transcript,
746                key_schedule: self.key_schedule,
747                client_auth: self.client_auth,
748                message_already_in_transcript: false,
749                ech_retry_configs: self.ech_retry_configs,
750            })
751            .handle(cx, m),
752            MessagePayload::Handshake {
753                parsed: HandshakeMessagePayload(HandshakePayload::CompressedCertificate(..)),
754                ..
755            } => Box::new(ExpectCompressedCertificate {
756                config: self.config,
757                server_name: self.server_name,
758                randoms: self.randoms,
759                suite: self.suite,
760                transcript: self.transcript,
761                key_schedule: self.key_schedule,
762                client_auth: self.client_auth,
763                ech_retry_configs: self.ech_retry_configs,
764            })
765            .handle(cx, m),
766            payload => Err(inappropriate_handshake_message(
767                &payload,
768                &[ContentType::Handshake],
769                &[
770                    HandshakeType::Certificate,
771                    HandshakeType::CompressedCertificate,
772                ],
773            )),
774        }
775    }
776
777    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
778        self
779    }
780}
781
782struct ExpectCertificateOrCertReq {
783    config: Arc<ClientConfig>,
784    server_name: ServerName<'static>,
785    randoms: ConnectionRandoms,
786    suite: &'static Tls13CipherSuite,
787    transcript: HandshakeHash,
788    key_schedule: KeyScheduleHandshake,
789    ech_retry_configs: Option<Vec<EchConfigPayload>>,
790}
791
792impl State<ClientConnectionData> for ExpectCertificateOrCertReq {
793    fn handle<'m>(
794        self: Box<Self>,
795        cx: &mut ClientContext<'_>,
796        m: Message<'m>,
797    ) -> hs::NextStateOrError<'m>
798    where
799        Self: 'm,
800    {
801        match m.payload {
802            MessagePayload::Handshake {
803                parsed: HandshakeMessagePayload(HandshakePayload::CertificateTls13(..)),
804                ..
805            } => Box::new(ExpectCertificate {
806                config: self.config,
807                server_name: self.server_name,
808                randoms: self.randoms,
809                suite: self.suite,
810                transcript: self.transcript,
811                key_schedule: self.key_schedule,
812                client_auth: None,
813                message_already_in_transcript: false,
814                ech_retry_configs: self.ech_retry_configs,
815            })
816            .handle(cx, m),
817            MessagePayload::Handshake {
818                parsed: HandshakeMessagePayload(HandshakePayload::CertificateRequestTls13(..)),
819                ..
820            } => Box::new(ExpectCertificateRequest {
821                config: self.config,
822                server_name: self.server_name,
823                randoms: self.randoms,
824                suite: self.suite,
825                transcript: self.transcript,
826                key_schedule: self.key_schedule,
827                offered_cert_compression: false,
828                ech_retry_configs: self.ech_retry_configs,
829            })
830            .handle(cx, m),
831            payload => Err(inappropriate_handshake_message(
832                &payload,
833                &[ContentType::Handshake],
834                &[
835                    HandshakeType::Certificate,
836                    HandshakeType::CertificateRequest,
837                ],
838            )),
839        }
840    }
841
842    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
843        self
844    }
845}
846
847// TLS1.3 version of CertificateRequest handling.  We then move to expecting the server
848// Certificate. Unfortunately the CertificateRequest type changed in an annoying way
849// in TLS1.3.
850struct ExpectCertificateRequest {
851    config: Arc<ClientConfig>,
852    server_name: ServerName<'static>,
853    randoms: ConnectionRandoms,
854    suite: &'static Tls13CipherSuite,
855    transcript: HandshakeHash,
856    key_schedule: KeyScheduleHandshake,
857    offered_cert_compression: bool,
858    ech_retry_configs: Option<Vec<EchConfigPayload>>,
859}
860
861impl State<ClientConnectionData> for ExpectCertificateRequest {
862    fn handle<'m>(
863        mut self: Box<Self>,
864        cx: &mut ClientContext<'_>,
865        m: Message<'m>,
866    ) -> hs::NextStateOrError<'m>
867    where
868        Self: 'm,
869    {
870        let certreq = &require_handshake_msg!(
871            m,
872            HandshakeType::CertificateRequest,
873            HandshakePayload::CertificateRequestTls13
874        )?;
875        self.transcript.add_message(&m);
876        debug!("Got CertificateRequest {certreq:?}");
877
878        // Fortunately the problems here in TLS1.2 and prior are corrected in
879        // TLS1.3.
880
881        // Must be empty during handshake.
882        if !certreq.context.0.is_empty() {
883            warn!("Server sent non-empty certreq context");
884            return Err(cx.common.send_fatal_alert(
885                AlertDescription::DecodeError,
886                InvalidMessage::InvalidCertRequest,
887            ));
888        }
889
890        let compat_sigschemes = certreq
891            .extensions
892            .signature_algorithms
893            .as_deref()
894            .unwrap_or_default()
895            .iter()
896            .cloned()
897            .filter(SignatureScheme::supported_in_tls13)
898            .collect::<Vec<SignatureScheme>>();
899
900        if compat_sigschemes.is_empty() {
901            return Err(cx.common.send_fatal_alert(
902                AlertDescription::HandshakeFailure,
903                PeerIncompatible::NoCertificateRequestSignatureSchemesInCommon,
904            ));
905        }
906
907        let compat_compressor = certreq
908            .extensions
909            .certificate_compression_algorithms
910            .as_deref()
911            .and_then(|offered| {
912                self.config
913                    .cert_compressors
914                    .iter()
915                    .find(|compressor| offered.contains(&compressor.algorithm()))
916            })
917            .cloned();
918
919        let client_auth = ClientAuthDetails::resolve(
920            self.config
921                .client_auth_cert_resolver
922                .as_ref(),
923            certreq
924                .extensions
925                .authority_names
926                .as_deref(),
927            &compat_sigschemes,
928            Some(certreq.context.0.clone()),
929            compat_compressor,
930        );
931
932        Ok(if self.offered_cert_compression {
933            Box::new(ExpectCertificateOrCompressedCertificate {
934                config: self.config,
935                server_name: self.server_name,
936                randoms: self.randoms,
937                suite: self.suite,
938                transcript: self.transcript,
939                key_schedule: self.key_schedule,
940                client_auth: Some(client_auth),
941                ech_retry_configs: self.ech_retry_configs,
942            })
943        } else {
944            Box::new(ExpectCertificate {
945                config: self.config,
946                server_name: self.server_name,
947                randoms: self.randoms,
948                suite: self.suite,
949                transcript: self.transcript,
950                key_schedule: self.key_schedule,
951                client_auth: Some(client_auth),
952                message_already_in_transcript: false,
953                ech_retry_configs: self.ech_retry_configs,
954            })
955        })
956    }
957
958    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
959        self
960    }
961}
962
963struct ExpectCompressedCertificate {
964    config: Arc<ClientConfig>,
965    server_name: ServerName<'static>,
966    randoms: ConnectionRandoms,
967    suite: &'static Tls13CipherSuite,
968    transcript: HandshakeHash,
969    key_schedule: KeyScheduleHandshake,
970    client_auth: Option<ClientAuthDetails>,
971    ech_retry_configs: Option<Vec<EchConfigPayload>>,
972}
973
974impl State<ClientConnectionData> for ExpectCompressedCertificate {
975    fn handle<'m>(
976        mut self: Box<Self>,
977        cx: &mut ClientContext<'_>,
978        m: Message<'m>,
979    ) -> hs::NextStateOrError<'m>
980    where
981        Self: 'm,
982    {
983        self.transcript.add_message(&m);
984        let compressed_cert = require_handshake_msg_move!(
985            m,
986            HandshakeType::CompressedCertificate,
987            HandshakePayload::CompressedCertificate
988        )?;
989
990        let selected_decompressor = self
991            .config
992            .cert_decompressors
993            .iter()
994            .find(|item| item.algorithm() == compressed_cert.alg);
995
996        let Some(decompressor) = selected_decompressor else {
997            return Err(cx.common.send_fatal_alert(
998                AlertDescription::BadCertificate,
999                PeerMisbehaved::SelectedUnofferedCertCompression,
1000            ));
1001        };
1002
1003        if compressed_cert.uncompressed_len as usize > CERTIFICATE_MAX_SIZE_LIMIT {
1004            return Err(cx.common.send_fatal_alert(
1005                AlertDescription::BadCertificate,
1006                InvalidMessage::MessageTooLarge,
1007            ));
1008        }
1009
1010        let mut decompress_buffer = vec![0u8; compressed_cert.uncompressed_len as usize];
1011        if let Err(compress::DecompressionFailed) =
1012            decompressor.decompress(compressed_cert.compressed.0.bytes(), &mut decompress_buffer)
1013        {
1014            return Err(cx.common.send_fatal_alert(
1015                AlertDescription::BadCertificate,
1016                PeerMisbehaved::InvalidCertCompression,
1017            ));
1018        }
1019
1020        let cert_payload =
1021            match CertificatePayloadTls13::read(&mut Reader::init(&decompress_buffer)) {
1022                Ok(cm) => cm,
1023                Err(err) => {
1024                    return Err(cx
1025                        .common
1026                        .send_fatal_alert(AlertDescription::BadCertificate, err));
1027                }
1028            };
1029        trace!(
1030            "Server certificate decompressed using {:?} ({} bytes -> {})",
1031            compressed_cert.alg,
1032            compressed_cert
1033                .compressed
1034                .0
1035                .bytes()
1036                .len(),
1037            compressed_cert.uncompressed_len,
1038        );
1039
1040        let m = Message {
1041            version: ProtocolVersion::TLSv1_3,
1042            payload: MessagePayload::handshake(HandshakeMessagePayload(
1043                HandshakePayload::CertificateTls13(cert_payload.into_owned()),
1044            )),
1045        };
1046
1047        Box::new(ExpectCertificate {
1048            config: self.config,
1049            server_name: self.server_name,
1050            randoms: self.randoms,
1051            suite: self.suite,
1052            transcript: self.transcript,
1053            key_schedule: self.key_schedule,
1054            client_auth: self.client_auth,
1055            message_already_in_transcript: true,
1056            ech_retry_configs: self.ech_retry_configs,
1057        })
1058        .handle(cx, m)
1059    }
1060
1061    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1062        self
1063    }
1064}
1065
1066struct ExpectCertificate {
1067    config: Arc<ClientConfig>,
1068    server_name: ServerName<'static>,
1069    randoms: ConnectionRandoms,
1070    suite: &'static Tls13CipherSuite,
1071    transcript: HandshakeHash,
1072    key_schedule: KeyScheduleHandshake,
1073    client_auth: Option<ClientAuthDetails>,
1074    message_already_in_transcript: bool,
1075    ech_retry_configs: Option<Vec<EchConfigPayload>>,
1076}
1077
1078impl State<ClientConnectionData> for ExpectCertificate {
1079    fn handle<'m>(
1080        mut self: Box<Self>,
1081        cx: &mut ClientContext<'_>,
1082        m: Message<'m>,
1083    ) -> hs::NextStateOrError<'m>
1084    where
1085        Self: 'm,
1086    {
1087        if !self.message_already_in_transcript {
1088            self.transcript.add_message(&m);
1089        }
1090        let cert_chain = require_handshake_msg_move!(
1091            m,
1092            HandshakeType::Certificate,
1093            HandshakePayload::CertificateTls13
1094        )?;
1095
1096        // This is only non-empty for client auth.
1097        if !cert_chain.context.0.is_empty() {
1098            return Err(cx.common.send_fatal_alert(
1099                AlertDescription::DecodeError,
1100                InvalidMessage::InvalidCertRequest,
1101            ));
1102        }
1103
1104        let end_entity_ocsp = cert_chain.end_entity_ocsp().to_vec();
1105        let server_cert = ServerCertDetails::new(
1106            cert_chain
1107                .into_certificate_chain()
1108                .into_owned(),
1109            end_entity_ocsp,
1110        );
1111
1112        Ok(Box::new(ExpectCertificateVerify {
1113            config: self.config,
1114            server_name: self.server_name,
1115            randoms: self.randoms,
1116            suite: self.suite,
1117            transcript: self.transcript,
1118            key_schedule: self.key_schedule,
1119            server_cert,
1120            client_auth: self.client_auth,
1121            ech_retry_configs: self.ech_retry_configs,
1122        }))
1123    }
1124
1125    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1126        self
1127    }
1128}
1129
1130// --- TLS1.3 CertificateVerify ---
1131struct ExpectCertificateVerify<'a> {
1132    config: Arc<ClientConfig>,
1133    server_name: ServerName<'static>,
1134    randoms: ConnectionRandoms,
1135    suite: &'static Tls13CipherSuite,
1136    transcript: HandshakeHash,
1137    key_schedule: KeyScheduleHandshake,
1138    server_cert: ServerCertDetails<'a>,
1139    client_auth: Option<ClientAuthDetails>,
1140    ech_retry_configs: Option<Vec<EchConfigPayload>>,
1141}
1142
1143impl State<ClientConnectionData> for ExpectCertificateVerify<'_> {
1144    fn handle<'m>(
1145        mut self: Box<Self>,
1146        cx: &mut ClientContext<'_>,
1147        m: Message<'m>,
1148    ) -> hs::NextStateOrError<'m>
1149    where
1150        Self: 'm,
1151    {
1152        let cert_verify = require_handshake_msg!(
1153            m,
1154            HandshakeType::CertificateVerify,
1155            HandshakePayload::CertificateVerify
1156        )?;
1157
1158        trace!("Server cert is {:?}", self.server_cert.cert_chain);
1159
1160        // 1. Verify the certificate chain.
1161        let (end_entity, intermediates) = self
1162            .server_cert
1163            .cert_chain
1164            .split_first()
1165            .ok_or(Error::NoCertificatesPresented)?;
1166
1167        let now = self.config.current_time()?;
1168
1169        let cert_verified = self
1170            .config
1171            .verifier
1172            .verify_server_cert(
1173                end_entity,
1174                intermediates,
1175                &self.server_name,
1176                &self.server_cert.ocsp_response,
1177                now,
1178            )
1179            .map_err(|err| {
1180                cx.common
1181                    .send_cert_verify_error_alert(err)
1182            })?;
1183
1184        // 2. Verify their signature on the handshake.
1185        let handshake_hash = self.transcript.current_hash();
1186        let sig_verified = self
1187            .config
1188            .verifier
1189            .verify_tls13_signature(
1190                construct_server_verify_message(&handshake_hash).as_ref(),
1191                end_entity,
1192                cert_verify,
1193            )
1194            .map_err(|err| {
1195                cx.common
1196                    .send_cert_verify_error_alert(err)
1197            })?;
1198
1199        cx.common.peer_certificates = Some(self.server_cert.cert_chain.into_owned());
1200        self.transcript.add_message(&m);
1201
1202        Ok(Box::new(ExpectFinished {
1203            config: self.config,
1204            server_name: self.server_name,
1205            randoms: self.randoms,
1206            suite: self.suite,
1207            transcript: self.transcript,
1208            key_schedule: self.key_schedule,
1209            client_auth: self.client_auth,
1210            cert_verified,
1211            sig_verified,
1212            ech_retry_configs: self.ech_retry_configs,
1213        }))
1214    }
1215
1216    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1217        Box::new(ExpectCertificateVerify {
1218            config: self.config,
1219            server_name: self.server_name,
1220            randoms: self.randoms,
1221            suite: self.suite,
1222            transcript: self.transcript,
1223            key_schedule: self.key_schedule,
1224            server_cert: self.server_cert.into_owned(),
1225            client_auth: self.client_auth,
1226            ech_retry_configs: self.ech_retry_configs,
1227        })
1228    }
1229}
1230
1231fn emit_compressed_certificate_tls13(
1232    flight: &mut HandshakeFlightTls13<'_>,
1233    certkey: &CertifiedKey,
1234    auth_context: Option<Vec<u8>>,
1235    compressor: &dyn compress::CertCompressor,
1236    config: &ClientConfig,
1237) {
1238    let mut cert_payload = CertificatePayloadTls13::new(certkey.cert.iter(), None);
1239    cert_payload.context = PayloadU8::new(auth_context.clone().unwrap_or_default());
1240
1241    let Ok(compressed) = config
1242        .cert_compression_cache
1243        .compression_for(compressor, &cert_payload)
1244    else {
1245        return emit_certificate_tls13(flight, Some(certkey), auth_context);
1246    };
1247
1248    flight.add(HandshakeMessagePayload(
1249        HandshakePayload::CompressedCertificate(compressed.compressed_cert_payload()),
1250    ));
1251}
1252
1253fn emit_certificate_tls13(
1254    flight: &mut HandshakeFlightTls13<'_>,
1255    certkey: Option<&CertifiedKey>,
1256    auth_context: Option<Vec<u8>>,
1257) {
1258    let certs = certkey
1259        .map(|ck| ck.cert.as_ref())
1260        .unwrap_or(&[][..]);
1261    let mut cert_payload = CertificatePayloadTls13::new(certs.iter(), None);
1262    cert_payload.context = PayloadU8::new(auth_context.unwrap_or_default());
1263
1264    flight.add(HandshakeMessagePayload(HandshakePayload::CertificateTls13(
1265        cert_payload,
1266    )));
1267}
1268
1269fn emit_certverify_tls13(
1270    flight: &mut HandshakeFlightTls13<'_>,
1271    signer: &dyn Signer,
1272) -> Result<(), Error> {
1273    let message = construct_client_verify_message(&flight.transcript.current_hash());
1274
1275    let scheme = signer.scheme();
1276    let sig = signer.sign(message.as_ref())?;
1277    let dss = DigitallySignedStruct::new(scheme, sig);
1278
1279    flight.add(HandshakeMessagePayload(
1280        HandshakePayload::CertificateVerify(dss),
1281    ));
1282    Ok(())
1283}
1284
1285fn emit_finished_tls13(flight: &mut HandshakeFlightTls13<'_>, verify_data: &crypto::hmac::Tag) {
1286    let verify_data_payload = Payload::new(verify_data.as_ref());
1287
1288    flight.add(HandshakeMessagePayload(HandshakePayload::Finished(
1289        verify_data_payload,
1290    )));
1291}
1292
1293fn emit_end_of_early_data_tls13(transcript: &mut HandshakeHash, common: &mut CommonState) {
1294    if common.is_quic() {
1295        return;
1296    }
1297
1298    let m = Message {
1299        version: ProtocolVersion::TLSv1_3,
1300        payload: MessagePayload::handshake(HandshakeMessagePayload(
1301            HandshakePayload::EndOfEarlyData,
1302        )),
1303    };
1304
1305    transcript.add_message(&m);
1306    common.send_msg(m, true);
1307}
1308
1309struct ExpectFinished {
1310    config: Arc<ClientConfig>,
1311    server_name: ServerName<'static>,
1312    randoms: ConnectionRandoms,
1313    suite: &'static Tls13CipherSuite,
1314    transcript: HandshakeHash,
1315    key_schedule: KeyScheduleHandshake,
1316    client_auth: Option<ClientAuthDetails>,
1317    cert_verified: verify::ServerCertVerified,
1318    sig_verified: verify::HandshakeSignatureValid,
1319    ech_retry_configs: Option<Vec<EchConfigPayload>>,
1320}
1321
1322impl State<ClientConnectionData> for ExpectFinished {
1323    fn handle<'m>(
1324        self: Box<Self>,
1325        cx: &mut ClientContext<'_>,
1326        m: Message<'m>,
1327    ) -> hs::NextStateOrError<'m>
1328    where
1329        Self: 'm,
1330    {
1331        let mut st = *self;
1332        let finished =
1333            require_handshake_msg!(m, HandshakeType::Finished, HandshakePayload::Finished)?;
1334
1335        let handshake_hash = st.transcript.current_hash();
1336        let expect_verify_data = st
1337            .key_schedule
1338            .sign_server_finish(&handshake_hash);
1339
1340        let fin = match ConstantTimeEq::ct_eq(expect_verify_data.as_ref(), finished.bytes()).into()
1341        {
1342            true => verify::FinishedMessageVerified::assertion(),
1343            false => {
1344                return Err(cx
1345                    .common
1346                    .send_fatal_alert(AlertDescription::DecryptError, Error::DecryptError));
1347            }
1348        };
1349
1350        st.transcript.add_message(&m);
1351
1352        let hash_after_handshake = st.transcript.current_hash();
1353        /* The EndOfEarlyData message to server is still encrypted with early data keys,
1354         * but appears in the transcript after the server Finished. */
1355        if cx.common.early_traffic {
1356            emit_end_of_early_data_tls13(&mut st.transcript, cx.common);
1357            cx.common.early_traffic = false;
1358            cx.data.early_data.finished();
1359            st.key_schedule
1360                .set_handshake_encrypter(cx.common);
1361        }
1362
1363        let mut flight = HandshakeFlightTls13::new(&mut st.transcript);
1364
1365        /* Send our authentication/finished messages.  These are still encrypted
1366         * with our handshake keys. */
1367        if let Some(client_auth) = st.client_auth {
1368            match client_auth {
1369                ClientAuthDetails::Empty {
1370                    auth_context_tls13: auth_context,
1371                } => {
1372                    emit_certificate_tls13(&mut flight, None, auth_context);
1373                }
1374                ClientAuthDetails::Verify {
1375                    auth_context_tls13: auth_context,
1376                    ..
1377                } if cx.data.ech_status == EchStatus::Rejected => {
1378                    // If ECH was offered, and rejected, we MUST respond with
1379                    // an empty certificate message.
1380                    emit_certificate_tls13(&mut flight, None, auth_context);
1381                }
1382                ClientAuthDetails::Verify {
1383                    certkey,
1384                    signer,
1385                    auth_context_tls13: auth_context,
1386                    compressor,
1387                } => {
1388                    if let Some(compressor) = compressor {
1389                        emit_compressed_certificate_tls13(
1390                            &mut flight,
1391                            &certkey,
1392                            auth_context,
1393                            compressor,
1394                            &st.config,
1395                        );
1396                    } else {
1397                        emit_certificate_tls13(&mut flight, Some(&certkey), auth_context);
1398                    }
1399                    emit_certverify_tls13(&mut flight, signer.as_ref())?;
1400                }
1401            }
1402        }
1403
1404        let (key_schedule_pre_finished, verify_data) = st
1405            .key_schedule
1406            .into_pre_finished_client_traffic(
1407                hash_after_handshake,
1408                flight.transcript.current_hash(),
1409                &*st.config.key_log,
1410                &st.randoms.client,
1411            );
1412
1413        emit_finished_tls13(&mut flight, &verify_data);
1414        flight.finish(cx.common);
1415
1416        /* We're now sure this server supports TLS1.3.  But if we run out of TLS1.3 tickets
1417         * when connecting to it again, we definitely don't want to attempt a TLS1.2 resumption. */
1418        st.config
1419            .resumption
1420            .store
1421            .remove_tls12_session(&st.server_name);
1422
1423        /* Now move to our application traffic keys. */
1424        cx.common.check_aligned_handshake()?;
1425        let (key_schedule, resumption) =
1426            key_schedule_pre_finished.into_traffic(cx.common, st.transcript.current_hash());
1427        cx.common
1428            .start_traffic(&mut cx.sendable_plaintext);
1429
1430        // Now that we've reached the end of the normal handshake we must enforce ECH acceptance by
1431        // sending an alert and returning an error (potentially with retry configs) if the server
1432        // did not accept our ECH offer.
1433        if cx.data.ech_status == EchStatus::Rejected {
1434            return Err(ech::fatal_alert_required(st.ech_retry_configs, cx.common));
1435        }
1436
1437        let st = ExpectTraffic {
1438            config: st.config.clone(),
1439            session_storage: st.config.resumption.store.clone(),
1440            server_name: st.server_name,
1441            suite: st.suite,
1442            key_schedule,
1443            resumption,
1444            _cert_verified: st.cert_verified,
1445            _sig_verified: st.sig_verified,
1446            _fin_verified: fin,
1447        };
1448
1449        Ok(match cx.common.is_quic() {
1450            true => Box::new(ExpectQuicTraffic(st)),
1451            false => Box::new(st),
1452        })
1453    }
1454
1455    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1456        self
1457    }
1458}
1459
1460// -- Traffic transit state (TLS1.3) --
1461// In this state we can be sent tickets, key updates,
1462// and application data.
1463struct ExpectTraffic {
1464    config: Arc<ClientConfig>,
1465    session_storage: Arc<dyn ClientSessionStore>,
1466    server_name: ServerName<'static>,
1467    suite: &'static Tls13CipherSuite,
1468    key_schedule: KeyScheduleTraffic,
1469    resumption: KeyScheduleResumption,
1470    _cert_verified: verify::ServerCertVerified,
1471    _sig_verified: verify::HandshakeSignatureValid,
1472    _fin_verified: verify::FinishedMessageVerified,
1473}
1474
1475impl ExpectTraffic {
1476    fn handle_new_ticket_impl(
1477        &mut self,
1478        cx: &mut KernelContext<'_>,
1479        nst: &NewSessionTicketPayloadTls13,
1480    ) -> Result<(), Error> {
1481        let secret = self
1482            .resumption
1483            .derive_ticket_psk(&nst.nonce.0);
1484
1485        let now = self.config.current_time()?;
1486
1487        #[allow(unused_mut)]
1488        let mut value = persist::Tls13ClientSessionValue::new(
1489            self.suite,
1490            nst.ticket.clone(),
1491            secret.as_ref(),
1492            cx.peer_certificates
1493                .cloned()
1494                .unwrap_or_default(),
1495            &self.config.verifier,
1496            &self.config.client_auth_cert_resolver,
1497            now,
1498            nst.lifetime,
1499            nst.age_add,
1500            nst.extensions
1501                .max_early_data_size
1502                .unwrap_or_default(),
1503        );
1504
1505        if cx.is_quic() {
1506            if let Some(sz) = nst.extensions.max_early_data_size {
1507                if sz != 0 && sz != 0xffff_ffff {
1508                    return Err(PeerMisbehaved::InvalidMaxEarlyDataSize.into());
1509                }
1510            }
1511
1512            if let Some(quic_params) = &cx.quic.params {
1513                value.set_quic_params(quic_params);
1514            }
1515        }
1516
1517        self.session_storage
1518            .insert_tls13_ticket(self.server_name.clone(), value);
1519        Ok(())
1520    }
1521
1522    fn handle_new_ticket_tls13(
1523        &mut self,
1524        cx: &mut ClientContext<'_>,
1525        nst: &NewSessionTicketPayloadTls13,
1526    ) -> Result<(), Error> {
1527        let mut kcx = KernelContext {
1528            peer_certificates: cx.common.peer_certificates.as_ref(),
1529            protocol: cx.common.protocol,
1530            quic: &cx.common.quic,
1531        };
1532        cx.common.tls13_tickets_received = cx
1533            .common
1534            .tls13_tickets_received
1535            .saturating_add(1);
1536        self.handle_new_ticket_impl(&mut kcx, nst)
1537    }
1538
1539    fn handle_key_update(
1540        &mut self,
1541        common: &mut CommonState,
1542        key_update_request: &KeyUpdateRequest,
1543    ) -> Result<(), Error> {
1544        if let Protocol::Quic = common.protocol {
1545            return Err(common.send_fatal_alert(
1546                AlertDescription::UnexpectedMessage,
1547                PeerMisbehaved::KeyUpdateReceivedInQuicConnection,
1548            ));
1549        }
1550
1551        // Mustn't be interleaved with other handshake messages.
1552        common.check_aligned_handshake()?;
1553
1554        if common.should_update_key(key_update_request)? {
1555            self.key_schedule
1556                .update_encrypter_and_notify(common);
1557        }
1558
1559        // Update our read-side keys.
1560        self.key_schedule
1561            .update_decrypter(common);
1562        Ok(())
1563    }
1564}
1565
1566impl State<ClientConnectionData> for ExpectTraffic {
1567    fn handle<'m>(
1568        mut self: Box<Self>,
1569        cx: &mut ClientContext<'_>,
1570        m: Message<'m>,
1571    ) -> hs::NextStateOrError<'m>
1572    where
1573        Self: 'm,
1574    {
1575        match m.payload {
1576            MessagePayload::ApplicationData(payload) => cx
1577                .common
1578                .take_received_plaintext(payload),
1579            MessagePayload::Handshake {
1580                parsed: HandshakeMessagePayload(HandshakePayload::NewSessionTicketTls13(new_ticket)),
1581                ..
1582            } => self.handle_new_ticket_tls13(cx, &new_ticket)?,
1583            MessagePayload::Handshake {
1584                parsed: HandshakeMessagePayload(HandshakePayload::KeyUpdate(key_update)),
1585                ..
1586            } => self.handle_key_update(cx.common, &key_update)?,
1587            payload => {
1588                return Err(inappropriate_handshake_message(
1589                    &payload,
1590                    &[ContentType::ApplicationData, ContentType::Handshake],
1591                    &[HandshakeType::NewSessionTicket, HandshakeType::KeyUpdate],
1592                ));
1593            }
1594        }
1595
1596        Ok(self)
1597    }
1598
1599    fn send_key_update_request(&mut self, common: &mut CommonState) -> Result<(), Error> {
1600        self.key_schedule
1601            .request_key_update_and_update_encrypter(common)
1602    }
1603
1604    fn export_keying_material(
1605        &self,
1606        output: &mut [u8],
1607        label: &[u8],
1608        context: Option<&[u8]>,
1609    ) -> Result<(), Error> {
1610        self.key_schedule
1611            .export_keying_material(output, label, context)
1612    }
1613
1614    fn extract_secrets(&self) -> Result<PartiallyExtractedSecrets, Error> {
1615        self.key_schedule
1616            .extract_secrets(Side::Client)
1617    }
1618
1619    fn into_external_state(self: Box<Self>) -> Result<Box<dyn KernelState + 'static>, Error> {
1620        Ok(self)
1621    }
1622
1623    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1624        self
1625    }
1626}
1627
1628impl KernelState for ExpectTraffic {
1629    fn update_secrets(&mut self, dir: Direction) -> Result<ConnectionTrafficSecrets, Error> {
1630        self.key_schedule
1631            .refresh_traffic_secret(match dir {
1632                Direction::Transmit => Side::Client,
1633                Direction::Receive => Side::Server,
1634            })
1635    }
1636
1637    fn handle_new_session_ticket(
1638        &mut self,
1639        cx: &mut KernelContext<'_>,
1640        message: &NewSessionTicketPayloadTls13,
1641    ) -> Result<(), Error> {
1642        self.handle_new_ticket_impl(cx, message)
1643    }
1644}
1645
1646struct ExpectQuicTraffic(ExpectTraffic);
1647
1648impl State<ClientConnectionData> for ExpectQuicTraffic {
1649    fn handle<'m>(
1650        mut self: Box<Self>,
1651        cx: &mut ClientContext<'_>,
1652        m: Message<'m>,
1653    ) -> hs::NextStateOrError<'m>
1654    where
1655        Self: 'm,
1656    {
1657        let nst = require_handshake_msg!(
1658            m,
1659            HandshakeType::NewSessionTicket,
1660            HandshakePayload::NewSessionTicketTls13
1661        )?;
1662        self.0
1663            .handle_new_ticket_tls13(cx, nst)?;
1664        Ok(self)
1665    }
1666
1667    fn export_keying_material(
1668        &self,
1669        output: &mut [u8],
1670        label: &[u8],
1671        context: Option<&[u8]>,
1672    ) -> Result<(), Error> {
1673        self.0
1674            .export_keying_material(output, label, context)
1675    }
1676
1677    fn into_external_state(self: Box<Self>) -> Result<Box<dyn KernelState + 'static>, Error> {
1678        Ok(self)
1679    }
1680
1681    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1682        self
1683    }
1684}
1685
1686impl KernelState for ExpectQuicTraffic {
1687    fn update_secrets(&mut self, _: Direction) -> Result<ConnectionTrafficSecrets, Error> {
1688        Err(Error::General(
1689            "KeyUpdate is not supported for QUIC connections".into(),
1690        ))
1691    }
1692
1693    fn handle_new_session_ticket(
1694        &mut self,
1695        cx: &mut KernelContext<'_>,
1696        nst: &NewSessionTicketPayloadTls13,
1697    ) -> Result<(), Error> {
1698        self.0.handle_new_ticket_impl(cx, nst)
1699    }
1700}