diff options
author | Steven Fackler <sfackler@gmail.com> | 2020-12-24 07:58:17 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-24 07:58:17 -0500 |
commit | 09dd721f05cf179bc9a337e953494f07035ec224 (patch) | |
tree | c19fcab9c359c2e955afc9f83df1ecba1f2bd19a | |
parent | bc657d1c4e01d27246bda15c8bb5ce738c7e27ab (diff) | |
parent | 625205de6fd3169101ce36468d9471b6cb686f75 (diff) | |
download | rust-openssl-09dd721f05cf179bc9a337e953494f07035ec224.zip |
Merge pull request #1397 from sfackler/always-unpin
Allow construction of unconnected SslStreams.
-rw-r--r-- | openssl/src/ssl/bio.rs | 32 | ||||
-rw-r--r-- | openssl/src/ssl/connector.rs | 19 | ||||
-rw-r--r-- | openssl/src/ssl/mod.rs | 318 | ||||
-rw-r--r-- | openssl/src/ssl/test/mod.rs | 27 |
4 files changed, 273 insertions, 123 deletions
diff --git a/openssl/src/ssl/bio.rs b/openssl/src/ssl/bio.rs index 2277d043..9edaed7b 100644 --- a/openssl/src/ssl/bio.rs +++ b/openssl/src/ssl/bio.rs @@ -24,8 +24,8 @@ pub struct StreamState<S> { pub struct BioMethod(BIO_METHOD); impl BioMethod { - fn new<S: Read + Write>() -> BioMethod { - BioMethod(BIO_METHOD::new::<S>()) + fn new<S: Read + Write>() -> Result<BioMethod, ErrorStack> { + BIO_METHOD::new::<S>().map(BioMethod) } } @@ -33,7 +33,7 @@ unsafe impl Sync for BioMethod {} unsafe impl Send for BioMethod {} pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, BioMethod), ErrorStack> { - let method = BioMethod::new::<S>(); + let method = BioMethod::new::<S>()?; let state = Box::new(StreamState { stream, @@ -191,6 +191,7 @@ unsafe extern "C" fn destroy<S>(bio: *mut BIO) -> c_int { cfg_if! { if #[cfg(any(ossl110, libressl273))] { use ffi::{BIO_get_data, BIO_set_data, BIO_set_flags, BIO_set_init}; + use cvt; #[allow(bad_style)] unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {} @@ -199,18 +200,17 @@ cfg_if! { struct BIO_METHOD(*mut ffi::BIO_METHOD); impl BIO_METHOD { - fn new<S: Read + Write>() -> BIO_METHOD { + fn new<S: Read + Write>() -> Result<BIO_METHOD, ErrorStack> { unsafe { - let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, b"rust\0".as_ptr() as *const _); - assert!(!ptr.is_null()); - let ret = BIO_METHOD(ptr); - assert!(ffi::BIO_meth_set_write(ptr, bwrite::<S>) != 0); - assert!(ffi::BIO_meth_set_read(ptr, bread::<S>) != 0); - assert!(ffi::BIO_meth_set_puts(ptr, bputs::<S>) != 0); - assert!(ffi::BIO_meth_set_ctrl(ptr, ctrl::<S>) != 0); - assert!(ffi::BIO_meth_set_create(ptr, create) != 0); - assert!(ffi::BIO_meth_set_destroy(ptr, destroy::<S>) != 0); - ret + let ptr = cvt_p(ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, b"rust\0".as_ptr() as *const _))?; + let method = BIO_METHOD(ptr); + cvt(ffi::BIO_meth_set_write(method.0, bwrite::<S>))?; + cvt(ffi::BIO_meth_set_read(method.0, bread::<S>))?; + cvt(ffi::BIO_meth_set_puts(method.0, bputs::<S>))?; + cvt(ffi::BIO_meth_set_ctrl(method.0, ctrl::<S>))?; + cvt(ffi::BIO_meth_set_create(method.0, create))?; + cvt(ffi::BIO_meth_set_destroy(method.0, destroy::<S>))?; + Ok(method) } } @@ -231,7 +231,7 @@ cfg_if! { struct BIO_METHOD(*mut ffi::BIO_METHOD); impl BIO_METHOD { - fn new<S: Read + Write>() -> BIO_METHOD { + fn new<S: Read + Write>() -> Result<BIO_METHOD, ErrorStack> { let ptr = Box::new(ffi::BIO_METHOD { type_: ffi::BIO_TYPE_NONE, name: b"rust\0".as_ptr() as *const _, @@ -245,7 +245,7 @@ cfg_if! { callback_ctrl: None, }); - BIO_METHOD(Box::into_raw(ptr)) + Ok(BIO_METHOD(Box::into_raw(ptr))) } fn get(&self) -> *mut ffi::BIO_METHOD { diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs index bc0bac92..644a0488 100644 --- a/openssl/src/ssl/connector.rs +++ b/openssl/src/ssl/connector.rs @@ -168,13 +168,10 @@ impl ConnectConfiguration { self.verify_hostname = verify_hostname; } - /// Initiates a client-side TLS session on a stream. + /// Returns an `Ssl` configured to connect to the provided domain. /// /// The domain is used for SNI and hostname verification if enabled. - pub fn connect<S>(mut self, domain: &str, stream: S) -> Result<SslStream<S>, HandshakeError<S>> - where - S: Read + Write, - { + pub fn into_ssl(mut self, domain: &str) -> Result<Ssl, ErrorStack> { if self.sni { self.ssl.set_hostname(domain)?; } @@ -183,7 +180,17 @@ impl ConnectConfiguration { setup_verify_hostname(&mut self.ssl, domain)?; } - self.ssl.connect(stream) + Ok(self.ssl) + } + + /// Initiates a client-side TLS session on a stream. + /// + /// The domain is used for SNI and hostname verification if enabled. + pub fn connect<S>(self, domain: &str, stream: S) -> Result<SslStream<S>, HandshakeError<S>> + where + S: Read + Write, + { + self.into_ssl(domain)?.connect(stream) } } diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index fc507c50..f60b1ee1 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -1823,6 +1823,14 @@ foreign_type_and_impl_send_sync! { impl Clone for SslContext { fn clone(&self) -> Self { + (**self).to_owned() + } +} + +impl ToOwned for SslContextRef { + type Owned = SslContext; + + fn to_owned(&self) -> Self::Owned { unsafe { SSL_CTX_up_ref(self.as_ptr()); SslContext::from_ptr(self.as_ptr()) @@ -2381,11 +2389,11 @@ impl Ssl { /// /// [`SSL_new`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_new.html // FIXME should take &SslContextRef - pub fn new(ctx: &SslContext) -> Result<Ssl, ErrorStack> { + pub fn new(ctx: &SslContextRef) -> Result<Ssl, ErrorStack> { unsafe { let ptr = cvt_p(ffi::SSL_new(ctx.as_ptr()))?; let mut ssl = Ssl::from_ptr(ptr); - ssl.set_ex_data(*SESSION_CTX_INDEX, ctx.clone()); + ssl.set_ex_data(*SESSION_CTX_INDEX, ctx.to_owned()); Ok(ssl) } @@ -2401,6 +2409,7 @@ impl Ssl { /// `SslConnector` rather than `Ssl` directly, as it manages that configuration. /// /// [`SSL_connect`]: https://www.openssl.org/docs/manmaster/man3/SSL_connect.html + #[allow(deprecated)] pub fn connect<S>(self, stream: S) -> Result<SslStream<S>, HandshakeError<S>> where S: Read + Write, @@ -2418,6 +2427,7 @@ impl Ssl { /// `SslAcceptor` rather than `Ssl` directly, as it manages that configuration. /// /// [`SSL_accept`]: https://www.openssl.org/docs/manmaster/man3/SSL_accept.html + #[allow(deprecated)] pub fn accept<S>(self, stream: S) -> Result<SslStream<S>, HandshakeError<S>> where S: Read + Write, @@ -2454,6 +2464,24 @@ impl SslRef { unsafe { ErrorCode::from_raw(ffi::SSL_get_error(self.as_ptr(), ret)) } } + /// Configure as an outgoing stream from a client. + /// + /// This corresponds to [`SSL_set_connect_state`]. + /// + /// [`SSL_set_connect_state`]: https://www.openssl.org/docs/manmaster/man3/SSL_set_connect_state.html + pub fn set_connect_state(&mut self) { + unsafe { ffi::SSL_set_connect_state(self.as_ptr()) } + } + + /// Configure as an incoming stream to a server. + /// + /// This corresponds to [`SSL_set_accept_state`]. + /// + /// [`SSL_set_accept_state`]: https://www.openssl.org/docs/manmaster/man3/SSL_set_accept_state.html + pub fn set_accept_state(&mut self) { + unsafe { ffi::SSL_set_accept_state(self.as_ptr()) } + } + /// Like [`SslContextBuilder::set_verify`]. /// /// This corresponds to [`SSL_set_verify`]. @@ -3389,23 +3417,28 @@ impl<S> MidHandshakeSslStream<S> { pub fn into_error(self) -> Error { self.error } +} +impl<S> MidHandshakeSslStream<S> +where + S: Read + Write, +{ /// Restarts the handshake process. /// /// This corresponds to [`SSL_do_handshake`]. /// /// [`SSL_do_handshake`]: https://www.openssl.org/docs/manmaster/man3/SSL_do_handshake.html pub fn handshake(mut self) -> Result<SslStream<S>, HandshakeError<S>> { - let ret = unsafe { ffi::SSL_do_handshake(self.stream.ssl.as_ptr()) }; - if ret > 0 { - Ok(self.stream) - } else { - self.error = self.stream.make_error(ret); - match self.error.code() { - ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => { - Err(HandshakeError::WouldBlock(self)) + match self.stream.do_handshake() { + Ok(()) => Ok(self.stream), + Err(error) => { + self.error = error; + match self.error.code() { + ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => { + Err(HandshakeError::WouldBlock(self)) + } + _ => Err(HandshakeError::Failure(self)), } - _ => Err(HandshakeError::Failure(self)), } } } @@ -3441,17 +3474,28 @@ where } impl<S: Read + Write> SslStream<S> { - fn new_base(ssl: Ssl, stream: S) -> Self { + /// Creates a new `SslStream`. + /// + /// This function performs no IO; the stream will not have performed any part of the handshake + /// with the peer. If the `Ssl` was configured with [`SslRef::set_client_state`] or + /// [`SslRef::set_server_state`], the handshake can be performed automatically during the first + /// call to read or write. Otherwise the `connect` and `accept` methods can be used to + /// explicitly perform the handshake. + /// + /// This corresponds to [`SSL_set_bio`]. + /// + /// [`SSL_set_bio`]: https://www.openssl.org/docs/manmaster/man3/SSL_set_bio.html + pub fn new(ssl: Ssl, stream: S) -> Result<Self, ErrorStack> { + let (bio, method) = bio::new(stream)?; unsafe { - let (bio, method) = bio::new(stream).unwrap(); ffi::SSL_set_bio(ssl.as_ptr(), bio, bio); - - SslStream { - ssl: ManuallyDrop::new(ssl), - method: ManuallyDrop::new(method), - _p: PhantomData, - } } + + Ok(SslStream { + ssl: ManuallyDrop::new(ssl), + method: ManuallyDrop::new(method), + _p: PhantomData, + }) } /// Constructs an `SslStream` from a pointer to the underlying OpenSSL `SSL` struct. @@ -3461,9 +3505,150 @@ impl<S: Read + Write> SslStream<S> { /// # Safety /// /// The caller must ensure the pointer is valid. + #[deprecated( + since = "0.10.32", + note = "use Ssl::from_ptr and SslStream::new instead" + )] pub unsafe fn from_raw_parts(ssl: *mut ffi::SSL, stream: S) -> Self { let ssl = Ssl::from_ptr(ssl); - Self::new_base(ssl, stream) + Self::new(ssl, stream).unwrap() + } + + /// Read application data transmitted by a client before handshake completion. + /// + /// Useful for reducing latency, but vulnerable to replay attacks. Call + /// [`SslRef::set_accept_state`] first. + /// + /// Returns `Ok(0)` if all early data has been read. + /// + /// Requires OpenSSL 1.1.1 or newer. + /// + /// This corresponds to [`SSL_read_early_data`]. + /// + /// [`SSL_read_early_data`]: https://www.openssl.org/docs/manmaster/man3/SSL_read_early_data.html + #[cfg(ossl111)] + pub fn read_early_data(&mut self, buf: &mut [u8]) -> Result<usize, Error> { + let mut read = 0; + let ret = unsafe { + ffi::SSL_read_early_data( + self.ssl.as_ptr(), + buf.as_ptr() as *mut c_void, + buf.len(), + &mut read, + ) + }; + match ret { + ffi::SSL_READ_EARLY_DATA_ERROR => Err(self.make_error(ret)), + ffi::SSL_READ_EARLY_DATA_SUCCESS => Ok(read), + ffi::SSL_READ_EARLY_DATA_FINISH => Ok(0), + _ => unreachable!(), + } + } + + /// Send data to the server without blocking on handshake completion. + /// + /// Useful for reducing latency, but vulnerable to replay attacks. Call + /// [`SslRef::set_connect_state`] first. + /// + /// Requires OpenSSL 1.1.1 or newer. + /// + /// This corresponds to [`SSL_write_early_data`]. + /// + /// [`SSL_write_early_data`]: https://www.openssl.org/docs/manmaster/man3/SSL_write_early_data.html + #[cfg(ossl111)] + pub fn write_early_data(&mut self, buf: &[u8]) -> Result<usize, Error> { + let mut written = 0; + let ret = unsafe { + ffi::SSL_write_early_data( + self.ssl.as_ptr(), + buf.as_ptr() as *const c_void, + buf.len(), + &mut written, + ) + }; + if ret > 0 { + Ok(written as usize) + } else { + Err(self.make_error(ret)) + } + } + + /// Initiates a client-side TLS handshake. + /// + /// This corresponds to [`SSL_connect`]. + /// + /// # Warning + /// + /// OpenSSL's default configuration is insecure. It is highly recommended to use + /// `SslConnector` rather than `Ssl` directly, as it manages that configuration. + /// + /// [`SSL_connect`]: https://www.openssl.org/docs/manmaster/man3/SSL_connect.html + pub fn connect(&mut self) -> Result<(), Error> { + let ret = unsafe { ffi::SSL_connect(self.ssl.as_ptr()) }; + if ret > 0 { + Ok(()) + } else { + Err(self.make_error(ret)) + } + } + + /// Initiates a server-side TLS handshake. + /// + /// This corresponds to [`SSL_accept`]. + /// + /// # Warning + /// + /// OpenSSL's default configuration is insecure. It is highly recommended to use + /// `SslAcceptor` rather than `Ssl` directly, as it manages that configuration. + /// + /// [`SSL_accept`]: https://www.openssl.org/docs/manmaster/man3/SSL_accept.html + pub fn accept(&mut self) -> Result<(), Error> { + let ret = unsafe { ffi::SSL_accept(self.ssl.as_ptr()) }; + if ret > 0 { + Ok(()) + } else { + Err(self.make_error(ret)) + } + } + + /// Initiates the handshake. + /// + /// This will fail if `set_accept_state` or `set_connect_state` was not called first. + /// + /// This corresponds to [`SSL_do_handshake`]. + /// + /// [`SSL_do_handshake`]: https://www.openssl.org/docs/manmaster/man3/SSL_do_handshake.html + pub fn do_handshake(&mut self) -> Result<(), Error> { + let ret = unsafe { ffi::SSL_do_handshake(self.ssl.as_ptr()) }; + if ret > 0 { + Ok(()) + } else { + Err(self.make_error(ret)) + } + } + + /// Perform a stateless server-side handshake. + /// + /// Requires that cookie generation and verification callbacks were + /// set on the SSL context. + /// + /// Returns `Ok(true)` if a complete ClientHello containing a valid cookie + /// was read, in which case the handshake should be continued via + /// `accept`. If a HelloRetryRequest containing a fresh cookie was + /// transmitted, `Ok(false)` is returned instead. If the handshake cannot + /// proceed at all, `Err` is returned. + /// + /// This corresponds to [`SSL_stateless`] + /// + /// [`SSL_stateless`]: https://www.openssl.org/docs/manmaster/man3/SSL_stateless.html + #[cfg(ossl111)] + pub fn stateless(&mut self) -> Result<bool, ErrorStack> { + match unsafe { ffi::SSL_stateless(self.ssl.as_ptr()) } { + 1 => Ok(true), + 0 => Ok(false), + -1 => Err(ErrorStack::get()), + _ => unreachable!(), + } } /// Like `read`, but returns an `ssl::Error` rather than an `io::Error`. @@ -3664,10 +3849,15 @@ impl<S: Read + Write> Write for SslStream<S> { } /// A partially constructed `SslStream`, useful for unusual handshakes. +#[deprecated( + since = "0.10.32", + note = "use the methods directly on Ssl/SslStream instead" +)] pub struct SslStreamBuilder<S> { inner: SslStream<S>, } +#[allow(deprecated)] impl<S> SslStreamBuilder<S> where S: Read + Write, @@ -3675,7 +3865,7 @@ where /// Begin creating an `SslStream` atop `stream` pub fn new(ssl: Ssl, stream: S) -> Self { Self { - inner: SslStream::new_base(ssl, stream), + inner: SslStream::new(ssl, stream).unwrap(), } } @@ -3722,48 +3912,40 @@ where } /// See `Ssl::connect` - pub fn connect(self) -> Result<SslStream<S>, HandshakeError<S>> { - let mut stream = self.inner; - let ret = unsafe { ffi::SSL_connect(stream.ssl.as_ptr()) }; - if ret > 0 { - Ok(stream) - } else { - let error = stream.make_error(ret); - match error.code() { + pub fn connect(mut self) -> Result<SslStream<S>, HandshakeError<S>> { + match self.inner.connect() { + Ok(()) => Ok(self.inner), + Err(error) => match error.code() { ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => { Err(HandshakeError::WouldBlock(MidHandshakeSslStream { - stream, + stream: self.inner, error, })) } _ => Err(HandshakeError::Failure(MidHandshakeSslStream { - stream, + stream: self.inner, error, })), - } + }, } } /// See `Ssl::accept` - pub fn accept(self) -> Result<SslStream<S>, HandshakeError<S>> { - let mut stream = self.inner; - let ret = unsafe { ffi::SSL_accept(stream.ssl.as_ptr()) }; - if ret > 0 { - Ok(stream) - } else { - let error = stream.make_error(ret); - match error.code() { + pub fn accept(mut self) -> Result<SslStream<S>, HandshakeError<S>> { + match self.inner.accept() { + Ok(()) => Ok(self.inner), + Err(error) => match error.code() { ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => { Err(HandshakeError::WouldBlock(MidHandshakeSslStream { - stream, + stream: self.inner, error, })) } _ => Err(HandshakeError::Failure(MidHandshakeSslStream { - stream, + stream: self.inner, error, })), - } + }, } } @@ -3774,25 +3956,21 @@ where /// This corresponds to [`SSL_do_handshake`]. /// /// [`SSL_do_handshake`]: https://www.openssl.org/docs/manmaster/man3/SSL_do_handshake.html - pub fn handshake(self) -> Result<SslStream<S>, HandshakeError<S>> { - let mut stream = self.inner; - let ret = unsafe { ffi::SSL_do_handshake(stream.ssl.as_ptr()) }; - if ret > 0 { - Ok(stream) - } else { - let error = stream.make_error(ret); - match error.code() { + pub fn handshake(mut self) -> Result<SslStream<S>, HandshakeError<S>> { + match self.inner.do_handshake() { + Ok(()) => Ok(self.inner), + Err(error) => match error.code() { ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => { Err(HandshakeError::WouldBlock(MidHandshakeSslStream { - stream, + stream: self.inner, error, })) } _ => Err(HandshakeError::Failure(MidHandshakeSslStream { - stream, + stream: self.inner, error, })), - } + }, } } @@ -3811,21 +3989,7 @@ where /// [`SSL_read_early_data`]: https://www.openssl.org/docs/manmaster/man3/SSL_read_early_data.html #[cfg(ossl111)] pub fn read_early_data(&mut self, buf: &mut [u8]) -> Result<usize, Error> { - let mut read = 0; - let ret = unsafe { - ffi::SSL_read_early_data( - self.inner.ssl.as_ptr(), - buf.as_ptr() as *mut c_void, - buf.len(), - &mut read, - ) - }; - match ret { - ffi::SSL_READ_EARLY_DATA_ERROR => Err(self.inner.make_error(ret)), - ffi::SSL_READ_EARLY_DATA_SUCCESS => Ok(read), - ffi::SSL_READ_EARLY_DATA_FINISH => Ok(0), - _ => unreachable!(), - } + self.inner.read_early_data(buf) } /// Send data to the server without blocking on handshake completion. @@ -3840,23 +4004,11 @@ where /// [`SSL_write_early_data`]: https://www.openssl.org/docs/manmaster/man3/SSL_write_early_data.html #[cfg(ossl111)] pub fn write_early_data(&mut self, buf: &[u8]) -> Result<usize, Error> { - let mut written = 0; - let ret = unsafe { - ffi::SSL_write_early_data( - self.inner.ssl.as_ptr(), - buf.as_ptr() as *const c_void, - buf.len(), - &mut written, - ) - }; - if ret > 0 { - Ok(written as usize) - } else { - Err(self.inner.make_error(ret)) - } + self.inner.write_early_data(buf) } } +#[allow(deprecated)] impl<S> SslStreamBuilder<S> { /// Returns a shared reference to the underlying stream. pub fn get_ref(&self) -> &S { diff --git a/openssl/src/ssl/test/mod.rs b/openssl/src/ssl/test/mod.rs index 37a23800..e886f7e1 100644 --- a/openssl/src/ssl/test/mod.rs +++ b/openssl/src/ssl/test/mod.rs @@ -31,7 +31,7 @@ use ssl::{ClientHelloResponse, ExtensionContext}; use ssl::{ Error, HandshakeError, MidHandshakeSslStream, ShutdownResult, ShutdownState, Ssl, SslAcceptor, SslAcceptorBuilder, SslConnector, SslContext, SslContextBuilder, SslFiletype, SslMethod, - SslOptions, SslSessionCacheMode, SslStream, SslStreamBuilder, SslVerifyMode, StatusType, + SslOptions, SslSessionCacheMode, SslStream, SslVerifyMode, StatusType, }; #[cfg(ossl102)] use x509::store::X509StoreBuilder; @@ -1253,23 +1253,14 @@ fn stateless() { to.extend_incoming(&from.take_outgoing()); } - fn hs<S: ::std::fmt::Debug>( - stream: Result<SslStream<S>, HandshakeError<S>>, - ) -> Result<SslStream<S>, MidHandshakeSslStream<S>> { - match stream { - Ok(stream) => Ok(stream), - Err(HandshakeError::WouldBlock(stream)) => Err(stream), - Err(e) => panic!("unexpected error: {:?}", e), - } - } - // // Setup // let mut client_ctx = SslContext::builder(SslMethod::tls()).unwrap(); client_ctx.clear_options(SslOptions::ENABLE_MIDDLEBOX_COMPAT); - let client_stream = Ssl::new(&client_ctx.build()).unwrap(); + let mut client_stream = + SslStream::new(Ssl::new(&client_ctx.build()).unwrap(), MemoryStream::new()).unwrap(); let mut server_ctx = SslContext::builder(SslMethod::tls()).unwrap(); server_ctx @@ -1285,29 +1276,29 @@ fn stateless() { }); server_ctx.set_stateless_cookie_verify_cb(|_tls, buf| buf == COOKIE); let mut server_stream = - ssl::SslStreamBuilder::new(Ssl::new(&server_ctx.build()).unwrap(), MemoryStream::new()); + SslStream::new(Ssl::new(&server_ctx.build()).unwrap(), MemoryStream::new()).unwrap(); // // Handshake // // Initial ClientHello - let mut client_stream = hs(client_stream.connect(MemoryStream::new())).unwrap_err(); + client_stream.connect().unwrap_err(); send(client_stream.get_mut(), server_stream.get_mut()); // HelloRetryRequest assert!(!server_stream.stateless().unwrap()); send(server_stream.get_mut(), client_stream.get_mut()); // Second ClientHello - let mut client_stream = hs(client_stream.handshake()).unwrap_err(); + client_stream.do_handshake().unwrap_err(); send(client_stream.get_mut(), server_stream.get_mut()); // OldServerHello assert!(server_stream.stateless().unwrap()); - let mut server_stream = hs(server_stream.accept()).unwrap_err(); + server_stream.accept().unwrap_err(); send(server_stream.get_mut(), client_stream.get_mut()); // Finished - let mut client_stream = hs(client_stream.handshake()).unwrap(); + client_stream.do_handshake().unwrap(); send(client_stream.get_mut(), server_stream.get_mut()); - hs(server_stream.handshake()).unwrap(); + server_stream.do_handshake().unwrap(); } #[cfg(not(osslconf = "OPENSSL_NO_PSK"))] |