diff options
author | Steven Fackler <sfackler@gmail.com> | 2018-05-20 11:27:45 -0700 |
---|---|---|
committer | Steven Fackler <sfackler@gmail.com> | 2018-05-20 12:33:02 -0700 |
commit | a6fcef01c0aa71359f583342c813b8db5835178d (patch) | |
tree | 33c47b59618e5fe286904462f2d4a540804dd7ef | |
parent | 9df403043b75e407305f7003636dbe1c55f7d245 (diff) | |
download | rust-openssl-a6fcef01c0aa71359f583342c813b8db5835178d.zip |
Overhaul openssl cfgs
Also expose hostname verification on libressl
-rw-r--r-- | openssl-sys/src/lib.rs | 10 | ||||
-rw-r--r-- | openssl-sys/src/libressl/mod.rs | 22 | ||||
-rw-r--r-- | openssl-sys/src/openssl/v10x.rs | 22 | ||||
-rw-r--r-- | openssl/Cargo.toml | 2 | ||||
-rw-r--r-- | openssl/build.rs | 31 | ||||
-rw-r--r-- | openssl/src/asn1.rs | 24 | ||||
-rw-r--r-- | openssl/src/bio.rs | 20 | ||||
-rw-r--r-- | openssl/src/bn.rs | 57 | ||||
-rw-r--r-- | openssl/src/dh.rs | 48 | ||||
-rw-r--r-- | openssl/src/dsa.rs | 50 | ||||
-rw-r--r-- | openssl/src/ecdsa.rs | 80 | ||||
-rw-r--r-- | openssl/src/hash.rs | 33 | ||||
-rw-r--r-- | openssl/src/lib.rs | 4 | ||||
-rw-r--r-- | openssl/src/rsa.rs | 219 | ||||
-rw-r--r-- | openssl/src/sign.rs | 27 | ||||
-rw-r--r-- | openssl/src/ssl/bio.rs | 204 | ||||
-rw-r--r-- | openssl/src/ssl/callbacks.rs | 68 | ||||
-rw-r--r-- | openssl/src/ssl/connector.rs | 388 | ||||
-rw-r--r-- | openssl/src/ssl/mod.rs | 233 | ||||
-rw-r--r-- | openssl/src/ssl/test.rs | 4 | ||||
-rw-r--r-- | openssl/src/stack.rs | 33 | ||||
-rw-r--r-- | openssl/src/symm.rs | 43 | ||||
-rw-r--r-- | openssl/src/version.rs | 25 | ||||
-rw-r--r-- | openssl/src/x509/mod.rs | 166 | ||||
-rw-r--r-- | openssl/src/x509/verify.rs | 2 |
25 files changed, 933 insertions, 882 deletions
diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 8d0790ea..0f6a4483 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1413,15 +1413,15 @@ pub const X509_V_ERR_EMAIL_MISMATCH: c_int = 63; #[cfg(ossl102)] pub const X509_V_ERR_IP_ADDRESS_MISMATCH: c_int = 64; -#[cfg(ossl102)] +#[cfg(any(ossl102, libressl261))] pub const X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT: c_uint = 0x1; -#[cfg(ossl102)] +#[cfg(any(ossl102, libressl261))] pub const X509_CHECK_FLAG_NO_WILDCARDS: c_uint = 0x2; -#[cfg(ossl102)] +#[cfg(any(ossl102, libressl261))] pub const X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS: c_uint = 0x4; -#[cfg(ossl102)] +#[cfg(any(ossl102, libressl261))] pub const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS: c_uint = 0x8; -#[cfg(ossl102)] +#[cfg(any(ossl102, libressl261))] pub const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS: c_uint = 0x10; pub const GEN_OTHERNAME: c_int = 0; diff --git a/openssl-sys/src/libressl/mod.rs b/openssl-sys/src/libressl/mod.rs index 5ae205bc..0080fc7d 100644 --- a/openssl-sys/src/libressl/mod.rs +++ b/openssl-sys/src/libressl/mod.rs @@ -447,6 +447,28 @@ pub unsafe fn SSL_session_reused(ssl: *mut ::SSL) -> c_int { ::SSL_ctrl(ssl, SSL_CTRL_GET_SESSION_REUSED, 0, ptr::null_mut()) as c_int } +pub unsafe fn SSL_CTX_get_options(ctx: *const ::SSL_CTX) -> c_ulong { + ::SSL_CTX_ctrl(ctx as *mut _, ::SSL_CTRL_OPTIONS, 0, ptr::null_mut()) as c_ulong +} + +pub unsafe fn SSL_CTX_set_options(ctx: *const ::SSL_CTX, op: c_ulong) -> c_ulong { + ::SSL_CTX_ctrl( + ctx as *mut _, + ::SSL_CTRL_OPTIONS, + op as c_long, + ptr::null_mut(), + ) as c_ulong +} + +pub unsafe fn SSL_CTX_clear_options(ctx: *const ::SSL_CTX, op: c_ulong) -> c_ulong { + ::SSL_CTX_ctrl( + ctx as *mut _, + ::SSL_CTRL_CLEAR_OPTIONS, + op as c_long, + ptr::null_mut(), + ) as c_ulong +} + extern "C" { pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO; pub fn BIO_s_file() -> *mut BIO_METHOD; diff --git a/openssl-sys/src/openssl/v10x.rs b/openssl-sys/src/openssl/v10x.rs index 8ee9c58f..c22bb7fc 100644 --- a/openssl-sys/src/openssl/v10x.rs +++ b/openssl-sys/src/openssl/v10x.rs @@ -807,6 +807,28 @@ pub unsafe fn SSL_session_reused(ssl: *mut ::SSL) -> c_int { ::SSL_ctrl(ssl, SSL_CTRL_GET_SESSION_REUSED, 0, ptr::null_mut()) as c_int } +pub unsafe fn SSL_CTX_get_options(ctx: *const ::SSL_CTX) -> c_ulong { + ::SSL_CTX_ctrl(ctx as *mut _, ::SSL_CTRL_OPTIONS, 0, ptr::null_mut()) as c_ulong +} + +pub unsafe fn SSL_CTX_set_options(ctx: *const ::SSL_CTX, op: c_ulong) -> c_ulong { + ::SSL_CTX_ctrl( + ctx as *mut _, + ::SSL_CTRL_OPTIONS, + op as c_long, + ptr::null_mut(), + ) as c_ulong +} + +pub unsafe fn SSL_CTX_clear_options(ctx: *const ::SSL_CTX, op: c_ulong) -> c_ulong { + ::SSL_CTX_ctrl( + ctx as *mut _, + ::SSL_CTRL_CLEAR_OPTIONS, + op as c_long, + ptr::null_mut(), + ) as c_ulong +} + extern "C" { pub fn BIO_new(type_: *mut BIO_METHOD) -> *mut BIO; pub fn BIO_s_file() -> *mut BIO_METHOD; diff --git a/openssl/Cargo.toml b/openssl/Cargo.toml index 25aab11d..8ce43b3d 100644 --- a/openssl/Cargo.toml +++ b/openssl/Cargo.toml @@ -18,9 +18,11 @@ v111 = [] [dependencies] bitflags = "1.0" +cfg-if = "0.1" foreign-types = "0.3.1" lazy_static = "1" libc = "0.2" + openssl-sys = { version = "0.9.30", path = "../openssl-sys" } [dev-dependencies] diff --git a/openssl/build.rs b/openssl/build.rs index 271fb662..5a5b86f2 100644 --- a/openssl/build.rs +++ b/openssl/build.rs @@ -1,25 +1,6 @@ use std::env; fn main() { - match env::var("DEP_OPENSSL_VERSION") { - Ok(ref v) if v == "101" => { - println!("cargo:rustc-cfg=ossl101"); - println!("cargo:rustc-cfg=ossl10x"); - } - Ok(ref v) if v == "102" => { - println!("cargo:rustc-cfg=ossl102"); - println!("cargo:rustc-cfg=ossl10x"); - } - Ok(ref v) if v == "110" => { - println!("cargo:rustc-cfg=ossl110"); - } - Ok(ref v) if v == "111" => { - println!("cargo:rustc-cfg=ossl110"); - println!("cargo:rustc-cfg=ossl111"); - } - _ => panic!("Unable to detect OpenSSL version"), - } - if let Ok(_) = env::var("DEP_OPENSSL_LIBRESSL") { println!("cargo:rustc-cfg=libressl"); } @@ -37,9 +18,21 @@ fn main() { if let Ok(version) = env::var("DEP_OPENSSL_VERSION_NUMBER") { let version = u64::from_str_radix(&version, 16).unwrap(); + if version >= 0x1_00_01_00_0 { + println!("cargo:rustc-cfg=ossl101"); + } + if version >= 0x1_00_02_00_0 { + println!("cargo:rustc-cfg=ossl102"); + } + if version >= 0x1_01_00_00_0 { + println!("cargo:rustc-cfg=ossl110"); + } if version >= 0x1_01_00_07_0 { println!("cargo:rustc-cfg=ossl110g"); } + if version >= 0x1_01_01_00_0 { + println!("cargo:rustc-cfg=ossl111"); + } } if let Ok(version) = env::var("DEP_OPENSSL_LIBRESSL_VERSION_NUMBER") { diff --git a/openssl/src/asn1.rs b/openssl/src/asn1.rs index f6917aae..03546a4d 100644 --- a/openssl/src/asn1.rs +++ b/openssl/src/asn1.rs @@ -32,12 +32,12 @@ use std::ptr; use std::slice; use std::str; -use {cvt, cvt_p}; use bio::MemBio; use bn::BigNum; use error::ErrorStack; use nid::Nid; use string::OpensslString; +use {cvt, cvt_p}; foreign_type_and_impl_send_sync! { type CType = ffi::ASN1_GENERALIZEDTIME; @@ -162,7 +162,7 @@ impl Asn1StringRef { /// /// [`as_utf8`]: struct.Asn1String.html#method.as_utf8 pub fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(ASN1_STRING_data(self.as_ptr()), self.len()) } + unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr()), self.len()) } } /// Return the length of the Asn1String (number of bytes) @@ -241,11 +241,11 @@ foreign_type_and_impl_send_sync! { impl Asn1BitStringRef { /// Returns the Asn1BitString as a slice pub fn as_slice(&self) -> &[u8] { - unsafe { slice::from_raw_parts(ASN1_STRING_data(self.as_ptr() as *mut _), self.len()) } + unsafe { slice::from_raw_parts(ASN1_STRING_get0_data(self.as_ptr() as *mut _), self.len()) } } /// Length of Asn1BitString in number of bytes. pub fn len(&self) -> usize { - unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *mut _) as usize } + unsafe { ffi::ASN1_STRING_length(self.as_ptr() as *const _) as usize } } } @@ -296,11 +296,13 @@ impl fmt::Display for Asn1ObjectRef { } } -#[cfg(any(ossl101, ossl102))] -use ffi::ASN1_STRING_data; - -#[cfg(ossl110)] -#[allow(bad_style)] -unsafe fn ASN1_STRING_data(s: *mut ffi::ASN1_STRING) -> *mut ::libc::c_uchar { - ffi::ASN1_STRING_get0_data(s) as *mut _ +cfg_if! { + if #[cfg(ossl110)] { + use ffi::ASN1_STRING_get0_data; + } else { + #[allow(bad_style)] + unsafe fn ASN1_STRING_get0_data(s: *mut ffi::ASN1_STRING) -> *const ::libc::c_uchar { + ffi::ASN1_STRING_data(s) + } + } } diff --git a/openssl/src/bio.rs b/openssl/src/bio.rs index 56ba1f3d..51724e3f 100644 --- a/openssl/src/bio.rs +++ b/openssl/src/bio.rs @@ -1,8 +1,8 @@ +use ffi; +use libc::c_int; use std::marker::PhantomData; use std::ptr; use std::slice; -use libc::c_int; -use ffi; use cvt_p; use error::ErrorStack; @@ -68,11 +68,13 @@ impl MemBio { } } -#[cfg(not(ossl101))] -use ffi::BIO_new_mem_buf; - -#[cfg(ossl101)] -#[allow(bad_style)] -unsafe fn BIO_new_mem_buf(buf: *const ::libc::c_void, len: ::libc::c_int) -> *mut ffi::BIO { - ffi::BIO_new_mem_buf(buf as *mut _, len) +cfg_if! { + if #[cfg(ossl102)] { + use ffi::BIO_new_mem_buf; + } else { + #[allow(bad_style)] + unsafe fn BIO_new_mem_buf(buf: *const ::libc::c_void, len: ::libc::c_int) -> *mut ffi::BIO { + ffi::BIO_new_mem_buf(buf as *mut _, len) + } + } } diff --git a/openssl/src/bn.rs b/openssl/src/bn.rs index fe662e85..15dd7368 100644 --- a/openssl/src/bn.rs +++ b/openssl/src/bn.rs @@ -30,28 +30,39 @@ use foreign_types::{ForeignType, ForeignTypeRef}; use libc::c_int; use std::cmp::Ordering; use std::ffi::CString; -use std::{fmt, ptr}; use std::ops::{Add, Deref, Div, Mul, Neg, Rem, Shl, Shr, Sub}; +use std::{fmt, ptr}; -use {cvt, cvt_n, cvt_p}; use asn1::Asn1Integer; use error::ErrorStack; use string::OpensslString; +use {cvt, cvt_n, cvt_p}; -#[cfg(ossl10x)] -use ffi::{get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024, - get_rfc2409_prime_768 as BN_get_rfc2409_prime_768, - get_rfc3526_prime_1536 as BN_get_rfc3526_prime_1536, - get_rfc3526_prime_2048 as BN_get_rfc3526_prime_2048, - get_rfc3526_prime_3072 as BN_get_rfc3526_prime_3072, - get_rfc3526_prime_4096 as BN_get_rfc3526_prime_4096, - get_rfc3526_prime_6144 as BN_get_rfc3526_prime_6144, - get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192}; - -#[cfg(ossl110)] -use ffi::{BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768, BN_get_rfc3526_prime_1536, - BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096, - BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192}; +cfg_if! { + if #[cfg(ossl110)] { + use ffi::{ + BN_get_rfc2409_prime_1024, BN_get_rfc2409_prime_768, BN_get_rfc3526_prime_1536, + BN_get_rfc3526_prime_2048, BN_get_rfc3526_prime_3072, BN_get_rfc3526_prime_4096, + BN_get_rfc3526_prime_6144, BN_get_rfc3526_prime_8192, BN_is_negative, + }; + } else { + use ffi::{ + get_rfc2409_prime_1024 as BN_get_rfc2409_prime_1024, + get_rfc2409_prime_768 as BN_get_rfc2409_prime_768, + get_rfc3526_prime_1536 as BN_get_rfc3526_prime_1536, + get_rfc3526_prime_2048 as BN_get_rfc3526_prime_2048, + get_rfc3526_prime_3072 as BN_get_rfc3526_prime_3072, + get_rfc3526_prime_4096 as BN_get_rfc3526_prime_4096, + get_rfc3526_prime_6144 as BN_get_rfc3526_prime_6144, + get_rfc3526_prime_8192 as BN_get_rfc3526_prime_8192, + }; + + #[allow(bad_style)] + unsafe fn BN_is_negative(bn: *const ffi::BIGNUM) -> c_int { + (*bn).neg + } + } +} /// Options for the most significant bits of a randomly generated `BigNum`. pub struct MsbOption(c_int); @@ -361,17 +372,7 @@ impl BigNumRef { /// Returns `true` if `self` is negative. pub fn is_negative(&self) -> bool { - self._is_negative() - } - - #[cfg(ossl10x)] - fn _is_negative(&self) -> bool { - unsafe { (*self.as_ptr()).neg == 1 } - } - - #[cfg(ossl110)] - fn _is_negative(&self) -> bool { - unsafe { ffi::BN_is_negative(self.as_ptr()) == 1 } + unsafe { BN_is_negative(self.as_ptr()) == 1 } } /// Returns the number of significant bits in `self`. @@ -1218,7 +1219,7 @@ macro_rules! delegate { $t::$m(self.deref(), oth.deref()) } } - } + }; } impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef { diff --git a/openssl/src/dh.rs b/openssl/src/dh.rs index a90b10b8..730a5180 100644 --- a/openssl/src/dh.rs +++ b/openssl/src/dh.rs @@ -4,9 +4,9 @@ use foreign_types::{ForeignType, ForeignTypeRef}; use std::mem; use std::ptr; -use {cvt, cvt_p}; use bn::BigNum; use pkey::{HasParams, Params}; +use {cvt, cvt_p}; generic_foreign_type_and_impl_send_sync! { type CType = ffi::DH; @@ -48,12 +48,7 @@ impl Dh<Params> { pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<Dh<Params>, ErrorStack> { unsafe { let dh = Dh::from_ptr(cvt_p(ffi::DH_new())?); - cvt(compat::DH_set0_pqg( - dh.0, - p.as_ptr(), - q.as_ptr(), - g.as_ptr(), - ))?; + cvt(DH_set0_pqg(dh.0, p.as_ptr(), q.as_ptr(), g.as_ptr()))?; mem::forget((p, g, q)); Ok(dh) } @@ -111,34 +106,29 @@ impl Dh<Params> { } } -#[cfg(ossl110)] -mod compat { - pub use ffi::DH_set0_pqg; -} - -#[cfg(ossl10x)] -#[allow(bad_style)] -mod compat { - use ffi; - use libc::c_int; - - pub unsafe fn DH_set0_pqg( - dh: *mut ffi::DH, - p: *mut ffi::BIGNUM, - q: *mut ffi::BIGNUM, - g: *mut ffi::BIGNUM, - ) -> c_int { - (*dh).p = p; - (*dh).q = q; - (*dh).g = g; - 1 +cfg_if! { + if #[cfg(ossl110)] { + use ffi::DH_set0_pqg; + } else { + #[allow(bad_style)] + unsafe fn DH_set0_pqg( + dh: *mut ffi::DH, + p: *mut ffi::BIGNUM, + q: *mut ffi::BIGNUM, + g: *mut ffi::BIGNUM, + ) -> ::libc::c_int { + (*dh).p = p; + (*dh).q = q; + (*dh).g = g; + 1 + } } } #[cfg(test)] mod tests { - use dh::Dh; use bn::BigNum; + use dh::Dh; use ssl::{SslContext, SslMethod}; #[test] diff --git a/openssl/src/dsa.rs b/openssl/src/dsa.rs index 0a14ccc3..abc2e297 100644 --- a/openssl/src/dsa.rs +++ b/openssl/src/dsa.rs @@ -11,10 +11,10 @@ use libc::c_int; use std::fmt; use std::ptr; -use {cvt, cvt_p}; use bn::BigNumRef; use error::ErrorStack; use pkey::{HasParams, HasPublic, Private, Public}; +use {cvt, cvt_p}; generic_foreign_type_and_impl_send_sync! { type CType = ffi::DSA; @@ -101,7 +101,8 @@ where /// Returns the DSA prime parameter of `self`. pub fn p(&self) -> &BigNumRef { unsafe { - let p = compat::pqg(self.as_ptr())[0]; + let mut p = ptr::null(); + DSA_get0_pqg(self.as_ptr(), &mut p, ptr::null_mut(), ptr::null_mut()); BigNumRef::from_ptr(p as *mut _) } } @@ -109,7 +110,8 @@ where /// Returns the DSA sub-prime parameter of `self`. pub fn q(&self) -> &BigNumRef { unsafe { - let q = compat::pqg(self.as_ptr())[1]; + let mut q = ptr::null(); + DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), &mut q, ptr::null_mut()); BigNumRef::from_ptr(q as *mut _) } } @@ -117,7 +119,8 @@ where /// Returns the DSA base parameter of `self`. pub fn g(&self) -> &BigNumRef { unsafe { - let g = compat::pqg(self.as_ptr())[2]; + let mut g = ptr::null(); + DSA_get0_pqg(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut g); BigNumRef::from_ptr(g as *mut _) } } @@ -184,24 +187,27 @@ impl<T> fmt::Debug for Dsa<T> { } } -#[cfg(ossl110)] -mod compat { - use std::ptr; - use ffi::{self, BIGNUM, DSA}; - - pub unsafe fn pqg(d: *const DSA) -> [*const BIGNUM; 3] { - let (mut p, mut q, mut g) = (ptr::null(), ptr::null(), ptr::null()); - ffi::DSA_get0_pqg(d, &mut p, &mut q, &mut g); - [p, q, g] - } -} - -#[cfg(ossl10x)] -mod compat { - use ffi::{BIGNUM, DSA}; - - pub unsafe fn pqg(d: *const DSA) -> [*const BIGNUM; 3] { - [(*d).p, (*d).q, (*d).g] +cfg_if! { + if #[cfg(ossl110)] { + use ffi::DSA_get0_pqg; + } else { + #[allow(bad_style)] + unsafe fn DSA_get0_pqg( + d: *mut ffi::DSA, + p: *mut *const ffi::BIGNUM, + q: *mut *const ffi::BIGNUM, + g: *mut *const ffi::BIGNUM) + { + if !p.is_null() { + *p = (*d).p; + } + if !q.is_null() { + *q = (*d).q; + } + if !g.is_null() { + *g = (*d).g; + } + } } } diff --git a/openssl/src/ecdsa.rs b/openssl/src/ecdsa.rs index 120f6531..d07dfda4 100644 --- a/openssl/src/ecdsa.rs +++ b/openssl/src/ecdsa.rs @@ -3,12 +3,13 @@ use ffi; use foreign_types::{ForeignType, ForeignTypeRef}; use libc::c_int; use std::mem; +use std::ptr; use bn::{BigNum, BigNumRef}; -use {cvt, cvt_n, cvt_p}; use ec::EcKeyRef; use error::ErrorStack; use pkey::{Private, Public}; +use {cvt_n, cvt_p}; foreign_type_and_impl_send_sync! { type CType = ffi::ECDSA_SIG; @@ -53,7 +54,7 @@ impl EcdsaSig { pub fn from_private_components(r: BigNum, s: BigNum) -> Result<EcdsaSig, ErrorStack> { unsafe { let sig = cvt_p(ffi::ECDSA_SIG_new())?; - cvt(compat::set_numbers(sig, r.as_ptr(), s.as_ptr()))?; + ECDSA_SIG_set0(sig, r.as_ptr(), s.as_ptr()); mem::forget((r, s)); Ok(EcdsaSig::from_ptr(sig as *mut _)) } @@ -83,8 +84,9 @@ impl EcdsaSig { /// [`ECDSA_SIG_get0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_get0.html pub fn r(&self) -> &BigNumRef { unsafe { - let xs = compat::get_numbers(self.as_ptr()); - BigNumRef::from_ptr(xs[0] as *mut _) + let mut r = ptr::null(); + ECDSA_SIG_get0(self.as_ptr(), &mut r, ptr::null_mut()); + BigNumRef::from_ptr(r as *mut _) } } @@ -95,53 +97,50 @@ impl EcdsaSig { /// [`ECDSA_SIG_get0`]: https://www.openssl.org/docs/man1.1.0/crypto/ECDSA_SIG_get0.html pub fn s(&self) -> &BigNumRef { unsafe { - let xs = compat::get_numbers(self.as_ptr()); - BigNumRef::from_ptr(xs[1] as *mut _) + let mut s = ptr::null(); + ECDSA_SIG_get0(self.as_ptr(), ptr::null_mut(), &mut s); + BigNumRef::from_ptr(s as *mut _) } } } -#[cfg(ossl110)] -mod compat { - use std::ptr; - - use libc::c_int; - use ffi::{self, BIGNUM, ECDSA_SIG}; - - pub unsafe fn set_numbers(sig: *mut ECDSA_SIG, r: *mut BIGNUM, s: *mut BIGNUM) -> c_int { - ffi::ECDSA_SIG_set0(sig, r, s) - } - - pub unsafe fn get_numbers(sig: *mut ECDSA_SIG) -> [*const BIGNUM; 2] { - let (mut r, mut s) = (ptr::null(), ptr::null()); - ffi::ECDSA_SIG_get0(sig, &mut r, &mut s); - [r, s] - } -} - -#[cfg(ossl10x)] -mod compat { - use libc::c_int; - use ffi::{BIGNUM, ECDSA_SIG}; - - pub unsafe fn set_numbers(sig: *mut ECDSA_SIG, r: *mut BIGNUM, s: *mut BIGNUM) -> c_int { - (*sig).r = r; - (*sig).s = s; - 1 - } +cfg_if! { + if #[cfg(ossl110)] { + use ffi::{ECDSA_SIG_set0, ECDSA_SIG_get0}; + } else { + #[allow(bad_style)] + unsafe fn ECDSA_SIG_set0( + sig: *mut ffi::ECDSA_SIG, + r: *mut ffi::BIGNUM, + s: *mut ffi::BIGNUM, + ) -> c_int { + (*sig).r = r; + (*sig).s = s; + 1 + } - pub unsafe fn get_numbers(sig: *mut ECDSA_SIG) -> [*const BIGNUM; 2] { - [(*sig).r, (*sig).s] + #[allow(bad_style)] + unsafe fn ECDSA_SIG_get0( + sig: *const ffi::ECDSA_SIG, + pr: *mut *const ffi::BIGNUM, + ps: *mut *const ffi::BIGNUM) + { + if !pr.is_null() { + (*pr) = (*sig).r; + } + if !ps.is_null() { + (*ps) = (*sig).s; + } + } } - } #[cfg(test)] mod test { - use nid::Nid; + use super::*; use ec::EcGroup; use ec::EcKey; - use super::*; + use nid::Nid; #[cfg(not(osslconf = "OPENSSL_NO_EC2M"))] static CURVE_IDENTIFER: Nid = Nid::X9_62_PRIME192V1; @@ -171,7 +170,8 @@ mod test { assert!(verification); // Signature will not be verified using the incorrect data but the correct public key - let verification2 = res.verify(String::from("hello2").as_bytes(), &public_key) + let verification2 = res + .verify(String::from("hello2").as_bytes(), &public_key) .unwrap(); assert!(verification2 == false); diff --git a/openssl/src/hash.rs b/openssl/src/hash.rs index 726ebe9c..582a2ada 100644 --- a/openssl/src/hash.rs +++ b/openssl/src/hash.rs @@ -1,22 +1,27 @@ -use std::io::prelude::*; +use ffi; +use std::fmt; use std::io; +use std::io::prelude::*; use std::ops::{Deref, DerefMut}; -use std::fmt; -use ffi; -#[cfg(ossl110)] -use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; -#[cfg(any(ossl101, ossl102))] -use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; +cfg_if! { + if #[cfg(ossl110)] { + use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; + } else { + use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; + } +} -use {cvt, cvt_p}; use error::ErrorStack; +use {cvt, cvt_p}; #[derive(Copy, Clone)] pub struct MessageDigest(*const ffi::EVP_MD); impl MessageDigest { - pub unsafe fn from_ptr(x: *const ffi::EVP_MD) -> Self { MessageDigest(x) } + pub unsafe fn from_ptr(x: *const ffi::EVP_MD) -> Self { + MessageDigest(x) + } pub fn md5() -> MessageDigest { unsafe { MessageDigest(ffi::EVP_md5()) } @@ -382,12 +387,10 @@ mod tests { #[test] fn test_sha256() { - let tests = [ - ( - "616263", - "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", - ), - ]; + let tests = [( + "616263", + "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", + )]; for test in tests.iter() { hash_test(MessageDigest::sha256(), test); diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index a66a7743..d74ce65f 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -3,6 +3,8 @@ #[macro_use] extern crate bitflags; #[macro_use] +extern crate cfg_if; +#[macro_use] extern crate foreign_types; #[macro_use] extern crate lazy_static; @@ -53,8 +55,8 @@ pub mod pkcs5; pub mod pkey; pub mod rand; pub mod rsa; -pub mod sign; pub mod sha; +pub mod sign; pub mod ssl; pub mod stack; pub mod string; diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs index 718ae59d..92a5799e 100644 --- a/openssl/src/rsa.rs +++ b/openssl/src/rsa.rs @@ -189,7 +189,8 @@ where /// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html pub fn d(&self) -> &BigNumRef { unsafe { - let d = compat::key(self.as_ptr())[2]; + let mut d = ptr::null(); + RSA_get0_key(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut d); BigNumRef::from_ptr(d as *mut _) } } @@ -201,7 +202,8 @@ where /// [`RSA_get0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html pub fn p(&self) -> Option<&BigNumRef> { unsafe { - let p = compat::factors(self.as_ptr())[0]; + let mut p = ptr::null(); + RSA_get0_factors(self.as_ptr(), &mut p, ptr::null_mut()); if p.is_null() { None } else { @@ -217,7 +219,8 @@ where /// [`RSA_get0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html pub fn q(&self) -> Option<&BigNumRef> { unsafe { - let q = compat::factors(self.as_ptr())[1]; + let mut q = ptr::null(); + RSA_get0_factors(self.as_ptr(), ptr::null_mut(), &mut q); if q.is_null() { None } else { @@ -233,7 +236,8 @@ where /// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html pub fn dmp1(&self) -> Option<&BigNumRef> { unsafe { - let dp = compat::crt_params(self.as_ptr())[0]; + let mut dp = ptr::null(); + RSA_get0_crt_params(self.as_ptr(), &mut dp, ptr::null_mut(), ptr::null_mut()); if dp.is_null() { None } else { @@ -249,7 +253,8 @@ where /// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html pub fn dmq1(&self) -> Option<&BigNumRef> { unsafe { - let dq = compat::crt_params(self.as_ptr())[1]; + let mut dq = ptr::null(); + RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), &mut dq, ptr::null_mut()); if dq.is_null() { None } else { @@ -265,7 +270,8 @@ where /// [`RSA_get0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html pub fn iqmp(&self) -> Option<&BigNumRef> { unsafe { - let qi = compat::crt_params(self.as_ptr())[2]; + let mut qi = ptr::null(); + RSA_get0_crt_params(self.as_ptr(), ptr::null_mut(), ptr::null_mut(), &mut qi); if qi.is_null() { None } else { @@ -391,7 +397,8 @@ where /// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html pub fn n(&self) -> &BigNumRef { unsafe { - let n = compat::key(self.as_ptr())[0]; + let mut n = ptr::null(); + RSA_get0_key(self.as_ptr(), &mut n, ptr::null_mut(), ptr::null_mut()); BigNumRef::from_ptr(n as *mut _) } } @@ -403,7 +410,8 @@ where /// [`RSA_get0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_get0_key.html pub fn e(&self) -> &BigNumRef { unsafe { - let e = compat::key(self.as_ptr())[1]; + let mut e = ptr::null(); + RSA_get0_key(self.as_ptr(), ptr::null_mut(), &mut e, ptr::null_mut()); BigNumRef::from_ptr(e as *mut _) } } @@ -421,15 +429,10 @@ impl Rsa<Public> { /// [`RSA_set0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_key.html pub fn from_public_components(n: BigNum, e: BigNum) -> Result<Rsa<Public>, ErrorStack> { unsafe { - let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?); - cvt(compat::set_key( - rsa.0, - n.as_ptr(), - e.as_ptr(), - ptr::null_mut(), - ))?; + let rsa = cvt_p(ffi::RSA_new())?; + RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), ptr::null_mut()); mem::forget((n, e)); - Ok(rsa) + Ok(Rsa::from_ptr(rsa)) } } @@ -498,10 +501,12 @@ impl RsaPrivateKeyBuilder { /// [`RSA_set0_key`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_key.html pub fn new(n: BigNum, e: BigNum, d: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> { unsafe { - let rsa = Rsa::from_ptr(cvt_p(ffi::RSA_new())?); - cvt(compat::set_key(rsa.0, n.as_ptr(), e.as_ptr(), d.as_ptr()))?; + let rsa = cvt_p(ffi::RSA_new())?; + RSA_set0_key(rsa, n.as_ptr(), e.as_ptr(), d.as_ptr()); mem::forget((n, e, d)); - Ok(RsaPrivateKeyBuilder { rsa }) + Ok(RsaPrivateKeyBuilder { + rsa: Rsa::from_ptr(rsa), + }) } } @@ -512,9 +517,10 @@ impl RsaPrivateKeyBuilder { /// This correspond to [`RSA_set0_factors`]. /// /// [`RSA_set0_factors`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_factors.html + // FIXME should be infallible pub fn set_factors(self, p: BigNum, q: BigNum) -> Result<RsaPrivateKeyBuilder, ErrorStack> { unsafe { - cvt(compat::set_factors(self.rsa.0, p.as_ptr(), q.as_ptr()))?; + RSA_set0_factors(self.rsa.as_ptr(), p.as_ptr(), q.as_ptr()); mem::forget((p, q)); } Ok(self) @@ -528,6 +534,7 @@ impl RsaPrivateKeyBuilder { /// This correspond to [`RSA_set0_crt_params`]. /// /// [`RSA_set0_crt_params`]: https://www.openssl.org/docs/man1.1.0/crypto/RSA_set0_crt_params.html + // FIXME should be infallible pub fn set_crt_params( self, dmp1: BigNum, @@ -535,12 +542,12 @@ impl RsaPrivateKeyBuilder { iqmp: BigNum, ) -> Result<RsaPrivateKeyBuilder, ErrorStack> { unsafe { - cvt(compat::set_crt_params( - self.rsa.0, + RSA_set0_crt_params( + self.rsa.as_ptr(), dmp1.as_ptr(), dmq1.as_ptr(), iqmp.as_ptr(), - ))?; + ); mem::forget((dmp1, dmq1, iqmp)); } Ok(self) @@ -637,89 +644,99 @@ impl<T> fmt::Debug for Rsa<T> { } } -#[cfg(ossl110)] -mod compat { - use std::ptr; - - use ffi::{self, BIGNUM, RSA}; - use libc::c_int; - - pub unsafe fn key(r: *const RSA) -> [*const BIGNUM; 3] { - let (mut n, mut e, mut d) = (ptr::null(), ptr::null(), ptr::null()); - ffi::RSA_get0_key(r, &mut n, &mut e, &mut d); - [n, e, d] - } - - pub unsafe fn factors(r: *const RSA) -> [*const BIGNUM; 2] { - let (mut p, mut q) = (ptr::null(), ptr::null()); - ffi::RSA_get0_factors(r, &mut p, &mut q); - [p, q] - } - - pub unsafe fn crt_params(r: *const RSA) -> [*const BIGNUM; 3] { - let (mut dp, mut dq, mut qi) = (ptr::null(), ptr::null(), ptr::null()); - ffi::RSA_get0_crt_params(r, &mut dp, &mut dq, &mut qi); - [dp, dq, qi] - } - - pub unsafe fn set_key(r: *mut RSA, n: *mut BIGNUM, e: *mut BIGNUM, d: *mut BIGNUM) -> c_int { - ffi::RSA_set0_key(r, n, e, d) - } - - pub unsafe fn set_factors(r: *mut RSA, p: *mut BIGNUM, q: *mut BIGNUM) -> c_int { - ffi::RSA_set0_factors(r, p, q) - } - - pub unsafe fn set_crt_params( - r: *mut RSA, - dmp1: *mut BIGNUM, - dmq1: *mut BIGNUM, - iqmp: *mut BIGNUM, - ) -> c_int { - ffi::RSA_set0_crt_params(r, dmp1, dmq1, iqmp) - } -} - -#[cfg(ossl10x)] -mod compat { - use ffi::{BIGNUM, RSA}; - use libc::c_int; - - pub unsafe fn key(r: *const RSA) -> [*const BIGNUM; 3] { - [(*r).n, (*r).e, (*r).d] - } +cfg_if! { + if #[cfg(ossl110)] { + use ffi::{ + RSA_get0_key, RSA_get0_factors, RSA_get0_crt_params, RSA_set0_key, RSA_set0_factors, + RSA_set0_crt_params, + }; + } else { + #[allow(bad_style)] + unsafe fn RSA_get0_key( + r: *const ffi::RSA, + n: *mut *const ffi::BIGNUM, + e: *mut *const ffi::BIGNUM, + d: *mut *const ffi::BIGNUM, + ) { + if !n.is_null() { + *n = (*r).n; + } + if !e.is_null() { + *e = (*r).e; + } + if !d.is_null() { + *d = (*r).d; + } + } - pub unsafe fn factors(r: *const RSA) -> [*const BIGNUM; 2] { - [(*r).p, (*r).q] - } + #[allow(bad_style)] + unsafe fn RSA_get0_factors( + r: *const ffi::RSA, + p: *mut *const ffi::BIGNUM, + q: *mut *const ffi::BIGNUM, + ) { + if !p.is_null() { + *p = (*r).p; + } + if !q.is_null() { + *q = (*r).q; + } + } - pub unsafe fn crt_params(r: *const RSA) -> [*const BIGNUM; 3] { - [(*r).dmp1, (*r).dmq1, (*r).iqmp] - } + #[allow(bad_style)] + unsafe fn RSA_get0_crt_params( + r: *const ffi::RSA, + dmp1: *mut *const ffi::BIGNUM, + dmq1: *mut *const ffi::BIGNUM, + iqmp: *mut *const ffi::BIGNUM, + ) { + if !dmp1.is_null() { + *dmp1 = (*r).dmp1; + } + if !dmq1.is_null() { + *dmq1 = (*r).dmq1; + } + if !iqmp.is_null() { + *iqmp = (*r).iqmp; + } + } - pub unsafe fn set_key(r: *mut RSA, n: *mut BIGNUM, e: *mut BIGNUM, d: *mut BIGNUM) -> c_int { - (*r).n = n; - (*r).e = e; - (*r).d = d; - 1 // TODO: is this right? should it be 0? what's success? - } + #[allow(bad_style)] + unsafe fn RSA_set0_key( + r: *mut ffi::RSA, + n: *mut ffi::BIGNUM, + e: *mut ffi::BIGNUM, + d: *mut ffi::BIGNUM, + ) -> c_int { + (*r).n = n; + (*r).e = e; + (*r).d = d; + 1 + } - pub unsafe fn set_factors(r: *mut RSA, p: *mut BIGNUM, q: *mut BIGNUM) -> c_int { - (*r).p = p; - (*r).q = q; - 1 // TODO: is this right? should it be 0? what's success? - } + #[allow(bad_style)] + unsafe fn RSA_set0_factors( + r: *mut ffi::RSA, + p: *mut ffi::BIGNUM, + q: *mut ffi::BIGNUM, + ) -> c_int { + (*r).p = p; + (*r).q = q; + 1 + } - pub unsafe fn set_crt_params( - r: *mut RSA, - dmp1: *mut BIGNUM, - dmq1: *mut BIGNUM, - iqmp: *mut BIGNUM, - ) -> c_int { - (*r).dmp1 = dmp1; - (*r).dmq1 = dmq1; - (*r).iqmp = iqmp; - 1 // TODO: is this right? should it be 0? what's success? + #[allow(bad_style)] + unsafe fn RSA_set0_crt_params( + r: *mut ffi::RSA, + dmp1: *mut ffi::BIGNUM, + dmq1: *mut ffi::BIGNUM, + iqmp: *mut ffi::BIGNUM, + ) -> c_int { + (*r).dmp1 = dmp1; + (*r).dmq1 = dmq1; + (*r).iqmp = iqmp; + 1 + } } } diff --git a/openssl/src/sign.rs b/openssl/src/sign.rs index c8032686..849831ed 100644 --- a/openssl/src/sign.rs +++ b/openssl/src/sign.rs @@ -63,21 +63,24 @@ //! ``` use ffi; use foreign_types::ForeignTypeRef; +use libc::c_int; use std::io::{self, Write}; use std::marker::PhantomData; use std::ptr; -use libc::c_int; -use {cvt, cvt_p}; +use error::ErrorStack; use hash::MessageDigest; use pkey::{HasPrivate, HasPublic, PKeyRef}; -use error::ErrorStack; use rsa::Padding; +use {cvt, cvt_p}; -#[cfg(ossl110)] -use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; -#[cfg(any(ossl101, ossl102))] -use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; +cfg_if! { + if #[cfg(ossl110)] { + use ffi::{EVP_MD_CTX_free, EVP_MD_CTX_new}; + } else { + use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; + } +} /// Salt lengths that must be used with `set_rsa_pss_saltlen`. pub struct RsaPssSaltlen(c_int); @@ -459,7 +462,7 @@ impl<'a> Verifier<'a> { pub fn verify(&self, signature: &[u8]) -> Result<bool, ErrorStack> { unsafe { let r = - EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *const _, signature.len()); + EVP_DigestVerifyFinal(self.md_ctx, signature.as_ptr() as *mut _, signature.len()); match r { 1 => Ok(true), 0 => { @@ -501,12 +504,12 @@ mod test { use hex::{self, FromHex}; use std::iter; - use hash::MessageDigest; - use sign::{RsaPssSaltlen, Signer, Verifier}; use ec::{EcGroup, EcKey}; + use hash::MessageDigest; use nid::Nid; - use rsa::{Padding, Rsa}; use pkey::PKey; + use rsa::{Padding, Rsa}; + use sign::{RsaPssSaltlen, Signer, Verifier}; const INPUT: &'static str = "65794a68624763694f694a53557a49314e694a392e65794a7063334d694f694a71623255694c41304b49434a6c\ @@ -673,7 +676,7 @@ mod test { signer.update(data as &[u8]).unwrap(); let expected = vec![ - 136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19 + 136, 101, 61, 167, 61, 30, 248, 234, 124, 166, 196, 157, 203, 52, 171, 19, ]; assert_eq!(signer.sign_to_vec().unwrap(), expected); } diff --git a/openssl/src/ssl/bio.rs b/openssl/src/ssl/bio.rs index 4b792a75..1a149b6d 100644 --- a/openssl/src/ssl/bio.rs +++ b/openssl/src/ssl/bio.rs @@ -1,11 +1,13 @@ +use ffi::{ + self, BIO_clear_retry_flags, BIO_new, BIO_set_retry_read, BIO_set_retry_write, BIO, + BIO_CTRL_FLUSH, +}; use libc::{c_char, c_int, c_long, c_void, strlen}; -use ffi::{BIO, BIO_CTRL_FLUSH, BIO_new, BIO_clear_retry_flags, BIO_set_retry_read, - BIO_set_retry_write}; use std::any::Any; use std::io; use std::io::prelude::*; use std::mem; -use std::panic::{AssertUnwindSafe, catch_unwind}; +use std::panic::{catch_unwind, AssertUnwindSafe}; use std::ptr; use std::slice; @@ -19,11 +21,11 @@ pub struct StreamState<S> { } /// Safe wrapper for BIO_METHOD -pub struct BioMethod(compat::BIO_METHOD); +pub struct BioMethod(BIO_METHOD); impl BioMethod { fn new<S: Read + Write>() -> BioMethod { - BioMethod(compat::BIO_METHOD::new::<S>()) + BioMethod(BIO_METHOD::new::<S>()) } } @@ -41,8 +43,8 @@ pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, BioMethod), ErrorSta unsafe { let bio = cvt_p(BIO_new(method.0.get()))?; - compat::BIO_set_data(bio, Box::into_raw(state) as *mut _); - compat::BIO_set_init(bio, 1); + BIO_set_data(bio, Box::into_raw(state) as *mut _); + BIO_set_init(bio, 1); return Ok((bio, method)); } @@ -59,7 +61,7 @@ pub unsafe fn take_panic<S>(bio: *mut BIO) -> Option<Box<Any + Send>> { } pub unsafe fn get_ref<'a, S: 'a>(bio: *mut BIO) -> &'a S { - let state: &'a StreamState<S> = mem::transmute(compat::BIO_get_data(bio)); + let state: &'a StreamState<S> = mem::transmute(BIO_get_data(bio)); &state.stream } @@ -68,7 +70,7 @@ pub unsafe fn get_mut<'a, S: 'a>(bio: *mut BIO) -> &'a mut S { } unsafe fn state<'a, S: 'a>(bio: *mut BIO) -> &'a mut StreamState<S> { - &mut *(compat::BIO_get_data(bio) as *mut _) + &mut *(BIO_get_data(bio) as *mut _) } unsafe extern "C" fn bwrite<S: Write>(bio: *mut BIO, buf: *const c_char, len: c_int) -> c_int { @@ -117,8 +119,7 @@ unsafe extern "C" fn bread<S: Read>(bio: *mut BIO, buf: *mut c_char, len: c_int) fn retriable_error(err: &io::Error) -> bool { match err.kind() { - io::ErrorKind::WouldBlock | - io::ErrorKind::NotConnected => true, + io::ErrorKind::WouldBlock | io::ErrorKind::NotConnected => true, _ => false, } } @@ -153,10 +154,10 @@ unsafe extern "C" fn ctrl<S: Write>( } unsafe extern "C" fn create(bio: *mut BIO) -> c_int { - compat::BIO_set_init(bio, 0); - compat::BIO_set_num(bio, 0); - compat::BIO_set_data(bio, ptr::null_mut()); - compat::BIO_set_flags(bio, 0); + BIO_set_init(bio, 0); + BIO_set_num(bio, 0); + BIO_set_data(bio, ptr::null_mut()); + BIO_set_flags(bio, 0); 1 } @@ -165,115 +166,110 @@ unsafe extern "C" fn destroy<S>(bio: *mut BIO) -> c_int { return 0; } - let data = compat::BIO_get_data(bio); + let data = BIO_get_data(bio); assert!(!data.is_null()); Box::<StreamState<S>>::from_raw(data as *mut _); - compat::BIO_set_data(bio, ptr::null_mut()); - compat::BIO_set_init(bio, 0); + BIO_set_data(bio, ptr::null_mut()); + BIO_set_init(bio, 0); 1 } -#[cfg(ossl110)] -#[allow(bad_style)] -mod compat { - use std::io::{Read, Write}; - - use libc::c_int; - use ffi; - pub use ffi::{BIO_set_init, BIO_set_flags, BIO_set_data, BIO_get_data}; - - pub unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {} - - pub struct BIO_METHOD(*mut ffi::BIO_METHOD); - - impl BIO_METHOD { - pub fn new<S: Read + Write>() -> BIO_METHOD { - unsafe { - let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, b"rust\0".as_ptr() as *const _); - assert!(!ptr.is_null()); - let ret = BIO_METHOD(ptr); - assert!(ffi::BIO_meth_set_write(ptr, super::bwrite::<S>) != 0); - assert!(ffi::BIO_meth_set_read(ptr, super::bread::<S>) != 0); - assert!(ffi::BIO_meth_set_puts(ptr, super::bputs::<S>) != 0); - assert!(ffi::BIO_meth_set_ctrl(ptr, super::ctrl::<S>) != 0); - assert!(ffi::BIO_meth_set_create(ptr, super::create) != 0); - assert!(ffi::BIO_meth_set_destroy(ptr, super::destroy::<S>) != 0); - return ret; +cfg_if! { + if #[cfg(ossl110)] { + use ffi::{BIO_get_data, BIO_set_data, BIO_set_flags, BIO_set_init}; + + #[allow(bad_style)] + unsafe fn BIO_set_num(_bio: *mut ffi::BIO, _num: c_int) {} + + #[allow(bad_style)] + struct BIO_METHOD(*mut ffi::BIO_METHOD); + + impl BIO_METHOD { + fn new<S: Read + Write>() -> BIO_METHOD { + unsafe { + let ptr = ffi::BIO_meth_new(ffi::BIO_TYPE_NONE, b"rust\0".as_ptr() as *const _); + assert!(!ptr.is_null()); + let ret = BIO_METHOD(ptr); + assert!(ffi::BIO_meth_set_write(ptr, bwrite::<S>) != 0); + assert!(ffi::BIO_meth_set_read(ptr, bread::<S>) != 0); + assert!(ffi::BIO_meth_set_puts(ptr, bputs::<S>) != 0); + assert!(ffi::BIO_meth_set_ctrl(ptr, ctrl::<S>) != 0); + assert!(ffi::BIO_meth_set_create(ptr, create) != 0); + assert!(ffi::BIO_meth_set_destroy(ptr, destroy::<S>) != 0); + return ret; + } } - } - - pub fn get(&self) -> *mut ffi::BIO_METHOD { - self.0 - } - } - impl Drop for BIO_METHOD { - fn drop(&mut self) { - unsafe { - ffi::BIO_meth_free(self.0); + fn get(&self) -> *mut ffi::BIO_METHOD { + self.0 } } - } -} -#[cfg(ossl10x)] -#[allow(bad_style)] -mod compat { - use std::io::{Read, Write}; - - use ffi; - use libc::{c_int, c_void}; - - pub struct BIO_METHOD(*mut ffi::BIO_METHOD); - - impl BIO_METHOD { - pub fn new<S: Read + Write>() -> BIO_METHOD { - let ptr = Box::new(ffi::BIO_METHOD { - type_: ffi::BIO_TYPE_NONE, - name: b"rust\0".as_ptr() as *const _, - bwrite: Some(super::bwrite::<S>), - bread: Some(super::bread::<S>), - bputs: Some(super::bputs::<S>), - bgets: None, - ctrl: Some(super::ctrl::<S>), - create: Some(super::create), - destroy: Some(super::destroy::<S>), - callback_ctrl: None, - }); - - BIO_METHOD(Box::into_raw(ptr)) + impl Drop for BIO_METHOD { + fn drop(&mut self) { + unsafe { + ffi::BIO_meth_free(self.0); + } + } } + } else { + #[allow(bad_style)] + struct BIO_METHOD(*mut ffi::BIO_METHOD); + + impl BIO_METHOD { + fn new<S: Read + Write>() -> BIO_METHOD { + let ptr = Box::new(ffi::BIO_METHOD { + type_: ffi::BIO_TYPE_NONE, + name: b"rust\0".as_ptr() as *const _, + bwrite: Some(bwrite::<S>), + bread: Some(bread::<S>), + bputs: Some(bputs::<S>), + bgets: None, + ctrl: Some(ctrl::<S>), + create: Some(create), + destroy: Some(destroy::<S>), + callback_ctrl: None, + }); + + BIO_METHOD(Box::into_raw(ptr)) + } - pub fn get(&self) -> *mut ffi::BIO_METHOD { - self.0 + fn get(&self) -> *mut ffi::BIO_METHOD { + self.0 + } } - } - impl Drop for BIO_METHOD { - fn drop(&mut self) { - unsafe { - Box::<ffi::BIO_METHOD>::from_raw(self.0); + impl Drop for BIO_METHOD { + fn drop(&mut self) { + unsafe { + Box::<ffi::BIO_METHOD>::from_raw(self.0); + } } } - } - pub unsafe fn BIO_set_init(bio: *mut ffi::BIO, init: c_int) { - (*bio).init = init; - } + #[allow(bad_style)] + unsafe fn BIO_set_init(bio: *mut ffi::BIO, init: c_int) { + (*bio).init = init; + } - pub unsafe fn BIO_set_flags(bio: *mut ffi::BIO, flags: c_int) { - (*bio).flags = flags; - } + #[allow(bad_style)] + unsafe fn BIO_set_flags(bio: *mut ffi::BIO, flags: c_int) { + (*bio).flags = flags; + } - pub unsafe fn BIO_get_data(bio: *mut ffi::BIO) -> *mut c_void { - (*bio).ptr - } + #[allow(bad_style)] + unsafe fn BIO_get_data(bio: *mut ffi::BIO) -> *mut c_void { + (*bio).ptr + } - pub unsafe fn BIO_set_data(bio: *mut ffi::BIO, data: *mut c_void) { - (*bio).ptr = data; - } + #[allow(bad_style)] + unsafe fn BIO_set_data(bio: *mut ffi::BIO, data: *mut c_void) { + (*bio).ptr = data; + } - pub unsafe fn BIO_set_num(bio: *mut ffi::BIO, num: c_int) { - (*bio).num = num; + #[allow(bad_style)] + unsafe fn BIO_set_num(bio: *mut ffi::BIO, num: c_int) { + (*bio).num = num; + } } } diff --git a/openssl/src/ssl/callbacks.rs b/openssl/src/ssl/callbacks.rs index fd5b7ef5..6ec9aef9 100644 --- a/openssl/src/ssl/callbacks.rs +++ b/openssl/src/ssl/callbacks.rs @@ -13,11 +13,11 @@ use std::str; use std::sync::Arc; use dh::Dh; -#[cfg(any(ossl101, ossl102))] +#[cfg(all(ossl101, not(ossl110)))] use ec::EcKey; use error::ErrorStack; use pkey::Params; -#[cfg(any(ossl102, ossl110))] +#[cfg(ossl102)] use ssl::AlpnError; #[cfg(ossl111)] use ssl::ExtensionContext; @@ -37,7 +37,8 @@ where // raw pointer shenanigans to break the borrow of ctx // the callback can't mess with its own ex_data slot so this is safe - let verify = ctx.ex_data(ssl_idx) + let verify = ctx + .ex_data(ssl_idx) .expect("BUG: store context missing ssl") .ssl_context() .ex_data(verify_idx) @@ -66,7 +67,8 @@ where let ssl = SslRef::from_ptr_mut(ssl); let callback_idx = SslContext::cached_ex_index::<F>(); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(callback_idx) .expect("BUG: psk callback missing") as *const F; let hint = if hint != ptr::null() { @@ -96,7 +98,8 @@ where let ssl_idx = X509StoreContext::ssl_idx().expect("BUG: store context ssl index missing"); let callback_idx = Ssl::cached_ex_index::<Arc<F>>(); - let callback = ctx.ex_data(ssl_idx) + let callback = ctx + .ex_data(ssl_idx) .expect("BUG: store context missing ssl") .ex_data(callback_idx) .expect("BUG: ssl verify callback missing") @@ -112,7 +115,8 @@ where { unsafe { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: sni callback missing") as *const F; let mut alert = SslAlert(*al); @@ -140,7 +144,8 @@ where { unsafe { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: alpn callback missing") as *const F; let protos = slice::from_raw_parts(inbuf as *const u8, inlen as usize); @@ -165,7 +170,8 @@ where F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send, { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: tmp dh callback missing") as *const F; @@ -182,7 +188,7 @@ where } } -#[cfg(any(ossl101, ossl102))] +#[cfg(all(ossl101, not(ossl110)))] pub unsafe extern "C" fn raw_tmp_ecdh<F>( ssl: *mut ffi::SSL, is_export: c_int, @@ -192,7 +198,8 @@ where F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send, { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: tmp ecdh callback missing") as *const F; @@ -218,7 +225,8 @@ where F: Fn(&mut SslRef, bool, u32) -> Result<Dh<Params>, ErrorStack> + 'static + Sync + Send, { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ex_data(Ssl::cached_ex_index::<Arc<F>>()) + let callback = ssl + .ex_data(Ssl::cached_ex_index::<Arc<F>>()) .expect("BUG: ssl tmp dh callback missing") .clone(); @@ -235,7 +243,7 @@ where } } -#[cfg(any(ossl101, ossl102))] +#[cfg(all(ossl101, not(ossl110)))] pub unsafe extern "C" fn raw_tmp_ecdh_ssl<F>( ssl: *mut ffi::SSL, is_export: c_int, @@ -245,7 +253,8 @@ where F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send, { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ex_data(Ssl::cached_ex_index::<Arc<F>>()) + let callback = ssl + .ex_data(Ssl::cached_ex_index::<Arc<F>>()) .expect("BUG: ssl tmp ecdh callback missing") .clone(); @@ -267,7 +276,8 @@ where F: Fn(&mut SslRef) -> Result<bool, ErrorStack> + 'static + Sync + Send, { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: ocsp callback missing") as *const F; let ret = (*callback)(ssl); @@ -301,7 +311,8 @@ where F: Fn(&mut SslRef, SslSession) + 'static + Sync + Send, { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: new session callback missing") as *const F; let session = SslSession::from_ptr(session); @@ -319,7 +330,8 @@ pub unsafe extern "C" fn raw_remove_session<F>( F: Fn(&SslContextRef, &SslSessionRef) + 'static + Sync + Send, { let ctx = SslContextRef::from_ptr(ctx); - let callback = ctx.ex_data(SslContext::cached_ex_index::<F>()) + let callback = ctx + .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: remove session callback missing"); let session = SslSessionRef::from_ptr(session); @@ -341,7 +353,8 @@ where F: Fn(&mut SslRef, &[u8]) -> Option<SslSession> + 'static + Sync + Send, { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: get session callback missing") as *const F; let data = slice::from_raw_parts(data as *const u8, len as usize); @@ -363,7 +376,8 @@ where F: Fn(&SslRef, &str) + 'static + Sync + Send, { let ssl = SslRef::from_ptr(ssl as *mut _); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: get session callback missing"); let line = CStr::from_ptr(line).to_bytes(); @@ -382,7 +396,8 @@ where F: Fn(&mut SslRef, &mut [u8]) -> Result<usize, ErrorStack> + 'static + Sync + Send, { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: stateless cookie generate callback missing") as *const F; let slice = slice::from_raw_parts_mut(cookie as *mut u8, ffi::SSL_COOKIE_LENGTH as usize); @@ -408,7 +423,8 @@ where F: Fn(&mut SslRef, &[u8]) -> bool + 'static + Sync + Send, { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: stateless cookie verify callback missing") as *const F; let slice = slice::from_raw_parts(cookie as *const c_uchar as *const u8, cookie_len as usize); @@ -425,7 +441,8 @@ where { unsafe { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: cookie generate callback missing") as *const F; // We subtract 1 from DTLS1_COOKIE_LENGTH as the ostensible value, 256, is erroneous but retained for @@ -461,7 +478,8 @@ where { unsafe { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: cookie verify callback missing") as *const F; let slice = @@ -494,7 +512,8 @@ where { unsafe { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: custom ext add callback missing") as *const F; let ectx = ExtensionContext::from_bits_truncate(context); @@ -570,7 +589,8 @@ where { unsafe { let ssl = SslRef::from_ptr_mut(ssl); - let callback = ssl.ssl_context() + let callback = ssl + .ssl_context() .ex_data(SslContext::cached_ex_index::<F>()) .expect("BUG: custom ext parse callback missing") as *const F; let ectx = ExtensionContext::from_bits_truncate(context); diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs index 9966a5a0..f10a0e23 100644 --- a/openssl/src/ssl/connector.rs +++ b/openssl/src/ssl/connector.rs @@ -3,16 +3,22 @@ use std::ops::{Deref, DerefMut}; use dh::Dh; use error::ErrorStack; -use ssl::{HandshakeError, Ssl, SslContext, SslContextBuilder, SslMethod, SslMode, SslOptions, - SslRef, SslStream, SslVerifyMode}; +use ssl::{ + HandshakeError, Ssl, SslContext, SslContextBuilder, SslMethod, SslMode, SslOptions, SslRef, + SslStream, SslVerifyMode, +}; use version; fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> { let mut ctx = SslContextBuilder::new(method)?; - let mut opts = SslOptions::ALL | SslOptions::NO_COMPRESSION | SslOptions::NO_SSLV2 - | SslOptions::NO_SSLV3 | SslOptions::SINGLE_DH_USE - | SslOptions::SINGLE_ECDH_USE | SslOptions::CIPHER_SERVER_PREFERENCE; + let mut opts = SslOptions::ALL + | SslOptions::NO_COMPRESSION + | SslOptions::NO_SSLV2 + | SslOptions::NO_SSLV3 + | SslOptions::SINGLE_DH_USE + | SslOptions::SINGLE_ECDH_USE + | SslOptions::CIPHER_SERVER_PREFERENCE; opts &= !SslOptions::DONT_INSERT_EMPTY_FRAGMENTS; ctx.set_options(opts); @@ -23,7 +29,7 @@ fn ctx(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> { // This is quite a useful optimization for saving memory, but historically // caused CVEs in OpenSSL pre-1.0.1h, according to // https://bugs.python.org/issue25672 - if version::number() >= 0x1000108f { + if version::number() >= 0x1_00_01_08_0 { mode |= SslMode::RELEASE_BUFFERS; } @@ -277,226 +283,228 @@ impl DerefMut for SslAcceptorBuilder { } } -#[cfg(ossl101)] -fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> { - use ec::EcKey; - use nid::Nid; - - let curve = EcKey::from_curve_name(Nid::X9_62_PRIME256V1)?; - ctx.set_tmp_ecdh(&curve) -} - -#[cfg(ossl102)] -fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> { - ctx.set_ecdh_auto(true) -} - -#[cfg(ossl110)] -fn setup_curves(_: &mut SslContextBuilder) -> Result<(), ErrorStack> { - Ok(()) -} - -#[cfg(any(ossl102, ossl110))] -fn setup_verify(ctx: &mut SslContextBuilder) { - ctx.set_verify(SslVerifyMode::PEER); -} - -#[cfg(ossl101)] -fn setup_verify(ctx: &mut SslContextBuilder) { - ctx.set_verify_callback(SslVerifyMode::PEER, verify::verify_callback); -} - -#[cfg(any(ossl102, ossl110))] -fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> { - use x509::verify::X509CheckFlags; +cfg_if! { + if #[cfg(ossl110)] { + fn setup_curves(_: &mut SslContextBuilder) -> Result<(), ErrorStack> { + Ok(()) + } + } else if #[cfg(any(ossl102, libressl))] { + fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> { + ctx.set_ecdh_auto(true) + } + } else { + fn setup_curves(ctx: &mut SslContextBuilder) -> Result<(), ErrorStack> { + use ec::EcKey; + use nid::Nid; - let param = ssl.param_mut(); - param.set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS); - match domain.parse() { - Ok(ip) => param.set_ip(ip), - Err(_) => param.set_host(domain), + let curve = EcKey::from_curve_name(Nid::X9_62_PRIME256V1)?; + ctx.set_tmp_ecdh(&curve) + } } } -#[cfg(ossl101)] -fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> { - let domain = domain.to_string(); - ssl.set_ex_data(*verify::HOSTNAME_IDX, domain); - Ok(()) -} - -#[cfg(ossl101)] -mod verify { - use std::net::IpAddr; - use std::str; - - use ex_data::Index; - use nid::Nid; - use x509::{GeneralName, X509NameRef, X509Ref, X509StoreContext, X509StoreContextRef, - X509VerifyResult}; - use stack::Stack; - use ssl::Ssl; +cfg_if! { + if #[cfg(any(ossl102, libressl261))] { + fn setup_verify(ctx: &mut SslContextBuilder) { + ctx.set_verify(SslVerifyMode::PEER); + } - lazy_static! { - pub static ref HOSTNAME_IDX: Index<Ssl, String> = Ssl::new_ex_index().unwrap(); - } + fn setup_verify_hostname(ssl: &mut SslRef, domain: &str) -> Result<(), ErrorStack> { + use x509::verify::X509CheckFlags; - pub fn verify_callback(preverify_ok: bool, x509_ctx: &mut X509StoreContextRef) -> bool { - if !preverify_ok || x509_ctx.error_depth() != 0 { - return preverify_ok; + let param = ssl.param_mut(); + param.set_hostflags(X509CheckFlags::NO_PARTIAL_WILDCARDS); + match domain.parse() { + Ok(ip) => param.set_ip(ip), + Err(_) => param.set_host(domain), + } + } + } else { + fn setup_verify(ctx: &mut SslContextBuilder) { + ctx.set_verify_callback(SslVerifyMode::PEER, verify::verify_callback); } - let ok = match ( - x509_ctx.current_cert(), - X509StoreContext::ssl_idx() - .ok() - .and_then(|idx| x509_ctx.ex_data(idx)) - .and_then(|ssl| ssl.ex_data(*HOSTNAME_IDX)), - ) { - (Some(x509), Some(domain)) => verify_hostname(domain, &x509), - _ => true, - }; - - if !ok { - x509_ctx.set_error(X509VerifyResult::APPLICATION_VERIFICATION); + fn setup_verify_hostname(ssl: &mut Ssl, domain: &str) -> Result<(), ErrorStack> { + let domain = domain.to_string(); + ssl.set_ex_data(*verify::HOSTNAME_IDX, domain); + Ok(()) } - ok - } + mod verify { + use std::net::IpAddr; + use std::str; + + use ex_data::Index; + use nid::Nid; + use ssl::Ssl; + use stack::Stack; + use x509::{ + GeneralName, X509NameRef, X509Ref, X509StoreContext, X509StoreContextRef, + X509VerifyResult, + }; + + lazy_static! { + pub static ref HOSTNAME_IDX: Index<Ssl, String> = Ssl::new_ex_index().unwrap(); + } - fn verify_hostname(domain: &str, cert: &X509Ref) -> bool { - match cert.subject_alt_names() { - Some(names) => verify_subject_alt_names(domain, names), - None => verify_subject_name(domain, &cert.subject_name()), - } - } + pub fn verify_callback(preverify_ok: bool, x509_ctx: &mut X509StoreContextRef) -> bool { + if !preverify_ok || x509_ctx.error_depth() != 0 { + return preverify_ok; + } + + let ok = match ( + x509_ctx.current_cert(), + X509StoreContext::ssl_idx() + .ok() + .and_then(|idx| x509_ctx.ex_data(idx)) + .and_then(|ssl| ssl.ex_data(*HOSTNAME_IDX)), + ) { + (Some(x509), Some(domain)) => verify_hostname(domain, &x509), + _ => true, + }; - fn verify_subject_alt_names(domain: &str, names: Stack<GeneralName>) -> bool { - let ip = domain.parse(); + if !ok { + x509_ctx.set_error(X509VerifyResult::APPLICATION_VERIFICATION); + } + + ok + } - for name in &names { - match ip { - Ok(ip) => { - if let Some(actual) = name.ipaddress() { - if matches_ip(&ip, actual) { - return true; + fn verify_hostname(domain: &str, cert: &X509Ref) -> bool { + match cert.subject_alt_names() { + Some(names) => verify_subject_alt_names(domain, names), + None => verify_subject_name(domain, &cert.subject_name()), + } + } + + fn verify_subject_alt_names(domain: &str, names: Stack<GeneralName>) -> bool { + let ip = domain.parse(); + + for name in &names { + match ip { + Ok(ip) => { + if let Some(actual) = name.ipaddress() { + if matches_ip(&ip, actual) { + return true; + } + } + } + Err(_) => { + if let Some(pattern) = name.dnsname() { + if matches_dns(pattern, domain) { + return true; + } + } } } } - Err(_) => { - if let Some(pattern) = name.dnsname() { - if matches_dns(pattern, domain) { - return true; + + false + } + + fn verify_subject_name(domain: &str, subject_name: &X509NameRef) -> bool { + match subject_name.entries_by_nid(Nid::COMMONNAME).next() { + Some(pattern) => { + let pattern = match str::from_utf8(pattern.data().as_slice()) { + Ok(pattern) => pattern, + Err(_) => return false, + }; + + // Unlike SANs, IP addresses in the subject name don't have a + // different encoding. + match domain.parse::<IpAddr>() { + Ok(ip) => pattern + .parse::<IpAddr>() + .ok() + .map_or(false, |pattern| pattern == ip), + Err(_) => matches_dns(pattern, domain), } } + None => false, } } - } - false - } - - fn verify_subject_name(domain: &str, subject_name: &X509NameRef) -> bool { - match subject_name.entries_by_nid(Nid::COMMONNAME).next() { - Some(pattern) => { - let pattern = match str::from_utf8(pattern.data().as_slice()) { - Ok(pattern) => pattern, - Err(_) => return false, - }; - - // Unlike SANs, IP addresses in the subject name don't have a - // different encoding. - match domain.parse::<IpAddr>() { - Ok(ip) => pattern - .parse::<IpAddr>() - .ok() - .map_or(false, |pattern| pattern == ip), - Err(_) => matches_dns(pattern, domain), + fn matches_dns(mut pattern: &str, mut hostname: &str) -> bool { + // first strip trailing . off of pattern and hostname to normalize + if pattern.ends_with('.') { + pattern = &pattern[..pattern.len() - 1]; } + if hostname.ends_with('.') { + hostname = &hostname[..hostname.len() - 1]; + } + + matches_wildcard(pattern, hostname).unwrap_or_else(|| pattern == hostname) } - None => false, - } - } - fn matches_dns(mut pattern: &str, mut hostname: &str) -> bool { - // first strip trailing . off of pattern and hostname to normalize - if pattern.ends_with('.') { - pattern = &pattern[..pattern.len() - 1]; - } - if hostname.ends_with('.') { - hostname = &hostname[..hostname.len() - 1]; - } + fn matches_wildcard(pattern: &str, hostname: &str) -> Option<bool> { + // internationalized domains can't involved in wildcards + if pattern.starts_with("xn--") { + return None; + } - matches_wildcard(pattern, hostname).unwrap_or_else(|| pattern == hostname) - } + let wildcard_location = match pattern.find('*') { + Some(l) => l, + None => return None, + }; - fn matches_wildcard(pattern: &str, hostname: &str) -> Option<bool> { - // internationalized domains can't involved in wildcards - if pattern.starts_with("xn--") { - return None; - } + let mut dot_idxs = pattern.match_indices('.').map(|(l, _)| l); + let wildcard_end = match dot_idxs.next() { + Some(l) => l, + None => return None, + }; - let wildcard_location = match pattern.find('*') { - Some(l) => l, - None => return None, - }; - - let mut dot_idxs = pattern.match_indices('.').map(|(l, _)| l); - let wildcard_end = match dot_idxs.next() { - Some(l) => l, - None => return None, - }; - - // Never match wildcards if the pattern has less than 2 '.'s (no *.com) - // - // This is a bit dubious, as it doesn't disallow other TLDs like *.co.uk. - // Chrome has a black- and white-list for this, but Firefox (via NSS) does - // the same thing we do here. - // - // The Public Suffix (https://www.publicsuffix.org/) list could - // potentially be used here, but it's both huge and updated frequently - // enough that management would be a PITA. - if dot_idxs.next().is_none() { - return None; - } + // Never match wildcards if the pattern has less than 2 '.'s (no *.com) + // + // This is a bit dubious, as it doesn't disallow other TLDs like *.co.uk. + // Chrome has a black- and white-list for this, but Firefox (via NSS) does + // the same thing we do here. + // + // The Public Suffix (https://www.publicsuffix.org/) list could + // potentially be used here, but it's both huge and updated frequently + // enough that management would be a PITA. + if dot_idxs.next().is_none() { + return None; + } - // Wildcards can only be in the first component - if wildcard_location > wildcard_end { - return None; - } + // Wildcards can only be in the first component + if wildcard_location > wildcard_end { + return None; + } - let hostname_label_end = match hostname.find('.') { - Some(l) => l, - None => return None, - }; + let hostname_label_end = match hostname.find('.') { + Some(l) => l, + None => return None, + }; - // check that the non-wildcard parts are identical - if pattern[wildcard_end..] != hostname[hostname_label_end..] { - return Some(false); - } + // check that the non-wildcard parts are identical + if pattern[wildcard_end..] != hostname[hostname_label_end..] { + return Some(false); + } - let wildcard_prefix = &pattern[..wildcard_location]; - let wildcard_suffix = &pattern[wildcard_location + 1..wildcard_end]; + let wildcard_prefix = &pattern[..wildcard_location]; + let wildcard_suffix = &pattern[wildcard_location + 1..wildcard_end]; - let hostname_label = &hostname[..hostname_label_end]; + let hostname_label = &hostname[..hostname_label_end]; - // check the prefix of the first label - if !hostname_label.starts_with(wildcard_prefix) { - return Some(false); - } + // check the prefix of the first label + if !hostname_label.starts_with(wildcard_prefix) { + return Some(false); + } - // and the suffix - if !hostname_label[wildcard_prefix.len()..].ends_with(wildcard_suffix) { - return Some(false); - } + // and the suffix + if !hostname_label[wildcard_prefix.len()..].ends_with(wildcard_suffix) { + return Some(false); + } - Some(true) - } + Some(true) + } - fn matches_ip(expected: &IpAddr, actual: &[u8]) -> bool { - match *expected { - IpAddr::V4(ref addr) => actual == addr.octets(), - IpAddr::V6(ref addr) => actual == addr.octets(), + fn matches_ip(expected: &IpAddr, actual: &[u8]) -> bool { + match *expected { + IpAddr::V4(ref addr) => actual == addr.octets(), + IpAddr::V6(ref addr) => actual == addr.octets(), + } + } } } } diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index adec060c..ce9c4b1d 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -78,7 +78,7 @@ use std::str; use std::sync::{Arc, Mutex}; use dh::{Dh, DhRef}; -#[cfg(any(ossl101, ossl102))] +#[cfg(all(ossl101, not(ossl110)))] use ec::EcKey; use ec::EcKeyRef; use error::ErrorStack; @@ -91,10 +91,10 @@ use ssl::bio::BioMethod; use ssl::callbacks::*; use ssl::error::InnerError; use stack::{Stack, StackRef}; -#[cfg(any(ossl102, ossl110))] +#[cfg(ossl102)] use x509::store::X509Store; use x509::store::{X509StoreBuilderRef, X509StoreRef}; -#[cfg(any(ossl102, ossl110))] +#[cfg(any(ossl102, libressl261))] use x509::verify::X509VerifyParamRef; use x509::{X509, X509Name, X509Ref, X509StoreContextRef, X509VerifyResult}; use {cvt, cvt_n, cvt_p, init}; @@ -284,7 +284,7 @@ impl SslMethod { /// This corresponds to `TLS_method` on OpenSSL 1.1.0 and `SSLv23_method` /// on OpenSSL 1.0.x. pub fn tls() -> SslMethod { - SslMethod(compat::tls_method()) + unsafe { SslMethod(TLS_method()) } } /// Support all versions of the DTLS protocol. @@ -292,7 +292,7 @@ impl SslMethod { /// This corresponds to `DTLS_method` on OpenSSL 1.1.0 and `DTLSv1_method` /// on OpenSSL 1.0.x. pub fn dtls() -> SslMethod { - SslMethod(compat::dtls_method()) + unsafe { SslMethod(DTLS_method()) } } /// Constructs an `SslMethod` from a pointer to the underlying OpenSSL value. @@ -767,7 +767,7 @@ impl SslContextBuilder { /// Requires OpenSSL 1.0.1 or 1.0.2. /// /// This corresponds to `SSL_CTX_set_tmp_ecdh_callback`. - #[cfg(any(ossl101, ossl102))] + #[cfg(all(ossl101, not(ossl110)))] pub fn set_tmp_ecdh_callback<F>(&mut self, callback: F) where F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send, @@ -976,7 +976,7 @@ impl SslContextBuilder { /// This corresponds to [`SSL_CTX_set_ecdh_auto`]. /// /// [`SSL_CTX_set_ecdh_auto`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_ecdh_auto.html - #[cfg(any(ossl102, libressl))] + #[cfg(any(libressl, all(ossl102, not(ossl110))))] pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_set_ecdh_auto(self.as_ptr(), onoff as c_int)).map(|_| ()) } } @@ -992,7 +992,7 @@ impl SslContextBuilder { /// /// [`SSL_CTX_set_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html pub fn set_options(&mut self, option: SslOptions) -> SslOptions { - let bits = unsafe { compat::SSL_CTX_set_options(self.as_ptr(), option.bits()) }; + let bits = unsafe { ffi::SSL_CTX_set_options(self.as_ptr(), option.bits()) }; SslOptions { bits } } @@ -1002,7 +1002,7 @@ impl SslContextBuilder { /// /// [`SSL_CTX_get_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html pub fn options(&self) -> SslOptions { - let bits = unsafe { compat::SSL_CTX_get_options(self.as_ptr()) }; + let bits = unsafe { ffi::SSL_CTX_get_options(self.as_ptr()) }; SslOptions { bits } } @@ -1012,7 +1012,7 @@ impl SslContextBuilder { /// /// [`SSL_CTX_clear_options`]: https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html pub fn clear_options(&mut self, option: SslOptions) -> SslOptions { - let bits = unsafe { compat::SSL_CTX_clear_options(self.as_ptr(), option.bits()) }; + let bits = unsafe { ffi::SSL_CTX_clear_options(self.as_ptr(), option.bits()) }; SslOptions { bits } } @@ -1514,7 +1514,7 @@ foreign_type_and_impl_send_sync! { impl Clone for SslContext { fn clone(&self) -> Self { unsafe { - compat::SSL_CTX_up_ref(self.as_ptr()); + SSL_CTX_up_ref(self.as_ptr()); SslContext::from_ptr(self.as_ptr()) } } @@ -1547,7 +1547,7 @@ impl SslContext { { unsafe { ffi::init(); - let idx = cvt_n(compat::get_new_idx(free_data_box::<T>))?; + let idx = cvt_n(get_new_idx(free_data_box::<T>))?; Ok(Index::from_raw(idx)) } } @@ -1833,7 +1833,7 @@ impl ToOwned for SslSessionRef { fn to_owned(&self) -> SslSession { unsafe { - compat::SSL_SESSION_up_ref(self.as_ptr()); + SSL_SESSION_up_ref(self.as_ptr()); SslSession(self.as_ptr()) } } @@ -1859,7 +1859,7 @@ impl SslSessionRef { /// /// [`SSL_SESSION_get_master_key`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_SESSION_get_master_key.html pub fn master_key_len(&self) -> usize { - unsafe { compat::SSL_SESSION_get_master_key(self.as_ptr(), ptr::null_mut(), 0) } + unsafe { SSL_SESSION_get_master_key(self.as_ptr(), ptr::null_mut(), 0) } } /// Copies the master key into the provided buffer. @@ -1870,7 +1870,7 @@ impl SslSessionRef { /// /// [`SSL_SESSION_get_master_key`]: https://www.openssl.org/docs/man1.1.0/ssl/SSL_SESSION_get_master_key.html pub fn master_key(&self, buf: &mut [u8]) -> usize { - unsafe { compat::SSL_SESSION_get_master_key(self.as_ptr(), buf.as_mut_ptr(), buf.len()) } + unsafe { SSL_SESSION_get_master_key(self.as_ptr(), buf.as_mut_ptr(), buf.len()) } } to_der! { @@ -1926,7 +1926,7 @@ impl Ssl { { unsafe { ffi::init(); - let idx = cvt_n(compat::get_new_ssl_idx(free_data_box::<T>))?; + let idx = cvt_n(get_new_ssl_idx(free_data_box::<T>))?; Ok(Index::from_raw(idx)) } } @@ -2091,7 +2091,7 @@ impl SslRef { /// This corresponds to `SSL_set_tmp_ecdh_callback`. /// /// [`SslContextBuilder::set_tmp_ecdh_callback`]: struct.SslContextBuilder.html#method.set_tmp_ecdh_callback - #[cfg(any(ossl101, ossl102))] + #[cfg(any(all(ossl101, not(ossl110))))] pub fn set_tmp_ecdh_callback<F>(&mut self, callback: F) where F: Fn(&mut SslRef, bool, u32) -> Result<EcKey<Params>, ErrorStack> + 'static + Sync + Send, @@ -2111,7 +2111,7 @@ impl SslRef { /// /// [`SslContextBuilder::set_tmp_ecdh`]: struct.SslContextBuilder.html#method.set_tmp_ecdh /// [`SSL_set_ecdh_auto`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_set_ecdh_auto.html - #[cfg(ossl102)] + #[cfg(all(ossl102, not(ossl110)))] pub fn set_ecdh_auto(&mut self, onoff: bool) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_set_ecdh_auto(self.as_ptr(), onoff as c_int)).map(|_| ()) } } @@ -2363,7 +2363,7 @@ impl SslRef { /// This corresponds to [`SSL_get0_param`]. /// /// [`SSL_get0_param`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_get0_param.html - #[cfg(any(ossl102, ossl110))] + #[cfg(any(ossl102, libressl261))] pub fn param_mut(&mut self) -> &mut X509VerifyParamRef { unsafe { X509VerifyParamRef::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) } } @@ -2541,7 +2541,7 @@ impl SslRef { /// /// [`SSL_is_server`]: https://www.openssl.org/docs/manmaster/man3/SSL_is_server.html pub fn is_server(&self) -> bool { - unsafe { compat::SSL_is_server(self.as_ptr()) != 0 } + unsafe { SSL_is_server(self.as_ptr()) != 0 } } /// Sets the extra data at the specified index. @@ -2987,133 +2987,88 @@ pub enum ShutdownResult { Received, } -#[cfg(ossl110)] -mod compat { - use std::ptr; - - use ffi; - use libc::c_int; - - pub use ffi::{ - SSL_CTX_clear_options, SSL_CTX_get_options, SSL_CTX_set_options, SSL_CTX_up_ref, - SSL_SESSION_get_master_key, SSL_SESSION_up_ref, SSL_is_server, - }; - - pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int { - ffi::CRYPTO_get_ex_new_index( - ffi::CRYPTO_EX_INDEX_SSL_CTX, - 0, - ptr::null_mut(), - None, - None, - Some(f), - ) - } - - pub unsafe fn get_new_ssl_idx(f: ffi::CRYPTO_EX_free) -> c_int { - ffi::CRYPTO_get_ex_new_index( - ffi::CRYPTO_EX_INDEX_SSL, - 0, - ptr::null_mut(), - None, - None, - Some(f), - ) - } - - pub fn tls_method() -> *const ffi::SSL_METHOD { - unsafe { ffi::TLS_method() } - } - - pub fn dtls_method() -> *const ffi::SSL_METHOD { - unsafe { ffi::DTLS_method() } - } -} - -#[cfg(ossl10x)] -#[allow(bad_style)] -mod compat { - use std::ptr; - - use ffi; - use libc::{self, c_int, c_long, c_uchar, c_ulong, size_t}; - - pub unsafe fn SSL_CTX_get_options(ctx: *const ffi::SSL_CTX) -> c_ulong { - ffi::SSL_CTX_ctrl(ctx as *mut _, ffi::SSL_CTRL_OPTIONS, 0, ptr::null_mut()) as c_ulong - } - - pub unsafe fn SSL_CTX_set_options(ctx: *const ffi::SSL_CTX, op: c_ulong) -> c_ulong { - ffi::SSL_CTX_ctrl( - ctx as *mut _, - ffi::SSL_CTRL_OPTIONS, - op as c_long, - ptr::null_mut(), - ) as c_ulong - } - - pub unsafe fn SSL_CTX_clear_options(ctx: *const ffi::SSL_CTX, op: c_ulong) -> c_ulong { - ffi::SSL_CTX_ctrl( - ctx as *mut _, - ffi::SSL_CTRL_CLEAR_OPTIONS, - op as c_long, - ptr::null_mut(), - ) as c_ulong - } - - pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int { - ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f)) - } +cfg_if! { + if #[cfg(ossl110)] { + use ffi::{ + SSL_CTX_up_ref, + SSL_SESSION_get_master_key, SSL_SESSION_up_ref, SSL_is_server, TLS_method, DTLS_method, + }; - pub unsafe fn get_new_ssl_idx(f: ffi::CRYPTO_EX_free) -> c_int { - ffi::SSL_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f)) - } + pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int { + ffi::CRYPTO_get_ex_new_index( + ffi::CRYPTO_EX_INDEX_SSL_CTX, + 0, + ptr::null_mut(), + None, + None, + Some(f), + ) + } - pub unsafe fn SSL_CTX_up_ref(ssl: *mut ffi::SSL_CTX) -> libc::c_int { - ffi::CRYPTO_add_lock( - &mut (*ssl).references, - 1, - ffi::CRYPTO_LOCK_SSL_CTX, - "mod.rs\0".as_ptr() as *const _, - line!() as libc::c_int, - ); - 0 - } + pub unsafe fn get_new_ssl_idx(f: ffi::CRYPTO_EX_free) -> c_int { + ffi::CRYPTO_get_ex_new_index( + ffi::CRYPTO_EX_INDEX_SSL, + 0, + ptr::null_mut(), + None, + None, + Some(f), + ) + } + } else { + use ffi::{SSLv23_method as TLS_method, DTLSv1_method as DTLS_method}; - pub unsafe fn SSL_SESSION_get_master_key( - session: *const ffi::SSL_SESSION, - out: *mut c_uchar, - mut outlen: size_t, - ) -> size_t { - if outlen == 0 { - return (*session).master_key_length as size_t; + pub unsafe fn get_new_idx(f: ffi::CRYPTO_EX_free) -> c_int { + ffi::SSL_CTX_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f)) } - if outlen > (*session).master_key_length as size_t { - outlen = (*session).master_key_length as size_t; + + pub unsafe fn get_new_ssl_idx(f: ffi::CRYPTO_EX_free) -> c_int { + ffi::SSL_get_ex_new_index(0, ptr::null_mut(), None, None, Some(f)) } - ptr::copy_nonoverlapping((*session).master_key.as_ptr(), out, outlen); - outlen - } - pub fn tls_method() -> *const ffi::SSL_METHOD { - unsafe { ffi::SSLv23_method() } - } + #[allow(bad_style)] + pub unsafe fn SSL_CTX_up_ref(ssl: *mut ffi::SSL_CTX) -> c_int { + ffi::CRYPTO_add_lock( + &mut (*ssl).references, + 1, + ffi::CRYPTO_LOCK_SSL_CTX, + "mod.rs\0".as_ptr() as *const _, + line!() as c_int, + ); + 0 + } - pub fn dtls_method() -> *const ffi::SSL_METHOD { - unsafe { ffi::DTLSv1_method() } - } + #[allow(bad_style)] + pub unsafe fn SSL_SESSION_get_master_key( + session: *const ffi::SSL_SESSION, + out: *mut c_uchar, + mut outlen: usize, + ) -> usize { + if outlen == 0 { + return (*session).master_key_length as usize; + } + if outlen > (*session).master_key_length as usize { + outlen = (*session).master_key_length as usize; + } + ptr::copy_nonoverlapping((*session).master_key.as_ptr(), out, outlen); + outlen + } - pub unsafe fn SSL_is_server(s: *mut ffi::SSL) -> c_int { - (*s).server - } + #[allow(bad_style)] + pub unsafe fn SSL_is_server(s: *mut ffi::SSL) -> c_int { + (*s).server + } - pub unsafe fn SSL_SESSION_up_ref(ses: *mut ffi::SSL_SESSION) -> c_int { - ffi::CRYPTO_add_lock( - &mut (*ses).references, - 1, - ffi::CRYPTO_LOCK_SSL_CTX, - "mod.rs\0".as_ptr() as *const _, - line!() as libc::c_int, - ); - 0 + #[allow(bad_style)] + pub unsafe fn SSL_SESSION_up_ref(ses: *mut ffi::SSL_SESSION) -> c_int { + ffi::CRYPTO_add_lock( + &mut (*ses).references, + 1, + ffi::CRYPTO_LOCK_SSL_CTX, + "mod.rs\0".as_ptr() as *const _, + line!() as c_int, + ); + 0 + } } } diff --git a/openssl/src/ssl/test.rs b/openssl/src/ssl/test.rs index b90199f0..f2dc4a65 100644 --- a/openssl/src/ssl/test.rs +++ b/openssl/src/ssl/test.rs @@ -1063,7 +1063,7 @@ fn tmp_dh_callback() { } #[test] -#[cfg(any(all(ossl101, not(libressl)), ossl102))] +#[cfg(all(ossl101, not(ossl110)))] fn tmp_ecdh_callback() { use ec::EcKey; use nid::Nid; @@ -1137,7 +1137,7 @@ fn tmp_dh_callback_ssl() { } #[test] -#[cfg(any(all(ossl101, not(libressl)), ossl102))] +#[cfg(all(ossl101, not(ossl110)))] fn tmp_ecdh_callback_ssl() { use ec::EcKey; use nid::Nid; diff --git a/openssl/src/stack.rs b/openssl/src/stack.rs index d8589352..4d5c0a13 100644 --- a/openssl/src/stack.rs +++ b/openssl/src/stack.rs @@ -1,23 +1,30 @@ -use foreign_types::{ForeignTypeRef, ForeignType, Opaque}; +use ffi; +use foreign_types::{ForeignType, ForeignTypeRef, Opaque}; use libc::c_int; use std::borrow::Borrow; use std::convert::AsRef; use std::iter; use std::marker::PhantomData; use std::mem; -use ffi; -use {cvt, cvt_p}; use error::ErrorStack; use std::ops::{Deref, DerefMut, Index, IndexMut}; +use {cvt, cvt_p}; -#[cfg(ossl10x)] -use ffi::{sk_pop as OPENSSL_sk_pop, sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num, - sk_value as OPENSSL_sk_value, _STACK as OPENSSL_STACK, - sk_new_null as OPENSSL_sk_new_null, sk_push as OPENSSL_sk_push}; -#[cfg(ossl110)] -use ffi::{OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK, - OPENSSL_sk_new_null, OPENSSL_sk_push}; +cfg_if! { + if #[cfg(ossl110)] { + use ffi::{ + OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK, + OPENSSL_sk_new_null, OPENSSL_sk_push, + }; + } else { + use ffi::{ + sk_pop as OPENSSL_sk_pop, sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num, + sk_value as OPENSSL_sk_value, _STACK as OPENSSL_STACK, + sk_new_null as OPENSSL_sk_new_null, sk_push as OPENSSL_sk_push, + }; + } +} /// Trait implemented by types which can be placed in a stack. /// @@ -87,7 +94,7 @@ impl<T: Stackable> ForeignType for Stack<T> { assert!( !ptr.is_null(), "Must not instantiate a Stack from a null-ptr - use Stack::new() in \ - that case" + that case" ); Stack(ptr) } @@ -218,9 +225,7 @@ impl<T: Stackable> StackRef<T> { /// Pushes a value onto the top of the stack. pub fn push(&mut self, data: T) -> Result<(), ErrorStack> { unsafe { - cvt( - OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _), - )?; + cvt(OPENSSL_sk_push(self.as_stack(), data.as_ptr() as *mut _))?; mem::forget(data); Ok(()) } diff --git a/openssl/src/symm.rs b/openssl/src/symm.rs index 904fb8de..33655874 100644 --- a/openssl/src/symm.rs +++ b/openssl/src/symm.rs @@ -52,14 +52,14 @@ //! println!("Decrypted: '{}'", output_string); //! ``` +use ffi; +use libc::c_int; use std::cmp; use std::ptr; -use libc::c_int; -use ffi; -use {cvt, cvt_p}; use error::ErrorStack; use nid::Nid; +use {cvt, cvt_p}; #[derive(Copy, Clone)] pub enum Mode { @@ -718,34 +718,31 @@ pub fn decrypt_aead( Ok(out) } -#[cfg(ossl110)] -use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length}; - -#[cfg(ossl10x)] -#[allow(bad_style)] -mod compat { - use libc::c_int; - use ffi::EVP_CIPHER; - - pub unsafe fn EVP_CIPHER_iv_length(ptr: *const EVP_CIPHER) -> c_int { - (*ptr).iv_len - } +cfg_if! { + if #[cfg(ossl110)] { + use ffi::{EVP_CIPHER_block_size, EVP_CIPHER_iv_length, EVP_CIPHER_key_length}; + } else { + #[allow(bad_style)] + pub unsafe fn EVP_CIPHER_iv_length(ptr: *const ffi::EVP_CIPHER) -> c_int { + (*ptr).iv_len + } - pub unsafe fn EVP_CIPHER_block_size(ptr: *const EVP_CIPHER) -> c_int { - (*ptr).block_size - } + #[allow(bad_style)] + pub unsafe fn EVP_CIPHER_block_size(ptr: *const ffi::EVP_CIPHER) -> c_int { + (*ptr).block_size + } - pub unsafe fn EVP_CIPHER_key_length(ptr: *const EVP_CIPHER) -> c_int { - (*ptr).key_len + #[allow(bad_style)] + pub unsafe fn EVP_CIPHER_key_length(ptr: *const ffi::EVP_CIPHER) -> c_int { + (*ptr).key_len + } } } -#[cfg(ossl10x)] -use self::compat::*; #[cfg(test)] mod tests { - use hex::{self, FromHex}; use super::*; + use hex::{self, FromHex}; // Test vectors from FIPS-197: // http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf diff --git a/openssl/src/version.rs b/openssl/src/version.rs index 7254d7ba..dc8508d1 100644 --- a/openssl/src/version.rs +++ b/openssl/src/version.rs @@ -13,15 +13,21 @@ use std::ffi::CStr; -#[cfg(ossl10x)] -use ffi::{SSLEAY_VERSION as OPENSSL_VERSION, SSLEAY_CFLAGS as OPENSSL_CFLAGS, - SSLEAY_BUILT_ON as OPENSSL_BUILT_ON, SSLEAY_PLATFORM as OPENSSL_PLATFORM, - SSLEAY_DIR as OPENSSL_DIR, SSLeay as OpenSSL_version_num, - SSLeay_version as OpenSSL_version}; - -#[cfg(ossl110)] -use ffi::{OPENSSL_VERSION, OPENSSL_CFLAGS, OPENSSL_BUILT_ON, OPENSSL_PLATFORM, OPENSSL_DIR, - OpenSSL_version_num, OpenSSL_version}; +cfg_if! { + if #[cfg(ossl110)] { + use ffi::{ + OPENSSL_VERSION, OPENSSL_CFLAGS, OPENSSL_BUILT_ON, OPENSSL_PLATFORM, OPENSSL_DIR, + OpenSSL_version_num, OpenSSL_version, + }; + } else { + use ffi::{ + SSLEAY_VERSION as OPENSSL_VERSION, SSLEAY_CFLAGS as OPENSSL_CFLAGS, + SSLEAY_BUILT_ON as OPENSSL_BUILT_ON, SSLEAY_PLATFORM as OPENSSL_PLATFORM, + SSLEAY_DIR as OPENSSL_DIR, SSLeay as OpenSSL_version_num, + SSLeay_version as OpenSSL_version, + }; + } +} /// OPENSSL_VERSION_NUMBER is a numeric release version identifier: /// @@ -51,7 +57,6 @@ pub fn number() -> i64 { unsafe { OpenSSL_version_num() as i64 } } - /// The text variant of the version number and the release date. For example, "OpenSSL 0.9.5a 1 Apr 2000". pub fn version() -> &'static str { unsafe { diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index c1ae3b16..19760f25 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -7,9 +7,9 @@ //! Internet protocols, including SSL/TLS, which is the basis for HTTPS, //! the secure protocol for browsing the web. -use libc::{c_int, c_long}; use ffi; use foreign_types::{ForeignType, ForeignTypeRef}; +use libc::{c_int, c_long}; use std::error::Error; use std::ffi::{CStr, CString}; use std::fmt; @@ -20,7 +20,6 @@ use std::ptr; use std::slice; use std::str; -use {cvt, cvt_n, cvt_p}; use asn1::{Asn1BitStringRef, Asn1IntegerRef, Asn1ObjectRef, Asn1StringRef, Asn1TimeRef}; use bio::MemBioSlice; use conf::ConfRef; @@ -29,18 +28,12 @@ use ex_data::Index; use hash::MessageDigest; use nid::Nid; use pkey::{HasPrivate, HasPublic, PKey, PKeyRef, Public}; +use ssl::SslRef; use stack::{Stack, StackRef, Stackable}; use string::OpensslString; -use ssl::SslRef; - -#[cfg(ossl10x)] -use ffi::{ASN1_STRING_data, X509_STORE_CTX_get_chain, X509_set_notAfter, X509_set_notBefore}; -#[cfg(ossl110)] -use ffi::{ASN1_STRING_get0_data as ASN1_STRING_data, - X509_STORE_CTX_get0_chain as X509_STORE_CTX_get_chain, - X509_set1_notAfter as X509_set_notAfter, X509_set1_notBefore as X509_set_notBefore}; +use {cvt, cvt_n, cvt_p}; -#[cfg(any(ossl102, ossl110))] +#[cfg(any(ossl102, libressl261))] pub mod verify; pub mod extension; @@ -215,7 +208,7 @@ impl X509StoreContextRef { /// [`X509_STORE_CTX_get0_chain`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_STORE_CTX_get0_chain.html pub fn chain(&self) -> Option<&StackRef<X509>> { unsafe { - let chain = X509_STORE_CTX_get_chain(self.as_ptr()); + let chain = X509_STORE_CTX_get0_chain(self.as_ptr()); if chain.is_null() { None @@ -240,12 +233,12 @@ impl X509Builder { /// Sets the notAfter constraint on the certificate. pub fn set_not_after(&mut self, not_after: &Asn1TimeRef) -> Result<(), ErrorStack> { - unsafe { cvt(X509_set_notAfter(self.0.as_ptr(), not_after.as_ptr())).map(|_| ()) } + unsafe { cvt(X509_set1_notAfter(self.0.as_ptr(), not_after.as_ptr())).map(|_| ()) } } /// Sets the notBefore constraint on the certificate. pub fn set_not_before(&mut self, not_before: &Asn1TimeRef) -> Result<(), ErrorStack> { - unsafe { cvt(X509_set_notBefore(self.0.as_ptr(), not_before.as_ptr())).map(|_| ()) } + unsafe { cvt(X509_set1_notBefore(self.0.as_ptr(), not_before.as_ptr())).map(|_| ()) } } /// Sets the version of the certificate. @@ -474,7 +467,7 @@ impl X509Ref { /// Returns the certificate's Not After validity period. pub fn not_after(&self) -> &Asn1TimeRef { unsafe { - let date = compat::X509_get_notAfter(self.as_ptr()); + let date = X509_getm_notAfter(self.as_ptr()); assert!(!date.is_null()); Asn1TimeRef::from_ptr(date) } @@ -483,7 +476,7 @@ impl X509Ref { /// Returns the certificate's Not Before validity period. pub fn not_before(&self) -> &Asn1TimeRef { unsafe { - let date = compat::X509_get_notBefore(self.as_ptr()); + let date = X509_getm_notBefore(self.as_ptr()); assert!(!date.is_null()); Asn1TimeRef::from_ptr(date) } @@ -493,7 +486,7 @@ impl X509Ref { pub fn signature(&self) -> &Asn1BitStringRef { unsafe { let mut signature = ptr::null(); - compat::X509_get0_signature(&mut signature, ptr::null_mut(), self.as_ptr()); + X509_get0_signature(&mut signature, ptr::null_mut(), self.as_ptr()); assert!(!signature.is_null()); Asn1BitStringRef::from_ptr(signature as *mut _) } @@ -503,7 +496,7 @@ impl X509Ref { pub fn signature_algorithm(&self) -> &X509AlgorithmRef { unsafe { let mut algor = ptr::null(); - compat::X509_get0_signature(ptr::null_mut(), &mut algor, self.as_ptr()); + X509_get0_signature(ptr::null_mut(), &mut algor, self.as_ptr()); assert!(!algor.is_null()); X509AlgorithmRef::from_ptr(algor as *mut _) } @@ -564,7 +557,7 @@ impl ToOwned for X509Ref { fn to_owned(&self) -> X509 { unsafe { - compat::X509_up_ref(self.as_ptr()); + X509_up_ref(self.as_ptr()); X509::from_ptr(self.as_ptr()) } } @@ -1054,7 +1047,7 @@ impl X509ReqRef { /// /// [`X509_REQ_get_version`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_get_version.html pub fn version(&self) -> i32 { - unsafe { compat::X509_REQ_get_version(self.as_ptr()) as i32 } + unsafe { X509_REQ_get_version(self.as_ptr()) as i32 } } /// Returns the subject name of the certificate request. @@ -1064,7 +1057,7 @@ impl X509ReqRef { /// [`X509_REQ_get_subject_name`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_REQ_get_subject_name.html pub fn subject_name(&self) -> &X509NameRef { unsafe { - let name = compat::X509_REQ_get_subject_name(self.as_ptr()); + let name = X509_REQ_get_subject_name(self.as_ptr()); assert!(!name.is_null()); X509NameRef::from_ptr(name) } @@ -1172,7 +1165,7 @@ impl GeneralNameRef { return None; } - let ptr = ASN1_STRING_data((*self.as_ptr()).d as *mut _); + let ptr = ASN1_STRING_get0_data((*self.as_ptr()).d as *mut _); let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _); let slice = slice::from_raw_parts(ptr as *const u8, len as usize); @@ -1205,7 +1198,7 @@ impl GeneralNameRef { return None; } - let ptr = ASN1_STRING_data((*self.as_ptr()).d as *mut _); + let ptr = ASN1_STRING_get0_data((*self.as_ptr()).d as *mut _); let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _); Some(slice::from_raw_parts(ptr as *const u8, len as usize)) @@ -1232,79 +1225,86 @@ impl X509AlgorithmRef { pub fn object(&self) -> &Asn1ObjectRef { unsafe { let mut oid = ptr::null(); - compat::X509_ALGOR_get0(&mut oid, ptr::null_mut(), ptr::null_mut(), self.as_ptr()); + X509_ALGOR_get0(&mut oid, ptr::null_mut(), ptr::null_mut(), self.as_ptr()); assert!(!oid.is_null()); Asn1ObjectRef::from_ptr(oid as *mut _) } } } -#[cfg(ossl110)] -mod compat { - pub use ffi::X509_getm_notAfter as X509_get_notAfter; - pub use ffi::X509_getm_notBefore as X509_get_notBefore; - pub use ffi::X509_up_ref; - pub use ffi::X509_REQ_get_version; - pub use ffi::X509_REQ_get_subject_name; - pub use ffi::X509_get0_signature; - pub use ffi::X509_ALGOR_get0; -} - -#[cfg(ossl10x)] -#[allow(bad_style)] -mod compat { - use libc::{c_int, c_void}; - use ffi; - - pub unsafe fn X509_get_notAfter(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME { - (*(*(*x).cert_info).validity).notAfter - } - - pub unsafe fn X509_get_notBefore(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME { - (*(*(*x).cert_info).validity).notBefore - } +cfg_if! { + if #[cfg(ossl110)] { + use ffi::{ + X509_ALGOR_get0, X509_REQ_get_subject_name, X509_REQ_get_version, + X509_get0_signature, X509_getm_notAfter, X509_getm_notBefore, X509_up_ref, + ASN1_STRING_get0_data, X509_STORE_CTX_get0_chain, X509_set1_notAfter, + X509_set1_notBefore, + }; + } else { + use ffi::{ + ASN1_STRING_data as ASN1_STRING_get0_data, + X509_STORE_CTX_get_chain as X509_STORE_CTX_get0_chain, + X509_set_notAfter as X509_set1_notAfter, + X509_set_notBefore as X509_set1_notBefore, + }; + + #[allow(bad_style)] + unsafe fn X509_getm_notAfter(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME { + (*(*(*x).cert_info).validity).notAfter + } - pub unsafe fn X509_up_ref(x: *mut ffi::X509) { - ffi::CRYPTO_add_lock( - &mut (*x).references, - 1, - ffi::CRYPTO_LOCK_X509, - "mod.rs\0".as_ptr() as *const _, - line!() as c_int, - ); - } + #[allow(bad_style)] + unsafe fn X509_getm_notBefore(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME { + (*(*(*x).cert_info).validity).notBefore + } - pub unsafe fn X509_REQ_get_version(x: *mut ffi::X509_REQ) -> ::libc::c_long { - ::ffi::ASN1_INTEGER_get((*(*x).req_info).version) - } + #[allow(bad_style)] + unsafe fn X509_up_ref(x: *mut ffi::X509) { + ffi::CRYPTO_add_lock( + &mut (*x).references, + 1, + ffi::CRYPTO_LOCK_X509, + "mod.rs\0".as_ptr() as *const _, + line!() as c_int, + ); + } - pub unsafe fn X509_REQ_get_subject_name(x: *mut ffi::X509_REQ) -> *mut ::ffi::X509_NAME { - (*(*x).req_info).subject - } + #[allow(bad_style)] + unsafe fn X509_REQ_get_version(x: *mut ffi::X509_REQ) -> ::libc::c_long { + ffi::ASN1_INTEGER_get((*(*x).req_info).version) + } - pub unsafe fn X509_get0_signature( - psig: *mut *const ffi::ASN1_BIT_STRING, - palg: *mut *const ffi::X509_ALGOR, - x: *const ffi::X509, - ) { - if !psig.is_null() { - *psig = (*x).signature; + #[allow(bad_style)] + unsafe fn X509_REQ_get_subject_name(x: *mut ffi::X509_REQ) -> *mut ::ffi::X509_NAME { + (*(*x).req_info).subject } - if !palg.is_null() { - *palg = (*x).sig_alg; + + #[allow(bad_style)] + unsafe fn X509_get0_signature( + psig: *mut *const ffi::ASN1_BIT_STRING, + palg: *mut *const ffi::X509_ALGOR, + x: *const ffi::X509, + ) { + if !psig.is_null() { + *psig = (*x).signature; + } + if !palg.is_null() { + *palg = (*x).sig_alg; + } } - } - pub unsafe fn X509_ALGOR_get0( - paobj: *mut *const ffi::ASN1_OBJECT, - pptype: *mut c_int, - pval: *mut *mut c_void, - alg: *const ffi::X509_ALGOR, - ) { - if !paobj.is_null() { - *paobj = (*alg).algorithm; + #[allow(bad_style)] + unsafe fn X509_ALGOR_get0( + paobj: *mut *const ffi::ASN1_OBJECT, + pptype: *mut c_int, + pval: *mut *mut ::libc::c_void, + alg: *const ffi::X509_ALGOR, + ) { + if !paobj.is_null() { + *paobj = (*alg).algorithm; + } + assert!(pptype.is_null()); + assert!(pval.is_null()); } - assert!(pptype.is_null()); - assert!(pval.is_null()); } } diff --git a/openssl/src/x509/verify.rs b/openssl/src/x509/verify.rs index b90c8f58..2eabe38c 100644 --- a/openssl/src/x509/verify.rs +++ b/openssl/src/x509/verify.rs @@ -1,6 +1,6 @@ -use libc::c_uint; use ffi; use foreign_types::ForeignTypeRef; +use libc::c_uint; use std::net::IpAddr; use cvt; |