diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index e4b621ef..a66a7743 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -61,8 +61,6 @@ pub mod string; pub mod symm; pub mod version; pub mod x509; -#[cfg(any(ossl102, ossl110))] -mod verify; fn cvt_p(r: *mut T) -> Result<*mut T, ErrorStack> { if r.is_null() { diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs index 89eb0ac3..9966a5a0 100644 --- a/openssl/src/ssl/connector.rs +++ b/openssl/src/ssl/connector.rs @@ -192,11 +192,7 @@ impl SslAcceptor { pub fn mozilla_intermediate(method: SslMethod) -> Result { let mut ctx = ctx(method)?; #[cfg(ossl111)] - { - ctx.set_options(SslOptions { - bits: ::ffi::SSL_OP_NO_TLSv1_3, - }); - } + ctx.set_options(SslOptions::NO_TLSV1_3); let dh = Dh::params_from_pem( b" -----BEGIN DH PARAMETERS----- @@ -236,11 +232,7 @@ ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== let mut ctx = ctx(method)?; ctx.set_options(SslOptions::NO_TLSV1 | SslOptions::NO_TLSV1_1); #[cfg(ossl111)] - { - ctx.set_options(SslOptions { - bits: ::ffi::SSL_OP_NO_TLSv1_3, - }); - } + ctx.set_options(SslOptions::NO_TLSV1_3); setup_curves(&mut ctx)?; ctx.set_cipher_list( "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\ @@ -316,8 +308,10 @@ fn setup_verify(ctx: &mut SslContextBuilder) { #[cfg(any(ossl102, ossl110))] fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> { + use x509::verify::X509CheckFlags; + let param = ssl.param_mut(); - param.set_hostflags(::verify::X509CheckFlags::NO_PARTIAL_WILDCARDS); + param.set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS); match domain.parse() { Ok(ip) => param.set_ip(ip), Err(_) => param.set_host(domain), diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index f3c4ed3a..c1021b8b 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -87,7 +87,7 @@ use x509::store::{X509StoreBuilderRef, X509StoreRef}; #[cfg(any(ossl102, ossl110))] use x509::store::X509Store; #[cfg(any(ossl102, ossl110))] -use verify::X509VerifyParamRef; +use x509::verify::X509VerifyParamRef; use pkey::{HasPrivate, PKeyRef, Params, Private}; use error::ErrorStack; use ex_data::Index; @@ -1512,12 +1512,14 @@ impl SslContextBuilder { parse_cb: ParseFn, ) -> Result<(), ErrorStack> where - AddFn: Fn(&mut SslRef, ExtensionContext, Option<(usize, &X509Ref)>) -> Result, SslAlert> + AddFn: Fn(&mut SslRef, ExtensionContext, Option<(usize, &X509Ref)>) + -> Result, SslAlert> + 'static + Sync + Send, T: AsRef<[u8]> + 'static + Sync + Send, - ParseFn: Fn(&mut SslRef, ExtensionContext, &[u8], Option<(usize, &X509Ref)>) -> Result<(), SslAlert> + ParseFn: Fn(&mut SslRef, ExtensionContext, &[u8], Option<(usize, &X509Ref)>) + -> Result<(), SslAlert> + 'static + Sync + Send, diff --git a/openssl/src/verify.rs b/openssl/src/verify.rs deleted file mode 100644 index 19e57c17..00000000 --- a/openssl/src/verify.rs +++ /dev/null @@ -1,86 +0,0 @@ -use libc::c_uint; -use ffi; -use foreign_types::ForeignTypeRef; -use std::net::IpAddr; - -use cvt; -use error::ErrorStack; - -bitflags! { - /// Flags used to check an `X509` certificate. - pub struct X509CheckFlags: c_uint { - const ALWAYS_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT; - const FLAG_NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS; - const NO_PARTIAL_WILDCARDS = ffi::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS; - const MULTI_LABEL_WILDCARDS = ffi::X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS; - const SINGLE_LABEL_SUBDOMAINS - = ffi::X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS; - /// Requires OpenSSL 1.1.0 or newer. - #[cfg(any(ossl110))] - const NEVER_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_NEVER_CHECK_SUBJECT; - } -} - -foreign_type_and_impl_send_sync! { - type CType = ffi::X509_VERIFY_PARAM; - fn drop = ffi::X509_VERIFY_PARAM_free; - - /// Adjust parameters associated with certificate verification. - pub struct X509VerifyParam; - /// Reference to `X509VerifyParam`. - pub struct X509VerifyParamRef; -} - -impl X509VerifyParamRef { - /// Set the host flags. - /// - /// This corresponds to [`X509_VERIFY_PARAM_set_hostflags`]. - /// - /// [`X509_VERIFY_PARAM_set_hostflags`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set_hostflags.html - pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) { - unsafe { - ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits); - } - } - - /// Set the expected DNS hostname. - /// - /// This corresponds to [`X509_VERIFY_PARAM_set1_host`]. - /// - /// [`X509_VERIFY_PARAM_set1_host`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set1_host.html - pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> { - unsafe { - cvt(ffi::X509_VERIFY_PARAM_set1_host( - self.as_ptr(), - host.as_ptr() as *const _, - host.len(), - )).map(|_| ()) - } - } - - /// Set the expected IPv4 or IPv6 address. - /// - /// This corresponds to [`X509_VERIFY_PARAM_set1_ip`]. - /// - /// [`X509_VERIFY_PARAM_set1_ip`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set1_ip.html - pub fn set_ip(&mut self, ip: IpAddr) -> Result<(), ErrorStack> { - unsafe { - let mut buf = [0; 16]; - let len = match ip { - IpAddr::V4(addr) => { - buf[..4].copy_from_slice(&addr.octets()); - 4 - } - IpAddr::V6(addr) => { - buf.copy_from_slice(&addr.octets()); - 16 - } - }; - cvt(ffi::X509_VERIFY_PARAM_set1_ip( - self.as_ptr(), - buf.as_ptr() as *const _, - len, - )).map(|_| ()) - } - } -} diff --git a/openssl/src/x509/verify.rs b/openssl/src/x509/verify.rs index 8a57ce5c..b90c8f58 100644 --- a/openssl/src/x509/verify.rs +++ b/openssl/src/x509/verify.rs @@ -1,5 +1,88 @@ -//! X509 certificate verification -//! -//! Requires OpenSSL 1.0.2, 1.1.0, or 1.1.1 and the corresponding Cargo feature. +use libc::c_uint; +use ffi; +use foreign_types::ForeignTypeRef; +use std::net::IpAddr; -pub use verify::*; +use cvt; +use error::ErrorStack; + +bitflags! { + /// Flags used to check an `X509` certificate. + pub struct X509CheckFlags: c_uint { + const ALWAYS_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT; + const NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS; + const NO_PARTIAL_WILDCARDS = ffi::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS; + const MULTI_LABEL_WILDCARDS = ffi::X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS; + const SINGLE_LABEL_SUBDOMAINS = ffi::X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS; + /// Requires OpenSSL 1.1.0 or newer. + #[cfg(any(ossl110))] + const NEVER_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_NEVER_CHECK_SUBJECT; + + #[deprecated(since = "0.10.6", note = "renamed to NO_WILDCARDS")] + const FLAG_NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS; + } +} + +foreign_type_and_impl_send_sync! { + type CType = ffi::X509_VERIFY_PARAM; + fn drop = ffi::X509_VERIFY_PARAM_free; + + /// Adjust parameters associated with certificate verification. + pub struct X509VerifyParam; + /// Reference to `X509VerifyParam`. + pub struct X509VerifyParamRef; +} + +impl X509VerifyParamRef { + /// Set the host flags. + /// + /// This corresponds to [`X509_VERIFY_PARAM_set_hostflags`]. + /// + /// [`X509_VERIFY_PARAM_set_hostflags`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set_hostflags.html + pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) { + unsafe { + ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits); + } + } + + /// Set the expected DNS hostname. + /// + /// This corresponds to [`X509_VERIFY_PARAM_set1_host`]. + /// + /// [`X509_VERIFY_PARAM_set1_host`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set1_host.html + pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::X509_VERIFY_PARAM_set1_host( + self.as_ptr(), + host.as_ptr() as *const _, + host.len(), + )).map(|_| ()) + } + } + + /// Set the expected IPv4 or IPv6 address. + /// + /// This corresponds to [`X509_VERIFY_PARAM_set1_ip`]. + /// + /// [`X509_VERIFY_PARAM_set1_ip`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_VERIFY_PARAM_set1_ip.html + pub fn set_ip(&mut self, ip: IpAddr) -> Result<(), ErrorStack> { + unsafe { + let mut buf = [0; 16]; + let len = match ip { + IpAddr::V4(addr) => { + buf[..4].copy_from_slice(&addr.octets()); + 4 + } + IpAddr::V6(addr) => { + buf.copy_from_slice(&addr.octets()); + 16 + } + }; + cvt(ffi::X509_VERIFY_PARAM_set1_ip( + self.as_ptr(), + buf.as_ptr() as *const _, + len, + )).map(|_| ()) + } + } +}