Skip to main content

Connection

Struct Connection 

Source
pub struct Connection<Side: SideData, T: Transport> { /* private fields */ }
Expand description

A TLS connection, parametrized by the side (ClientSide or ServerSide).

This is one of the core abstractions of the rustls API. It represents a single connection to a peer, and holds all the state associated with that connection. Note that it does not hold any IO objects: the application is responsible for reading and writing TLS records.

This object is generic over the Side type parameter, which must be either ClientSide or ServerSide. While most of the API for a connection is shared between both types, some API is asymmetric, which is reflected by the type parameter. As such, some methods (including constructors) are specific on the Side type. See the implementations for ClientSide and ServerSide below.

Implementations§

Source§

impl<Side: SideData, T: Transport> Connection<Side, T>

Source

pub fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error>

Returns an object that can derive key material from the agreed connection secrets.

See RFC 5705 for more details on what this is for.

This function can be called at most once per connection.

This function will error:

  • if called prior to the handshake completing; (check with CommonState::is_handshaking first).
  • if called more than once per connection.
Source

pub fn side(&self) -> &Side

Returns data learned during the connection.

Source

pub fn fips(&self) -> FipsStatus

Return the FIPS validation status of the connection.

This is different from CryptoProvider::fips(): it is concerned only with cryptography, whereas this also covers TLS-level configuration that NIST recommends, as well as ECH HPKE suites if applicable.

Source

pub fn is_handshaking(&self) -> bool

Returns true if the connection is currently performing the TLS handshake.

During this time, Self::write() will return an error.

Source§

impl<Side: SideData> Connection<Side, Tcp>

Source

