Skip to content

Commit 655c6fe

Browse files
committed
Remove all connect and accept functions
Those functions were blurring the line between setup failures (which are caused by the developer misusing the API) and actual failures encountered on the stream while trying to achieve the TLS handshake, especially on SslConnector and SslAcceptor. Removing them allows for the removal of HandshakeError, as the HandshakeError::SetupFailure variant becomes useless, and there is no real need to distinguish in that error type between Failure and WouldBlock when we can just check the error stored in MidHandshakeSslStream. This then allow us to simplify tokio_boring's own entry points, also making them distinguish between setup failures and failures on the stream.
1 parent a095d95 commit 655c6fe

16 files changed

Lines changed: 178 additions & 336 deletions

File tree

boring/src/ssl/connector.rs

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use std::ops::{Deref, DerefMut};
44
use crate::dh::Dh;
55
use crate::error::ErrorStack;
66
use crate::ssl::{
7-
HandshakeError, Ssl, SslContext, SslContextBuilder, SslContextRef, SslMethod, SslMode,
8-
SslOptions, SslRef, SslStream, SslVerifyMode,
7+
Ssl, SslContext, SslContextBuilder, SslContextRef, SslMethod, SslMode, SslOptions, SslRef,
8+
SslVerifyMode,
99
};
1010
use crate::version;
1111
use std::net::IpAddr;
@@ -112,21 +112,6 @@ impl SslConnector {
112112
self.configure()?.setup_connect(domain, stream)
113113
}
114114

