rustls/client/
hs.rs

1#[cfg(feature = "logging")]
2use crate::bs_debug;
3use crate::check::check_message;
4use crate::cipher;
5use crate::client::ClientSessionImpl;
6use crate::error::TLSError;
7use crate::key_schedule::{KeyScheduleEarly, KeyScheduleHandshake};
8#[cfg(feature = "logging")]
9use crate::log::{debug, trace};
10use crate::msgs::base::Payload;
11#[cfg(feature = "quic")]
12use crate::msgs::base::PayloadU16;
13use crate::msgs::codec::{Codec, Reader};
14use crate::msgs::enums::{AlertDescription, Compression, ProtocolVersion};
15use crate::msgs::enums::{ContentType, ExtensionType, HandshakeType};
16use crate::msgs::enums::{ECPointFormat, PSKKeyExchangeMode};
17use crate::msgs::handshake::HelloRetryRequest;
18use crate::msgs::handshake::{CertificateStatusRequest, SCTList};
19use crate::msgs::handshake::{ClientExtension, HasServerExtensions};
20use crate::msgs::handshake::{ClientHelloPayload, HandshakeMessagePayload, HandshakePayload};
21use crate::msgs::handshake::{ConvertProtocolNameList, ProtocolNameList};
22use crate::msgs::handshake::{ECPointFormatList, SupportedPointFormats};
23use crate::msgs::handshake::{Random, SessionID};
24use crate::msgs::message::{Message, MessagePayload};
25use crate::msgs::persist;
26use crate::rand;
27use crate::session::SessionSecrets;
28use crate::suites;
29use crate::ticketer;
30use crate::verify;
31
32use crate::client::common::{ClientHelloDetails, ReceivedTicketDetails};
33use crate::client::common::{HandshakeDetails, ServerCertDetails};
34use crate::client::{tls12, tls13};
35
36use webpki;
37
38pub type NextState = Box<dyn State + Send + Sync>;
39pub type NextStateOrError = Result<NextState, TLSError>;
40
41pub trait State {
42    /// Each handle() implementation consumes a whole TLS message, and returns
43    /// either an error or the next state.
44    fn handle(self: Box<Self>, sess: &mut ClientSessionImpl, m: Message) -> NextStateOrError;
45
46    fn export_keying_material(
47        &self,
48        _output: &mut [u8],
49        _label: &[u8],
50        _context: Option<&[u8]>,
51    ) -> Result<(), TLSError> {
52        Err(TLSError::HandshakeNotComplete)
53    }
54
55    fn perhaps_write_key_update(&mut self, _sess: &mut ClientSessionImpl) {}
56}
57
58pub fn illegal_param(sess: &mut ClientSessionImpl, why: &str) -> TLSError {
59    sess.common
60        .send_fatal_alert(AlertDescription::IllegalParameter);
61    TLSError::PeerMisbehavedError(why.to_string())
62}
63
64pub fn check_aligned_handshake(sess: &mut ClientSessionImpl) -> Result<(), TLSError> {
65    if !sess.common.handshake_joiner.is_empty() {
66        sess.common
67            .send_fatal_alert(AlertDescription::UnexpectedMessage);
68        Err(TLSError::PeerMisbehavedError(
69            "key epoch or handshake flight with pending fragment".to_string(),
70        ))
71    } else {
72        Ok(())
73    }
74}
75
76fn find_session(
77    sess: &mut ClientSessionImpl,
78    dns_name: webpki::DNSNameRef,
79) -> Option<persist::ClientSessionValue> {
80    let key = persist::ClientSessionKey::session_for_dns_name(dns_name);
81    let key_buf = key.get_encoding();
82
83    let maybe_value = sess
84        .config
85        .session_persistence
86        .get(&key_buf);
87
88    if maybe_value.is_none() {
89        debug!("No cached session for {:?}", dns_name);
90        return None;
91    }
92
93    let value = maybe_value.unwrap();
94    let mut reader = Reader::init(&value[..]);
95    if let Some(result) = persist::ClientSessionValue::read(&mut reader) {
96        if result.has_expired(ticketer::timebase()) {
97            None
98        } else {
99            #[cfg(feature = "quic")]
100            {
101                if sess.common.is_quic() {
102                    let params = PayloadU16::read(&mut reader)?;
103                    sess.common.quic.params = Some(params.0);
104                }
105            }
106            Some(result)
107        }
108    } else {
109        None
110    }
111}
112
113fn random_sessionid() -> SessionID {
114    let mut random_id = [0u8; 32];
115    rand::fill_random(&mut random_id);
116    SessionID::new(&random_id)
117}
118
119/// If we have a ticket, we use the sessionid as a signal that we're
120/// doing an abbreviated handshake.  See section 3.4 in RFC5077.
121fn random_sessionid_for_ticket(csv: &mut persist::ClientSessionValue) {
122    if !csv.ticket.0.is_empty() {
123        csv.session_id = random_sessionid();
124    }
125}
126
127struct InitialState {
128    handshake: HandshakeDetails,
129}
130
131impl InitialState {
132    fn new(host_name: webpki::DNSName, extra_exts: Vec<ClientExtension>) -> InitialState {
133        InitialState {
134            handshake: HandshakeDetails::new(host_name, extra_exts),
135        }
136    }
137
138    fn emit_initial_client_hello(mut self, sess: &mut ClientSessionImpl) -> NextState {
139        if sess
140            .config
141            .client_auth_cert_resolver
142            .has_certs()
143        {
144            self.handshake
145                .transcript
146                .set_client_auth_enabled();
147        }
148        let hello_details = ClientHelloDetails::new();
149        emit_client_hello_for_retry(sess, self.handshake, hello_details, None)
150    }
151}
152
153pub fn start_handshake(
154    sess: &mut ClientSessionImpl,
155    host_name: webpki::DNSName,
156    extra_exts: Vec<ClientExtension>,
157) -> NextState {
158    InitialState::new(host_name, extra_exts).emit_initial_client_hello(sess)
159}
160
161struct ExpectServerHello {
162    handshake: HandshakeDetails,
163    early_key_schedule: Option<KeyScheduleEarly>,
164    hello: ClientHelloDetails,
165    server_cert: ServerCertDetails,
166    may_send_cert_status: bool,
167    must_issue_new_ticket: bool,
168}
169
170struct ExpectServerHelloOrHelloRetryRequest(ExpectServerHello);
171
172pub fn compatible_suite(
173    sess: &ClientSessionImpl,
174    resuming_suite: Option<&suites::SupportedCipherSuite>,
175) -> bool {
176    match resuming_suite {
177        Some(resuming_suite) => {
178            if let Some(suite) = sess.common.get_suite() {
179                suite.can_resume_to(&resuming_suite)
180            } else {
181                true
182            }
183        }
184        None => false,
185    }
186}
187
188fn emit_client_hello_for_retry(
189    sess: &mut ClientSessionImpl,
190    mut handshake: HandshakeDetails,
191    mut hello: ClientHelloDetails,
192    retryreq: Option<&HelloRetryRequest>,
193) -> NextState {
194    // Do we have a SessionID or ticket cached for this host?
195    handshake.resuming_session = find_session(sess, handshake.dns_name.as_ref());
196    let (session_id, ticket, resume_version) = if handshake.resuming_session.is_some() {
197        let resuming = handshake
198            .resuming_session
199            .as_mut()
200            .unwrap();
201        if resuming.version == ProtocolVersion::TLSv1_2 {
202            random_sessionid_for_ticket(resuming);
203        }
204        debug!("Resuming session");
205        (
206            resuming.session_id,
207            resuming.ticket.0.clone(),
208            resuming.version,
209        )
210    } else {
211        debug!("Not resuming any session");
212        if handshake.session_id.is_empty() && !sess.common.is_quic() {
213            handshake.session_id = random_sessionid();
214        }
215        (
216            handshake.session_id,
217            Vec::new(),
218            ProtocolVersion::Unknown(0),
219        )
220    };
221
222    let support_tls12 = sess
223        .config
224        .supports_version(ProtocolVersion::TLSv1_2);
225    let support_tls13 = sess
226        .config
227        .supports_version(ProtocolVersion::TLSv1_3);
228
229    let mut supported_versions = Vec::new();
230    if support_tls13 {
231        supported_versions.push(ProtocolVersion::TLSv1_3);
232    }
233
234    if support_tls12 {
235        supported_versions.push(ProtocolVersion::TLSv1_2);
236    }
237
238    let mut exts = Vec::new();
239    if !supported_versions.is_empty() {
240        exts.push(ClientExtension::SupportedVersions(supported_versions));
241    }
242    if sess.config.enable_sni {
243        exts.push(ClientExtension::make_sni(handshake.dns_name.as_ref()));
244    }
245    exts.push(ClientExtension::ECPointFormats(
246        ECPointFormatList::supported(),
247    ));
248    exts.push(ClientExtension::NamedGroups(
249        suites::KeyExchange::supported_groups().to_vec(),
250    ));
251    exts.push(ClientExtension::SignatureAlgorithms(
252        sess.config
253            .get_verifier()
254            .supported_verify_schemes(),
255    ));
256    exts.push(ClientExtension::ExtendedMasterSecretRequest);
257    exts.push(ClientExtension::CertificateStatusRequest(
258        CertificateStatusRequest::build_ocsp(),
259    ));
260
261    if sess.config.ct_logs.is_some() {
262        exts.push(ClientExtension::SignedCertificateTimestampRequest);
263    }
264
265    if support_tls13 {
266        tls13::choose_kx_groups(sess, &mut exts, &mut hello, &mut handshake, retryreq);
267    }
268
269    if let Some(cookie) = retryreq.and_then(HelloRetryRequest::get_cookie) {
270        exts.push(ClientExtension::Cookie(cookie.clone()));
271    }
272
273    if support_tls13 && sess.config.enable_tickets {
274        // We could support PSK_KE here too. Such connections don't
275        // have forward secrecy, and are similar to TLS1.2 resumption.
276        let psk_modes = vec![PSKKeyExchangeMode::PSK_DHE_KE];
277        exts.push(ClientExtension::PresharedKeyModes(psk_modes));
278    }
279
280    if !sess.config.alpn_protocols.is_empty() {
281        exts.push(ClientExtension::Protocols(ProtocolNameList::from_slices(
282            &sess
283                .config
284                .alpn_protocols
285                .iter()
286                .map(|proto| &proto[..])
287                .collect::<Vec<_>>(),
288        )));
289    }
290
291    // Extra extensions must be placed before the PSK extension
292    exts.extend(handshake.extra_exts.iter().cloned());
293
294    let fill_in_binder = if support_tls13
295        && sess.config.enable_tickets
296        && resume_version == ProtocolVersion::TLSv1_3
297        && !ticket.is_empty()
298    {
299        tls13::prepare_resumption(sess, ticket, &handshake, &mut exts, retryreq.is_some())
300    } else if sess.config.enable_tickets {
301        // If we have a ticket, include it.  Otherwise, request one.
302        if ticket.is_empty() {
303            exts.push(ClientExtension::SessionTicketRequest);
304        } else {
305            exts.push(ClientExtension::SessionTicketOffer(Payload::new(ticket)));
306        }
307        false
308    } else {
309        false
310    };
311
312    // Note what extensions we sent.
313    hello.sent_extensions = exts
314        .iter()
315        .map(ClientExtension::get_type)
316        .collect();
317
318    let mut chp = HandshakeMessagePayload {
319        typ: HandshakeType::ClientHello,
320        payload: HandshakePayload::ClientHello(ClientHelloPayload {
321            client_version: ProtocolVersion::TLSv1_2,
322            random: Random::from_slice(&handshake.randoms.client),
323            session_id,
324            cipher_suites: sess.get_cipher_suites(),
325            compression_methods: vec![Compression::Null],
326            extensions: exts,
327        }),
328    };
329
330    let early_key_schedule = if fill_in_binder {
331        Some(tls13::fill_in_psk_binder(sess, &mut handshake, &mut chp))
332    } else {
333        None
334    };
335
336    let ch = Message {
337        typ: ContentType::Handshake,
338        // "This value MUST be set to 0x0303 for all records generated
339        //  by a TLS 1.3 implementation other than an initial ClientHello
340        //  (i.e., one not generated after a HelloRetryRequest)"
341        version: if retryreq.is_some() {
342            ProtocolVersion::TLSv1_2
343        } else {
344            ProtocolVersion::TLSv1_0
345        },
346        payload: MessagePayload::Handshake(chp),
347    };
348
349    if retryreq.is_some() {
350        // send dummy CCS to fool middleboxes prior
351        // to second client hello
352        tls13::emit_fake_ccs(&mut handshake, sess);
353    }
354
355    trace!("Sending ClientHello {:#?}", ch);
356
357    handshake.transcript.add_message(&ch);
358    sess.common.send_msg(ch, false);
359
360    // Calculate the hash of ClientHello and use it to derive EarlyTrafficSecret
361    if sess.early_data.is_enabled() {
362        // For middlebox compatibility
363        tls13::emit_fake_ccs(&mut handshake, sess);
364
365        // It is safe to call unwrap() because fill_in_binder is true.
366        let resuming_suite = handshake
367            .resuming_session
368            .as_ref()
369            .and_then(|resume| sess.find_cipher_suite(resume.cipher_suite))
370            .unwrap();
371
372        let client_hello_hash = handshake
373            .transcript
374            .get_hash_given(resuming_suite.get_hash(), &[]);
375        let client_early_traffic_secret = early_key_schedule
376            .as_ref()
377            .unwrap()
378            .client_early_traffic_secret(
379                &client_hello_hash,
380                &*sess.config.key_log,
381                &handshake.randoms.client,
382            );
383        // Set early data encryption key
384        sess.common
385            .record_layer
386            .set_message_encrypter(cipher::new_tls13_write(
387                resuming_suite,
388                &client_early_traffic_secret,
389            ));
390
391        #[cfg(feature = "quic")]
392        {
393            sess.common.quic.early_secret = Some(client_early_traffic_secret);
394        }
395
396        // Now the client can send encrypted early data
397        sess.common.early_traffic = true;
398        trace!("Starting early data traffic");
399    }
400
401    let next = ExpectServerHello {
402        handshake,
403        hello,
404        early_key_schedule,
405        server_cert: ServerCertDetails::new(),
406        may_send_cert_status: false,
407        must_issue_new_ticket: false,
408    };
409
410    if support_tls13 && retryreq.is_none() {
411        Box::new(ExpectServerHelloOrHelloRetryRequest(next))
412    } else {
413        Box::new(next)
414    }
415}
416
417pub fn process_alpn_protocol(
418    sess: &mut ClientSessionImpl,
419    proto: Option<&[u8]>,
420) -> Result<(), TLSError> {
421    sess.alpn_protocol = proto.map(ToOwned::to_owned);
422    if sess.alpn_protocol.is_some()
423        && !sess
424            .config
425            .alpn_protocols
426            .contains(sess.alpn_protocol.as_ref().unwrap())
427    {
428        return Err(illegal_param(sess, "server sent non-offered ALPN protocol"));
429    }
430    debug!(
431        "ALPN protocol is {:?}",
432        sess.alpn_protocol
433            .as_ref()
434            .map(|v| bs_debug::BsDebug(&v))
435    );
436    Ok(())
437}
438
439pub fn sct_list_is_invalid(scts: &SCTList) -> bool {
440    scts.is_empty() || scts.iter().any(|sct| sct.0.is_empty())
441}
442
443impl ExpectServerHello {
444    fn into_expect_tls13_encrypted_extensions(
445        self,
446        key_schedule: KeyScheduleHandshake,
447    ) -> NextState {
448        Box::new(tls13::ExpectEncryptedExtensions {
449            handshake: self.handshake,
450            key_schedule,
451            server_cert: self.server_cert,
452            hello: self.hello,
453        })
454    }
455
456    fn into_expect_tls12_new_ticket_resume(
457        self,
458        secrets: SessionSecrets,
459        certv: verify::ServerCertVerified,
460        sigv: verify::HandshakeSignatureValid,
461    ) -> NextState {
462        Box::new(tls12::ExpectNewTicket {
463            secrets,
464            handshake: self.handshake,
465            resuming: true,
466            cert_verified: certv,
467            sig_verified: sigv,
468        })
469    }
470
471    fn into_expect_tls12_ccs_resume(
472        self,
473        secrets: SessionSecrets,
474        certv: verify::ServerCertVerified,
475        sigv: verify::HandshakeSignatureValid,
476    ) -> NextState {
477        Box::new(tls12::ExpectCCS {
478            secrets,
479            handshake: self.handshake,
480            ticket: ReceivedTicketDetails::new(),
481            resuming: true,
482            cert_verified: certv,
483            sig_verified: sigv,
484        })
485    }
486
487    fn into_expect_tls12_certificate(self) -> NextState {
488        Box::new(tls12::ExpectCertificate {
489            handshake: self.handshake,
490            server_cert: self.server_cert,
491            may_send_cert_status: self.may_send_cert_status,
492            must_issue_new_ticket: self.must_issue_new_ticket,
493        })
494    }
495}
496
497impl State for ExpectServerHello {
498    fn handle(mut self: Box<Self>, sess: &mut ClientSessionImpl, m: Message) -> NextStateOrError {
499        let server_hello =
500            require_handshake_msg!(m, HandshakeType::ServerHello, HandshakePayload::ServerHello)?;
501        trace!("We got ServerHello {:#?}", server_hello);
502
503        use crate::ProtocolVersion::{TLSv1_2, TLSv1_3};
504        let tls13_supported = sess.config.supports_version(TLSv1_3);
505
506        let server_version = if server_hello.legacy_version == TLSv1_2 {
507            server_hello
508                .get_supported_versions()
509                .unwrap_or(server_hello.legacy_version)
510        } else {
511            server_hello.legacy_version
512        };
513
514        match server_version {
515            TLSv1_3 if tls13_supported => {
516                sess.common.negotiated_version = Some(TLSv1_3);
517            }
518            TLSv1_2 if sess.config.supports_version(TLSv1_2) => {
519                if sess.early_data.is_enabled() && sess.common.early_traffic {
520                    // The client must fail with a dedicated error code if the server
521                    // responds with TLS 1.2 when offering 0-RTT.
522                    return Err(TLSError::PeerMisbehavedError(
523                        "server chose v1.2 when offering 0-rtt".to_string(),
524                    ));
525                }
526                sess.common.negotiated_version = Some(TLSv1_2);
527
528                if server_hello
529                    .get_supported_versions()
530                    .is_some()
531                {
532                    return Err(illegal_param(
533                        sess,
534                        "server chose v1.2 using v1.3 extension",
535                    ));
536                }
537            }
538            _ => {
539                sess.common
540                    .send_fatal_alert(AlertDescription::ProtocolVersion);
541                return Err(TLSError::PeerIncompatibleError(
542                    "server does not support TLS v1.2/v1.3".to_string(),
543                ));
544            }
545        };
546
547        if server_hello.compression_method != Compression::Null {
548            return Err(illegal_param(sess, "server chose non-Null compression"));
549        }
550
551        if server_hello.has_duplicate_extension() {
552            sess.common
553                .send_fatal_alert(AlertDescription::DecodeError);
554            return Err(TLSError::PeerMisbehavedError(
555                "server sent duplicate extensions".to_string(),
556            ));
557        }
558
559        let allowed_unsolicited = [ExtensionType::RenegotiationInfo];
560        if self
561            .hello
562            .server_sent_unsolicited_extensions(&server_hello.extensions, &allowed_unsolicited)
563        {
564            sess.common
565                .send_fatal_alert(AlertDescription::UnsupportedExtension);
566            return Err(TLSError::PeerMisbehavedError(
567                "server sent unsolicited extension".to_string(),
568            ));
569        }
570
571        // Extract ALPN protocol
572        if !sess.common.is_tls13() {
573            process_alpn_protocol(sess, server_hello.get_alpn_protocol())?;
574        }
575
576        // If ECPointFormats extension is supplied by the server, it must contain
577        // Uncompressed.  But it's allowed to be omitted.
578        if let Some(point_fmts) = server_hello.get_ecpoints_extension() {
579            if !point_fmts.contains(&ECPointFormat::Uncompressed) {
580                sess.common
581                    .send_fatal_alert(AlertDescription::HandshakeFailure);
582                return Err(TLSError::PeerMisbehavedError(
583                    "server does not support uncompressed points".to_string(),
584                ));
585            }
586        }
587
588        let scs = sess.find_cipher_suite(server_hello.cipher_suite);
589
590        if scs.is_none() {
591            sess.common
592                .send_fatal_alert(AlertDescription::HandshakeFailure);
593            return Err(TLSError::PeerMisbehavedError(
594                "server chose non-offered ciphersuite".to_string(),
595            ));
596        }
597
598        debug!("Using ciphersuite {:?}", server_hello.cipher_suite);
599        if !sess.common.set_suite(scs.unwrap()) {
600            return Err(illegal_param(sess, "server varied selected ciphersuite"));
601        }
602
603        let version = sess.common.negotiated_version.unwrap();
604        if !sess
605            .common
606            .get_suite_assert()
607            .usable_for_version(version)
608        {
609            return Err(illegal_param(
610                sess,
611                "server chose unusable ciphersuite for version",
612            ));
613        }
614
615        // Start our handshake hash, and input the server-hello.
616        let starting_hash = sess
617            .common
618            .get_suite_assert()
619            .get_hash();
620        self.handshake
621            .transcript
622            .start_hash(starting_hash);
623        self.handshake
624            .transcript
625            .add_message(&m);
626
627        // For TLS1.3, start message encryption using
628        // handshake_traffic_secret.
629        if sess.common.is_tls13() {
630            tls13::validate_server_hello(sess, &server_hello)?;
631            let key_schedule = tls13::start_handshake_traffic(
632                sess,
633                self.early_key_schedule.take(),
634                &server_hello,
635                &mut self.handshake,
636                &mut self.hello,
637            )?;
638            tls13::emit_fake_ccs(&mut self.handshake, sess);
639            return Ok(self.into_expect_tls13_encrypted_extensions(key_schedule));
640        }
641
642        // TLS1.2 only from here-on
643
644        // Save ServerRandom and SessionID
645        server_hello
646            .random
647            .write_slice(&mut self.handshake.randoms.server);
648        self.handshake.session_id = server_hello.session_id;
649
650        // Look for TLS1.3 downgrade signal in server random
651        if tls13_supported
652            && self
653                .handshake
654                .randoms
655                .has_tls12_downgrade_marker()
656        {
657            return Err(illegal_param(
658                sess,
659                "downgrade to TLS1.2 when TLS1.3 is supported",
660            ));
661        }
662
663        // Doing EMS?
664        if server_hello.ems_support_acked() {
665            self.handshake.using_ems = true;
666        }
667
668        // Might the server send a ticket?
669        let with_tickets = if server_hello
670            .find_extension(ExtensionType::SessionTicket)
671            .is_some()
672        {
673            debug!("Server supports tickets");
674            true
675        } else {
676            false
677        };
678        self.must_issue_new_ticket = with_tickets;
679
680        // Might the server send a CertificateStatus between Certificate and
681        // ServerKeyExchange?
682        if server_hello
683            .find_extension(ExtensionType::StatusRequest)
684            .is_some()
685        {
686            debug!("Server may staple OCSP response");
687            self.may_send_cert_status = true;
688        }
689
690        // Save any sent SCTs for verification against the certificate.
691        if let Some(sct_list) = server_hello.get_sct_list() {
692            debug!("Server sent {:?} SCTs", sct_list.len());
693
694            if sct_list_is_invalid(sct_list) {
695                let error_msg = "server sent invalid SCT list".to_string();
696                return Err(TLSError::PeerMisbehavedError(error_msg));
697            }
698            self.server_cert.scts = Some(sct_list.clone());
699        }
700
701        // See if we're successfully resuming.
702        if let Some(ref resuming) = self.handshake.resuming_session {
703            if resuming.session_id == self.handshake.session_id {
704                debug!("Server agreed to resume");
705
706                // Is the server telling lies about the ciphersuite?
707                if resuming.cipher_suite != scs.unwrap().suite {
708                    let error_msg = "abbreviated handshake offered, but with varied cs".to_string();
709                    return Err(TLSError::PeerMisbehavedError(error_msg));
710                }
711
712                // And about EMS support?
713                if resuming.extended_ms != self.handshake.using_ems {
714                    let error_msg = "server varied ems support over resume".to_string();
715                    return Err(TLSError::PeerMisbehavedError(error_msg));
716                }
717
718                let secrets = SessionSecrets::new_resume(
719                    &self.handshake.randoms,
720                    scs.unwrap().get_hash(),
721                    &resuming.master_secret.0,
722                );
723                sess.config.key_log.log(
724                    "CLIENT_RANDOM",
725                    &secrets.randoms.client,
726                    &secrets.master_secret,
727                );
728                sess.common
729                    .start_encryption_tls12(&secrets);
730
731                // Since we're resuming, we verified the certificate and
732                // proof of possession in the prior session.
733                sess.server_cert_chain = resuming.server_cert_chain.clone();
734                let certv = verify::ServerCertVerified::assertion();
735                let sigv = verify::HandshakeSignatureValid::assertion();
736
737                return if self.must_issue_new_ticket {
738                    Ok(self.into_expect_tls12_new_ticket_resume(secrets, certv, sigv))
739                } else {
740                    Ok(self.into_expect_tls12_ccs_resume(secrets, certv, sigv))
741                };
742            }
743        }
744
745        Ok(self.into_expect_tls12_certificate())
746    }
747}
748
749impl ExpectServerHelloOrHelloRetryRequest {
750    fn into_expect_server_hello(self) -> NextState {
751        Box::new(self.0)
752    }
753
754    fn handle_hello_retry_request(
755        mut self,
756        sess: &mut ClientSessionImpl,
757        m: Message,
758    ) -> NextStateOrError {
759        let hrr = require_handshake_msg!(
760            m,
761            HandshakeType::HelloRetryRequest,
762            HandshakePayload::HelloRetryRequest
763        )?;
764        trace!("Got HRR {:?}", hrr);
765
766        check_aligned_handshake(sess)?;
767
768        let has_cookie = hrr.get_cookie().is_some();
769        let req_group = hrr.get_requested_key_share_group();
770
771        // A retry request is illegal if it contains no cookie and asks for
772        // retry of a group we already sent.
773        if !has_cookie
774            && req_group
775                .map(|g| self.0.hello.has_key_share(g))
776                .unwrap_or(false)
777        {
778            return Err(illegal_param(sess, "server requested hrr with our group"));
779        }
780
781        // Or asks for us to retry on an unsupported group.
782        if let Some(group) = req_group {
783            if !suites::KeyExchange::supported_groups().contains(&group) {
784                return Err(illegal_param(sess, "server requested hrr with bad group"));
785            }
786        }
787
788        // Or has an empty cookie.
789        if has_cookie && hrr.get_cookie().unwrap().0.is_empty() {
790            return Err(illegal_param(
791                sess,
792                "server requested hrr with empty cookie",
793            ));
794        }
795
796        // Or has something unrecognised
797        if hrr.has_unknown_extension() {
798            sess.common
799                .send_fatal_alert(AlertDescription::UnsupportedExtension);
800            return Err(TLSError::PeerIncompatibleError(
801                "server sent hrr with unhandled extension".to_string(),
802            ));
803        }
804
805        // Or has the same extensions more than once
806        if hrr.has_duplicate_extension() {
807            return Err(illegal_param(sess, "server send duplicate hrr extensions"));
808        }
809
810        // Or asks us to change nothing.
811        if !has_cookie && req_group.is_none() {
812            return Err(illegal_param(sess, "server requested hrr with no changes"));
813        }
814
815        // Or asks us to talk a protocol we didn't offer, or doesn't support HRR at all.
816        match hrr.get_supported_versions() {
817            Some(ProtocolVersion::TLSv1_3) => {
818                sess.common.negotiated_version = Some(ProtocolVersion::TLSv1_3);
819            }
820            _ => {
821                return Err(illegal_param(
822                    sess,
823                    "server requested unsupported version in hrr",
824                ));
825            }
826        }
827
828        // Or asks us to use a ciphersuite we didn't offer.
829        let maybe_cs = sess.find_cipher_suite(hrr.cipher_suite);
830        let cs = match maybe_cs {
831            Some(cs) => cs,
832            None => {
833                return Err(illegal_param(
834                    sess,
835                    "server requested unsupported cs in hrr",
836                ));
837            }
838        };
839
840        // HRR selects the ciphersuite.
841        sess.common.set_suite(cs);
842
843        // This is the draft19 change where the transcript became a tree
844        self.0
845            .handshake
846            .transcript
847            .start_hash(cs.get_hash());
848        self.0
849            .handshake
850            .transcript
851            .rollup_for_hrr();
852        self.0
853            .handshake
854            .transcript
855            .add_message(&m);
856
857        // Early data is not alllowed after HelloRetryrequest
858        if sess.early_data.is_enabled() {
859            sess.early_data.rejected();
860        }
861
862        Ok(emit_client_hello_for_retry(
863            sess,
864            self.0.handshake,
865            self.0.hello,
866            Some(&hrr),
867        ))
868    }
869}
870
871impl State for ExpectServerHelloOrHelloRetryRequest {
872    fn handle(self: Box<Self>, sess: &mut ClientSessionImpl, m: Message) -> NextStateOrError {
873        check_message(
874            &m,
875            &[ContentType::Handshake],
876            &[HandshakeType::ServerHello, HandshakeType::HelloRetryRequest],
877        )?;
878        if m.is_handshake_type(HandshakeType::ServerHello) {
879            self.into_expect_server_hello()
880                .handle(sess, m)
881        } else {
882            self.handle_hello_retry_request(sess, m)
883        }
884    }
885}
886
887pub fn send_cert_error_alert(sess: &mut ClientSessionImpl, err: TLSError) -> TLSError {
888    match err {
889        TLSError::WebPKIError(webpki::Error::BadDER) => {
890            sess.common
891                .send_fatal_alert(AlertDescription::DecodeError);
892        }
893        TLSError::PeerMisbehavedError(_) => {
894            sess.common
895                .send_fatal_alert(AlertDescription::IllegalParameter);
896        }
897        _ => {
898            sess.common
899                .send_fatal_alert(AlertDescription::BadCertificate);
900        }
901    };
902
903    err
904}