Skip to content

Commit 5f74ec0

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 5f74ec0

16 files changed

Lines changed: 162 additions & 334 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: 21 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,17 +3878,14 @@ 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)
39173889
}
39183890
}
39193891
}
@@ -4249,22 +4221,20 @@ where
42494221

42504222
/// Configure as an outgoing stream from a client.
42514223
#[corresponds(SSL_set_connect_state)]
4252-
pub fn set_connect_state(&mut self) {
4224+
fn set_connect_state(&mut self) {
42534225
unsafe { ffi::SSL_set_connect_state(self.inner.ssl.as_ptr()) }
42544226
}
42554227

42564228
/// Configure as an incoming stream to a server.
42574229
#[corresponds(SSL_set_accept_state)]
4258-
pub fn set_accept_state(&mut self) {
4230+
fn set_accept_state(&mut self) {
42594231
unsafe { ffi::SSL_set_accept_state(self.inner.ssl.as_ptr()) }
42604232
}
42614233

42624234
/// Initiates a client-side TLS handshake, returning a [`MidHandshakeSslStream`].
42634235
///
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]
4236+
/// The caller is then free to call [`MidHandshakeSslStream::handshake`] and retry
4237+
/// on blocking errors.
42684238
pub fn setup_connect(mut self) -> MidHandshakeSslStream<S> {
42694239
self.set_connect_state();
42704240

@@ -4280,20 +4250,10 @@ where
42804250
}
42814251
}
42824252

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-
42914253
/// Initiates a server-side TLS handshake, returning a [`MidHandshakeSslStream`].
42924254
///
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]
4255+
/// The caller is then free to call [`MidHandshakeSslStream::handshake`] and retry
4256+
/// on blocking errors.
42974257
pub fn setup_accept(mut self) -> MidHandshakeSslStream<S> {
42984258
self.set_accept_state();
42994259

@@ -4308,33 +4268,6 @@ where
43084268
},
43094269
}
43104270
}
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-
}
43384271
}
43394272

43404273
impl<S> SslStreamBuilder<S> {

boring/src/ssl/test/custom_verify.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::server::Server;
2-
use crate::ssl::{ErrorCode, HandshakeError, SslAlert, SslVerifyMode};
2+
use crate::ssl::{ErrorCode, SslAlert, SslVerifyMode};
33
use crate::x509::X509StoreContext;
44
use crate::{hash::MessageDigest, ssl::SslVerifyError};
55
use hex;
@@ -9,11 +9,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
99
fn untrusted_callback_override_bad() {
1010
let mut server = Server::builder();
1111

12-
server.err_cb(|err| {
13-
let HandshakeError::Failure(handshake) = err else {
14-
panic!("expected failure error");
15-
};
16-
12+
server.err_cb(|handshake| {
1713
assert_eq!(
1814
handshake.error().to_string(),
1915
"[SSLV3_ALERT_CERTIFICATE_REVOKED]"
@@ -242,11 +238,7 @@ fn both_callback() {
242238
fn retry() {
243239
let mut server = Server::builder();
244240

245-
server.err_cb(|err| {
246-
let HandshakeError::Failure(handshake) = err else {
247-
panic!("expected failure error");
248-
};
249-
241+
server.err_cb(|handshake| {
250242
assert_eq!(
251243
handshake.error().to_string(),
252244
"[SSLV3_ALERT_CERTIFICATE_REVOKED]"
@@ -267,9 +259,7 @@ fn retry() {
267259
Err(SslVerifyError::Invalid(SslAlert::CERTIFICATE_REVOKED))
268260
});
269261

270-
let HandshakeError::WouldBlock(handshake) = client.connect_err() else {
271-
panic!("should be WouldBlock");
272-
};
262+
let handshake = client.connect_err();
273263

274264
assert!(CALLED_BACK.load(Ordering::SeqCst));
275265
assert!(handshake.error().would_block());

0 commit comments

Comments
 (0)