rustls/client/
tls12.rs

1use alloc::borrow::ToOwned;
2use alloc::boxed::Box;
3use alloc::vec;
4use alloc::vec::Vec;
5
6use pki_types::ServerName;
7pub(super) use server_hello::CompleteServerHelloHandling;
8use subtle::ConstantTimeEq;
9
10use super::client_conn::ClientConnectionData;
11use super::hs::ClientContext;
12use crate::ConnectionTrafficSecrets;
13use crate::check::{inappropriate_handshake_message, inappropriate_message};
14use crate::client::common::{ClientAuthDetails, ServerCertDetails};
15use crate::client::{ClientConfig, hs};
16use crate::common_state::{CommonState, HandshakeKind, KxState, Side, State};
17use crate::conn::ConnectionRandoms;
18use crate::conn::kernel::{Direction, KernelContext, KernelState};
19use crate::crypto::KeyExchangeAlgorithm;
20use crate::enums::{AlertDescription, ContentType, HandshakeType, ProtocolVersion};
21use crate::error::{Error, InvalidMessage, PeerIncompatible, PeerMisbehaved};
22use crate::hash_hs::HandshakeHash;
23use crate::log::{debug, trace, warn};
24use crate::msgs::base::{Payload, PayloadU8, PayloadU16};
25use crate::msgs::ccs::ChangeCipherSpecPayload;
26use crate::msgs::handshake::{
27    CertificateChain, ClientDhParams, ClientEcdhParams, ClientKeyExchangeParams,
28    HandshakeMessagePayload, HandshakePayload, NewSessionTicketPayload,
29    NewSessionTicketPayloadTls13, ServerKeyExchangeParams, SessionId,
30};
31use crate::msgs::message::{Message, MessagePayload};
32use crate::msgs::persist;
33use crate::sign::Signer;
34use crate::suites::{PartiallyExtractedSecrets, SupportedCipherSuite};
35use crate::sync::Arc;
36use crate::tls12::{self, ConnectionSecrets, Tls12CipherSuite};
37use crate::verify::{self, DigitallySignedStruct};
38
39mod server_hello {
40    use super::*;
41    use crate::msgs::enums::ExtensionType;
42    use crate::msgs::handshake::{HasServerExtensions, ServerHelloPayload};
43
44    pub(in crate::client) struct CompleteServerHelloHandling {
45        pub(in crate::client) config: Arc<ClientConfig>,
46        pub(in crate::client) resuming_session: Option<persist::Tls12ClientSessionValue>,
47        pub(in crate::client) server_name: ServerName<'static>,
48        pub(in crate::client) randoms: ConnectionRandoms,
49        pub(in crate::client) using_ems: bool,
50        pub(in crate::client) transcript: HandshakeHash,
51    }
52
53    impl CompleteServerHelloHandling {
54        pub(in crate::client) fn handle_server_hello(
55            mut self,
56            cx: &mut ClientContext<'_>,
57            suite: &'static Tls12CipherSuite,
58            server_hello: &ServerHelloPayload,
59            tls13_supported: bool,
60        ) -> hs::NextStateOrError<'static> {
61            self.randoms
62                .server
63                .clone_from_slice(&server_hello.random.0[..]);
64
65            // Look for TLS1.3 downgrade signal in server random
66            // both the server random and TLS12_DOWNGRADE_SENTINEL are
67            // public values and don't require constant time comparison
68            let has_downgrade_marker = self.randoms.server[24..] == tls12::DOWNGRADE_SENTINEL;
69            if tls13_supported && has_downgrade_marker {
70                return Err({
71                    cx.common.send_fatal_alert(
72                        AlertDescription::IllegalParameter,
73                        PeerMisbehaved::AttemptedDowngradeToTls12WhenTls13IsSupported,
74                    )
75                });
76            }
77
78            // Doing EMS?
79            self.using_ems = server_hello.ems_support_acked();
80            if self.config.require_ems && !self.using_ems {
81                return Err({
82                    cx.common.send_fatal_alert(
83                        AlertDescription::HandshakeFailure,
84                        PeerIncompatible::ExtendedMasterSecretExtensionRequired,
85                    )
86                });
87            }
88
89            // Might the server send a ticket?
90            let must_issue_new_ticket = if server_hello
91                .find_extension(ExtensionType::SessionTicket)
92                .is_some()
93            {
94                debug!("Server supports tickets");
95                true
96            } else {
97                false
98            };
99
100            // Might the server send a CertificateStatus between Certificate and
101            // ServerKeyExchange?
102            let may_send_cert_status = server_hello
103                .find_extension(ExtensionType::StatusRequest)
104                .is_some();
105            if may_send_cert_status {
106                debug!("Server may staple OCSP response");
107            }
108
109            // See if we're successfully resuming.
110            if let Some(resuming) = self.resuming_session {
111                if resuming.session_id == server_hello.session_id {
112                    debug!("Server agreed to resume");
113
114                    // Is the server telling lies about the ciphersuite?
115                    if resuming.suite() != suite {
116                        return Err(PeerMisbehaved::ResumptionOfferedWithVariedCipherSuite.into());
117                    }
118
119                    // And about EMS support?
120                    if resuming.extended_ms() != self.using_ems {
121                        return Err(PeerMisbehaved::ResumptionOfferedWithVariedEms.into());
122                    }
123
124                    let secrets =
125                        ConnectionSecrets::new_resume(self.randoms, suite, resuming.secret());
126                    self.config.key_log.log(
127                        "CLIENT_RANDOM",
128                        &secrets.randoms.client,
129                        &secrets.master_secret,
130                    );
131                    cx.common
132                        .start_encryption_tls12(&secrets, Side::Client);
133
134                    // Since we're resuming, we verified the certificate and
135                    // proof of possession in the prior session.
136                    cx.common.peer_certificates = Some(
137                        resuming
138                            .server_cert_chain()
139                            .clone()
140                            .into_owned(),
141                    );
142                    cx.common.handshake_kind = Some(HandshakeKind::Resumed);
143                    let cert_verified = verify::ServerCertVerified::assertion();
144                    let sig_verified = verify::HandshakeSignatureValid::assertion();
145
146                    return if must_issue_new_ticket {
147                        Ok(Box::new(ExpectNewTicket {
148                            config: self.config,
149                            secrets,
150                            resuming_session: Some(resuming),
151                            session_id: server_hello.session_id,
152                            server_name: self.server_name,
153                            using_ems: self.using_ems,
154                            transcript: self.transcript,
155                            resuming: true,
156                            cert_verified,
157                            sig_verified,
158                        }))
159                    } else {
160                        Ok(Box::new(ExpectCcs {
161                            config: self.config,
162                            secrets,
163                            resuming_session: Some(resuming),
164                            session_id: server_hello.session_id,
165                            server_name: self.server_name,
166                            using_ems: self.using_ems,
167                            transcript: self.transcript,
168                            ticket: None,
169                            resuming: true,
170                            cert_verified,
171                            sig_verified,
172                        }))
173                    };
174                }
175            }
176
177            cx.common.handshake_kind = Some(HandshakeKind::Full);
178            Ok(Box::new(ExpectCertificate {
179                config: self.config,
180                resuming_session: None,
181                session_id: server_hello.session_id,
182                server_name: self.server_name,
183                randoms: self.randoms,
184                using_ems: self.using_ems,
185                transcript: self.transcript,
186                suite,
187                may_send_cert_status,
188                must_issue_new_ticket,
189            }))
190        }
191    }
192}
193
194struct ExpectCertificate {
195    config: Arc<ClientConfig>,
196    resuming_session: Option<persist::Tls12ClientSessionValue>,
197    session_id: SessionId,
198    server_name: ServerName<'static>,
199    randoms: ConnectionRandoms,
200    using_ems: bool,
201    transcript: HandshakeHash,
202    pub(super) suite: &'static Tls12CipherSuite,
203    may_send_cert_status: bool,
204    must_issue_new_ticket: bool,
205}
206
207impl State<ClientConnectionData> for ExpectCertificate {
208    fn handle<'m>(
209        mut self: Box<Self>,
210        _cx: &mut ClientContext<'_>,
211        m: Message<'m>,
212    ) -> hs::NextStateOrError<'m>
213    where
214        Self: 'm,
215    {
216        self.transcript.add_message(&m);
217        let server_cert_chain = require_handshake_msg_move!(
218            m,
219            HandshakeType::Certificate,
220            HandshakePayload::Certificate
221        )?;
222
223        if self.may_send_cert_status {
224            Ok(Box::new(ExpectCertificateStatusOrServerKx {
225                config: self.config,
226                resuming_session: self.resuming_session,
227                session_id: self.session_id,
228                server_name: self.server_name,
229                randoms: self.randoms,
230                using_ems: self.using_ems,
231                transcript: self.transcript,
232                suite: self.suite,
233                server_cert_chain,
234                must_issue_new_ticket: self.must_issue_new_ticket,
235            }))
236        } else {
237            let server_cert = ServerCertDetails::new(server_cert_chain, vec![]);
238
239            Ok(Box::new(ExpectServerKx {
240                config: self.config,
241                resuming_session: self.resuming_session,
242                session_id: self.session_id,
243                server_name: self.server_name,
244                randoms: self.randoms,
245                using_ems: self.using_ems,
246                transcript: self.transcript,
247                suite: self.suite,
248                server_cert,
249                must_issue_new_ticket: self.must_issue_new_ticket,
250            }))
251        }
252    }
253
254    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
255        self
256    }
257}
258
259struct ExpectCertificateStatusOrServerKx<'m> {
260    config: Arc<ClientConfig>,
261    resuming_session: Option<persist::Tls12ClientSessionValue>,
262    session_id: SessionId,
263    server_name: ServerName<'static>,
264    randoms: ConnectionRandoms,
265    using_ems: bool,
266    transcript: HandshakeHash,
267    suite: &'static Tls12CipherSuite,
268    server_cert_chain: CertificateChain<'m>,
269    must_issue_new_ticket: bool,
270}
271
272impl State<ClientConnectionData> for ExpectCertificateStatusOrServerKx<'_> {
273    fn handle<'m>(
274        self: Box<Self>,
275        cx: &mut ClientContext<'_>,
276        m: Message<'m>,
277    ) -> hs::NextStateOrError<'m>
278    where
279        Self: 'm,
280    {
281        match m.payload {
282            MessagePayload::Handshake {
283                parsed:
284                    HandshakeMessagePayload {
285                        payload: HandshakePayload::ServerKeyExchange(..),
286                        ..
287                    },
288                ..
289            } => Box::new(ExpectServerKx {
290                config: self.config,
291                resuming_session: self.resuming_session,
292                session_id: self.session_id,
293                server_name: self.server_name,
294                randoms: self.randoms,
295                using_ems: self.using_ems,
296                transcript: self.transcript,
297                suite: self.suite,
298                server_cert: ServerCertDetails::new(self.server_cert_chain, vec![]),
299                must_issue_new_ticket: self.must_issue_new_ticket,
300            })
301            .handle(cx, m),
302            MessagePayload::Handshake {
303                parsed:
304                    HandshakeMessagePayload {
305                        payload: HandshakePayload::CertificateStatus(..),
306                        ..
307                    },
308                ..
309            } => Box::new(ExpectCertificateStatus {
310                config: self.config,
311                resuming_session: self.resuming_session,
312                session_id: self.session_id,
313                server_name: self.server_name,
314                randoms: self.randoms,
315                using_ems: self.using_ems,
316                transcript: self.transcript,
317                suite: self.suite,
318                server_cert_chain: self.server_cert_chain,
319                must_issue_new_ticket: self.must_issue_new_ticket,
320            })
321            .handle(cx, m),
322            payload => Err(inappropriate_handshake_message(
323                &payload,
324                &[ContentType::Handshake],
325                &[
326                    HandshakeType::ServerKeyExchange,
327                    HandshakeType::CertificateStatus,
328                ],
329            )),
330        }
331    }
332
333    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
334        Box::new(ExpectCertificateStatusOrServerKx {
335            config: self.config,
336            resuming_session: self.resuming_session,
337            session_id: self.session_id,
338            server_name: self.server_name,
339            randoms: self.randoms,
340            using_ems: self.using_ems,
341            transcript: self.transcript,
342            suite: self.suite,
343            server_cert_chain: self.server_cert_chain.into_owned(),
344            must_issue_new_ticket: self.must_issue_new_ticket,
345        })
346    }
347}
348
349struct ExpectCertificateStatus<'a> {
350    config: Arc<ClientConfig>,
351    resuming_session: Option<persist::Tls12ClientSessionValue>,
352    session_id: SessionId,
353    server_name: ServerName<'static>,
354    randoms: ConnectionRandoms,
355    using_ems: bool,
356    transcript: HandshakeHash,
357    suite: &'static Tls12CipherSuite,
358    server_cert_chain: CertificateChain<'a>,
359    must_issue_new_ticket: bool,
360}
361
362impl State<ClientConnectionData> for ExpectCertificateStatus<'_> {
363    fn handle<'m>(
364        mut self: Box<Self>,
365        _cx: &mut ClientContext<'_>,
366        m: Message<'m>,
367    ) -> hs::NextStateOrError<'m>
368    where
369        Self: 'm,
370    {
371        self.transcript.add_message(&m);
372        let server_cert_ocsp_response = require_handshake_msg_move!(
373            m,
374            HandshakeType::CertificateStatus,
375            HandshakePayload::CertificateStatus
376        )?
377        .into_inner();
378
379        trace!(
380            "Server stapled OCSP response is {:?}",
381            &server_cert_ocsp_response
382        );
383
384        let server_cert = ServerCertDetails::new(self.server_cert_chain, server_cert_ocsp_response);
385
386        Ok(Box::new(ExpectServerKx {
387            config: self.config,
388            resuming_session: self.resuming_session,
389            session_id: self.session_id,
390            server_name: self.server_name,
391            randoms: self.randoms,
392            using_ems: self.using_ems,
393            transcript: self.transcript,
394            suite: self.suite,
395            server_cert,
396            must_issue_new_ticket: self.must_issue_new_ticket,
397        }))
398    }
399
400    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
401        Box::new(ExpectCertificateStatus {
402            config: self.config,
403            resuming_session: self.resuming_session,
404            session_id: self.session_id,
405            server_name: self.server_name,
406            randoms: self.randoms,
407            using_ems: self.using_ems,
408            transcript: self.transcript,
409            suite: self.suite,
410            server_cert_chain: self.server_cert_chain.into_owned(),
411            must_issue_new_ticket: self.must_issue_new_ticket,
412        })
413    }
414}
415
416struct ExpectServerKx<'a> {
417    config: Arc<ClientConfig>,
418    resuming_session: Option<persist::Tls12ClientSessionValue>,
419    session_id: SessionId,
420    server_name: ServerName<'static>,
421    randoms: ConnectionRandoms,
422    using_ems: bool,
423    transcript: HandshakeHash,
424    suite: &'static Tls12CipherSuite,
425    server_cert: ServerCertDetails<'a>,
426    must_issue_new_ticket: bool,
427}
428
429impl State<ClientConnectionData> for ExpectServerKx<'_> {
430    fn handle<'m>(
431        mut self: Box<Self>,
432        cx: &mut ClientContext<'_>,
433        m: Message<'m>,
434    ) -> hs::NextStateOrError<'m>
435    where
436        Self: 'm,
437    {
438        let opaque_kx = require_handshake_msg!(
439            m,
440            HandshakeType::ServerKeyExchange,
441            HandshakePayload::ServerKeyExchange
442        )?;
443        self.transcript.add_message(&m);
444
445        let kx = opaque_kx
446            .unwrap_given_kxa(self.suite.kx)
447            .ok_or_else(|| {
448                cx.common.send_fatal_alert(
449                    AlertDescription::DecodeError,
450                    InvalidMessage::MissingKeyExchange,
451                )
452            })?;
453
454        // Save the signature and signed parameters for later verification.
455        let mut kx_params = Vec::new();
456        kx.params.encode(&mut kx_params);
457        let server_kx = ServerKxDetails::new(kx_params, kx.dss);
458
459        #[cfg_attr(not(feature = "logging"), allow(unused_variables))]
460        {
461            match &kx.params {
462                ServerKeyExchangeParams::Ecdh(ecdhe) => {
463                    debug!("ECDHE curve is {:?}", ecdhe.curve_params)
464                }
465                ServerKeyExchangeParams::Dh(dhe) => {
466                    debug!("DHE params are p = {:?}, g = {:?}", dhe.dh_p, dhe.dh_g)
467                }
468            }
469        }
470
471        Ok(Box::new(ExpectServerDoneOrCertReq {
472            config: self.config,
473            resuming_session: self.resuming_session,
474            session_id: self.session_id,
475            server_name: self.server_name,
476            randoms: self.randoms,
477            using_ems: self.using_ems,
478            transcript: self.transcript,
479            suite: self.suite,
480            server_cert: self.server_cert,
481            server_kx,
482            must_issue_new_ticket: self.must_issue_new_ticket,
483        }))
484    }
485
486    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
487        Box::new(ExpectServerKx {
488            config: self.config,
489            resuming_session: self.resuming_session,
490            session_id: self.session_id,
491            server_name: self.server_name,
492            randoms: self.randoms,
493            using_ems: self.using_ems,
494            transcript: self.transcript,
495            suite: self.suite,
496            server_cert: self.server_cert.into_owned(),
497            must_issue_new_ticket: self.must_issue_new_ticket,
498        })
499    }
500}
501
502fn emit_certificate(
503    transcript: &mut HandshakeHash,
504    cert_chain: CertificateChain<'static>,
505    common: &mut CommonState,
506) {
507    let cert = Message {
508        version: ProtocolVersion::TLSv1_2,
509        payload: MessagePayload::handshake(HandshakeMessagePayload {
510            typ: HandshakeType::Certificate,
511            payload: HandshakePayload::Certificate(cert_chain),
512        }),
513    };
514
515    transcript.add_message(&cert);
516    common.send_msg(cert, false);
517}
518
519fn emit_client_kx(
520    transcript: &mut HandshakeHash,
521    kxa: KeyExchangeAlgorithm,
522    common: &mut CommonState,
523    pub_key: &[u8],
524) {
525    let mut buf = Vec::new();
526    match kxa {
527        KeyExchangeAlgorithm::ECDHE => ClientKeyExchangeParams::Ecdh(ClientEcdhParams {
528            public: PayloadU8::new(pub_key.to_vec()),
529        }),
530        KeyExchangeAlgorithm::DHE => ClientKeyExchangeParams::Dh(ClientDhParams {
531            public: PayloadU16::new(pub_key.to_vec()),
532        }),
533    }
534    .encode(&mut buf);
535    let pubkey = Payload::new(buf);
536
537    let ckx = Message {
538        version: ProtocolVersion::TLSv1_2,
539        payload: MessagePayload::handshake(HandshakeMessagePayload {
540            typ: HandshakeType::ClientKeyExchange,
541            payload: HandshakePayload::ClientKeyExchange(pubkey),
542        }),
543    };
544
545    transcript.add_message(&ckx);
546    common.send_msg(ckx, false);
547}
548
549fn emit_certverify(
550    transcript: &mut HandshakeHash,
551    signer: &dyn Signer,
552    common: &mut CommonState,
553) -> Result<(), Error> {
554    let message = transcript
555        .take_handshake_buf()
556        .ok_or_else(|| Error::General("Expected transcript".to_owned()))?;
557
558    let scheme = signer.scheme();
559    let sig = signer.sign(&message)?;
560    let body = DigitallySignedStruct::new(scheme, sig);
561
562    let m = Message {
563        version: ProtocolVersion::TLSv1_2,
564        payload: MessagePayload::handshake(HandshakeMessagePayload {
565            typ: HandshakeType::CertificateVerify,
566            payload: HandshakePayload::CertificateVerify(body),
567        }),
568    };
569
570    transcript.add_message(&m);
571    common.send_msg(m, false);
572    Ok(())
573}
574
575fn emit_ccs(common: &mut CommonState) {
576    let ccs = Message {
577        version: ProtocolVersion::TLSv1_2,
578        payload: MessagePayload::ChangeCipherSpec(ChangeCipherSpecPayload {}),
579    };
580
581    common.send_msg(ccs, false);
582}
583
584fn emit_finished(
585    secrets: &ConnectionSecrets,
586    transcript: &mut HandshakeHash,
587    common: &mut CommonState,
588) {
589    let vh = transcript.current_hash();
590    let verify_data = secrets.client_verify_data(&vh);
591    let verify_data_payload = Payload::new(verify_data);
592
593    let f = Message {
594        version: ProtocolVersion::TLSv1_2,
595        payload: MessagePayload::handshake(HandshakeMessagePayload {
596            typ: HandshakeType::Finished,
597            payload: HandshakePayload::Finished(verify_data_payload),
598        }),
599    };
600
601    transcript.add_message(&f);
602    common.send_msg(f, true);
603}
604
605struct ServerKxDetails {
606    kx_params: Vec<u8>,
607    kx_sig: DigitallySignedStruct,
608}
609
610impl ServerKxDetails {
611    fn new(params: Vec<u8>, sig: DigitallySignedStruct) -> Self {
612        Self {
613            kx_params: params,
614            kx_sig: sig,
615        }
616    }
617}
618
619// --- Either a CertificateRequest, or a ServerHelloDone. ---
620// Existence of the CertificateRequest tells us the server is asking for
621// client auth.  Otherwise we go straight to ServerHelloDone.
622struct ExpectServerDoneOrCertReq<'a> {
623    config: Arc<ClientConfig>,
624    resuming_session: Option<persist::Tls12ClientSessionValue>,
625    session_id: SessionId,
626    server_name: ServerName<'static>,
627    randoms: ConnectionRandoms,
628    using_ems: bool,
629    transcript: HandshakeHash,
630    suite: &'static Tls12CipherSuite,
631    server_cert: ServerCertDetails<'a>,
632    server_kx: ServerKxDetails,
633    must_issue_new_ticket: bool,
634}
635
636impl State<ClientConnectionData> for ExpectServerDoneOrCertReq<'_> {
637    fn handle<'m>(
638        mut self: Box<Self>,
639        cx: &mut ClientContext<'_>,
640        m: Message<'m>,
641    ) -> hs::NextStateOrError<'m>
642    where
643        Self: 'm,
644    {
645        if matches!(
646            m.payload,
647            MessagePayload::Handshake {
648                parsed: HandshakeMessagePayload {
649                    payload: HandshakePayload::CertificateRequest(_),
650                    ..
651                },
652                ..
653            }
654        ) {
655            Box::new(ExpectCertificateRequest {
656                config: self.config,
657                resuming_session: self.resuming_session,
658                session_id: self.session_id,
659                server_name: self.server_name,
660                randoms: self.randoms,
661                using_ems: self.using_ems,
662                transcript: self.transcript,
663                suite: self.suite,
664                server_cert: self.server_cert,
665                server_kx: self.server_kx,
666                must_issue_new_ticket: self.must_issue_new_ticket,
667            })
668            .handle(cx, m)
669        } else {
670            self.transcript.abandon_client_auth();
671
672            Box::new(ExpectServerDone {
673                config: self.config,
674                resuming_session: self.resuming_session,
675                session_id: self.session_id,
676                server_name: self.server_name,
677                randoms: self.randoms,
678                using_ems: self.using_ems,
679                transcript: self.transcript,
680                suite: self.suite,
681                server_cert: self.server_cert,
682                server_kx: self.server_kx,
683                client_auth: None,
684                must_issue_new_ticket: self.must_issue_new_ticket,
685            })
686            .handle(cx, m)
687        }
688    }
689
690    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
691        Box::new(ExpectServerDoneOrCertReq {
692            config: self.config,
693            resuming_session: self.resuming_session,
694            session_id: self.session_id,
695            server_name: self.server_name,
696            randoms: self.randoms,
697            using_ems: self.using_ems,
698            transcript: self.transcript,
699            suite: self.suite,
700            server_cert: self.server_cert.into_owned(),
701            server_kx: self.server_kx,
702            must_issue_new_ticket: self.must_issue_new_ticket,
703        })
704    }
705}
706
707struct ExpectCertificateRequest<'a> {
708    config: Arc<ClientConfig>,
709    resuming_session: Option<persist::Tls12ClientSessionValue>,
710    session_id: SessionId,
711    server_name: ServerName<'static>,
712    randoms: ConnectionRandoms,
713    using_ems: bool,
714    transcript: HandshakeHash,
715    suite: &'static Tls12CipherSuite,
716    server_cert: ServerCertDetails<'a>,
717    server_kx: ServerKxDetails,
718    must_issue_new_ticket: bool,
719}
720
721impl State<ClientConnectionData> for ExpectCertificateRequest<'_> {
722    fn handle<'m>(
723        mut self: Box<Self>,
724        _cx: &mut ClientContext<'_>,
725        m: Message<'m>,
726    ) -> hs::NextStateOrError<'m>
727    where
728        Self: 'm,
729    {
730        let certreq = require_handshake_msg!(
731            m,
732            HandshakeType::CertificateRequest,
733            HandshakePayload::CertificateRequest
734        )?;
735        self.transcript.add_message(&m);
736        debug!("Got CertificateRequest {:?}", certreq);
737
738        // The RFC jovially describes the design here as 'somewhat complicated'
739        // and 'somewhat underspecified'.  So thanks for that.
740        //
741        // We ignore certreq.certtypes as a result, since the information it contains
742        // is entirely duplicated in certreq.sigschemes.
743
744        const NO_CONTEXT: Option<Vec<u8>> = None; // TLS 1.2 doesn't use a context.
745        let no_compression = None; // or compression
746        let client_auth = ClientAuthDetails::resolve(
747            self.config
748                .client_auth_cert_resolver
749                .as_ref(),
750            Some(&certreq.canames),
751            &certreq.sigschemes,
752            NO_CONTEXT,
753            no_compression,
754        );
755
756        Ok(Box::new(ExpectServerDone {
757            config: self.config,
758            resuming_session: self.resuming_session,
759            session_id: self.session_id,
760            server_name: self.server_name,
761            randoms: self.randoms,
762            using_ems: self.using_ems,
763            transcript: self.transcript,
764            suite: self.suite,
765            server_cert: self.server_cert,
766            server_kx: self.server_kx,
767            client_auth: Some(client_auth),
768            must_issue_new_ticket: self.must_issue_new_ticket,
769        }))
770    }
771
772    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
773        Box::new(ExpectCertificateRequest {
774            config: self.config,
775            resuming_session: self.resuming_session,
776            session_id: self.session_id,
777            server_name: self.server_name,
778            randoms: self.randoms,
779            using_ems: self.using_ems,
780            transcript: self.transcript,
781            suite: self.suite,
782            server_cert: self.server_cert.into_owned(),
783            server_kx: self.server_kx,
784            must_issue_new_ticket: self.must_issue_new_ticket,
785        })
786    }
787}
788
789struct ExpectServerDone<'a> {
790    config: Arc<ClientConfig>,
791    resuming_session: Option<persist::Tls12ClientSessionValue>,
792    session_id: SessionId,
793    server_name: ServerName<'static>,
794    randoms: ConnectionRandoms,
795    using_ems: bool,
796    transcript: HandshakeHash,
797    suite: &'static Tls12CipherSuite,
798    server_cert: ServerCertDetails<'a>,
799    server_kx: ServerKxDetails,
800    client_auth: Option<ClientAuthDetails>,
801    must_issue_new_ticket: bool,
802}
803
804impl State<ClientConnectionData> for ExpectServerDone<'_> {
805    fn handle<'m>(
806        self: Box<Self>,
807        cx: &mut ClientContext<'_>,
808        m: Message<'m>,
809    ) -> hs::NextStateOrError<'m>
810    where
811        Self: 'm,
812    {
813        match m.payload {
814            MessagePayload::Handshake {
815                parsed:
816                    HandshakeMessagePayload {
817                        payload: HandshakePayload::ServerHelloDone,
818                        ..
819                    },
820                ..
821            } => {}
822            payload => {
823                return Err(inappropriate_handshake_message(
824                    &payload,
825                    &[ContentType::Handshake],
826                    &[HandshakeType::ServerHelloDone],
827                ));
828            }
829        }
830
831        let mut st = *self;
832        st.transcript.add_message(&m);
833
834        cx.common.check_aligned_handshake()?;
835
836        trace!("Server cert is {:?}", st.server_cert.cert_chain);
837        debug!("Server DNS name is {:?}", st.server_name);
838
839        let suite = st.suite;
840
841        // 1. Verify the cert chain.
842        // 2. Verify that the top certificate signed their kx.
843        // 3. If doing client auth, send our Certificate.
844        // 4. Complete the key exchange:
845        //    a) generate our kx pair
846        //    b) emit a ClientKeyExchange containing it
847        //    c) if doing client auth, emit a CertificateVerify
848        //    d) derive the shared keys
849        //    e) emit a CCS
850        //    f) use the derived keys to start encryption
851        // 5. emit a Finished, our first encrypted message under the new keys.
852
853        // 1.
854        let (end_entity, intermediates) = st
855            .server_cert
856            .cert_chain
857            .split_first()
858            .ok_or(Error::NoCertificatesPresented)?;
859
860        let now = st.config.current_time()?;
861
862        let cert_verified = st
863            .config
864            .verifier
865            .verify_server_cert(
866                end_entity,
867                intermediates,
868                &st.server_name,
869                &st.server_cert.ocsp_response,
870                now,
871            )
872            .map_err(|err| {
873                cx.common
874                    .send_cert_verify_error_alert(err)
875            })?;
876
877        // 2.
878        // Build up the contents of the signed message.
879        // It's ClientHello.random || ServerHello.random || ServerKeyExchange.params
880        let sig_verified = {
881            let mut message = Vec::new();
882            message.extend_from_slice(&st.randoms.client);
883            message.extend_from_slice(&st.randoms.server);
884            message.extend_from_slice(&st.server_kx.kx_params);
885
886            // Check the signature is compatible with the ciphersuite.
887            let sig = &st.server_kx.kx_sig;
888            if !SupportedCipherSuite::from(suite)
889                .usable_for_signature_algorithm(sig.scheme.algorithm())
890            {
891                warn!(
892                    "peer signed kx with wrong algorithm (got {:?} expect {:?})",
893                    sig.scheme.algorithm(),
894                    suite.sign
895                );
896                return Err(PeerMisbehaved::SignedKxWithWrongAlgorithm.into());
897            }
898
899            st.config
900                .verifier
901                .verify_tls12_signature(&message, end_entity, sig)
902                .map_err(|err| {
903                    cx.common
904                        .send_cert_verify_error_alert(err)
905                })?
906        };
907        cx.common.peer_certificates = Some(st.server_cert.cert_chain.into_owned());
908
909        // 3.
910        if let Some(client_auth) = &st.client_auth {
911            let certs = match client_auth {
912                ClientAuthDetails::Empty { .. } => CertificateChain::default(),
913                ClientAuthDetails::Verify { certkey, .. } => CertificateChain(certkey.cert.clone()),
914            };
915            emit_certificate(&mut st.transcript, certs, cx.common);
916        }
917
918        // 4a.
919        let kx_params = tls12::decode_kx_params::<ServerKeyExchangeParams>(
920            st.suite.kx,
921            cx.common,
922            &st.server_kx.kx_params,
923        )?;
924        let maybe_skxg = match &kx_params {
925            ServerKeyExchangeParams::Ecdh(ecdh) => st
926                .config
927                .find_kx_group(ecdh.curve_params.named_group, ProtocolVersion::TLSv1_2),
928            ServerKeyExchangeParams::Dh(dh) => {
929                let ffdhe_group = dh.as_ffdhe_group();
930
931                st.config
932                    .provider
933                    .kx_groups
934                    .iter()
935                    .find(|kxg| kxg.ffdhe_group() == Some(ffdhe_group))
936                    .copied()
937            }
938        };
939        let Some(skxg) = maybe_skxg else {
940            return Err(cx.common.send_fatal_alert(
941                AlertDescription::IllegalParameter,
942                PeerMisbehaved::SelectedUnofferedKxGroup,
943            ));
944        };
945        cx.common.kx_state = KxState::Start(skxg);
946        let kx = skxg.start()?;
947
948        // 4b.
949        let mut transcript = st.transcript;
950        emit_client_kx(&mut transcript, st.suite.kx, cx.common, kx.pub_key());
951        // Note: EMS handshake hash only runs up to ClientKeyExchange.
952        let ems_seed = st
953            .using_ems
954            .then(|| transcript.current_hash());
955
956        // 4c.
957        if let Some(ClientAuthDetails::Verify { signer, .. }) = &st.client_auth {
958            emit_certverify(&mut transcript, signer.as_ref(), cx.common)?;
959        }
960
961        // 4d. Derive secrets.
962        // An alert at this point will be sent in plaintext.  That must happen
963        // prior to the CCS, or else the peer will try to decrypt it.
964        let secrets = ConnectionSecrets::from_key_exchange(
965            kx,
966            kx_params.pub_key(),
967            ems_seed,
968            st.randoms,
969            suite,
970        )
971        .map_err(|err| {
972            cx.common
973                .send_fatal_alert(AlertDescription::IllegalParameter, err)
974        })?;
975        cx.common.kx_state.complete();
976
977        // 4e. CCS. We are definitely going to switch on encryption.
978        emit_ccs(cx.common);
979
980        // 4f. Now commit secrets.
981        st.config.key_log.log(
982            "CLIENT_RANDOM",
983            &secrets.randoms.client,
984            &secrets.master_secret,
985        );
986        cx.common
987            .start_encryption_tls12(&secrets, Side::Client);
988        cx.common
989            .record_layer
990            .start_encrypting();
991
992        // 5.
993        emit_finished(&secrets, &mut transcript, cx.common);
994
995        if st.must_issue_new_ticket {
996            Ok(Box::new(ExpectNewTicket {
997                config: st.config,
998                secrets,
999                resuming_session: st.resuming_session,
1000                session_id: st.session_id,
1001                server_name: st.server_name,
1002                using_ems: st.using_ems,
1003                transcript,
1004                resuming: false,
1005                cert_verified,
1006                sig_verified,
1007            }))
1008        } else {
1009            Ok(Box::new(ExpectCcs {
1010                config: st.config,
1011                secrets,
1012                resuming_session: st.resuming_session,
1013                session_id: st.session_id,
1014                server_name: st.server_name,
1015                using_ems: st.using_ems,
1016                transcript,
1017                ticket: None,
1018                resuming: false,
1019                cert_verified,
1020                sig_verified,
1021            }))
1022        }
1023    }
1024
1025    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1026        Box::new(ExpectServerDone {
1027            config: self.config,
1028            resuming_session: self.resuming_session,
1029            session_id: self.session_id,
1030            server_name: self.server_name,
1031            randoms: self.randoms,
1032            using_ems: self.using_ems,
1033            transcript: self.transcript,
1034            suite: self.suite,
1035            server_cert: self.server_cert.into_owned(),
1036            server_kx: self.server_kx,
1037            client_auth: self.client_auth,
1038            must_issue_new_ticket: self.must_issue_new_ticket,
1039        })
1040    }
1041}
1042
1043struct ExpectNewTicket {
1044    config: Arc<ClientConfig>,
1045    secrets: ConnectionSecrets,
1046    resuming_session: Option<persist::Tls12ClientSessionValue>,
1047    session_id: SessionId,
1048    server_name: ServerName<'static>,
1049    using_ems: bool,
1050    transcript: HandshakeHash,
1051    resuming: bool,
1052    cert_verified: verify::ServerCertVerified,
1053    sig_verified: verify::HandshakeSignatureValid,
1054}
1055
1056impl State<ClientConnectionData> for ExpectNewTicket {
1057    fn handle<'m>(
1058        mut self: Box<Self>,
1059        _cx: &mut ClientContext<'_>,
1060        m: Message<'m>,
1061    ) -> hs::NextStateOrError<'m>
1062    where
1063        Self: 'm,
1064    {
1065        self.transcript.add_message(&m);
1066
1067        let nst = require_handshake_msg_move!(
1068            m,
1069            HandshakeType::NewSessionTicket,
1070            HandshakePayload::NewSessionTicket
1071        )?;
1072
1073        Ok(Box::new(ExpectCcs {
1074            config: self.config,
1075            secrets: self.secrets,
1076            resuming_session: self.resuming_session,
1077            session_id: self.session_id,
1078            server_name: self.server_name,
1079            using_ems: self.using_ems,
1080            transcript: self.transcript,
1081            ticket: Some(nst),
1082            resuming: self.resuming,
1083            cert_verified: self.cert_verified,
1084            sig_verified: self.sig_verified,
1085        }))
1086    }
1087
1088    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1089        self
1090    }
1091}
1092
1093// -- Waiting for their CCS --
1094struct ExpectCcs {
1095    config: Arc<ClientConfig>,
1096    secrets: ConnectionSecrets,
1097    resuming_session: Option<persist::Tls12ClientSessionValue>,
1098    session_id: SessionId,
1099    server_name: ServerName<'static>,
1100    using_ems: bool,
1101    transcript: HandshakeHash,
1102    ticket: Option<NewSessionTicketPayload>,
1103    resuming: bool,
1104    cert_verified: verify::ServerCertVerified,
1105    sig_verified: verify::HandshakeSignatureValid,
1106}
1107
1108impl State<ClientConnectionData> for ExpectCcs {
1109    fn handle<'m>(
1110        self: Box<Self>,
1111        cx: &mut ClientContext<'_>,
1112        m: Message<'m>,
1113    ) -> hs::NextStateOrError<'m>
1114    where
1115        Self: 'm,
1116    {
1117        match m.payload {
1118            MessagePayload::ChangeCipherSpec(..) => {}
1119            payload => {
1120                return Err(inappropriate_message(
1121                    &payload,
1122                    &[ContentType::ChangeCipherSpec],
1123                ));
1124            }
1125        }
1126        // CCS should not be received interleaved with fragmented handshake-level
1127        // message.
1128        cx.common.check_aligned_handshake()?;
1129
1130        // Note: msgs layer validates trivial contents of CCS.
1131        cx.common
1132            .record_layer
1133            .start_decrypting();
1134
1135        Ok(Box::new(ExpectFinished {
1136            config: self.config,
1137            secrets: self.secrets,
1138            resuming_session: self.resuming_session,
1139            session_id: self.session_id,
1140            server_name: self.server_name,
1141            using_ems: self.using_ems,
1142            transcript: self.transcript,
1143            ticket: self.ticket,
1144            resuming: self.resuming,
1145            cert_verified: self.cert_verified,
1146            sig_verified: self.sig_verified,
1147        }))
1148    }
1149
1150    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1151        self
1152    }
1153}
1154
1155struct ExpectFinished {
1156    config: Arc<ClientConfig>,
1157    resuming_session: Option<persist::Tls12ClientSessionValue>,
1158    session_id: SessionId,
1159    server_name: ServerName<'static>,
1160    using_ems: bool,
1161    transcript: HandshakeHash,
1162    ticket: Option<NewSessionTicketPayload>,
1163    secrets: ConnectionSecrets,
1164    resuming: bool,
1165    cert_verified: verify::ServerCertVerified,
1166    sig_verified: verify::HandshakeSignatureValid,
1167}
1168
1169impl ExpectFinished {
1170    // -- Waiting for their finished --
1171    fn save_session(&mut self, cx: &ClientContext<'_>) {
1172        // Save a ticket.  If we got a new ticket, save that.  Otherwise, save the
1173        // original ticket again.
1174        let (mut ticket, lifetime) = match self.ticket.take() {
1175            Some(nst) => (nst.ticket, nst.lifetime_hint),
1176            None => (Arc::new(PayloadU16::empty()), 0),
1177        };
1178
1179        if ticket.0.is_empty() {
1180            if let Some(resuming_session) = &mut self.resuming_session {
1181                ticket = resuming_session.ticket();
1182            }
1183        }
1184
1185        if self.session_id.is_empty() && ticket.0.is_empty() {
1186            debug!("Session not saved: server didn't allocate id or ticket");
1187            return;
1188        }
1189
1190        let Ok(now) = self.config.current_time() else {
1191            debug!("Could not get current time");
1192            return;
1193        };
1194
1195        let session_value = persist::Tls12ClientSessionValue::new(
1196            self.secrets.suite(),
1197            self.session_id,
1198            ticket,
1199            self.secrets.master_secret(),
1200            cx.common
1201                .peer_certificates
1202                .clone()
1203                .unwrap_or_default(),
1204            &self.config.verifier,
1205            &self.config.client_auth_cert_resolver,
1206            now,
1207            lifetime,
1208            self.using_ems,
1209        );
1210
1211        self.config
1212            .resumption
1213            .store
1214            .set_tls12_session(self.server_name.clone(), session_value);
1215    }
1216}
1217
1218impl State<ClientConnectionData> for ExpectFinished {
1219    fn handle<'m>(
1220        self: Box<Self>,
1221        cx: &mut ClientContext<'_>,
1222        m: Message<'m>,
1223    ) -> hs::NextStateOrError<'m>
1224    where
1225        Self: 'm,
1226    {
1227        let mut st = *self;
1228        let finished =
1229            require_handshake_msg!(m, HandshakeType::Finished, HandshakePayload::Finished)?;
1230
1231        cx.common.check_aligned_handshake()?;
1232
1233        // Work out what verify_data we expect.
1234        let vh = st.transcript.current_hash();
1235        let expect_verify_data = st.secrets.server_verify_data(&vh);
1236
1237        // Constant-time verification of this is relatively unimportant: they only
1238        // get one chance.  But it can't hurt.
1239        let _fin_verified =
1240            match ConstantTimeEq::ct_eq(&expect_verify_data[..], finished.bytes()).into() {
1241                true => verify::FinishedMessageVerified::assertion(),
1242                false => {
1243                    return Err(cx
1244                        .common
1245                        .send_fatal_alert(AlertDescription::DecryptError, Error::DecryptError));
1246                }
1247            };
1248
1249        // Hash this message too.
1250        st.transcript.add_message(&m);
1251
1252        st.save_session(cx);
1253
1254        if st.resuming {
1255            emit_ccs(cx.common);
1256            cx.common
1257                .record_layer
1258                .start_encrypting();
1259            emit_finished(&st.secrets, &mut st.transcript, cx.common);
1260        }
1261
1262        cx.common
1263            .start_traffic(&mut cx.sendable_plaintext);
1264        Ok(Box::new(ExpectTraffic {
1265            secrets: st.secrets,
1266            _cert_verified: st.cert_verified,
1267            _sig_verified: st.sig_verified,
1268            _fin_verified,
1269        }))
1270    }
1271
1272    // we could not decrypt the encrypted handshake message with session resumption
1273    // this might mean that the ticket was invalid for some reason, so we remove it
1274    // from the store to restart a session from scratch
1275    fn handle_decrypt_error(&self) {
1276        if self.resuming {
1277            self.config
1278                .resumption
1279                .store
1280                .remove_tls12_session(&self.server_name);
1281        }
1282    }
1283
1284    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1285        self
1286    }
1287}
1288
1289// -- Traffic transit state --
1290struct ExpectTraffic {
1291    secrets: ConnectionSecrets,
1292    _cert_verified: verify::ServerCertVerified,
1293    _sig_verified: verify::HandshakeSignatureValid,
1294    _fin_verified: verify::FinishedMessageVerified,
1295}
1296
1297impl State<ClientConnectionData> for ExpectTraffic {
1298    fn handle<'m>(
1299        self: Box<Self>,
1300        cx: &mut ClientContext<'_>,
1301        m: Message<'m>,
1302    ) -> hs::NextStateOrError<'m>
1303    where
1304        Self: 'm,
1305    {
1306        match m.payload {
1307            MessagePayload::ApplicationData(payload) => cx
1308                .common
1309                .take_received_plaintext(payload),
1310            payload => {
1311                return Err(inappropriate_message(
1312                    &payload,
1313                    &[ContentType::ApplicationData],
1314                ));
1315            }
1316        }
1317        Ok(self)
1318    }
1319
1320    fn export_keying_material(
1321        &self,
1322        output: &mut [u8],
1323        label: &[u8],
1324        context: Option<&[u8]>,
1325    ) -> Result<(), Error> {
1326        self.secrets
1327            .export_keying_material(output, label, context);
1328        Ok(())
1329    }
1330
1331    fn extract_secrets(&self) -> Result<PartiallyExtractedSecrets, Error> {
1332        self.secrets
1333            .extract_secrets(Side::Client)
1334    }
1335
1336    fn into_external_state(self: Box<Self>) -> Result<Box<dyn KernelState + 'static>, Error> {
1337        Ok(self)
1338    }
1339
1340    fn into_owned(self: Box<Self>) -> hs::NextState<'static> {
1341        self
1342    }
1343}
1344
1345impl KernelState for ExpectTraffic {
1346    fn update_secrets(&mut self, _: Direction) -> Result<ConnectionTrafficSecrets, Error> {
1347        Err(Error::General(
1348            "TLS 1.2 connections do not support traffic secret updates".into(),
1349        ))
1350    }
1351
1352    fn handle_new_session_ticket(
1353        &mut self,
1354        _cx: &mut KernelContext<'_>,
1355        _message: &NewSessionTicketPayloadTls13,
1356    ) -> Result<(), Error> {
1357        Err(Error::General(
1358            "TLS 1.2 session tickets may not be sent once the handshake has completed".into(),
1359        ))
1360    }
1361}