Skip to main content

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