diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml index 3845c51d6ec2b76539d3e7de7149cd1e34f516a0..4891d79bcee6e399fe9b237c5381361d54ff0140 100644 --- a/openssl/Cargo.toml +++ b/openssl/Cargo.toml @@ -12,8 +12,9 @@ build = "build.rs" exclude = ["test/*"] [features] -openssl-102 = [] -openssl-110 = ["openssl-102"] +v101 = [] +v102 = [] +v110 = [] [dependencies] bitflags = "0.7" diff --git a/openssl/build.rs b/openssl/build.rs index 8bb113acc2339373412c6925e8b8d3a4b81d1327..cd1dc3ecf00cfc568529b3f4cdec6dfd38bc5560 100644 --- a/openssl/build.rs +++ b/openssl/build.rs @@ -4,20 +4,17 @@ fn main() { if env::var("DEP_OPENSSL_IS_110").is_ok() { println!("cargo:rustc-cfg=ossl110"); return; - } else if cfg!(feature = "openssl-110") { - panic!("the openssl-110 feature is enabled but OpenSSL 1.1.0+ is not being linked against"); - } - if env::var("DEP_OPENSSL_IS_102").is_ok() { + } else if env::var("DEP_OPENSSL_IS_102").is_ok() { println!("cargo:rustc-cfg=ossl102"); println!("cargo:rustc-cfg=ossl10x"); return; - } else if cfg!(feature = "openssl-102") { - panic!("the openssl-102 feature is enabled but OpenSSL 1.0.2+") - } - if env::var("DEP_OPENSSL_IS_101").is_ok() { + } else if env::var("DEP_OPENSSL_IS_101").is_ok() { println!("cargo:rustc-cfg=ossl101"); println!("cargo:rustc-cfg=ossl10x"); + } else { + panic!("Unable to detect OpenSSL version"); } + if let Ok(vars) = env::var("DEP_OPENSSL_OSSLCONF") { for var in vars.split(",") { println!("cargo:rustc-cfg=osslconf=\"{}\"", var); diff --git a/openssl/src/dh.rs b/openssl/src/dh.rs index fec6bd9855ae5d58f70a02c475ce3c058cae83c2..3b06951e11011f04f742ea405b102750fa26f42d 100644 --- a/openssl/src/dh.rs +++ b/openssl/src/dh.rs @@ -33,21 +33,24 @@ impl DH { } } - #[cfg(feature = "openssl-102")] + /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0. + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub fn get_1024_160() -> Result { unsafe { cvt_p(ffi::DH_get_1024_160()).map(DH) } } - #[cfg(feature = "openssl-102")] + /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0. + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub fn get_2048_224() -> Result { unsafe { cvt_p(ffi::DH_get_2048_224()).map(DH) } } - #[cfg(feature = "openssl-102")] + /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0. + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub fn get_2048_256() -> Result { unsafe { cvt_p(ffi::DH_get_2048_256()).map(DH) @@ -96,7 +99,7 @@ mod tests { use ssl::{SslMethod, SslContext}; #[test] - #[cfg(feature = "openssl-102")] + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] fn test_dh_rfc5114() { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); let dh1 = DH::get_1024_160().unwrap(); diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index ad21e5638e211b16a00b4143e9a13615547a02a2..11ecd32d72aa46b7c73fd8ed94129d5f2a387942 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -22,7 +22,7 @@ use ffi; use {init, cvt, cvt_p}; use dh::DH; use x509::{X509StoreContext, X509FileType, X509, X509Ref}; -#[cfg(feature = "openssl-102")] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] use x509::verify::X509VerifyParamRef; use crypto::pkey::PKey; use error::ErrorStack; @@ -67,11 +67,14 @@ bitflags! { const SSL_OP_NO_TLSV1 = ffi::SSL_OP_NO_TLSv1, const SSL_OP_NO_TLSV1_2 = ffi::SSL_OP_NO_TLSv1_2, const SSL_OP_NO_TLSV1_1 = ffi::SSL_OP_NO_TLSv1_1, - #[cfg(feature = "openssl-102")] + /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0. + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] const SSL_OP_NO_DTLSV1 = ffi::SSL_OP_NO_DTLSv1, - #[cfg(feature = "openssl-102")] + /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0. + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] const SSL_OP_NO_DTLSV1_2 = ffi::SSL_OP_NO_DTLSv1_2, - #[cfg(feature = "openssl-102")] + /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0. + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] const SSL_OP_NO_SSL_MASK = ffi::SSL_OP_NO_SSL_MASK, } } @@ -133,7 +136,8 @@ fn get_ssl_verify_data_idx() -> c_int { lazy_static! { static ref NPN_PROTOS_IDX: c_int = get_new_idx::>(); } -#[cfg(feature = "openssl-102")] + +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] lazy_static! { static ref ALPN_PROTOS_IDX: c_int = get_new_idx::>(); } @@ -276,7 +280,7 @@ extern fn raw_next_proto_select_cb(ssl: *mut ffi::SSL, unsafe { select_proto_using(ssl, out, outlen, inbuf, inlen, *NPN_PROTOS_IDX) } } -#[cfg(feature = "openssl-102")] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] extern fn raw_alpn_select_cb(ssl: *mut ffi::SSL, out: *mut *const c_uchar, outlen: *mut c_uchar, @@ -538,17 +542,9 @@ impl<'a> SslContextRef<'a> { /// compatible clients, and automatically select an appropriate elliptic /// curve. /// - /// This feature is always enabled on OpenSSL 1.1.0, and calling this - /// method does nothing. - /// - /// This method requires the `openssl-102` feature. - #[cfg(feature = "openssl-102")] + /// Requires the `v102` feature and OpenSSL 1.0.2. + #[cfg(all(feature = "v102", ossl102))] pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> { - self._set_ecdh_auto(onoff) - } - - #[cfg(all(feature = "openssl-102", ossl102))] - fn _set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_ctrl(self.as_ptr(), ffi::SSL_CTRL_SET_ECDH_AUTO, @@ -558,11 +554,6 @@ impl<'a> SslContextRef<'a> { } } - #[cfg(all(feature = "openssl-102", ossl110))] - fn _set_ecdh_auto(&mut self, _onoff: bool) -> Result<(), ErrorStack> { - Ok(()) - } - pub fn set_options(&mut self, option: SslContextOptions) -> SslContextOptions { let ret = unsafe { compat::SSL_CTX_set_options(self.as_ptr(), option.bits()) }; SslContextOptions::from_bits(ret).unwrap() @@ -610,8 +601,8 @@ impl<'a> SslContextRef<'a> { /// /// Note that ordering of the protocols controls the priority with which they are chosen. /// - /// This method needs the `openssl-102` feature. - #[cfg(feature = "openssl-102")] + /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0. + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub fn set_alpn_protocols(&mut self, protocols: &[&[u8]]) { let protocols: Box> = Box::new(ssl_encode_byte_strings(protocols)); unsafe { @@ -928,8 +919,8 @@ impl<'a> SslRef<'a> { /// The protocol's name is returned is an opaque sequence of bytes. It is up to the client /// to interpret it. /// - /// This method needs the `alpn` feature. - #[cfg(feature = "openssl-102")] + /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or OpenSSL 1.1.0. + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub fn selected_alpn_protocol(&self) -> Option<&[u8]> { unsafe { let mut data: *const c_uchar = ptr::null(); @@ -1007,8 +998,8 @@ impl<'a> SslRef<'a> { /// Returns the X509 verification configuration. /// - /// Requires the `openssl-102` feature. - #[cfg(feature = "openssl-102")] + /// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or 1.1.0. + #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub fn param(&mut self) -> X509VerifyParamRef<'a> { unsafe { X509VerifyParamRef::from_ptr(ffi::SSL_get0_param(self.as_ptr())) diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index 2dd49cb06d3da7c379341d1f3e62d638c4994bb6..051a12f550006247f683859f9776f499270e47a0 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -20,12 +20,12 @@ use ssl::SSL_VERIFY_PEER; use ssl::{SslMethod, HandshakeError}; use ssl::error::Error; use ssl::{SslContext, SslStream}; -#[cfg(feature = "openssl-102")] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] use ssl::IntoSsl; use x509::X509StoreContext; use x509::X509FileType; use x509::X509; -#[cfg(feature = "openssl-102")] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] use x509::verify::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS; use crypto::pkey::PKey; @@ -509,7 +509,7 @@ fn test_state() { /// Tests that connecting with the client using ALPN, but the server not does not /// break the existing connection behavior. #[test] -#[cfg(feature = "openssl-102")] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] fn test_connect_with_unilateral_alpn() { let (_s, stream) = Server::new(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); @@ -552,7 +552,7 @@ fn test_connect_with_unilateral_npn() { /// Tests that when both the client as well as the server use ALPN and their /// lists of supported protocols have an overlap, the correct protocol is chosen. #[test] -#[cfg(feature = "openssl-102")] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] fn test_connect_with_alpn_successful_multiple_matching() { let (_s, stream) = Server::new_alpn(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); @@ -574,7 +574,7 @@ fn test_connect_with_alpn_successful_multiple_matching() { /// Tests that when both the client as well as the server use NPN and their /// lists of supported protocols have an overlap, the correct protocol is chosen. #[test] -#[cfg(feature = "openssl-102")] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] fn test_connect_with_npn_successful_multiple_matching() { let (_s, stream) = Server::new_alpn(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); @@ -597,7 +597,7 @@ fn test_connect_with_npn_successful_multiple_matching() { /// lists of supported protocols have an overlap -- with only ONE protocol /// being valid for both. #[test] -#[cfg(feature = "openssl-102")] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] fn test_connect_with_alpn_successful_single_match() { let (_s, stream) = Server::new_alpn(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); @@ -621,7 +621,7 @@ fn test_connect_with_alpn_successful_single_match() { /// lists of supported protocols have an overlap -- with only ONE protocol /// being valid for both. #[test] -#[cfg(feature = "openssl-102")] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] fn test_connect_with_npn_successful_single_match() { let (_s, stream) = Server::new_alpn(); let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); @@ -683,7 +683,7 @@ fn test_npn_server_advertise_multiple() { /// Tests that when the `SslStream` is created as a server stream, the protocols /// are correctly advertised to the client. #[test] -#[cfg(feature = "openssl-102")] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] fn test_alpn_server_advertise_multiple() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let localhost = listener.local_addr().unwrap(); @@ -724,7 +724,7 @@ fn test_alpn_server_advertise_multiple() { /// Test that Servers supporting ALPN don't report a protocol when none of their protocols match /// the client's reported protocol. #[test] -#[cfg(all(feature = "openssl-102", ossl102))] +#[cfg(all(feature = "v102", ossl102))] fn test_alpn_server_select_none() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let localhost = listener.local_addr().unwrap(); @@ -759,7 +759,7 @@ fn test_alpn_server_select_none() { // In 1.1.0, ALPN negotiation failure is a fatal error #[test] -#[cfg(all(feature = "openssl-102", ossl110))] +#[cfg(all(feature = "v110", ossl110))] fn test_alpn_server_select_none() { let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let localhost = listener.local_addr().unwrap(); @@ -1066,7 +1066,7 @@ fn add_extra_chain_cert() { #[test] #[cfg_attr(windows, ignore)] // don't have a trusted CA list easily available :( -#[cfg(feature = "openssl-102")] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] fn valid_hostname() { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_default_verify_paths().unwrap(); @@ -1090,7 +1090,7 @@ fn valid_hostname() { #[test] #[cfg_attr(windows, ignore)] // don't have a trusted CA list easily available :( -#[cfg(feature = "openssl-102")] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] fn invalid_hostname() { let mut ctx = SslContext::new(SslMethod::tls()).unwrap(); ctx.set_default_verify_paths().unwrap(); diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 1cd7471ffe5b4b2f90d6ba8fa4779c0b91001274..e801b1da1dcad08a16b4352e3b17286b8ae4a1b7 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -36,7 +36,7 @@ use ffi::{ pub mod extension; -#[cfg(feature = "openssl-102")] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub mod verify; use self::extension::{ExtensionType, Extension}; diff --git a/openssl/src/x509/verify.rs b/openssl/src/x509/verify.rs index 5cce9bd7b50aef6e108abbc76a3ec76bf4596eec..be8d3d7e168e4de3d8638d0059693c7e1a5e6e77 100644 --- a/openssl/src/x509/verify.rs +++ b/openssl/src/x509/verify.rs @@ -1,3 +1,7 @@ +//! X509 certificate verification +//! +//! Requires the `v102` or `v110` features and OpenSSL 1.0.2 or 1.1.0. + use std::marker::PhantomData; use libc::c_uint; use ffi; @@ -13,7 +17,8 @@ bitflags! { const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS = ffi::X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS, const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS = ffi::X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS, - #[cfg(feature = "openssl-110")] + /// Requires the `v110` feature and OpenSSL 1.1.0. + #[cfg(all(feature = "v110", ossl110))] const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_NEVER_CHECK_SUBJECT, } } diff --git a/openssl/test/run.sh b/openssl/test/run.sh index cd422db753f50165165a01f7cb1da8d6e4d8a0cc..4d3397a60a8028028268ee367595d933033e7411 100755 --- a/openssl/test/run.sh +++ b/openssl/test/run.sh @@ -3,10 +3,10 @@ set -e case "$BUILD_OPENSSL_VERSION" in 1.0.2*) - FEATURES="openssl-102" + FEATURES="v102" ;; 1.1.0*) - FEATURES="openssl-110" + FEATURES="v110" ;; esac