diff --git a/openssl-sys/src/handwritten/ssl.rs b/openssl-sys/src/handwritten/ssl.rs index d4f4b619f4..944a476618 100644 --- a/openssl-sys/src/handwritten/ssl.rs +++ b/openssl-sys/src/handwritten/ssl.rs @@ -924,3 +924,17 @@ extern "C" { #[cfg(all(ossl111, not(ossl111b)))] pub fn SSL_get_num_tickets(s: *mut SSL) -> size_t; } + +extern "C" { + #[cfg(any(ossl110, libressl360))] + pub fn SSL_CTX_set_security_level(ctx: *mut SSL_CTX, level: c_int); + + #[cfg(any(ossl110, libressl360))] + pub fn SSL_set_security_level(s: *mut SSL, level: c_int); + + #[cfg(any(ossl110, libressl360))] + pub fn SSL_CTX_get_security_level(ctx: *const SSL_CTX) -> c_int; + + #[cfg(any(ossl110, libressl360))] + pub fn SSL_get_security_level(s: *const SSL) -> c_int; +} diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index bdfbfc14f0..d147c3c343 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -1718,6 +1718,16 @@ impl SslContextBuilder { unsafe { cvt(ffi::SSL_CTX_set_num_tickets(self.as_ptr(), num_tickets)).map(|_| ()) } } + /// Set the context's security level to a value between 0 and 5, inclusive. + /// A security value of 0 allows allows all parameters and algorithms. + /// + /// Requires OpenSSL 1.1.0 or newer. + #[corresponds(SSL_CTX_set_security_level)] + #[cfg(any(ossl110, libressl360))] + pub fn set_security_level(&mut self, level: u32) { + unsafe { ffi::SSL_CTX_set_security_level(self.as_ptr(), level as c_int) } + } + /// Consumes the builder, returning a new `SslContext`. pub fn build(self) -> SslContext { self.0 @@ -1921,6 +1931,16 @@ impl SslContextRef { pub fn num_tickets(&self) -> usize { unsafe { ffi::SSL_CTX_get_num_tickets(self.as_ptr()) } } + + /// Get the context's security level, which controls the allowed parameters + /// and algorithms. + /// + /// Requires OpenSSL 1.1.0 or newer. + #[corresponds(SSL_CTX_get_security_level)] + #[cfg(any(ossl110, libressl360))] + pub fn security_level(&self) -> u32 { + unsafe { ffi::SSL_CTX_get_security_level(self.as_ptr()) as u32 } + } } /// Information about the state of a cipher. @@ -3405,6 +3425,26 @@ impl SslRef { pub fn num_tickets(&self) -> usize { unsafe { ffi::SSL_get_num_tickets(self.as_ptr()) } } + + /// Set the context's security level to a value between 0 and 5, inclusive. + /// A security value of 0 allows allows all parameters and algorithms. + /// + /// Requires OpenSSL 1.1.0 or newer. + #[corresponds(SSL_set_security_level)] + #[cfg(any(ossl110, libressl360))] + pub fn set_security_level(&mut self, level: u32) { + unsafe { ffi::SSL_set_security_level(self.as_ptr(), level as c_int) } + } + + /// Get the connection's security level, which controls the allowed parameters + /// and algorithms. + /// + /// Requires OpenSSL 1.1.0 or newer. + #[corresponds(SSL_get_security_level)] + #[cfg(any(ossl110, libressl360))] + pub fn security_level(&self) -> u32 { + unsafe { ffi::SSL_get_security_level(self.as_ptr()) as u32 } + } } /// An SSL stream midway through the handshake process. diff --git a/openssl/src/ssl/test/mod.rs b/openssl/src/ssl/test/mod.rs index 6013614118..542656cb04 100644 --- a/openssl/src/ssl/test/mod.rs +++ b/openssl/src/ssl/test/mod.rs @@ -1574,3 +1574,17 @@ fn set_num_tickets() { let ssl = ssl; assert_eq!(5, ssl.num_tickets()); } + +#[test] +#[cfg(ossl110)] +fn set_security_level() { + let mut ctx = SslContext::builder(SslMethod::tls_server()).unwrap(); + ctx.set_security_level(3); + let ctx = ctx.build(); + assert_eq!(3, ctx.security_level()); + + let mut ssl = Ssl::new(&ctx).unwrap(); + ssl.set_security_level(4); + let ssl = ssl; + assert_eq!(4, ssl.security_level()); +}