diff --git a/openssl-sys/src/ssl.rs b/openssl-sys/src/ssl.rs index 52ea5b2135..d0f760e64b 100644 --- a/openssl-sys/src/ssl.rs +++ b/openssl-sys/src/ssl.rs @@ -241,10 +241,28 @@ pub const SSL_MODE_SEND_CLIENTHELLO_TIME: c_long = 0x20; pub const SSL_MODE_SEND_SERVERHELLO_TIME: c_long = 0x40; #[cfg(ossl101)] pub const SSL_MODE_SEND_FALLBACK_SCSV: c_long = 0x80; +#[cfg(ossl110)] +pub const SSL_MODE_ASYNC: c_long = 0x100; pub unsafe fn SSL_CTX_set_mode(ctx: *mut SSL_CTX, op: c_long) -> c_long { SSL_CTX_ctrl(ctx, SSL_CTRL_MODE, op, ptr::null_mut()) } +pub unsafe fn SSL_CTX_clear_mode(ctx: *mut SSL_CTX, op: c_long) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_CLEAR_MODE, op, ptr::null_mut()) +} +pub unsafe fn SSL_CTX_get_mode(ctx: *mut SSL_CTX) -> c_long { + SSL_CTX_ctrl(ctx, SSL_CTRL_MODE, 0, ptr::null_mut()) +} + +pub unsafe fn SSL_set_mode(ssl: *mut SSL, op: c_long) -> c_long { + SSL_ctrl(ssl, SSL_CTRL_MODE, op, ptr::null_mut()) +} +pub unsafe fn SSL_clear_mode(ssl: *mut SSL, op: c_long) -> c_long { + SSL_ctrl(ssl, SSL_CTRL_CLEAR_MODE, op, ptr::null_mut()) +} +pub unsafe fn SSL_get_mode(ssl: *mut SSL) -> c_long { + SSL_ctrl(ssl, SSL_CTRL_MODE, 0, ptr::null_mut()) +} #[cfg(ossl111)] pub const SSL_COOKIE_LENGTH: c_int = 4096; @@ -338,6 +356,7 @@ pub const SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP: c_int = 70; pub const SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: c_int = 71; #[cfg(any(libressl, all(ossl101, not(ossl110))))] pub const SSL_CTRL_CLEAR_OPTIONS: c_int = 77; +pub const SSL_CTRL_CLEAR_MODE: c_int = 78; pub const SSL_CTRL_GET_EXTRA_CHAIN_CERTS: c_int = 82; #[cfg(ossl102)] pub const SSL_CTRL_CHAIN_CERT: c_int = 89; diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index fe1e38649f..4a97063963 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -332,6 +332,15 @@ bitflags! { /// Do not use this unless you know what you're doing! #[cfg(not(libressl))] const SEND_FALLBACK_SCSV = ffi::SSL_MODE_SEND_FALLBACK_SCSV; + + /// Enable asynchronous processing. + /// + /// TLS I/O operations may indicate a retry with SSL_ERROR_WANT_ASYNC with this mode set + /// if an asynchronous capable engine is used to perform cryptographic operations. + /// + /// Do not use this unless you know what you're doing! + #[cfg(ossl110)] + const ASYNC = ffi::SSL_MODE_ASYNC; } } @@ -675,11 +684,13 @@ cfg_if! { type SslCacheTy = i64; type SslCacheSize = libc::c_ulong; type MtuTy = u32; + type ModeTy = u32; type SizeTy = usize; } else { type SslCacheTy = i64; type SslCacheSize = c_long; type MtuTy = c_long; + type ModeTy = c_long; type SizeTy = u32; } } @@ -847,11 +858,31 @@ impl SslContextBuilder { } } - /// Sets the mode used by the context, returning the previous mode. + /// Sets the bit mask in mode to the mode set used by the context, returning the new mode bit mask. + /// + /// Options already set before are not cleared. #[corresponds(SSL_CTX_set_mode)] pub fn set_mode(&mut self, mode: SslMode) -> SslMode { unsafe { - let bits = ffi::SSL_CTX_set_mode(self.as_ptr(), mode.bits() as MtuTy) as SslBitType; + let bits = ffi::SSL_CTX_set_mode(self.as_ptr(), mode.bits() as ModeTy) as SslBitType; + SslMode::from_bits_retain(bits) + } + } + + /// Clear the bit mask in mode to the mode set used by the context, returning the new mode bit mask. + #[corresponds(SSL_CTX_clear_mode)] + pub fn clear_mode(&mut self, mode: SslMode) -> SslMode { + unsafe { + let bits = ffi::SSL_CTX_clear_mode(self.as_ptr(), mode.bits() as ModeTy) as SslBitType; + SslMode::from_bits_retain(bits) + } + } + + /// Returns the mode set for the context. + #[corresponds(SSL_CTX_get_mode)] + pub fn mode(&self) -> SslMode { + unsafe { + let bits = ffi::SSL_CTX_get_mode(self.as_ptr()) as SslBitType; SslMode::from_bits_retain(bits) } } @@ -2370,6 +2401,35 @@ impl SslRef { unsafe { ErrorCode::from_raw(ffi::SSL_get_error(self.as_ptr(), ret)) } } + /// Sets the bit mask in mode to the mode set used by the SSL, returning the new mode bit mask. + /// + /// Options already set before are not cleared. + #[corresponds(SSL_set_mode)] + pub fn set_mode(&mut self, mode: SslMode) -> SslMode { + unsafe { + let bits = ffi::SSL_set_mode(self.as_ptr(), mode.bits() as ModeTy) as SslBitType; + SslMode::from_bits_retain(bits) + } + } + + /// Clear the bit mask in mode to the mode set used by the SSL, returning the new mode bit mask. + #[corresponds(SSL_clear_mode)] + pub fn clear_mode(&mut self, mode: SslMode) -> SslMode { + unsafe { + let bits = ffi::SSL_clear_mode(self.as_ptr(), mode.bits() as ModeTy) as SslBitType; + SslMode::from_bits_retain(bits) + } + } + + /// Returns the mode set for the SSL. + #[corresponds(SSL_get_mode)] + pub fn mode(&self) -> SslMode { + unsafe { + let bits = ffi::SSL_get_mode(self.as_ptr()) as SslBitType; + SslMode::from_bits_retain(bits) + } + } + /// Configure as an outgoing stream from a client. #[corresponds(SSL_set_connect_state)] pub fn set_connect_state(&mut self) {