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