aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2018-05-22 20:42:46 -0700
committerGitHub <[email protected]>2018-05-22 20:42:46 -0700
commitc7db3d18ad8eba06012891eeb1117361310c637a (patch)
tree4c12ed8417fd5ce6e788bcc82b5535cdd234af85 /openssl/src
parentFix changelog (diff)
parentExpose early I/O (diff)
downloadrust-openssl-c7db3d18ad8eba06012891eeb1117361310c637a.tar.xz
rust-openssl-c7db3d18ad8eba06012891eeb1117361310c637a.zip
Merge pull request #920 from Ralith/max-early-data-accessors
TLS1.3 early data support
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/ssl/mod.rs187
1 files changed, 186 insertions, 1 deletions
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index 08475888..444a50cc 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -1490,6 +1490,24 @@ impl SslContextBuilder {
}
}
+ /// Sets the maximum amount of early data that will be accepted on incoming connections.
+ ///
+ /// Defaults to 0.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_CTX_set_max_early_data`].
+ ///
+ /// [`SSL_CTX_set_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_max_early_data.html
+ #[cfg(ossl111)]
+ pub fn set_max_early_data(&mut self, bytes: u32) -> Result<(), ErrorStack> {
+ if unsafe { ffi::SSL_CTX_set_max_early_data(self.as_ptr(), bytes) } == 1 {
+ Ok(())
+ } else {
+ Err(ErrorStack::get())
+ }
+ }
+
/// Consumes the builder, returning a new `SslContext`.
pub fn build(self) -> SslContext {
self.0
@@ -1644,6 +1662,18 @@ impl SslContextRef {
}
}
}
+
+ /// Gets the maximum amount of early data that will be accepted on incoming connections.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_CTX_get_max_early_data`].
+ ///
+ /// [`SSL_CTX_get_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_get_max_early_data.html
+ #[cfg(ossl111)]
+ pub fn max_early_data(&self) -> u32 {
+ unsafe { ffi::SSL_CTX_get_max_early_data(self.as_ptr()) }
+ }
}
/// Information about the state of a cipher.
@@ -1874,6 +1904,18 @@ impl SslSessionRef {
unsafe { SSL_SESSION_get_master_key(self.as_ptr(), buf.as_mut_ptr(), buf.len()) }
}
+ /// Gets the maximum amount of early data that can be sent on this session.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_SESSION_get_max_early_data`].
+ ///
+ /// [`SSL_SESSION_get_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_SESSION_get_max_early_data.html
+ #[cfg(ossl111)]
+ pub fn max_early_data(&self) -> u32 {
+ unsafe { ffi::SSL_SESSION_get_max_early_data(self.as_ptr()) }
+ }
+
to_der! {
/// Serializes the session into a DER-encoded structure.
///
@@ -2457,6 +2499,36 @@ 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`].
+ ///
+ /// [`SSL_export_keying_material_early`]: https://www.openssl.org/docs/manmaster/man3/SSL_export_keying_material_early.html
+ #[cfg(ossl111)]
+ pub fn export_keying_material_early(
+ &self,
+ out: &mut [u8],
+ label: &str,
+ context: &[u8],
+ ) -> Result<(), ErrorStack> {
+ unsafe {
+ cvt(ffi::SSL_export_keying_material_early(
+ self.as_ptr(),
+ out.as_mut_ptr() as *mut c_uchar,
+ out.len(),
+ label.as_ptr() as *const c_char,
+ label.len(),
+ context.as_ptr() as *const c_uchar,
+ context.len(),
+ )).map(|_| ())
+ }
+ }
+
/// Sets the session to be used.
///
/// This should be called before the handshake to attempt to reuse a previously established
@@ -2595,6 +2667,34 @@ impl SslRef {
}
}
}
+
+ /// Sets the maximum amount of early data that will be accepted on this connection.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_set_max_early_data`].
+ ///
+ /// [`SSL_set_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_set_max_early_data.html
+ #[cfg(ossl111)]
+ pub fn set_max_early_data(&mut self, bytes: u32) -> Result<(), ErrorStack> {
+ if unsafe { ffi::SSL_set_max_early_data(self.as_ptr(), bytes) } == 1 {
+ Ok(())
+ } else {
+ Err(ErrorStack::get())
+ }
+ }
+
+ /// Gets the maximum amount of early data that can be sent on this connection.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_get_max_early_data`].
+ ///
+ /// [`SSL_get_max_early_data`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_get_max_early_data.html
+ #[cfg(ossl111)]
+ pub fn max_early_data(&self) -> u32 {
+ unsafe { ffi::SSL_get_max_early_data(self.as_ptr()) }
+ }
}
/// An SSL stream midway through the handshake process.
@@ -2907,6 +3007,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;
@@ -2947,7 +3065,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> {