rustls/client/
mod.rs

1use crate::anchors;
2use crate::error::TLSError;
3use crate::key;
4use crate::keylog::{KeyLog, NoKeyLog};
5#[cfg(feature = "logging")]
6use crate::log::trace;
7use crate::msgs::enums::CipherSuite;
8use crate::msgs::enums::SignatureScheme;
9use crate::msgs::enums::{AlertDescription, HandshakeType};
10use crate::msgs::enums::{ContentType, ProtocolVersion};
11use crate::msgs::handshake::CertificatePayload;
12use crate::msgs::handshake::ClientExtension;
13use crate::msgs::message::Message;
14use crate::session::{MiddleboxCCS, Session, SessionCommon};
15use crate::sign;
16use crate::suites::{SupportedCipherSuite, ALL_CIPHERSUITES};
17use crate::verify;
18
19use std::fmt;
20use std::io::{self, IoSlice};
21use std::mem;
22use std::sync::Arc;
23
24use sct;
25use webpki;
26
27#[macro_use]
28mod hs;
29mod common;
30pub mod handy;
31mod tls12;
32mod tls13;
33
34/// A trait for the ability to store client session data.
35/// The keys and values are opaque.
36///
37/// Both the keys and values should be treated as
38/// **highly sensitive data**, containing enough key material
39/// to break all security of the corresponding session.
40///
41/// `put` is a mutating operation; this isn't expressed
42/// in the type system to allow implementations freedom in
43/// how to achieve interior mutability.  `Mutex` is a common
44/// choice.
45pub trait StoresClientSessions: Send + Sync {
46    /// Stores a new `value` for `key`.  Returns `true`
47    /// if the value was stored.
48    fn put(&self, key: Vec<u8>, value: Vec<u8>) -> bool;
49
50    /// Returns the latest value for `key`.  Returns `None`
51    /// if there's no such value.
52    fn get(&self, key: &[u8]) -> Option<Vec<u8>>;
53}
54
55/// A trait for the ability to choose a certificate chain and
56/// private key for the purposes of client authentication.
57pub trait ResolvesClientCert: Send + Sync {
58    /// With the server-supplied acceptable issuers in `acceptable_issuers`,
59    /// the server's supported signature schemes in `sigschemes`,
60    /// return a certificate chain and signing key to authenticate.
61    ///
62    /// `acceptable_issuers` is undecoded and unverified by the rustls
63    /// library, but it should be expected to contain a DER encodings
64    /// of X501 NAMEs.
65    ///
66    /// Return None to continue the handshake without any client
67    /// authentication.  The server may reject the handshake later
68    /// if it requires authentication.
69    fn resolve(
70        &self,
71        acceptable_issuers: &[&[u8]],
72        sigschemes: &[SignatureScheme],
73    ) -> Option<sign::CertifiedKey>;
74
75    /// Return true if any certificates at all are available.
76    fn has_certs(&self) -> bool;
77}
78
79/// Common configuration for (typically) all connections made by
80/// a program.
81///
82/// Making one of these can be expensive, and should be
83/// once per process rather than once per connection.
84#[derive(Clone)]
85pub struct ClientConfig {
86    /// List of ciphersuites, in preference order.
87    pub ciphersuites: Vec<&'static SupportedCipherSuite>,
88
89    /// Collection of root certificates.
90    pub root_store: anchors::RootCertStore,
91
92    /// Which ALPN protocols we include in our client hello.
93    /// If empty, no ALPN extension is sent.
94    pub alpn_protocols: Vec<Vec<u8>>,
95
96    /// How we store session data or tickets.
97    pub session_persistence: Arc<dyn StoresClientSessions>,
98
99    /// Our MTU.  If None, we don't limit TLS message sizes.
100    pub mtu: Option<usize>,
101
102    /// How to decide what client auth certificate/keys to use.
103    pub client_auth_cert_resolver: Arc<dyn ResolvesClientCert>,
104
105    /// Whether to support RFC5077 tickets.  You must provide a working
106    /// `session_persistence` member for this to have any meaningful
107    /// effect.
108    ///
109    /// The default is true.
110    pub enable_tickets: bool,
111
112    /// Supported versions, in no particular order.  The default
113    /// is all supported versions.
114    pub versions: Vec<ProtocolVersion>,
115
116    /// Collection of certificate transparency logs.
117    /// If this collection is empty, then certificate transparency
118    /// checking is disabled.
119    pub ct_logs: Option<&'static [&'static sct::Log<'static>]>,
120
121    /// Whether to send the Server Name Indication (SNI) extension
122    /// during the client handshake.
123    ///
124    /// The default is true.
125    pub enable_sni: bool,
126
127    /// How to verify the server certificate chain.
128    verifier: Arc<dyn verify::ServerCertVerifier>,
129
130    /// How to output key material for debugging.  The default
131    /// does nothing.
132    pub key_log: Arc<dyn KeyLog>,
133
134    /// Whether to send data on the first flight ("early data") in
135    /// TLS 1.3 handshakes.
136    ///
137    /// The default is false.
138    pub enable_early_data: bool,
139}
140
141impl Default for ClientConfig {
142    fn default() -> Self {
143        Self::new()
144    }
145}
146
147impl ClientConfig {
148    /// Make a `ClientConfig` with a default set of ciphersuites,
149    /// no root certificates, no ALPN protocols, and no client auth.
150    ///
151    /// The default session persistence provider stores up to 32
152    /// items in memory.
153    pub fn new() -> ClientConfig {
154        ClientConfig::with_ciphersuites(&ALL_CIPHERSUITES)
155    }
156
157    /// Make a `ClientConfig` with a custom set of ciphersuites,
158    /// no root certificates, no ALPN protocols, and no client auth.
159    ///
160    /// The default session persistence provider stores up to 32
161    /// items in memory.
162    pub fn with_ciphersuites(ciphersuites: &[&'static SupportedCipherSuite]) -> ClientConfig {
163        ClientConfig {
164            ciphersuites: ciphersuites.to_vec(),
165            root_store: anchors::RootCertStore::empty(),
166            alpn_protocols: Vec::new(),
167            session_persistence: handy::ClientSessionMemoryCache::new(32),
168            mtu: None,
169            client_auth_cert_resolver: Arc::new(handy::FailResolveClientCert {}),
170            enable_tickets: true,
171            versions: vec![ProtocolVersion::TLSv1_3, ProtocolVersion::TLSv1_2],
172            ct_logs: None,
173            enable_sni: true,
174            verifier: Arc::new(verify::WebPKIVerifier::new()),
175            key_log: Arc::new(NoKeyLog {}),
176            enable_early_data: false,
177        }
178    }
179
180    #[doc(hidden)]
181    /// We support a given TLS version if it's quoted in the configured
182    /// versions *and* at least one ciphersuite for this version is
183    /// also configured.
184    pub fn supports_version(&self, v: ProtocolVersion) -> bool {
185        self.versions.contains(&v)
186            && self
187                .ciphersuites
188                .iter()
189                .any(|cs| cs.usable_for_version(v))
190    }
191
192    #[doc(hidden)]
193    pub fn get_verifier(&self) -> &dyn verify::ServerCertVerifier {
194        self.verifier.as_ref()
195    }
196
197    /// Set the ALPN protocol list to the given protocol names.
198    /// Overwrites any existing configured protocols.
199    /// The first element in the `protocols` list is the most
200    /// preferred, the last is the least preferred.
201    pub fn set_protocols(&mut self, protocols: &[Vec<u8>]) {
202        self.alpn_protocols.clear();
203        self.alpn_protocols
204            .extend_from_slice(protocols);
205    }
206
207    /// Sets persistence layer to `persist`.
208    pub fn set_persistence(&mut self, persist: Arc<dyn StoresClientSessions>) {
209        self.session_persistence = persist;
210    }
211
212    /// Sets MTU to `mtu`.  If None, the default is used.
213    /// If Some(x) then x must be greater than 5 bytes.
214    pub fn set_mtu(&mut self, mtu: &Option<usize>) {
215        // Internally our MTU relates to fragment size, and does
216        // not include the TLS header overhead.
217        //
218        // Externally the MTU is the whole packet size.  The difference
219        // is PACKET_OVERHEAD.
220        if let Some(x) = *mtu {
221            use crate::msgs::fragmenter;
222            debug_assert!(x > fragmenter::PACKET_OVERHEAD);
223            self.mtu = Some(x - fragmenter::PACKET_OVERHEAD);
224        } else {
225            self.mtu = None;
226        }
227    }
228
229    /// Sets a single client authentication certificate and private key.
230    /// This is blindly used for all servers that ask for client auth.
231    ///
232    /// `cert_chain` is a vector of DER-encoded certificates,
233    /// `key_der` is a DER-encoded RSA or ECDSA private key.
234    pub fn set_single_client_cert(
235        &mut self,
236        cert_chain: Vec<key::Certificate>,
237        key_der: key::PrivateKey,
238    ) -> Result<(), TLSError> {
239        let resolver = handy::AlwaysResolvesClientCert::new(cert_chain, &key_der)?;
240        self.client_auth_cert_resolver = Arc::new(resolver);
241        Ok(())
242    }
243
244    /// Access configuration options whose use is dangerous and requires
245    /// extra care.
246    #[cfg(feature = "dangerous_configuration")]
247    pub fn dangerous(&mut self) -> danger::DangerousClientConfig {
248        danger::DangerousClientConfig { cfg: self }
249    }
250}
251
252/// Container for unsafe APIs
253#[cfg(feature = "dangerous_configuration")]
254pub mod danger {
255    use std::sync::Arc;
256
257    use super::verify::ServerCertVerifier;
258    use super::ClientConfig;
259
260    /// Accessor for dangerous configuration options.
261    pub struct DangerousClientConfig<'a> {
262        /// The underlying ClientConfig
263        pub cfg: &'a mut ClientConfig,
264    }
265
266    impl<'a> DangerousClientConfig<'a> {
267        /// Overrides the default `ServerCertVerifier` with something else.
268        pub fn set_certificate_verifier(&mut self, verifier: Arc<dyn ServerCertVerifier>) {
269            self.cfg.verifier = verifier;
270        }
271    }
272}
273
274#[derive(Debug, PartialEq)]
275enum EarlyDataState {
276    Disabled,
277    Ready,
278    Accepted,
279    AcceptedFinished,
280    Rejected,
281}
282
283pub struct EarlyData {
284    state: EarlyDataState,
285    left: usize,
286}
287
288impl EarlyData {
289    fn new() -> EarlyData {
290        EarlyData {
291            left: 0,
292            state: EarlyDataState::Disabled,
293        }
294    }
295
296    fn is_enabled(&self) -> bool {
297        match self.state {
298            EarlyDataState::Ready | EarlyDataState::Accepted => true,
299            _ => false,
300        }
301    }
302
303    fn is_accepted(&self) -> bool {
304        match self.state {
305            EarlyDataState::Accepted | EarlyDataState::AcceptedFinished => true,
306            _ => false,
307        }
308    }
309
310    fn enable(&mut self, max_data: usize) {
311        assert_eq!(self.state, EarlyDataState::Disabled);
312        self.state = EarlyDataState::Ready;
313        self.left = max_data;
314    }
315
316    fn rejected(&mut self) {
317        trace!("EarlyData rejected");
318        self.state = EarlyDataState::Rejected;
319    }
320
321    fn accepted(&mut self) {
322        trace!("EarlyData accepted");
323        assert_eq!(self.state, EarlyDataState::Ready);
324        self.state = EarlyDataState::Accepted;
325    }
326
327    fn finished(&mut self) {
328        trace!("EarlyData finished");
329        self.state = match self.state {
330            EarlyDataState::Accepted => EarlyDataState::AcceptedFinished,
331            _ => panic!("bad EarlyData state"),
332        }
333    }
334
335    fn check_write(&mut self, sz: usize) -> io::Result<usize> {
336        match self.state {
337            EarlyDataState::Disabled => unreachable!(),
338            EarlyDataState::Ready | EarlyDataState::Accepted => {
339                let take = if self.left < sz {
340                    mem::replace(&mut self.left, 0)
341                } else {
342                    self.left -= sz;
343                    sz
344                };
345
346                Ok(take)
347            }
348            EarlyDataState::Rejected | EarlyDataState::AcceptedFinished => {
349                Err(io::Error::from(io::ErrorKind::InvalidInput))
350            }
351        }
352    }
353
354    fn bytes_left(&self) -> usize {
355        self.left
356    }
357}
358
359/// Stub that implements io::Write and dispatches to `write_early_data`.
360pub struct WriteEarlyData<'a> {
361    sess: &'a mut ClientSessionImpl,
362}
363
364impl<'a> WriteEarlyData<'a> {
365    fn new(sess: &'a mut ClientSessionImpl) -> WriteEarlyData<'a> {
366        WriteEarlyData { sess }
367    }
368
369    /// How many bytes you may send.  Writes will become short
370    /// once this reaches zero.
371    pub fn bytes_left(&self) -> usize {
372        self.sess.early_data.bytes_left()
373    }
374}
375
376impl<'a> io::Write for WriteEarlyData<'a> {
377    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
378        self.sess.write_early_data(buf)
379    }
380
381    fn flush(&mut self) -> io::Result<()> {
382        Ok(())
383    }
384}
385
386pub struct ClientSessionImpl {
387    pub config: Arc<ClientConfig>,
388    pub alpn_protocol: Option<Vec<u8>>,
389    pub common: SessionCommon,
390    pub error: Option<TLSError>,
391    pub state: Option<hs::NextState>,
392    pub server_cert_chain: CertificatePayload,
393    pub early_data: EarlyData,
394    pub resumption_ciphersuite: Option<&'static SupportedCipherSuite>,
395}
396
397impl fmt::Debug for ClientSessionImpl {
398    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
399        f.debug_struct("ClientSessionImpl")
400            .finish()
401    }
402}
403
404impl ClientSessionImpl {
405    pub fn new(config: &Arc<ClientConfig>) -> ClientSessionImpl {
406        ClientSessionImpl {
407            config: config.clone(),
408            alpn_protocol: None,
409            common: SessionCommon::new(config.mtu, true),
410            error: None,
411            state: None,
412            server_cert_chain: Vec::new(),
413            early_data: EarlyData::new(),
414            resumption_ciphersuite: None,
415        }
416    }
417
418    pub fn start_handshake(&mut self, hostname: webpki::DNSName, extra_exts: Vec<ClientExtension>) {
419        self.state = Some(hs::start_handshake(self, hostname, extra_exts));
420    }
421
422    pub fn get_cipher_suites(&self) -> Vec<CipherSuite> {
423        let mut ret = Vec::new();
424
425        for cs in &self.config.ciphersuites {
426            ret.push(cs.suite);
427        }
428
429        // We don't do renegotation at all, in fact.
430        ret.push(CipherSuite::TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
431
432        ret
433    }
434
435    pub fn find_cipher_suite(&self, suite: CipherSuite) -> Option<&'static SupportedCipherSuite> {
436        for scs in &self.config.ciphersuites {
437            if scs.suite == suite {
438                return Some(scs);
439            }
440        }
441
442        None
443    }
444
445    pub fn wants_read(&self) -> bool {
446        // We want to read more data all the time, except when we
447        // have unprocessed plaintext.  This provides back-pressure
448        // to the TCP buffers.
449        //
450        // This also covers the handshake case, because we don't have
451        // readable plaintext before handshake has completed.
452        !self.common.has_readable_plaintext()
453    }
454
455    pub fn wants_write(&self) -> bool {
456        !self.common.sendable_tls.is_empty()
457    }
458
459    pub fn is_handshaking(&self) -> bool {
460        !self.common.traffic
461    }
462
463    pub fn set_buffer_limit(&mut self, len: usize) {
464        self.common.set_buffer_limit(len)
465    }
466
467    pub fn process_msg(&mut self, mut msg: Message) -> Result<(), TLSError> {
468        // TLS1.3: drop CCS at any time during handshaking
469        if let MiddleboxCCS::Drop = self.common.filter_tls13_ccs(&msg)? {
470            trace!("Dropping CCS");
471            return Ok(());
472        }
473
474        // Decrypt if demanded by current state.
475        if self.common.record_layer.is_decrypting() {
476            let dm = self.common.decrypt_incoming(msg)?;
477            msg = dm;
478        }
479
480        // For handshake messages, we need to join them before parsing
481        // and processing.
482        if self
483            .common
484            .handshake_joiner
485            .want_message(&msg)
486        {
487            self.common
488                .handshake_joiner
489                .take_message(msg)
490                .ok_or_else(|| {
491                    self.common
492                        .send_fatal_alert(AlertDescription::DecodeError);
493                    TLSError::CorruptMessagePayload(ContentType::Handshake)
494                })?;
495            return self.process_new_handshake_messages();
496        }
497
498        // Now we can fully parse the message payload.
499        if !msg.decode_payload() {
500            return Err(TLSError::CorruptMessagePayload(msg.typ));
501        }
502
503        // For alerts, we have separate logic.
504        if msg.is_content_type(ContentType::Alert) {
505            return self.common.process_alert(msg);
506        }
507
508        self.process_main_protocol(msg)
509    }
510
511    pub fn process_new_handshake_messages(&mut self) -> Result<(), TLSError> {
512        while let Some(msg) = self
513            .common
514            .handshake_joiner
515            .frames
516            .pop_front()
517        {
518            self.process_main_protocol(msg)?;
519        }
520
521        Ok(())
522    }
523
524    fn reject_renegotiation_attempt(&mut self) -> Result<(), TLSError> {
525        self.common
526            .send_warning_alert(AlertDescription::NoRenegotiation);
527        Ok(())
528    }
529
530    fn queue_unexpected_alert(&mut self) {
531        self.common
532            .send_fatal_alert(AlertDescription::UnexpectedMessage);
533    }
534
535    fn maybe_send_unexpected_alert(&mut self, rc: hs::NextStateOrError) -> hs::NextStateOrError {
536        match rc {
537            Err(TLSError::InappropriateMessage { .. })
538            | Err(TLSError::InappropriateHandshakeMessage { .. }) => {
539                self.queue_unexpected_alert();
540            }
541            _ => {}
542        };
543        rc
544    }
545
546    /// Process `msg`.  First, we get the current state.  Then we ask what messages
547    /// that state expects, enforced via `check_message`.  Finally, we ask the handler
548    /// to handle the message.
549    fn process_main_protocol(&mut self, msg: Message) -> Result<(), TLSError> {
550        // For TLS1.2, outside of the handshake, send rejection alerts for
551        // renegotation requests.  These can occur any time.
552        if msg.is_handshake_type(HandshakeType::HelloRequest)
553            && !self.common.is_tls13()
554            && !self.is_handshaking()
555        {
556            return self.reject_renegotiation_attempt();
557        }
558
559        let state = self.state.take().unwrap();
560        let maybe_next_state = state.handle(self, msg);
561        let next_state = self.maybe_send_unexpected_alert(maybe_next_state)?;
562        self.state = Some(next_state);
563
564        Ok(())
565    }
566
567    pub fn process_new_packets(&mut self) -> Result<(), TLSError> {
568        if let Some(ref err) = self.error {
569            return Err(err.clone());
570        }
571
572        if self.common.message_deframer.desynced {
573            return Err(TLSError::CorruptMessage);
574        }
575
576        while let Some(msg) = self
577            .common
578            .message_deframer
579            .frames
580            .pop_front()
581        {
582            match self.process_msg(msg) {
583                Ok(_) => {}
584                Err(err) => {
585                    self.error = Some(err.clone());
586                    return Err(err);
587                }
588            }
589        }
590
591        Ok(())
592    }
593
594    pub fn get_peer_certificates(&self) -> Option<Vec<key::Certificate>> {
595        if self.server_cert_chain.is_empty() {
596            return None;
597        }
598
599        Some(
600            self.server_cert_chain
601                .iter()
602                .cloned()
603                .collect(),
604        )
605    }
606
607    pub fn get_alpn_protocol(&self) -> Option<&[u8]> {
608        self.alpn_protocol
609            .as_ref()
610            .map(AsRef::as_ref)
611    }
612
613    pub fn get_protocol_version(&self) -> Option<ProtocolVersion> {
614        self.common.negotiated_version
615    }
616
617    pub fn get_negotiated_ciphersuite(&self) -> Option<&'static SupportedCipherSuite> {
618        self.common.get_suite()
619    }
620
621    pub fn write_early_data(&mut self, data: &[u8]) -> io::Result<usize> {
622        self.early_data
623            .check_write(data.len())
624            .and_then(|sz| {
625                Ok(self
626                    .common
627                    .send_early_plaintext(&data[..sz]))
628            })
629    }
630
631    fn export_keying_material(
632        &self,
633        output: &mut [u8],
634        label: &[u8],
635        context: Option<&[u8]>,
636    ) -> Result<(), TLSError> {
637        self.state
638            .as_ref()
639            .ok_or_else(|| TLSError::HandshakeNotComplete)
640            .and_then(|st| st.export_keying_material(output, label, context))
641    }
642
643    fn send_some_plaintext(&mut self, buf: &[u8]) -> usize {
644        let mut st = self.state.take();
645        st.as_mut()
646            .map(|st| st.perhaps_write_key_update(self));
647        self.state = st;
648
649        self.common.send_some_plaintext(buf)
650    }
651}
652
653/// This represents a single TLS client session.
654#[derive(Debug)]
655pub struct ClientSession {
656    // We use the pimpl idiom to hide unimportant details.
657    pub(crate) imp: ClientSessionImpl,
658}
659
660impl ClientSession {
661    /// Make a new ClientSession.  `config` controls how
662    /// we behave in the TLS protocol, `hostname` is the
663    /// hostname of who we want to talk to.
664    pub fn new(config: &Arc<ClientConfig>, hostname: webpki::DNSNameRef) -> ClientSession {
665        let mut imp = ClientSessionImpl::new(config);
666        imp.start_handshake(hostname.into(), vec![]);
667        ClientSession { imp }
668    }
669
670    /// Returns an `io::Write` implementor you can write bytes to
671    /// to send TLS1.3 early data (a.k.a. "0-RTT data") to the server.
672    ///
673    /// This returns None in many circumstances when the capability to
674    /// send early data is not available, including but not limited to:
675    ///
676    /// - The server hasn't been talked to previously.
677    /// - The server does not support resumption.
678    /// - The server does not support early data.
679    /// - The resumption data for the server has expired.
680    ///
681    /// The server specifies a maximum amount of early data.  You can
682    /// learn this limit through the returned object, and writes through
683    /// it will process only this many bytes.
684    ///
685    /// The server can choose not to accept any sent early data --
686    /// in this case the data is lost but the connection continues.  You
687    /// can tell this happened using `is_early_data_accepted`.
688    pub fn early_data(&mut self) -> Option<WriteEarlyData> {
689        if self.imp.early_data.is_enabled() {
690            Some(WriteEarlyData::new(&mut self.imp))
691        } else {
692            None
693        }
694    }
695
696    /// Returns True if the server signalled it will process early data.
697    ///
698    /// If you sent early data and this returns false at the end of the
699    /// handshake then the server will not process the data.  This
700    /// is not an error, but you may wish to resend the data.
701    pub fn is_early_data_accepted(&self) -> bool {
702        self.imp.early_data.is_accepted()
703    }
704}
705
706impl Session for ClientSession {
707    fn read_tls(&mut self, rd: &mut dyn io::Read) -> io::Result<usize> {
708        self.imp.common.read_tls(rd)
709    }
710
711    /// Writes TLS messages to `wr`.
712    fn write_tls(&mut self, wr: &mut dyn io::Write) -> io::Result<usize> {
713        self.imp.common.write_tls(wr)
714    }
715
716    fn process_new_packets(&mut self) -> Result<(), TLSError> {
717        self.imp.process_new_packets()
718    }
719
720    fn wants_read(&self) -> bool {
721        self.imp.wants_read()
722    }
723
724    fn wants_write(&self) -> bool {
725        self.imp.wants_write()
726    }
727
728    fn is_handshaking(&self) -> bool {
729        self.imp.is_handshaking()
730    }
731
732    fn set_buffer_limit(&mut self, len: usize) {
733        self.imp.set_buffer_limit(len)
734    }
735
736    fn send_close_notify(&mut self) {
737        self.imp.common.send_close_notify()
738    }
739
740    fn get_peer_certificates(&self) -> Option<Vec<key::Certificate>> {
741        self.imp.get_peer_certificates()
742    }
743
744    fn get_alpn_protocol(&self) -> Option<&[u8]> {
745        self.imp.get_alpn_protocol()
746    }
747
748    fn get_protocol_version(&self) -> Option<ProtocolVersion> {
749        self.imp.get_protocol_version()
750    }
751
752    fn export_keying_material(
753        &self,
754        output: &mut [u8],
755        label: &[u8],
756        context: Option<&[u8]>,
757    ) -> Result<(), TLSError> {
758        self.imp
759            .export_keying_material(output, label, context)
760    }
761
762    fn get_negotiated_ciphersuite(&self) -> Option<&'static SupportedCipherSuite> {
763        self.imp
764            .get_negotiated_ciphersuite()
765            .or(self.imp.resumption_ciphersuite)
766    }
767}
768
769impl io::Read for ClientSession {
770    /// Obtain plaintext data received from the peer over this TLS connection.
771    ///
772    /// If the peer closes the TLS session cleanly, this fails with an error of
773    /// kind ErrorKind::ConnectionAborted once all the pending data has been read.
774    /// No further data can be received on that connection, so the underlying TCP
775    /// connection should closed too.
776    ///
777    /// Note that support close notify varies in peer TLS libraries: many do not
778    /// support it and uncleanly close the TCP connection (this might be
779    /// vulnerable to truncation attacks depending on the application protocol).
780    /// This means applications using rustls must both handle ErrorKind::ConnectionAborted
781    /// from this function, *and* unexpected closure of the underlying TCP connection.
782    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
783        self.imp.common.read(buf)
784    }
785}
786
787impl io::Write for ClientSession {
788    /// Send the plaintext `buf` to the peer, encrypting
789    /// and authenticating it.  Once this function succeeds
790    /// you should call `write_tls` which will output the
791    /// corresponding TLS records.
792    ///
793    /// This function buffers plaintext sent before the
794    /// TLS handshake completes, and sends it as soon
795    /// as it can.  This buffer is of *unlimited size* so
796    /// writing much data before it can be sent will
797    /// cause excess memory usage.
798    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
799        Ok(self.imp.send_some_plaintext(buf))
800    }
801
802    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
803        let mut sz = 0;
804        for buf in bufs {
805            sz += self.imp.send_some_plaintext(buf);
806        }
807        Ok(sz)
808    }
809
810    fn flush(&mut self) -> io::Result<()> {
811        self.imp.common.flush_plaintext();
812        Ok(())
813    }
814}