aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/ssl/mod.rs
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2018-09-15 13:29:18 -0700
committerSteven Fackler <[email protected]>2018-09-15 13:29:18 -0700
commit22231d7547465eefc8a1bbb3ed439af24bb6970e (patch)
treef39cf232461c9cc708850c8df3d8300d595a53a0 /openssl/src/ssl/mod.rs
parentRelease openssl 0.10.12 (diff)
downloadrust-openssl-22231d7547465eefc8a1bbb3ed439af24bb6970e.tar.xz
rust-openssl-22231d7547465eefc8a1bbb3ed439af24bb6970e.zip
Support the client hello callback
Diffstat (limited to 'openssl/src/ssl/mod.rs')
-rw-r--r--openssl/src/ssl/mod.rs166
1 files changed, 166 insertions, 0 deletions
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index f3a02c6e..71fa1691 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -525,6 +525,22 @@ impl AlpnError {
pub const NOACK: AlpnError = AlpnError(ffi::SSL_TLSEXT_ERR_NOACK);
}
+/// The result of a client hello callback.
+///
+/// Requires OpenSSL 1.1.1 or newer.
+#[cfg(ossl111)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub struct ClientHelloResponse(c_int);
+
+#[cfg(ossl111)]
+impl ClientHelloResponse {
+ /// Continue the handshake.
+ pub const SUCCESS: ClientHelloResponse = ClientHelloResponse(ffi::SSL_CLIENT_HELLO_SUCCESS);
+
+ /// Return from the handshake with an `ErrorCode::WANT_CLIENT_HELLO_CB` error.
+ pub const RETRY: ClientHelloResponse = ClientHelloResponse(ffi::SSL_CLIENT_HELLO_RETRY);
+}
+
/// An SSL/TLS protocol version.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct SslVersion(c_int);
@@ -1600,6 +1616,31 @@ impl SslContextBuilder {
}
}
+ /// Sets a callback which will be invoked just after the client's hello message is received.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_CTX_set_client_hello_cb`].
+ ///
+ /// [`SSL_CTX_set_client_hello_cb`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html
+ #[cfg(ossl111)]
+ pub fn set_client_hello_callback<F>(&mut self, callback: F)
+ where
+ F: Fn(&mut SslRef, &mut SslAlert) -> Result<ClientHelloResponse, ErrorStack>
+ + 'static
+ + Sync
+ + Send,
+ {
+ unsafe {
+ let ptr = self.set_ex_data_inner(SslContext::cached_ex_index::<F>(), callback);
+ ffi::SSL_CTX_set_client_hello_cb(
+ self.as_ptr(),
+ Some(callbacks::raw_client_hello::<F>),
+ ptr,
+ );
+ }
+ }
+
/// Consumes the builder, returning a new `SslContext`.
pub fn build(self) -> SslContext {
self.0
@@ -2934,6 +2975,131 @@ impl SslRef {
ffi::SSL_get_peer_finished(self.as_ptr(), buf.as_mut_ptr() as *mut c_void, buf.len())
}
}
+
+ /// Determines if the client's hello message is in the SSLv2 format.
+ ///
+ /// This can only be used inside of the client hello callback. Otherwise, `false` is returned.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_client_hello_isv2`].
+ ///
+ /// [`SSL_client_hello_isv2`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html
+ #[cfg(ossl111)]
+ pub fn client_hello_isv2(&self) -> bool {
+ unsafe {
+ ffi::SSL_client_hello_isv2(self.as_ptr()) != 0
+ }
+ }
+
+ /// Returns the legacy version field of the client's hello message.
+ ///
+ /// This can only be used inside of the client hello callback. Otherwise, `None` is returned.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_client_hello_get0_legacy_version`].
+ ///
+ /// [`SSL_client_hello_get0_legacy_version`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html
+ #[cfg(ossl111)]
+ pub fn client_hello_legacy_version(&self) -> Option<SslVersion> {
+ unsafe {
+ let version = ffi::SSL_client_hello_get0_legacy_version(self.as_ptr());
+ if version == 0 {
+ None
+ } else {
+ Some(SslVersion(version as c_int))
+ }
+ }
+ }
+
+ /// Returns the random field of the client's hello message.
+ ///
+ /// This can only be used inside of the client hello callback. Otherwise, `None` is returend.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_client_hello_get0_random`].
+ ///
+ /// [`SSL_client_hello_get0_random`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html
+ #[cfg(ossl111)]
+ pub fn client_hello_random(&self) -> Option<&[u8]> {
+ unsafe {
+ let mut ptr = ptr::null();
+ let len = ffi::SSL_client_hello_get0_random(self.as_ptr(), &mut ptr);
+ if len == 0 {
+ None
+ } else {
+ Some(slice::from_raw_parts(ptr, len))
+ }
+ }
+ }
+
+ /// Returns the session ID field of the client's hello message.
+ ///
+ /// This can only be used inside of the client hello callback. Otherwise, `None` is returend.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_client_hello_get0_session_id`].
+ ///
+ /// [`SSL_client_hello_get0_session_id`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html
+ #[cfg(ossl111)]
+ pub fn client_hello_session_id(&self) -> Option<&[u8]> {
+ unsafe {
+ let mut ptr = ptr::null();
+ let len = ffi::SSL_client_hello_get0_session_id(self.as_ptr(), &mut ptr);
+ if len == 0 {
+ None
+ } else {
+ Some(slice::from_raw_parts(ptr, len))
+ }
+ }
+ }
+
+ /// Returns the ciphers field of the client's hello message.
+ ///
+ /// This can only be used inside of the client hello callback. Otherwise, `None` is returend.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_client_hello_get0_ciphers`].
+ ///
+ /// [`SSL_client_hello_get0_ciphers`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html
+ #[cfg(ossl111)]
+ pub fn client_hello_ciphers(&self) -> Option<&[u8]> {
+ unsafe {
+ let mut ptr = ptr::null();
+ let len = ffi::SSL_client_hello_get0_ciphers(self.as_ptr(), &mut ptr);
+ if len == 0 {
+ None
+ } else {
+ Some(slice::from_raw_parts(ptr, len))
+ }
+ }
+ }
+
+ /// Returns the compression methods field of the client's hello message.
+ ///
+ /// This can only be used inside of the client hello callback. Otherwise, `None` is returend.
+ ///
+ /// Requires OpenSSL 1.1.1 or newer.
+ ///
+ /// This corresponds to [`SSL_client_hello_get0_compression_methods`].
+ ///
+ /// [`SSL_client_hello_get0_compression_methods`]: https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_client_hello_cb.html
+ #[cfg(ossl111)]
+ pub fn client_hello_compression_methods(&self) -> Option<&[u8]> {
+ unsafe {
+ let mut ptr = ptr::null();
+ let len = ffi::SSL_client_hello_get0_compression_methods(self.as_ptr(), &mut ptr);
+ if len == 0 {
+ None
+ } else {
+ Some(slice::from_raw_parts(ptr, len))
+ }
+ }
+ }
}
/// An SSL stream midway through the handshake process.