pub struct Connection { /* private fields */ }Expand description
A unified TLS or DTLS connection (client or server, any supported version).
Construct via Connection::client or Connection::server, passing a
shared super::Config. The internal engine is picked from
config.max_version.
Implementations§
Source§impl Connection
impl Connection
Sourcepub fn client(config: &Config) -> Result<Self, Error>
pub fn client(config: &Config) -> Result<Self, Error>
Build a client connection. Picks the engine from config.max_version.
Sourcepub fn server(config: &Config) -> Result<Self, Error>
pub fn server(config: &Config) -> Result<Self, Error>
Build a server connection. Picks the engine from config.max_version.
Requires config.identity.is_some().
Sourcepub fn handshake(&mut self) -> Result<HandshakeStatus, Error>
pub fn handshake(&mut self) -> Result<HandshakeStatus, Error>
Drive the handshake forward. Returns the next HandshakeStatus.
Sourcepub fn drive(&mut self) -> Result<Step, Error>
pub fn drive(&mut self) -> Result<Step, Error>
Drive the handshake forward, transparently brokering the identity
signature through the HandshakeSigner installed via
ConfigBuilder::private_key.
This is the key-agnostic alternative to handshake:
the same loop drives an in-process key, a local TPM, or a network HSM,
because the signing device is folded into the returned Step. The
caller services peer I/O on WantRead/WantWrite exactly as with
handshake, and on WantSigner waits on the (opaque) device readiness
before calling drive again — it never touches the message, the
signature, or the device transport.
use std::io::{Read, Write};
let mut buf = [0u8; 16 * 1024];
loop {
match conn.drive().map_err(std::io::Error::other)? {
Step::WantWrite => sock.write_all(&conn.pop().map_err(std::io::Error::other)?)?,
Step::WantRead => {
let n = sock.read(&mut buf)?;
conn.feed(&buf[..n]).map_err(std::io::Error::other)?;
}
// Sync: block on the device fd. Async: register
// `r.as_raw_fd()` with your reactor and `.await` instead.
Step::WantSigner(Some(r)) => r.wait()?,
Step::WantSigner(None) => {} // no fd: just loop and re-drive
Step::Complete => break,
_ => {} // `Step` is #[non_exhaustive]
}
}Sourcepub fn signature_request(&self) -> Option<SignatureRequest>
pub fn signature_request(&self) -> Option<SignatureRequest>
If the handshake is suspended awaiting an external CertificateVerify
signature (an SigningKey::External
identity), returns the SignatureRequest describing what to sign;
otherwise None.
Drive loop: after feed and draining pop,
check this before blocking on a peer read. When it is Some, sign
request.message under request.scheme (on a TPM/HSM, synchronously or
.awaited) and call provide_signature; the
engine then emits the rest of its flight.
Sourcepub fn provide_signature(&mut self, signature: Vec<u8>) -> Result<(), Error>
pub fn provide_signature(&mut self, signature: Vec<u8>) -> Result<(), Error>
Resumes a handshake suspended by signature_request,
supplying the externally-produced CertificateVerify signature.
§Errors
Returns Error::InappropriateState if the handshake is not currently
awaiting an external signature.
Sourcepub fn feed(&mut self, wire_in: &[u8]) -> Result<usize, Error>
pub fn feed(&mut self, wire_in: &[u8]) -> Result<usize, Error>
Wire bytes from the peer into the engine. Returns the number of bytes consumed.
Sourcepub fn pop(&mut self) -> Result<Vec<u8>, Error>
pub fn pop(&mut self) -> Result<Vec<u8>, Error>
Wire bytes the engine wants to send to the peer. For TLS, this is a contiguous stream slice; for DTLS, this is one datagram per call.
Sourcepub fn send(&mut self, app: &[u8]) -> Result<(), Error>
pub fn send(&mut self, app: &[u8]) -> Result<(), Error>
App bytes into the engine (post-handshake).
Sourcepub fn take_early_data(&mut self) -> Result<Vec<u8>, Error>
pub fn take_early_data(&mut self) -> Result<Vec<u8>, Error>
Accepted 0-RTT early-data plaintext out (server side).
Early data is replayable by an active attacker (RFC 8446 §8), so
it is quarantined away from recv — recv only
ever returns data protected by the completed handshake. Drain the
replayable bytes explicitly here and only act on them when doing so
is idempotent. Returns an empty vector on client engines, on engines
without 0-RTT support, when the server did not accept early data, or
once the buffer has been drained.
Sourcepub fn tls_exporter(
&self,
label: &[u8],
context: &[u8],
out: &mut [u8],
) -> Result<(), Error>
pub fn tls_exporter( &self, label: &[u8], context: &[u8], out: &mut [u8], ) -> Result<(), Error>
Exports keying material bound to this connection (RFC 8446 §7.5 for
TLS 1.3, RFC 5705 for TLS 1.2 / DTLS). label and context namespace
the output; out is filled with out.len() bytes derived from the
connection’s master/exporter secret. Available once the handshake has
completed on every TLS and DTLS engine; an error is returned if called
too early.
Sourcepub fn write_early_data(&mut self, data: &[u8]) -> Result<(), Error>
pub fn write_early_data(&mut self, data: &[u8]) -> Result<(), Error>
Client 0-RTT: queue application data to be sent under the
early-traffic key before ServerHello arrives. Valid only on a TLS 1.3
client whose super::ConfigBuilder::resumption_session enabled 0-RTT
(the stored session carried a non-zero max_early_data_size); any other
engine returns Error::InappropriateState. See the 0-RTT replay
caveat in the crate docs — early data is replayable.
Sourcepub fn take_session(&mut self) -> Option<ResumptionSession>
pub fn take_session(&mut self) -> Option<ResumptionSession>
Client only: move out a ResumptionSession derived from a
NewSessionTicket the server sent, for resumption on a later
connection (feed it back via
super::ConfigBuilder::resumption_session). Returns None on a
server engine, or when the server issued no resumable ticket.
Sourcepub fn close(&mut self) -> Result<(), Error>
pub fn close(&mut self) -> Result<(), Error>
Close the connection, emitting a close_notify alert if the engine supports it.
Sourcepub fn is_handshake_complete(&self) -> bool
pub fn is_handshake_complete(&self) -> bool
True once the handshake has completed.
Sourcepub fn received_close_notify(&self) -> bool
pub fn received_close_notify(&self) -> bool
True once the peer’s close_notify alert has been processed.
Distinguishes a graceful TLS shutdown from an abrupt transport
close: after transport EOF, false here means the peer (or an
active attacker injecting a TCP FIN/RST) cut the stream without
the RFC 8446 §6.1 / RFC 5246 §7.2.1 closure alert. Callers using
EOF-delimited application framing should treat that as a
truncation attack and reject the data.
Always false for DTLS engines — purecrypto’s DTLS does not
exchange close_notify (datagram transports have no stream EOF to
authenticate; an application protocol signals its own end).
Sourcepub fn negotiated_version(&self) -> Option<ProtocolVersion>
pub fn negotiated_version(&self) -> Option<ProtocolVersion>
The negotiated wire version, if the handshake has progressed enough to determine it.
Sourcepub fn negotiated_cipher_suite(&self) -> Option<u16>
pub fn negotiated_cipher_suite(&self) -> Option<u16>
IANA cipher-suite identifier of the negotiated suite. None
until the handshake has advanced far enough to fix the suite
(ServerHello processed on the client, ClientHello processed on
the server).
Sourcepub fn negotiated_cipher_suite_name(&self) -> Option<&'static str>
pub fn negotiated_cipher_suite_name(&self) -> Option<&'static str>
The IANA name of the negotiated cipher suite, or None until the
suite is fixed. Returns the well-known strings for the suites
purecrypto negotiates (TLS 1.3 trio + the TLS 1.2 ECDHE-AEAD
set); unknown codes resolve to "UNKNOWN".
Sourcepub fn alpn_selected(&self) -> Option<&[u8]>
pub fn alpn_selected(&self) -> Option<&[u8]>
The negotiated ALPN protocol, if any.
Sourcepub fn peer_server_name(&self) -> Option<&str>
pub fn peer_server_name(&self) -> Option<&str>
Server-side: the SNI host_name the client offered in the ClientHello
server_name extension (RFC 6066 §3). None for client engines,
for DTLS engines (no SNI plumbing yet), or when the peer omitted the
extension. Available once the ClientHello has been processed.
Sourcepub fn peer_certificates(&self) -> &[Vec<u8>]
pub fn peer_certificates(&self) -> &[Vec<u8>]
The peer’s certificate chain (leaf first, DER).
Sourcepub fn next_timeout(&self) -> Option<Duration>
pub fn next_timeout(&self) -> Option<Duration>
DTLS: next retransmit timeout. None on TLS variants.
Sourcepub fn on_timeout(&mut self, now: Duration)
pub fn on_timeout(&mut self, now: Duration)
DTLS: notify the engine that the retransmit deadline has elapsed. No-op on TLS variants.