From a3cdf8769a4b7ab147760a4005ec9400d522dfe4 Mon Sep 17 00:00:00 2001 From: Yuchen Wu Date: Mon, 14 Aug 2023 19:15:41 -0700 Subject: [PATCH] Add new(), connect(), accept() and handshake() to SslStream These APIs allow more SslStream to be used more flexibly --- boring/src/ssl/mod.rs | 68 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/boring/src/ssl/mod.rs b/boring/src/ssl/mod.rs index 6fe8615b..00aa82a0 100644 --- a/boring/src/ssl/mod.rs +++ b/boring/src/ssl/mod.rs @@ -2320,6 +2320,23 @@ impl Ssl { } } + /// Creates a new `Ssl`. + /// + /// This corresponds to [`SSL_new`]. + /// This function does the same as [`Self:new()`] except that it takes &[SslContextRef]. + // Both functions exist for backward compatibility (no breaking API). + pub fn new_from_ref(ctx: &SslContextRef) -> Result { + unsafe { + let ptr = cvt_p(ffi::SSL_new(ctx.as_ptr()))?; + let mut ssl = Ssl::from_ptr(ptr); + SSL_CTX_up_ref(ctx.as_ptr()); + let ctx_owned = SslContext::from_ptr(ctx.as_ptr()); + ssl.set_ex_data(*SESSION_CTX_INDEX, ctx_owned); + + Ok(ssl) + } + } + /// Initiates a client-side TLS handshake. /// /// This corresponds to [`SSL_connect`]. @@ -3278,6 +3295,15 @@ impl SslStream { } } + /// Creates a new `SslStream`. + /// + /// This function performs no IO; the stream will not have performed any part of the handshake + /// with the peer. The `connect` and `accept` methods can be used to + /// explicitly perform the handshake. + pub fn new(ssl: Ssl, stream: S) -> Result { + Ok(Self::new_base(ssl, stream)) + } + /// Constructs an `SslStream` from a pointer to the underlying OpenSSL `SSL` struct. /// /// This is useful if the handshake has already been completed elsewhere. @@ -3382,6 +3408,48 @@ impl SslStream { pub fn set_shutdown(&mut self, state: ShutdownState) { unsafe { ffi::SSL_set_shutdown(self.ssl.as_ptr(), state.bits()) } } + + /// Initiates a client-side TLS handshake. + /// + /// This corresponds to [`SSL_connect`]. + /// + /// [`SSL_connect`]: https://www.openssl.org/docs/man1.1.1/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`]. + /// + /// [`SSL_accept`]: https://www.openssl.org/docs/man1.1.1/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 corresponds to [`SSL_do_handshake`]. + /// + /// [`SSL_do_handshake`]: https://www.openssl.org/docs/man1.1.1/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)) + } + } } impl SslStream {