pub fn read_tls<'a, 'm>( &'a mut self, input: &'m mut dyn TlsInputBuffer, tls: &'a mut Vec<u8>, ) -> MessageHandler<'a, 'm, Side>

Build a MessageHandler to process messages from the input buffer.

Any data appended to tls should be sent to the peer.

Source

pub fn write( &mut self, plaintext: OutboundPlain<'_>, tls: &mut Vec<u8>, ) -> Result<(), Error>

Writes the application data from plaintext into TLS records and appends them to tls.

Any data appended to tls should be sent to the peer.

This will fail if either the handshake is not complete yet (because we don’t yet have the keys to encrypt application data) or if the send path has been closed by sending a close_notify alert.

For TLS 1.2, this also fails with Error::EncryptError if encrypting plaintext would exceed the negotiated cipher suite’s confidentiality_limit. In that case, none of plaintext is sent; a close_notify alert is appended to tls instead.

If the connection previously encountered a fatal error (for example, while processing received data in Self::read_tls()), this returns that error, even if plaintext is empty.

Source

pub fn refresh_traffic_keys(&mut self, tls: &mut Vec<u8>) -> Result<(), Error>

Sends a TLS1.3 key_update message into tls to refresh a connection’s keys.

The main reason to call this manually is to roll keys when it is known a connection will be idle for a long period.

rustls implicitly and automatically refreshes traffic keys when needed according to the selected cipher suite’s cryptographic constraints. There is therefore no need to call this manually to avoid cryptographic keys “wearing out”.

This call refreshes our encryption keys. Once the peer receives the message, it refreshes its encryption and decryption keys and sends a response. Once we receive that response, we refresh our decryption keys to match. At the end of this process, keys in both directions have been refreshed.

This fails with Error::HandshakeNotComplete if called before the initial handshake is complete, or if a version prior to TLS1.3 is negotiated.

§Usage advice

Note that other implementations (including rustls) may enforce limits on the number of key_update messages allowed on a given connection to prevent denial of service. Therefore, this should be called sparingly.

rustls only allows one outstanding request at a time; this function succeeds but sends nothing if a request is already in-flight.

Source

pub fn split(self) -> Result<SplitConnection<Side>, Error>

Split a post-handshake connection into a SplitConnection.

This allows the two directions (transmit and receive) of the connection to be progressed separately (including by different threads, which would allow dedicating a CPU core for each direction rather than one per connection; this can dramatically improve performance for full-duplex protocols).

It also separates out the ConnectionOutputs which gives the application direct control of how long this is kept.

This fails if:

Source

pub fn early_exporter(&mut self) -> Result<KeyingMaterialExporter, Error>

Returns the “early” exporter that can derive key material for use in early data

See RFC 5705 for general details on what exporters are, and RFC 9846 S7.5 for specific details on the “early” exporter.

Beware that the early exporter requires care, as it is subject to the same potential for replay as early data itself. See RFC 9846 appendix F.5.1 for more detail.

This function can be called at most once per connection. This function will error if called more than once per connection.

If you are looking for the normal exporter, this is available from Connection::exporter().

Source

pub fn dangerous_extract_secrets(self) -> Result<ExtractedSecrets, Error>

Extract secrets, so they can be used when configuring kTLS, for example.

Should be used with care as it exposes secret key material.

All TLS data previously written into caller-provided buffers must be sent to the peer before calling this function.

This fails with ApiMisuse::KernelConnectionWithPendingSendData if the connection has pending data to send, which would otherwise be lost. Write out that pending data before calling this function.

Source

pub fn send_close_notify(&mut self, tls: &mut Vec<u8>) -> Result<(), Error>

Writes a close_notify warning alert into tls.

This informs the peer that the connection is being closed.

Does nothing if any close_notify or fatal alert was already sent.

Source§

impl<T: Transport> Connection<ClientSide, T>

Source

pub fn tls13_tickets_received(&self) -> u32

Returns the number of TLS1.3 tickets that have been received.

Source§

impl<T: Transport> Connection<ServerSide, T>

Source

pub fn set_resumption_data(&mut self, data: &[u8]) -> Result<(), Error>

Set the resumption data to embed in future resumption tickets supplied to the client.

Defaults to the empty byte string. Must be less than 2^15 bytes to allow room for other data. Should be called while is_handshaking returns true to ensure all transmitted resumption tickets are affected.

Integrity will be assured by rustls, but the data will be visible to the client. If secrecy from the client is desired, encrypt the data separately.

Source§

impl Connection<ClientSide, Tcp>

Source

pub fn early_data(&mut self) -> Option<WriteEarlyData<'_>>

Allows writing TLS1.3 0RTT/“early” data.

This returns None in many circumstances when the capability to send early data is not available, including but not limited to:

  • The server hasn’t been talked to previously.
  • The server does not support resumption.
  • The server does not support early data.
  • The resumption data for the server has expired.

The server specifies a maximum amount of early data. You can learn this limit through the returned object, and writes through it will process only this many bytes.

The server can choose not to accept any sent early data – in this case the data is lost but the connection continues. You can tell this happened using ClientSide::is_early_data_accepted().

Source§

impl Connection<ServerSide, Tcp>

Source

pub fn new(config: Arc<ServerConfig>) -> Result<Self, Error>

Make a new ServerSide Connection.

config controls how we behave in the TLS protocol.

Source§

impl Connection<ServerSide, Quic>

Source

pub fn new_quic( config: Arc<ServerConfig>, version: Version, params: Vec<u8>, ) -> Result<Self, Error>

Make a new QUIC server Connection

This differs from Connection::new() in that it takes an extra params argument, which contains the TLS-encoded transport parameters to send.

Source§

impl<Side: SideData> Connection<Side, Quic>

Source

pub fn read_hs(&mut self, input: &mut dyn TlsInputBuffer) -> Result<(), Error>

Consume unencrypted TLS handshake data.

Handshake data obtained from separate encryption levels should be supplied in separate calls.

How much of the input buffer is consumed is recorded by a call to TlsInputBuffer::discard(). Unconsumed data should be presented again on the next call.

Source

pub fn events(&mut self) -> impl Iterator<Item = QuicEvent>

Obtain pending events that the caller should process.

All pending events are returned as an iterator.

Source

pub fn zero_rtt_keys(&self) -> Option<DirectionalKeys>

Compute the keys for encrypting/decrypting 0-RTT packets, if available

Source

pub fn quic_transport_parameters(&self) -> Option<&[u8]>

Return the TLS-encoded transport parameters for the session’s peer.

While the transport parameters are technically available prior to the completion of the handshake, they cannot be fully trusted until the handshake completes, and reliance on them should be minimized. However, any tampering with the parameters will cause the handshake to fail.

Methods from Deref<Target = CommonState>§

Source

pub fn is_handshaking(&self) -> bool

Returns true if the connection is currently performing the TLS handshake.

During this time plaintext written to the connection is buffered in memory. After Connection::read_tls() has been called, this might start to return false while the final handshake packets still need to be extracted from the connection’s buffers.

Methods from Deref<Target = ConnectionOutputs>§

Source

pub fn peer_identity(&self) -> Option<&VerifiedIdentity<'static>>

Retrieves the certificate chain or the raw public key used by the peer to authenticate.

This is made available for both full and resumed handshakes.

For clients, this is the identity of the server. For servers, this is the identity of the client, if client authentication was completed.

The return value is None until this value is available.

Source

pub fn alpn_protocol(&self) -> Option<&ApplicationProtocol<'static>>

Retrieves the protocol agreed with the peer via ALPN.

A return value of None after handshake completion means no protocol was agreed (because no protocols were offered or accepted by the peer).

Source

pub fn negotiated_cipher_suite(&self) -> Option<SupportedCipherSuite>

Retrieves the cipher suite agreed with the peer.

This returns None until the cipher suite is agreed.

Source

pub fn negotiated_key_exchange_group( &self, ) -> Option<&'static dyn SupportedKxGroup>

Retrieves the key exchange group agreed with the peer.

This function may return None depending on the state of the connection, the type of handshake, and the protocol version.

If CommonState::is_handshaking() is true this function will return None. Similarly, if the ConnectionOutputs::handshake_kind() is HandshakeKind::Resumed and the ConnectionOutputs::protocol_version() is TLS 1.2, then no key exchange will have occurred and this function will return None.

Source

pub fn protocol_version(&self) -> Option<ProtocolVersion>

Retrieves the protocol version agreed with the peer.

This returns None until the version is agreed.

Source

pub fn extended_main_secret(&self) -> Option<bool>

Whether the Extended Main Secret extension was negotiated.

Returns:

  • None until the handshake reaches the point where this is known.
  • None for TLS 1.3, where the extension does not apply.
  • Some(true) for TLS 1.2 if the extension was negotiated.
  • Some(false) otherwise.
Source

pub fn handshake_kind(&self) -> Option<HandshakeKind>

Which kind of handshake was performed.

This tells you whether the handshake was a resumption or not.

This will return None before it is known which sort of handshake occurred.

Source

pub fn early_exporter(&mut self) -> Result<KeyingMaterialExporter, Error>

Returns the “early” exporter that can derive key material for use in early data

See RFC 5705 for general details on what exporters are, and RFC 9846 S7.5 for specific details on the “early” exporter.

Beware that the early exporter requires care, as it is subject to the same potential for replay as early data itself. See RFC 9846 appendix F.5.1 for more detail.

This function can be called at most once per connection. This function will error if called more than once per connection.

If you are looking for the normal exporter, this is available from Connection::exporter().

Source

pub fn exporter(&mut self) -> Result<KeyingMaterialExporter, Error>

Returns an object that can derive key material from the agreed connection secrets.

See RFC 5705 for more details on what this is for.

This function can be called at most once per connection.

This function will error:

  • if called prior to the handshake completing; (check with CommonState::is_handshaking first).
  • if called more than once per connection.

Trait Implementations§

Source§

impl<S: SideData, T: Transport> Debug for Connection<S, T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<Side: SideData, T: Transport> Deref for Connection<Side, T>

Source§

type Target = CommonState

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl TryFrom<Connection<ClientSide, Tcp>> for ClientHandshake

Source§

type Error = Error

The type returned in the event of a conversion error.
Source§

fn try_from(conn: Connection<ClientSide, Tcp>) -> Result<Self, Error>

Performs the conversion.
Source§

impl TryFrom<Connection<ServerSide, Tcp>> for ServerHandshake

Source§

type Error = Error

The type returned in the event of a conversion error.
Source§

fn try_from(conn: Connection<ServerSide, Tcp>) -> Result<Self, Error>

Performs the conversion.
Source§

impl<Side: SideData> TryFrom<Connection<Side, Tcp>> for SplitConnection<Side>

Source§

type Error = Error

The type returned in the event of a conversion error.
Source§

fn try_from(conn: Connection<Side, Tcp>) -> Result<Self, Error>

Performs the conversion.

Auto Trait Implementations§

§

impl<Side, T> !RefUnwindSafe for Connection<Side, T>

§

impl<Side, T> !UnwindSafe for Connection<Side, T>

§

impl<Side, T> Freeze for Connection<Side, T>
where Result<<Side as Side>::State, Error>: Freeze, Side: Freeze, T: Freeze,

§

impl<Side, T> Send for Connection<Side, T>
where Result<<Side as Side>::State, Error>: Send, Side: Send, T: Send,

§

impl<Side, T> Sync for Connection<Side, T>
where Result<<Side as Side>::State, Error>: Sync, Side: Sync, T: Sync,

§

impl<Side, T> Unpin for Connection<Side, T>
where Result<<Side as Side>::State, Error>: Unpin, Side: Unpin, T: Unpin,

§

impl<Side, T> UnsafeUnpin for Connection<Side, T>
where Result<<Side as Side>::State, Error>: UnsafeUnpin, Side: UnsafeUnpin, T: UnsafeUnpin,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more