Loading openssl-sys/src/lib.rs +3 −0 Original line number Diff line number Diff line Loading @@ -2832,4 +2832,7 @@ extern "C" { pub fn EVP_MD_size(md: *const EVP_MD) -> c_int; pub fn EVP_get_cipherbyname(name: *const c_char) -> *const EVP_CIPHER; pub fn SSL_set_connect_state(s: *mut SSL); pub fn SSL_set_accept_state(s: *mut SSL); } openssl-sys/src/openssl/v111.rs +6 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,9 @@ pub const SSL_EXT_TLS1_3_CERTIFICATE: c_uint = 0x1000; pub const SSL_EXT_TLS1_3_NEW_SESSION_TICKET: c_uint = 0x2000; pub const SSL_EXT_TLS1_3_CERTIFICATE_REQUEST: c_uint = 0x4000; pub const SSL_READ_EARLY_DATA_ERROR: c_int = 0; pub const SSL_READ_EARLY_DATA_SUCCESS: c_int = 1; pub const SSL_READ_EARLY_DATA_FINISH: c_int = 2; extern "C" { pub fn SSL_CTX_set_keylog_callback(ctx: *mut ::SSL_CTX, cb: SSL_CTX_keylog_cb_func); Loading Loading @@ -99,4 +102,7 @@ extern "C" { context: *const c_uchar, contextlen: size_t, ) -> c_int; pub fn SSL_write_early_data(s: *mut ::SSL, buf: *const c_void, num: size_t, written: *mut size_t) -> c_int; pub fn SSL_read_early_data(s: *mut ::SSL, buf: *mut c_void, num: size_t, readbytes: *mut size_t) -> c_int; } openssl/src/ssl/mod.rs +89 −1 Original line number Diff line number Diff line Loading @@ -2500,6 +2500,9 @@ impl SslRef { /// Derives keying material for application use in accordance to RFC 5705. /// /// This function is only usable with TLSv1.3, wherein there is no distinction between an empty context and no /// context. Therefore, unlike `export_keying_material`, `context` must always be supplied. /// /// Requires OpenSSL 1.1.1 or newer. /// /// This corresponds to [`SSL_export_keying_material_early`]. Loading Loading @@ -3001,6 +3004,24 @@ where } } /// 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.inner.ssl.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.inner.ssl.as_ptr()) } } /// See `Ssl::connect` pub fn connect(self) -> Result<SslStream<S>, HandshakeError<S>> { let mut stream = self.inner; Loading Loading @@ -3041,7 +3062,74 @@ where } } // Future work: early IO methods /// 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 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() { ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => { Err(HandshakeError::WouldBlock(MidHandshakeSslStream { stream, error })) } _ => Err(HandshakeError::Failure(MidHandshakeSslStream { stream, error })), } } } /// Read application data transmitted by a client before handshake /// completion. /// /// Useful for reducing latency, but vulnerable to replay attacks. Call /// `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.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!(), } } /// Send data to the server without blocking on handshake completion. /// /// Useful for reducing latency, but vulnerable to replay attacks. Call /// `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.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)) } } } impl<S> SslStreamBuilder<S> { Loading Loading
openssl-sys/src/lib.rs +3 −0 Original line number Diff line number Diff line Loading @@ -2832,4 +2832,7 @@ extern "C" { pub fn EVP_MD_size(md: *const EVP_MD) -> c_int; pub fn EVP_get_cipherbyname(name: *const c_char) -> *const EVP_CIPHER; pub fn SSL_set_connect_state(s: *mut SSL); pub fn SSL_set_accept_state(s: *mut SSL); }
openssl-sys/src/openssl/v111.rs +6 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,9 @@ pub const SSL_EXT_TLS1_3_CERTIFICATE: c_uint = 0x1000; pub const SSL_EXT_TLS1_3_NEW_SESSION_TICKET: c_uint = 0x2000; pub const SSL_EXT_TLS1_3_CERTIFICATE_REQUEST: c_uint = 0x4000; pub const SSL_READ_EARLY_DATA_ERROR: c_int = 0; pub const SSL_READ_EARLY_DATA_SUCCESS: c_int = 1; pub const SSL_READ_EARLY_DATA_FINISH: c_int = 2; extern "C" { pub fn SSL_CTX_set_keylog_callback(ctx: *mut ::SSL_CTX, cb: SSL_CTX_keylog_cb_func); Loading Loading @@ -99,4 +102,7 @@ extern "C" { context: *const c_uchar, contextlen: size_t, ) -> c_int; pub fn SSL_write_early_data(s: *mut ::SSL, buf: *const c_void, num: size_t, written: *mut size_t) -> c_int; pub fn SSL_read_early_data(s: *mut ::SSL, buf: *mut c_void, num: size_t, readbytes: *mut size_t) -> c_int; }
openssl/src/ssl/mod.rs +89 −1 Original line number Diff line number Diff line Loading @@ -2500,6 +2500,9 @@ impl SslRef { /// Derives keying material for application use in accordance to RFC 5705. /// /// This function is only usable with TLSv1.3, wherein there is no distinction between an empty context and no /// context. Therefore, unlike `export_keying_material`, `context` must always be supplied. /// /// Requires OpenSSL 1.1.1 or newer. /// /// This corresponds to [`SSL_export_keying_material_early`]. Loading Loading @@ -3001,6 +3004,24 @@ where } } /// 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.inner.ssl.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.inner.ssl.as_ptr()) } } /// See `Ssl::connect` pub fn connect(self) -> Result<SslStream<S>, HandshakeError<S>> { let mut stream = self.inner; Loading Loading @@ -3041,7 +3062,74 @@ where } } // Future work: early IO methods /// 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 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() { ErrorCode::WANT_READ | ErrorCode::WANT_WRITE => { Err(HandshakeError::WouldBlock(MidHandshakeSslStream { stream, error })) } _ => Err(HandshakeError::Failure(MidHandshakeSslStream { stream, error })), } } } /// Read application data transmitted by a client before handshake /// completion. /// /// Useful for reducing latency, but vulnerable to replay attacks. Call /// `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.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!(), } } /// Send data to the server without blocking on handshake completion. /// /// Useful for reducing latency, but vulnerable to replay attacks. Call /// `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.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)) } } } impl<S> SslStreamBuilder<S> { Loading