115-
/// Attempts a client-side TLS session on a stream.
116-
///
117-
/// The domain is used for SNI (if it is not an IP address) and hostname verification if enabled.
118-
///
119-
/// This is a convenience method which combines [`Self::setup_connect`] and
120-
/// [`MidHandshakeSslStream::handshake`].
121-
pub fn connect<S>(&self, domain: &str, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
122-
where
123-
S: Read + Write,
124-
{
125-
self.setup_connect(domain, stream)
126-
.map_err(HandshakeError::SetupFailure)?
127-
.handshake()
128-
}
129-
130115
/// Returns a structure allowing for configuration of a single TLS session before connection.
131116
pub fn configure(&self) -> Result<ConnectConfiguration, ErrorStack> {
132117
Ssl::new(&self.0).map(|ssl| ConnectConfiguration {
@@ -253,21 +238,6 @@ impl ConnectConfiguration {
253238
{
254239
Ok(self.into_ssl(domain)?.setup_connect(stream))
255240
}
256-
257-
/// Attempts a client-side TLS session on a stream.
258-
///
259-
/// The domain is used for SNI (if it is not an IP address) and hostname verification if enabled.
260-
///
261-
/// This is a convenience method which combines [`Self::setup_connect`] and
262-
/// [`MidHandshakeSslStream::handshake`].
263-
pub fn connect<S>(self, domain: &str, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
264-
where
265-
S: Read + Write,
266-
{
267-
self.setup_connect(domain, stream)
268-
.map_err(HandshakeError::SetupFailure)?
269-
.handshake()
270-
}
271241
}
272242

273243
impl Deref for ConnectConfiguration {
@@ -387,19 +357,6 @@ impl SslAcceptor {
387357
Ok(ssl.setup_accept(stream))
388358
}
389359

390-
/// Attempts a server-side TLS handshake on a stream.
391-
///
392-
/// This is a convenience method which combines [`Self::setup_accept`] and
393-
/// [`MidHandshakeSslStream::handshake`].
394-
pub fn accept<S>(&self, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
395-
where
396-
S: Read + Write,
397-
{
398-
self.setup_accept(stream)
399-
.map_err(HandshakeError::SetupFailure)?
400-
.handshake()
401-
}
402-
403360
/// Consumes the `SslAcceptor`, returning the inner raw `SslContext`.
404361
#[must_use]
405362
pub fn into_context(self) -> SslContext {

boring/src/ssl/error.rs

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
use crate::ffi;
2-
use crate::x509::X509VerifyError;
32
use libc::c_int;
43
use openssl_macros::corresponds;
54
use std::error;
6-
use std::error::Error as StdError;
75
use std::ffi::CStr;
86
use std::fmt;
97
use std::io;
108

119
use crate::error::ErrorStack;
12-
use crate::ssl::MidHandshakeSslStream;
1310

1411
/// `SSL_ERROR_*` error code returned from SSL functions.
1512
///
@@ -206,67 +203,3 @@ impl error::Error for Error {
206203
}
207204
}
208205
}
209-
210-
/// An error or intermediate state after a TLS handshake attempt.
211-
// FIXME overhaul
212-
#[derive(Debug)]
213-
pub enum HandshakeError<S> {
214-
/// Setup failed.
215-
SetupFailure(ErrorStack),
216-
/// The handshake failed.
217-
Failure(MidHandshakeSslStream<S>),
218-
/// The handshake encountered a `WouldBlock` error midway through.
219-
///
220-
/// This error will never be returned for blocking streams.
221-
WouldBlock(MidHandshakeSslStream<S>),
222-
}
223-
224-
impl<S: fmt::Debug> StdError for HandshakeError<S> {
225-
fn source(&self) -> Option<&(dyn StdError + 'static)> {
226-
match *self {
227-
HandshakeError::SetupFailure(ref e) => Some(e),
228-
HandshakeError::Failure(ref s) | HandshakeError::WouldBlock(ref s) => Some(s.error()),
229-
}
230-
}
231-
}
232-
233-
impl<S> fmt::Display for HandshakeError<S> {
234-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
235-
match *self {
236-
HandshakeError::SetupFailure(ref e) => {
237-
write!(f, "TLS stream setup failed {e}")
238-
}
239-
HandshakeError::Failure(ref s) => fmt_mid_handshake_error(s, f, "TLS handshake failed"),
240-
HandshakeError::WouldBlock(ref s) => {
241-
fmt_mid_handshake_error(s, f, "TLS handshake interrupted")
242-
}
243-
}
244-
}
245-
}
246-
247-
fn fmt_mid_handshake_error(
248-
s: &MidHandshakeSslStream<impl Sized>,
249-
f: &mut fmt::Formatter,
250-
prefix: &str,
251-
) -> fmt::Result {
252-
#[cfg(feature = "rpk")]
253-
if s.ssl().ssl_context().is_rpk() {
254-
write!(f, "{}", prefix)?;
255-
return write!(f, " {}", s.error());
256-
}
257-
258-
match s.ssl().verify_result() {
259-
// INVALID_CALL is returned if no verification took place,
260-
// such as before a cert is sent.
261-
Ok(()) | Err(X509VerifyError::INVALID_CALL) => write!(f, "{prefix}")?,
262-
Err(verify) => write!(f, "{prefix}: cert verification failed - {verify}")?,
263-
}
264-
265-
write!(f, " {}", s.error())
266-
}
267-
268-
impl<S> From<ErrorStack> for HandshakeError<S> {
269-
fn from(e: ErrorStack) -> HandshakeError<S> {
270-
HandshakeError::SetupFailure(e)
271-
}
272-
}

boring/src/ssl/mod.rs

Lines changed: 49 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515
//! let connector = SslConnector::builder(SslMethod::tls()).unwrap().build();
1616
//!
1717
//! let stream = TcpStream::connect("google.com:443").unwrap();
18-
//! let mut stream = connector.connect("google.com", stream).unwrap();
18+
//! let mut stream = connector
19+
//! .setup_connect("google.com", stream)
20+
//! .unwrap()
21+
//! .handshake()
22+
//! .unwrap();
1923
//!
2024
//! stream.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap();
2125
//! let mut res = vec![];
@@ -49,7 +53,12 @@
4953
//! Ok(stream) => {
5054
//! let acceptor = acceptor.clone();
5155
//! thread::spawn(move || {
52-
//! let stream = acceptor.accept(stream).unwrap();
56+
//! let stream = acceptor
57+
//! .setup_accept(stream)
58+
//! .unwrap()
59+
//! .handshake()
60+
//! .unwrap();
61+
//!
5362
//! handle_client(stream);
5463
//! });
5564
//! }
@@ -107,7 +116,7 @@ pub use self::connector::{
107116
ConnectConfiguration, SslAcceptor, SslAcceptorBuilder, SslConnector, SslConnectorBuilder,
108117
};
109118
pub use self::ech::{SslEchKeys, SslEchKeysRef};
110-
pub use self::error::{Error, ErrorCode, HandshakeError};
119+
pub use self::error::{Error, ErrorCode};
111120

112121
mod async_callbacks;
113122
mod bio;
@@ -2742,22 +2751,6 @@ impl Ssl {
27422751
SslStreamBuilder::new(self, stream).setup_connect()
27432752
}
27442753

2745-
/// Attempts a client-side TLS handshake.
2746-
///
2747-
/// This is a convenience method which combines [`Self::setup_connect`] and
2748-
/// [`MidHandshakeSslStream::handshake`].
2749-
///
2750-
/// # Warning
2751-
///
2752-
/// OpenSSL's default configuration is insecure. It is highly recommended to use
2753-
/// [`SslConnector`] rather than `Ssl` directly, as it manages that configuration.
2754-
pub fn connect<S>(self, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
2755-
where
2756-
S: Read + Write,
2757-
{
2758-
self.setup_connect(stream).handshake()
2759-
}
2760-
27612754
/// Initiates a server-side TLS handshake.
27622755
///
27632756
/// This method is guaranteed to return without calling any callback defined
@@ -2790,24 +2783,6 @@ impl Ssl {
27902783

27912784
SslStreamBuilder::new(self, stream).setup_accept()
27922785
}
2793-
2794-
/// Attempts a server-side TLS handshake.
2795-
///
2796-
/// This is a convenience method which combines [`Self::setup_accept`] and
2797-
/// [`MidHandshakeSslStream::handshake`].
2798-
///
2799-
/// # Warning
2800-
///
2801-
/// OpenSSL's default configuration is insecure. It is highly recommended to use
2802-
/// `SslAcceptor` rather than `Ssl` directly, as it manages that configuration.
2803-
///
2804-
/// [`SSL_accept`]: https://www.openssl.org/docs/manmaster/man3/SSL_accept.html
2805-
pub fn accept<S>(self, stream: S) -> Result<SslStream<S>, HandshakeError<S>>
2806-
where
2807-
S: Read + Write,
2808-
{
2809-
self.setup_accept(stream).handshake()
2810-
}
28112786
}
28122787

28132788
impl fmt::Debug for SslRef {
@@ -3903,18 +3878,43 @@ impl<S> MidHandshakeSslStream<S> {
39033878

39043879
/// Restarts the handshake process.
39053880
#[corresponds(SSL_do_handshake)]
3906-
pub fn handshake(mut self) -> Result<SslStream<S>, HandshakeError<S>> {
3881+
pub fn handshake(mut self) -> Result<SslStream<S>, Self> {
39073882
let ret = unsafe { ffi::SSL_do_handshake(self.stream.ssl.as_ptr()) };
39083883
if ret > 0 {
39093884
Ok(self.stream)
39103885
} else {
39113886
self.error = self.stream.make_error(ret);
3912-
Err(if self.error.would_block() {
3913-
HandshakeError::WouldBlock(self)
3914-
} else {
3915-
HandshakeError::Failure(self)
3916-
})
3887+
3888+
Err(self)
3889+
}
3890+
}
3891+
3892+
/// An `impl Display` suitable to represent the current error.
3893+
pub fn display_error<'a>(&'a self) -> impl fmt::Display + 'a {
3894+
struct Display<'a, S>(&'a MidHandshakeSslStream<S>);
3895+
3896+
impl<S> fmt::Display for Display<'_, S> {
3897+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
3898+
fmt.write_str("TLS handshake failed")?;
3899+
3900+
#[cfg(feature = "rpk")]
3901+
if self.0.ssl().ssl_context().is_rpk() {
3902+
return self.0.error().fmt(fmt);
3903+
}
3904+
3905+
match self.0.ssl().verify_result() {
3906+
// INVALID_CALL is returned if no verification took place,
3907+
// such as before a cert is sent.
3908+
Ok(()) | Err(X509VerifyError::INVALID_CALL) => {}
3909+
Err(verify) => write!(fmt, ": cert verification failed - {verify}")?,
3910+
}
3911+
3912+
fmt.write_str(" ")?;
3913+
self.0.error().fmt(fmt)
3914+
}
39173915
}
3916+
3917+
Display(self)
39183918
}
39193919
}
39203920

@@ -4249,22 +4249,20 @@ where
42494249

42504250
/// Configure as an outgoing stream from a client.
42514251
#[corresponds(SSL_set_connect_state)]
4252-
pub fn set_connect_state(&mut self) {
4252+
fn set_connect_state(&mut self) {
42534253
unsafe { ffi::SSL_set_connect_state(self.inner.ssl.as_ptr()) }
42544254
}
42554255

42564256
/// Configure as an incoming stream to a server.
42574257
#[corresponds(SSL_set_accept_state)]
4258-
pub fn set_accept_state(&mut self) {
4258+
fn set_accept_state(&mut self) {
42594259
unsafe { ffi::SSL_set_accept_state(self.inner.ssl.as_ptr()) }
42604260
}
42614261

42624262
/// Initiates a client-side TLS handshake, returning a [`MidHandshakeSslStream`].
42634263
///
4264-
/// This method calls [`Self::set_connect_state`] and returns without actually
4265-
/// initiating the handshake. The caller is then free to call
4266-
/// [`MidHandshakeSslStream`] and loop on [`HandshakeError::WouldBlock`].
4267-
#[must_use]
4264+
/// The caller is then free to call [`MidHandshakeSslStream::handshake`] and retry
4265+
/// on blocking errors.
42684266
pub fn setup_connect(mut self) -> MidHandshakeSslStream<S> {
42694267
self.set_connect_state();
42704268

@@ -4280,20 +4278,10 @@ where
42804278
}
42814279
}
42824280

4283-
/// Attempts a client-side TLS handshake.
4284-
///
4285-
/// This is a convenience method which combines [`Self::setup_connect`] and
4286-
/// [`MidHandshakeSslStream::handshake`].
4287-
pub fn connect(self) -> Result<SslStream<S>, HandshakeError<S>> {
4288-
self.setup_connect().handshake()
4289-
}
4290-
42914281
/// Initiates a server-side TLS handshake, returning a [`MidHandshakeSslStream`].
42924282
///
4293-
/// This method calls [`Self::set_accept_state`] and returns without actually
4294-
/// initiating the handshake. The caller is then free to call
4295-
/// [`MidHandshakeSslStream`] and loop on [`HandshakeError::WouldBlock`].
4296-
#[must_use]
4283+
/// The caller is then free to call [`MidHandshakeSslStream::handshake`] and retry
4284+
/// on blocking errors.
42974285
pub fn setup_accept(mut self) -> MidHandshakeSslStream<S> {
42984286
self.set_accept_state();
42994287

@@ -4308,33 +4296,6 @@ where
43084296
},
43094297
}
43104298
}
4311-
4312-
/// Attempts a server-side TLS handshake.
4313-
///
4314-
/// This is a convenience method which combines [`Self::setup_accept`] and
4315-
/// [`MidHandshakeSslStream::handshake`].
4316-
pub fn accept(self) -> Result<SslStream<S>, HandshakeError<S>> {
4317-
self.setup_accept().handshake()
4318-
}
4319-
4320-
/// Initiates the handshake.
4321-
///
4322-
/// This will fail if `set_accept_state` or `set_connect_state` was not called first.
4323-
#[corresponds(SSL_do_handshake)]
4324-
pub fn handshake(self) -> Result<SslStream<S>, HandshakeError<S>> {
4325-
let mut stream = self.inner;
4326-
let ret = unsafe { ffi::SSL_do_handshake(stream.ssl.as_ptr()) };
4327-
if ret > 0 {
4328-
Ok(stream)
4329-
} else {
4330-
let error = stream.make_error(ret);
4331-
Err(if error.would_block() {
4332-
HandshakeError::WouldBlock(MidHandshakeSslStream { stream, error })
4333-
} else {
4334-
HandshakeError::Failure(MidHandshakeSslStream { stream, error })
4335-
})
4336-
}
4337-
}
43384299
}
43394300

43404301
impl<S> SslStreamBuilder<S> {

0 commit comments

Comments
 (0)