From 927c3e924cd894cb4b32efff666f949a294ab7c7 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 19:37:21 -0700 Subject: [PATCH 01/13] Add a generic Ref type --- openssl/src/bn.rs | 15 +-------------- openssl/src/lib.rs | 39 +++++++++++++++++++++++++++++++++++++++ openssl/src/types.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 openssl/src/types.rs diff --git a/openssl/src/bn.rs b/openssl/src/bn.rs index 78684d0a..ab5f7769 100644 --- a/openssl/src/bn.rs +++ b/openssl/src/bn.rs @@ -23,16 +23,7 @@ pub enum RNGProperty { TwoMsbOne = 1, } -/// A context object for `BigNum` operations. -pub struct BnCtx(*mut ffi::BN_CTX); - -impl Drop for BnCtx { - fn drop(&mut self) { - unsafe { - ffi::BN_CTX_free(self.0); - } - } -} +type_!(BnCtx, ffi::BN_CTX, ffi::BN_CTX_free); impl BnCtx { /// Returns a new `BnCtx`. @@ -40,10 +31,6 @@ impl BnCtx { unsafe { cvt_p(ffi::BN_CTX_new()).map(BnCtx) } } - pub fn as_ptr(&self) -> *mut ffi::BN_CTX { - self.0 - } - /// Places the result of `a * b` in `r`. pub fn mul(&mut self, r: &mut BigNumRef, diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index f335c097..8fa53f3b 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -20,6 +20,44 @@ use libc::c_int; use error::ErrorStack; +macro_rules! type_ { + ($n:ident, $c:path, $d:path) => { + pub struct $n(*mut $c); + + unsafe impl ::types::OpenSslType for $n { + type CType = $c; + + unsafe fn from_ptr(ptr: *mut $c) -> $n { + $n(ptr) + } + + fn as_ptr(&self) -> *mut $c { + self.0 + } + } + + impl Drop for $n { + fn drop(&mut self) { + unsafe { $d(self.0) } + } + } + + impl ::std::ops::Deref for $n { + type Target = ::types::Ref<$n>; + + fn deref(&self) -> &::types::Ref<$n> { + unsafe { ::types::Ref::from_ptr(self.0) } + } + } + + impl ::std::ops::DerefMut for $n { + fn deref_mut(&mut self) -> &mut ::types::Ref<$n> { + unsafe { ::types::Ref::from_ptr_mut(self.0) } + } + } + } +} + mod bio; mod opaque; mod util; @@ -37,6 +75,7 @@ pub mod pkcs12; pub mod pkcs5; pub mod pkey; pub mod rand; +pub mod types; pub mod rsa; pub mod sign; pub mod ssl; diff --git a/openssl/src/types.rs b/openssl/src/types.rs new file mode 100644 index 00000000..16829ea4 --- /dev/null +++ b/openssl/src/types.rs @@ -0,0 +1,27 @@ +use std::marker::PhantomData; + +use opaque::Opaque; + +pub unsafe trait OpenSslType { + type CType; + + unsafe fn from_ptr(ptr: *mut Self::CType) -> Self; + + fn as_ptr(&self) -> *mut Self::CType; +} + +pub struct Ref(Opaque, PhantomData); + +impl Ref { + pub unsafe fn from_ptr<'a>(ptr: *mut T::CType) -> &'a Ref { + &*(ptr as *mut _) + } + + pub unsafe fn from_ptr_mut<'a>(ptr: *mut T::CType) -> &'a mut Ref { + &mut *(ptr as *mut _) + } + + pub fn as_ptr(&self) -> *mut T::CType { + self as *const _ as *mut _ + } +} From 3363046c34ca3f968ce8b34e885d25aebac2b1f4 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 19:45:52 -0700 Subject: [PATCH 02/13] Update bignum --- openssl/src/bn.rs | 231 ++++++++++++++++++--------------------------- openssl/src/dsa.rs | 19 ++-- openssl/src/rsa.rs | 23 ++--- 3 files changed, 114 insertions(+), 159 deletions(-) diff --git a/openssl/src/bn.rs b/openssl/src/bn.rs index ab5f7769..7542b25a 100644 --- a/openssl/src/bn.rs +++ b/openssl/src/bn.rs @@ -3,12 +3,12 @@ use libc::c_int; use std::cmp::Ordering; use std::ffi::CString; use std::{fmt, ptr}; -use std::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub, Deref, DerefMut}; +use std::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub, Deref}; use {cvt, cvt_p, cvt_n}; use crypto::CryptoString; use error::ErrorStack; -use opaque::Opaque; +use types::{Ref, OpenSslType}; /// Specifies the desired properties of a randomly generated `BigNum`. #[derive(Copy, Clone)] @@ -33,19 +33,19 @@ impl BnCtx { /// Places the result of `a * b` in `r`. pub fn mul(&mut self, - r: &mut BigNumRef, - a: &BigNumRef, - b: &BigNumRef) + r: &mut Ref, + a: &Ref, + b: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_mul(r.as_ptr(), a.as_ptr(), b.as_ptr(), self.as_ptr())).map(|_| ()) } } /// Places the result of `a / b` in `dv` and `a mod b` in `rem`. pub fn div(&mut self, - dv: Option<&mut BigNumRef>, - rem: Option<&mut BigNumRef>, - a: &BigNumRef, - b: &BigNumRef) + dv: Option<&mut Ref>, + rem: Option<&mut Ref>, + a: &Ref, + b: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_div(dv.map(|b| b.as_ptr()).unwrap_or(ptr::null_mut()), @@ -58,25 +58,25 @@ impl BnCtx { } /// Places the result of `a²` in `r`. - pub fn sqr(&mut self, r: &mut BigNumRef, a: &BigNumRef) -> Result<(), ErrorStack> { + pub fn sqr(&mut self, r: &mut Ref, a: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_sqr(r.as_ptr(), a.as_ptr(), self.as_ptr())).map(|_| ()) } } /// Places the result of `a mod m` in `r`. pub fn nnmod(&mut self, - r: &mut BigNumRef, - a: &BigNumRef, - m: &BigNumRef) + r: &mut Ref, + a: &Ref, + m: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_nnmod(r.as_ptr(), a.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) } } /// Places the result of `(a + b) mod m` in `r`. pub fn mod_add(&mut self, - r: &mut BigNumRef, - a: &BigNumRef, - b: &BigNumRef, - m: &BigNumRef) + r: &mut Ref, + a: &Ref, + b: &Ref, + m: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_mod_add(r.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) @@ -85,10 +85,10 @@ impl BnCtx { /// Places the result of `(a - b) mod m` in `r`. pub fn mod_sub(&mut self, - r: &mut BigNumRef, - a: &BigNumRef, - b: &BigNumRef, - m: &BigNumRef) + r: &mut Ref, + a: &Ref, + b: &Ref, + m: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_mod_sub(r.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) @@ -97,10 +97,10 @@ impl BnCtx { /// Places the result of `(a * b) mod m` in `r`. pub fn mod_mul(&mut self, - r: &mut BigNumRef, - a: &BigNumRef, - b: &BigNumRef, - m: &BigNumRef) + r: &mut Ref, + a: &Ref, + b: &Ref, + m: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_mod_mul(r.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) @@ -109,28 +109,28 @@ impl BnCtx { /// Places the result of `a² mod m` in `r`. pub fn mod_sqr(&mut self, - r: &mut BigNumRef, - a: &BigNumRef, - m: &BigNumRef) + r: &mut Ref, + a: &Ref, + m: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_mod_sqr(r.as_ptr(), a.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) } } /// Places the result of `a^p` in `r`. pub fn exp(&mut self, - r: &mut BigNumRef, - a: &BigNumRef, - p: &BigNumRef) + r: &mut Ref, + a: &Ref, + p: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_exp(r.as_ptr(), a.as_ptr(), p.as_ptr(), self.0)).map(|_| ()) } } /// Places the result of `a^p mod m` in `r`. pub fn mod_exp(&mut self, - r: &mut BigNumRef, - a: &BigNumRef, - p: &BigNumRef, - m: &BigNumRef) + r: &mut Ref, + a: &Ref, + p: &Ref, + m: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_mod_exp(r.as_ptr(), a.as_ptr(), p.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) @@ -139,9 +139,9 @@ impl BnCtx { /// Places the inverse of `a` modulo `n` in `r`. pub fn mod_inverse(&mut self, - r: &mut BigNumRef, - a: &BigNumRef, - n: &BigNumRef) + r: &mut Ref, + a: &Ref, + n: &Ref) -> Result<(), ErrorStack> { unsafe { cvt_p(ffi::BN_mod_inverse(r.as_ptr(), a.as_ptr(), n.as_ptr(), self.as_ptr())) @@ -151,9 +151,9 @@ impl BnCtx { /// Places the greatest common denominator of `a` and `b` in `r`. pub fn gcd(&mut self, - r: &mut BigNumRef, - a: &BigNumRef, - b: &BigNumRef) + r: &mut Ref, + a: &Ref, + b: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_gcd(r.as_ptr(), a.as_ptr(), b.as_ptr(), self.as_ptr())).map(|_| ()) } } @@ -163,7 +163,7 @@ impl BnCtx { /// Performs a Miller-Rabin probabilistic primality test with `checks` iterations. /// /// Returns `true` if `p` is prime with an error probability of less than `0.25 ^ checks`. - pub fn is_prime(&mut self, p: &BigNumRef, checks: i32) -> Result { + pub fn is_prime(&mut self, p: &Ref, checks: i32) -> Result { unsafe { cvt_n(ffi::BN_is_prime_ex(p.as_ptr(), checks.into(), self.as_ptr(), ptr::null_mut())) .map(|r| r != 0) @@ -180,7 +180,7 @@ impl BnCtx { /// /// Returns `true` if `p` is prime with an error probability of less than `0.25 ^ checks`. pub fn is_prime_fasttest(&mut self, - p: &BigNumRef, + p: &Ref, checks: i32, do_trial_division: bool) -> Result { @@ -201,7 +201,7 @@ impl BnCtx { /// * `bits`: Length of the number in bits. /// * `prop`: The desired properties of the number. /// * `odd`: If `true`, the generated number will be odd. - pub fn rand(r: &mut BigNumRef, + pub fn rand(r: &mut Ref, bits: i32, prop: RNGProperty, odd: bool) @@ -212,7 +212,7 @@ impl BnCtx { } /// The cryptographically weak counterpart to `checked_new_random`. - pub fn pseudo_rand(r: &mut BigNumRef, + pub fn pseudo_rand(r: &mut Ref, bits: i32, prop: RNGProperty, odd: bool) @@ -224,22 +224,7 @@ impl BnCtx { } } -/// A borrowed, signed, arbitrary-precision integer. -pub struct BigNumRef(Opaque); - -impl BigNumRef { - pub unsafe fn from_ptr<'a>(handle: *mut ffi::BIGNUM) -> &'a BigNumRef { - &*(handle as *mut _) - } - - pub unsafe fn from_ptr_mut<'a>(handle: *mut ffi::BIGNUM) -> &'a mut BigNumRef { - &mut *(handle as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::BIGNUM { - self as *const _ as *mut _ - } - +impl Ref { /// Adds a `u32` to `self`. pub fn add_word(&mut self, w: u32) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_add_word(self.as_ptr(), w as ffi::BN_ULONG)).map(|_| ()) } @@ -281,12 +266,12 @@ impl BigNumRef { /// Places a cryptographically-secure pseudo-random number nonnegative /// number less than `self` in `rnd`. - pub fn rand_in_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> { + pub fn rand_in_range(&self, rnd: &mut Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_rand_range(self.as_ptr(), rnd.as_ptr())).map(|_| ()) } } /// The cryptographically weak counterpart to `rand_in_range`. - pub fn pseudo_rand_in_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> { + pub fn pseudo_rand_in_range(&self, rnd: &mut Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_pseudo_rand_range(self.as_ptr(), rnd.as_ptr())).map(|_| ()) } } @@ -317,32 +302,32 @@ impl BigNumRef { } /// Places `self << 1` in `r`. - pub fn lshift1(&self, r: &mut BigNumRef) -> Result<(), ErrorStack> { + pub fn lshift1(&self, r: &mut Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_lshift1(r.as_ptr(), self.as_ptr())).map(|_| ()) } } /// Places `self >> 1` in `r`. - pub fn rshift1(&self, r: &mut BigNumRef) -> Result<(), ErrorStack> { + pub fn rshift1(&self, r: &mut Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_rshift1(r.as_ptr(), self.as_ptr())).map(|_| ()) } } /// Places `self + b` in `r`. - pub fn add(&self, r: &mut BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> { + pub fn add(&self, r: &mut Ref, b: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_add(r.as_ptr(), self.as_ptr(), b.as_ptr())).map(|_| ()) } } /// Places `self - b` in `r`. - pub fn sub(&self, r: &mut BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> { + pub fn sub(&self, r: &mut Ref, b: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_sub(r.as_ptr(), self.as_ptr(), b.as_ptr())).map(|_| ()) } } /// Places `self << n` in `r`. - pub fn lshift(&self, r: &mut BigNumRef, b: i32) -> Result<(), ErrorStack> { + pub fn lshift(&self, r: &mut Ref, b: i32) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_lshift(r.as_ptr(), self.as_ptr(), b.into())).map(|_| ()) } } /// Places `self >> n` in `r`. - pub fn rshift(&self, r: &mut BigNumRef, n: i32) -> Result<(), ErrorStack> { + pub fn rshift(&self, r: &mut Ref, n: i32) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_rshift(r.as_ptr(), self.as_ptr(), n.into())).map(|_| ()) } } @@ -365,7 +350,7 @@ impl BigNumRef { /// /// assert_eq!(s.ucmp(&o), Ordering::Equal); /// ``` - pub fn ucmp(&self, oth: &BigNumRef) -> Ordering { + pub fn ucmp(&self, oth: &Ref) -> Ordering { unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) } } @@ -446,13 +431,7 @@ impl BigNumRef { } } -/// An owned, signed, arbitrary-precision integer. -/// -/// `BigNum` provides wrappers around OpenSSL's checked arithmetic functions. -/// Additionally, it implements the standard operators (`std::ops`), which -/// perform unchecked arithmetic, unwrapping the returned `Result` of the -/// checked operations. -pub struct BigNum(*mut ffi::BIGNUM); +type_!(BigNum, ffi::BIGNUM, ffi::BN_clear_free); impl BigNum { /// Creates a new `BigNum` with the value 0. @@ -491,10 +470,6 @@ impl BigNum { } } - pub unsafe fn from_ptr(handle: *mut ffi::BIGNUM) -> BigNum { - BigNum(handle) - } - /// Creates a new `BigNum` from an unsigned, big-endian encoded number of arbitrary length. /// /// ``` @@ -519,11 +494,11 @@ impl BigNum { /// * `safe`: If true, returns a "safe" prime `p` so that `(p-1)/2` is also prime. /// * `add`/`rem`: If `add` is set to `Some(add)`, `p % add == rem` will hold, where `p` is the /// generated prime and `rem` is `1` if not specified (`None`). - pub fn generate_prime(r: &mut BigNumRef, + pub fn generate_prime(r: &mut Ref, bits: i32, safe: bool, - add: Option<&BigNumRef>, - rem: Option<&BigNumRef>) + add: Option<&Ref>, + rem: Option<&Ref>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_generate_prime_ex(r.as_ptr(), @@ -537,35 +512,13 @@ impl BigNum { } } -impl Drop for BigNum { - fn drop(&mut self) { - unsafe { - ffi::BN_clear_free(self.as_ptr()); - } - } -} - -impl Deref for BigNum { - type Target = BigNumRef; - - fn deref(&self) -> &BigNumRef { - unsafe { BigNumRef::from_ptr(self.0) } - } -} - -impl DerefMut for BigNum { - fn deref_mut(&mut self) -> &mut BigNumRef { - unsafe { BigNumRef::from_ptr_mut(self.0) } - } -} - -impl AsRef for BigNum { - fn as_ref(&self) -> &BigNumRef { +impl AsRef> for BigNum { + fn as_ref(&self) -> &Ref { self.deref() } } -impl fmt::Debug for BigNumRef { +impl fmt::Debug for Ref { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.to_dec_str() { Ok(s) => f.write_str(&s), @@ -583,7 +536,7 @@ impl fmt::Debug for BigNum { } } -impl fmt::Display for BigNumRef { +impl fmt::Display for Ref { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.to_dec_str() { Ok(s) => f.write_str(&s), @@ -601,19 +554,19 @@ impl fmt::Display for BigNum { } } -impl PartialEq for BigNumRef { - fn eq(&self, oth: &BigNumRef) -> bool { +impl PartialEq> for Ref { + fn eq(&self, oth: &Ref) -> bool { self.cmp(oth) == Ordering::Equal } } -impl PartialEq for BigNumRef { +impl PartialEq for Ref { fn eq(&self, oth: &BigNum) -> bool { self.eq(oth.deref()) } } -impl Eq for BigNumRef {} +impl Eq for Ref {} impl PartialEq for BigNum { fn eq(&self, oth: &BigNum) -> bool { @@ -621,28 +574,28 @@ impl PartialEq for BigNum { } } -impl PartialEq for BigNum { - fn eq(&self, oth: &BigNumRef) -> bool { +impl PartialEq> for BigNum { + fn eq(&self, oth: &Ref) -> bool { self.deref().eq(oth) } } impl Eq for BigNum {} -impl PartialOrd for BigNumRef { - fn partial_cmp(&self, oth: &BigNumRef) -> Option { +impl PartialOrd> for Ref { + fn partial_cmp(&self, oth: &Ref) -> Option { Some(self.cmp(oth)) } } -impl PartialOrd for BigNumRef { +impl PartialOrd for Ref { fn partial_cmp(&self, oth: &BigNum) -> Option { Some(self.cmp(oth.deref())) } } -impl Ord for BigNumRef { - fn cmp(&self, oth: &BigNumRef) -> Ordering { +impl Ord for Ref { + fn cmp(&self, oth: &Ref) -> Ordering { unsafe { ffi::BN_cmp(self.as_ptr(), oth.as_ptr()).cmp(&0) } } } @@ -653,8 +606,8 @@ impl PartialOrd for BigNum { } } -impl PartialOrd for BigNum { - fn partial_cmp(&self, oth: &BigNumRef) -> Option { +impl PartialOrd> for BigNum { + fn partial_cmp(&self, oth: &Ref) -> Option { self.deref().partial_cmp(oth) } } @@ -667,7 +620,7 @@ impl Ord for BigNum { macro_rules! delegate { ($t:ident, $m:ident) => { - impl<'a, 'b> $t<&'b BigNum> for &'a BigNumRef { + impl<'a, 'b> $t<&'b BigNum> for &'a Ref { type Output = BigNum; fn $m(self, oth: &BigNum) -> BigNum { @@ -675,10 +628,10 @@ macro_rules! delegate { } } - impl<'a, 'b> $t<&'b BigNumRef> for &'a BigNum { + impl<'a, 'b> $t<&'b Ref> for &'a BigNum { type Output = BigNum; - fn $m(self, oth: &BigNumRef) -> BigNum { + fn $m(self, oth: &Ref) -> BigNum { $t::$m(self.deref(), oth) } } @@ -693,10 +646,10 @@ macro_rules! delegate { } } -impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef { +impl<'a, 'b> Add<&'b Ref> for &'a Ref { type Output = BigNum; - fn add(self, oth: &BigNumRef) -> BigNum { + fn add(self, oth: &Ref) -> BigNum { let mut r = BigNum::new().unwrap(); self.add(&mut r, oth).unwrap(); r @@ -705,10 +658,10 @@ impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef { delegate!(Add, add); -impl<'a, 'b> Sub<&'b BigNumRef> for &'a BigNumRef { +impl<'a, 'b> Sub<&'b Ref> for &'a Ref { type Output = BigNum; - fn sub(self, oth: &BigNumRef) -> BigNum { + fn sub(self, oth: &Ref) -> BigNum { let mut r = BigNum::new().unwrap(); self.sub(&mut r, oth).unwrap(); r @@ -717,10 +670,10 @@ impl<'a, 'b> Sub<&'b BigNumRef> for &'a BigNumRef { delegate!(Sub, sub); -impl<'a, 'b> Mul<&'b BigNumRef> for &'a BigNumRef { +impl<'a, 'b> Mul<&'b Ref> for &'a Ref { type Output = BigNum; - fn mul(self, oth: &BigNumRef) -> BigNum { + fn mul(self, oth: &Ref) -> BigNum { let mut ctx = BnCtx::new().unwrap(); let mut r = BigNum::new().unwrap(); ctx.mul(&mut r, self, oth).unwrap(); @@ -730,10 +683,10 @@ impl<'a, 'b> Mul<&'b BigNumRef> for &'a BigNumRef { delegate!(Mul, mul); -impl<'a, 'b> Div<&'b BigNumRef> for &'a BigNumRef { +impl<'a, 'b> Div<&'b Ref> for &'a Ref { type Output = BigNum; - fn div(self, oth: &'b BigNumRef) -> BigNum { + fn div(self, oth: &'b Ref) -> BigNum { let mut ctx = BnCtx::new().unwrap(); let mut dv = BigNum::new().unwrap(); ctx.div(Some(&mut dv), None, self, oth).unwrap(); @@ -743,10 +696,10 @@ impl<'a, 'b> Div<&'b BigNumRef> for &'a BigNumRef { delegate!(Div, div); -impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef { +impl<'a, 'b> Rem<&'b Ref> for &'a Ref { type Output = BigNum; - fn rem(self, oth: &'b BigNumRef) -> BigNum { + fn rem(self, oth: &'b Ref) -> BigNum { let mut ctx = BnCtx::new().unwrap(); let mut rem = BigNum::new().unwrap(); ctx.div(None, Some(&mut rem), self, oth).unwrap(); @@ -756,7 +709,7 @@ impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef { delegate!(Rem, rem); -impl<'a> Shl for &'a BigNumRef { +impl<'a> Shl for &'a Ref { type Output = BigNum; fn shl(self, n: i32) -> BigNum { @@ -774,7 +727,7 @@ impl<'a> Shl for &'a BigNum { } } -impl<'a> Shr for &'a BigNumRef { +impl<'a> Shr for &'a Ref { type Output = BigNum; fn shr(self, n: i32) -> BigNum { @@ -792,7 +745,7 @@ impl<'a> Shr for &'a BigNum { } } -impl<'a> Neg for &'a BigNumRef { +impl<'a> Neg for &'a Ref { type Output = BigNum; fn neg(self) -> BigNum { diff --git a/openssl/src/dsa.rs b/openssl/src/dsa.rs index e92b8ca3..c98d9c35 100644 --- a/openssl/src/dsa.rs +++ b/openssl/src/dsa.rs @@ -5,11 +5,12 @@ use std::fmt; use std::ops::Deref; use std::ptr; -use {cvt, cvt_p}; -use bn::BigNumRef; use bio::{MemBio, MemBioSlice}; -use util::{CallbackState, invoke_passwd_cb}; +use bn::BigNum; +use {cvt, cvt_p}; use opaque::Opaque; +use types::Ref; +use util::{CallbackState, invoke_passwd_cb}; pub struct DsaRef(Opaque); @@ -53,35 +54,35 @@ impl DsaRef { } } - pub fn p(&self) -> Option<&BigNumRef> { + pub fn p(&self) -> Option<&Ref> { unsafe { let p = compat::pqg(self.as_ptr())[0]; if p.is_null() { None } else { - Some(BigNumRef::from_ptr(p as *mut _)) + Some(Ref::::from_ptr(p as *mut _)) } } } - pub fn q(&self) -> Option<&BigNumRef> { + pub fn q(&self) -> Option<&Ref> { unsafe { let q = compat::pqg(self.as_ptr())[1]; if q.is_null() { None } else { - Some(BigNumRef::from_ptr(q as *mut _)) + Some(Ref::::from_ptr(q as *mut _)) } } } - pub fn g(&self) -> Option<&BigNumRef> { + pub fn g(&self) -> Option<&Ref> { unsafe { let g = compat::pqg(self.as_ptr())[2]; if g.is_null() { None } else { - Some(BigNumRef::from_ptr(g as *mut _)) + Some(Ref::::from_ptr(g as *mut _)) } } } diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs index c6c96223..a12dc4d1 100644 --- a/openssl/src/rsa.rs +++ b/openssl/src/rsa.rs @@ -6,10 +6,11 @@ use std::ops::Deref; use libc::{c_int, c_void, c_char}; use {cvt, cvt_p, cvt_n}; -use bn::{BigNum, BigNumRef}; +use bn::BigNum; use bio::{MemBio, MemBioSlice}; use error::ErrorStack; use util::{CallbackState, invoke_passwd_cb}; +use types::{OpenSslType, Ref}; use opaque::Opaque; /// Type of encryption padding to use. @@ -162,57 +163,57 @@ impl RsaRef { } } - pub fn n(&self) -> Option<&BigNumRef> { + pub fn n(&self) -> Option<&Ref> { unsafe { let n = compat::key(self.as_ptr())[0]; if n.is_null() { None } else { - Some(BigNumRef::from_ptr(n as *mut _)) + Some(Ref::::from_ptr(n as *mut _)) } } } - pub fn d(&self) -> Option<&BigNumRef> { + pub fn d(&self) -> Option<&Ref> { unsafe { let d = compat::key(self.as_ptr())[2]; if d.is_null() { None } else { - Some(BigNumRef::from_ptr(d as *mut _)) + Some(Ref::::from_ptr(d as *mut _)) } } } - pub fn e(&self) -> Option<&BigNumRef> { + pub fn e(&self) -> Option<&Ref> { unsafe { let e = compat::key(self.as_ptr())[1]; if e.is_null() { None } else { - Some(BigNumRef::from_ptr(e as *mut _)) + Some(Ref::::from_ptr(e as *mut _)) } } } - pub fn p(&self) -> Option<&BigNumRef> { + pub fn p(&self) -> Option<&Ref> { unsafe { let p = compat::factors(self.as_ptr())[0]; if p.is_null() { None } else { - Some(BigNumRef::from_ptr(p as *mut _)) + Some(Ref::::from_ptr(p as *mut _)) } } } - pub fn q(&self) -> Option<&BigNumRef> { + pub fn q(&self) -> Option<&Ref> { unsafe { let q = compat::factors(self.as_ptr())[1]; if q.is_null() { None } else { - Some(BigNumRef::from_ptr(q as *mut _)) + Some(Ref::::from_ptr(q as *mut _)) } } } From 849fca4a7b285368ea3fc6f484350d6fa59c29e8 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 19:49:37 -0700 Subject: [PATCH 03/13] Convert Asn1Time --- openssl/src/asn1.rs | 44 +++-------------------------------------- openssl/src/x509/mod.rs | 10 +++++----- 2 files changed, 8 insertions(+), 46 deletions(-) diff --git a/openssl/src/asn1.rs b/openssl/src/asn1.rs index 9a83a5da..a089b41b 100644 --- a/openssl/src/asn1.rs +++ b/openssl/src/asn1.rs @@ -1,30 +1,15 @@ use libc::c_long; use std::{ptr, fmt}; -use std::ops::Deref; - use ffi; -use opaque::Opaque; use {cvt, cvt_p}; use bio::MemBio; use error::ErrorStack; +use types::{OpenSslType, Ref}; -/// A borrowed Asn1Time -pub struct Asn1TimeRef(Opaque); +type_!(Asn1Time, ffi::ASN1_TIME, ffi::ASN1_TIME_free); -impl Asn1TimeRef { - /// Creates a new `Asn1TimeRef` wrapping the provided handle. - pub unsafe fn from_ptr<'a>(handle: *mut ffi::ASN1_TIME) -> &'a Asn1TimeRef { - &*(handle as *mut _) - } - - /// Returns the raw handle - pub fn as_ptr(&self) -> *mut ffi::ASN1_TIME { - self as *const _ as *mut _ - } -} - -impl fmt::Display for Asn1TimeRef { +impl fmt::Display for Ref { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mem_bio = try!(MemBio::new()); let as_str = unsafe { @@ -35,16 +20,7 @@ impl fmt::Display for Asn1TimeRef { } } - -/// Corresponds to the ASN.1 structure Time defined in RFC5280 -pub struct Asn1Time(*mut ffi::ASN1_TIME); - impl Asn1Time { - /// Wraps existing ASN1_TIME and takes ownership - pub unsafe fn from_ptr(handle: *mut ffi::ASN1_TIME) -> Asn1Time { - Asn1Time(handle) - } - fn from_period(period: c_long) -> Result { ffi::init(); @@ -59,17 +35,3 @@ impl Asn1Time { Asn1Time::from_period(days as c_long * 60 * 60 * 24) } } - -impl Deref for Asn1Time { - type Target = Asn1TimeRef; - - fn deref(&self) -> &Asn1TimeRef { - unsafe { Asn1TimeRef::from_ptr(self.0) } - } -} - -impl Drop for Asn1Time { - fn drop(&mut self) { - unsafe { ffi::ASN1_TIME_free(self.as_ptr()) }; - } -} diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index b49a9848..8a4941ea 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -14,7 +14,6 @@ use std::str; use {cvt, cvt_p}; use asn1::Asn1Time; -use asn1::Asn1TimeRef; use bio::{MemBio, MemBioSlice}; use crypto::CryptoString; use hash::MessageDigest; @@ -24,6 +23,7 @@ use error::ErrorStack; use ffi; use nid::Nid; use opaque::Opaque; +use types::Ref; #[cfg(ossl10x)] use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data}; @@ -401,20 +401,20 @@ impl X509Ref { } /// Returns certificate Not After validity period. - pub fn not_after<'a>(&'a self) -> &'a Asn1TimeRef { + pub fn not_after<'a>(&'a self) -> &'a Ref { unsafe { let date = compat::X509_get_notAfter(self.as_ptr()); assert!(!date.is_null()); - Asn1TimeRef::from_ptr(date) + Ref::from_ptr(date) } } /// Returns certificate Not Before validity period. - pub fn not_before<'a>(&'a self) -> &'a Asn1TimeRef { + pub fn not_before<'a>(&'a self) -> &'a Ref { unsafe { let date = compat::X509_get_notBefore(self.as_ptr()); assert!(!date.is_null()); - Asn1TimeRef::from_ptr(date) + Ref::from_ptr(date) } } From 28f375974a21342f3ae4c39f0a4df17570d89e69 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 19:56:03 -0700 Subject: [PATCH 04/13] Convert Dh --- openssl/src/dh.rs | 31 ++----------------------------- openssl/src/ssl/mod.rs | 5 +++-- 2 files changed, 5 insertions(+), 31 deletions(-) diff --git a/openssl/src/dh.rs b/openssl/src/dh.rs index 5c5ea05e..4ae145d6 100644 --- a/openssl/src/dh.rs +++ b/openssl/src/dh.rs @@ -3,25 +3,12 @@ use error::ErrorStack; use bio::MemBioSlice; use std::ptr; use std::mem; -use std::ops::Deref; use {cvt, cvt_p}; use bn::BigNum; -use opaque::Opaque; +use types::OpenSslType; -pub struct DhRef(Opaque); - -impl DhRef { - pub unsafe fn from_ptr<'a>(ptr: *mut ffi::DH) -> &'a DhRef { - &*(ptr as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::DH { - self as *const _ as *mut _ - } -} - -pub struct Dh(*mut ffi::DH); +type_!(Dh, ffi::DH, ffi::DH_free); impl Dh { pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result { @@ -63,20 +50,6 @@ impl Dh { } } -impl Drop for Dh { - fn drop(&mut self) { - unsafe { ffi::DH_free(self.0) } - } -} - -impl Deref for Dh { - type Target = DhRef; - - fn deref(&self) -> &DhRef { - unsafe { DhRef::from_ptr(self.0) } - } -} - #[cfg(ossl110)] mod compat { pub use ffi::DH_set0_pqg; diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 5466f26e..695b2382 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -91,7 +91,7 @@ use std::marker::PhantomData; use ffi; use {init, cvt, cvt_p}; -use dh::DhRef; +use dh::Dh; use ec_key::EcKeyRef; use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError}; #[cfg(any(ossl102, ossl110))] @@ -99,6 +99,7 @@ use verify::X509VerifyParamRef; use pkey::PKeyRef; use error::ErrorStack; use opaque::Opaque; +use types::Ref; mod error; mod connector; @@ -513,7 +514,7 @@ impl SslContextBuilder { } } - pub fn set_tmp_dh(&mut self, dh: &DhRef) -> Result<(), ErrorStack> { + pub fn set_tmp_dh(&mut self, dh: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_set_tmp_dh(self.as_ptr(), dh.as_ptr()) as c_int).map(|_| ()) } } From fe5fb75d45c69a2cfca87982e57ea14876d1b795 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 20:04:55 -0700 Subject: [PATCH 05/13] Update Dsa --- openssl/src/dsa.rs | 44 ++++++-------------------------------------- 1 file changed, 6 insertions(+), 38 deletions(-) diff --git a/openssl/src/dsa.rs b/openssl/src/dsa.rs index c98d9c35..6efa7050 100644 --- a/openssl/src/dsa.rs +++ b/openssl/src/dsa.rs @@ -2,27 +2,17 @@ use error::ErrorStack; use ffi; use libc::{c_int, c_char, c_void}; use std::fmt; -use std::ops::Deref; use std::ptr; use bio::{MemBio, MemBioSlice}; use bn::BigNum; use {cvt, cvt_p}; -use opaque::Opaque; use types::Ref; use util::{CallbackState, invoke_passwd_cb}; -pub struct DsaRef(Opaque); - -impl DsaRef { - pub unsafe fn from_ptr<'a>(ptr: *mut ffi::DSA) -> &'a DsaRef { - &*(ptr as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::DSA { - self as *const _ as *mut _ - } +type_!(Dsa, ffi::DSA, ffi::DSA_free); +impl Ref { /// Writes an DSA private key as unencrypted PEM formatted data pub fn private_key_to_pem(&self) -> Result, ErrorStack> { assert!(self.has_private_key()); @@ -96,21 +86,7 @@ impl DsaRef { } } -pub struct Dsa(*mut ffi::DSA); - -impl Drop for Dsa { - fn drop(&mut self) { - unsafe { - ffi::DSA_free(self.0); - } - } -} - impl Dsa { - pub unsafe fn from_ptr(dsa: *mut ffi::DSA) -> Dsa { - Dsa(dsa) - } - /// Generate a DSA key pair. pub fn generate(bits: u32) -> Result { unsafe { @@ -122,7 +98,7 @@ impl Dsa { ptr::null_mut(), ptr::null_mut(), ptr::null_mut()))); - try!(cvt(ffi::DSA_generate_key(dsa .0))); + try!(cvt(ffi::DSA_generate_key(dsa.0))); Ok(dsa) } } @@ -178,11 +154,9 @@ impl Dsa { } } -impl Deref for Dsa { - type Target = DsaRef; - - fn deref(&self) -> &DsaRef { - unsafe { DsaRef::from_ptr(self.0) } +impl fmt::Debug for Dsa { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "DSA") } } @@ -217,12 +191,6 @@ mod compat { } } -impl fmt::Debug for Dsa { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "DSA") - } -} - #[cfg(test)] mod test { use libc::c_char; From d6579ab058a22b8e7e2d82cd0d707fb3e670d5ec Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 20:06:06 -0700 Subject: [PATCH 06/13] Update EcKey --- openssl/src/ec_key.rs | 36 +----------------------------------- openssl/src/ssl/mod.rs | 4 ++-- 2 files changed, 3 insertions(+), 37 deletions(-) diff --git a/openssl/src/ec_key.rs b/openssl/src/ec_key.rs index 81b790aa..95175eaa 100644 --- a/openssl/src/ec_key.rs +++ b/openssl/src/ec_key.rs @@ -1,49 +1,15 @@ use ffi; -use std::ops::Deref; use cvt_p; use error::ErrorStack; use nid::Nid; -use opaque::Opaque; -pub struct EcKeyRef(Opaque); - -impl EcKeyRef { - pub unsafe fn from_ptr<'a>(ptr: *mut ffi::EC_KEY) -> &'a EcKeyRef { - &*(ptr as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::EC_KEY { - self as *const _ as *mut _ - } -} - -pub struct EcKey(*mut ffi::EC_KEY); - -impl Drop for EcKey { - fn drop(&mut self) { - unsafe { - ffi::EC_KEY_free(self.0); - } - } -} +type_!(EcKey, ffi::EC_KEY, ffi::EC_KEY_free); impl EcKey { pub fn new_by_curve_name(nid: Nid) -> Result { unsafe { cvt_p(ffi::EC_KEY_new_by_curve_name(nid.as_raw())).map(EcKey) } } - - pub unsafe fn from_ptr(ptr: *mut ffi::EC_KEY) -> EcKey { - EcKey(ptr) - } -} - -impl Deref for EcKey { - type Target = EcKeyRef; - - fn deref(&self) -> &EcKeyRef { - unsafe { EcKeyRef::from_ptr(self.0) } - } } #[cfg(test)] diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 695b2382..97b0fe6e 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -92,7 +92,7 @@ use ffi; use {init, cvt, cvt_p}; use dh::Dh; -use ec_key::EcKeyRef; +use ec_key::EcKey; use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError}; #[cfg(any(ossl102, ossl110))] use verify::X509VerifyParamRef; @@ -518,7 +518,7 @@ impl SslContextBuilder { unsafe { cvt(ffi::SSL_CTX_set_tmp_dh(self.as_ptr(), dh.as_ptr()) as c_int).map(|_| ()) } } - pub fn set_tmp_ecdh(&mut self, key: &EcKeyRef) -> Result<(), ErrorStack> { + pub fn set_tmp_ecdh(&mut self, key: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_set_tmp_ecdh(self.as_ptr(), key.as_ptr()) as c_int).map(|_| ()) } } From f640613863f0b66bc004f9d9d89f73a31701d396 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 20:12:55 -0700 Subject: [PATCH 07/13] Update PKey --- openssl/src/pkcs12.rs | 1 + openssl/src/pkey.rs | 41 ++++-------------------------------- openssl/src/ssl/connector.rs | 9 ++++---- openssl/src/ssl/mod.rs | 4 ++-- openssl/src/x509/mod.rs | 8 +++---- 5 files changed, 16 insertions(+), 47 deletions(-) diff --git a/openssl/src/pkcs12.rs b/openssl/src/pkcs12.rs index ab0934a8..1318f7f7 100644 --- a/openssl/src/pkcs12.rs +++ b/openssl/src/pkcs12.rs @@ -10,6 +10,7 @@ use {cvt, cvt_p}; use pkey::PKey; use error::ErrorStack; use x509::X509; +use types::OpenSslType; /// A PKCS #12 archive. pub struct Pkcs12(*mut ffi::PKCS12); diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index 8e4041b1..2561ab29 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -1,7 +1,6 @@ use libc::{c_void, c_char, c_int}; use std::ptr; use std::mem; -use std::ops::Deref; use ffi; use {cvt, cvt_p}; @@ -10,20 +9,11 @@ use dsa::Dsa; use rsa::{Rsa, RsaRef}; use error::ErrorStack; use util::{CallbackState, invoke_passwd_cb}; -use opaque::Opaque; +use types::{OpenSslType, Ref}; -/// A borrowed `PKey`. -pub struct PKeyRef(Opaque); - -impl PKeyRef { - pub unsafe fn from_ptr<'a>(ptr: *mut ffi::EVP_PKEY) -> &'a PKeyRef { - &*(ptr as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::EVP_PKEY { - self as *const _ as *mut _ - } +type_!(PKey, ffi::EVP_PKEY, ffi::EVP_PKEY_free); +impl Ref { /// Get a reference to the interal RSA key for direct access to the key components pub fn rsa(&self) -> Result { unsafe { @@ -59,14 +49,11 @@ impl PKeyRef { Ok(mem_bio.get_buf().to_owned()) } - pub fn public_eq(&self, other: &PKeyRef) -> bool { + pub fn public_eq(&self, other: &Ref) -> bool { unsafe { ffi::EVP_PKEY_cmp(self.as_ptr(), other.as_ptr()) == 1 } } } -/// Represents a public key, optionally with a private key attached. -pub struct PKey(*mut ffi::EVP_PKEY); - unsafe impl Send for PKey {} unsafe impl Sync for PKey {} @@ -105,10 +92,6 @@ impl PKey { } } - pub unsafe fn from_ptr(handle: *mut ffi::EVP_PKEY) -> PKey { - PKey(handle) - } - /// Reads private key from PEM, takes ownership of handle pub fn private_key_from_pem(buf: &[u8]) -> Result { ffi::init(); @@ -166,22 +149,6 @@ impl PKey { } } -impl Drop for PKey { - fn drop(&mut self) { - unsafe { - ffi::EVP_PKEY_free(self.0); - } - } -} - -impl Deref for PKey { - type Target = PKeyRef; - - fn deref(&self) -> &PKeyRef { - unsafe { PKeyRef::from_ptr(self.0) } - } -} - #[cfg(test)] mod tests { #[test] diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs index c7bfb209..752126e0 100644 --- a/openssl/src/ssl/connector.rs +++ b/openssl/src/ssl/connector.rs @@ -4,8 +4,9 @@ use dh::Dh; use error::ErrorStack; use ssl::{self, SslMethod, SslContextBuilder, SslContext, Ssl, SSL_VERIFY_PEER, SslStream, HandshakeError}; -use pkey::PKeyRef; +use pkey::PKey; use x509::X509Ref; +use types::Ref; // apps/dh2048.pem const DHPARAM_PEM: &'static str = r#" @@ -116,7 +117,7 @@ impl SslAcceptorBuilder { /// /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS pub fn mozilla_intermediate(method: SslMethod, - private_key: &PKeyRef, + private_key: &Ref, certificate: &X509Ref, chain: I) -> Result @@ -151,7 +152,7 @@ impl SslAcceptorBuilder { /// /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS pub fn mozilla_modern(method: SslMethod, - private_key: &PKeyRef, + private_key: &Ref, certificate: &X509Ref, chain: I) -> Result @@ -169,7 +170,7 @@ impl SslAcceptorBuilder { } fn finish_setup(mut ctx: SslContextBuilder, - private_key: &PKeyRef, + private_key: &Ref, certificate: &X509Ref, chain: I) -> Result diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 97b0fe6e..6a6916fc 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -96,7 +96,7 @@ use ec_key::EcKey; use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError}; #[cfg(any(ossl102, ossl110))] use verify::X509VerifyParamRef; -use pkey::PKeyRef; +use pkey::PKey; use error::ErrorStack; use opaque::Opaque; use types::Ref; @@ -615,7 +615,7 @@ impl SslContextBuilder { } /// Specifies the private key - pub fn set_private_key(&mut self, key: &PKeyRef) -> Result<(), ErrorStack> { + pub fn set_private_key(&mut self, key: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_use_PrivateKey(self.as_ptr(), key.as_ptr())).map(|_| ()) } } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 8a4941ea..d3f7fbc0 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -17,13 +17,13 @@ use asn1::Asn1Time; use bio::{MemBio, MemBioSlice}; use crypto::CryptoString; use hash::MessageDigest; -use pkey::{PKey, PKeyRef}; +use pkey::PKey; use rand::rand_bytes; use error::ErrorStack; use ffi; use nid::Nid; use opaque::Opaque; -use types::Ref; +use types::{OpenSslType, Ref}; #[cfg(ossl10x)] use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data}; @@ -269,7 +269,7 @@ impl X509Generator { } /// Sets the certificate public-key, then self-sign and return it - pub fn sign(&self, p_key: &PKeyRef) -> Result { + pub fn sign(&self, p_key: &Ref) -> Result { ffi::init(); unsafe { @@ -321,7 +321,7 @@ impl X509Generator { } /// Obtain a certificate signing request (CSR) - pub fn request(&self, p_key: &PKeyRef) -> Result { + pub fn request(&self, p_key: &Ref) -> Result { let cert = match self.sign(p_key) { Ok(c) => c, Err(x) => return Err(x), From e9d78181c334bb0398f65b30f6165ec1b54fe623 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 20:15:12 -0700 Subject: [PATCH 08/13] Update Rsa --- openssl/src/pkey.rs | 4 ++-- openssl/src/rsa.rs | 36 ++---------------------------------- 2 files changed, 4 insertions(+), 36 deletions(-) diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index 2561ab29..6236b642 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -6,7 +6,7 @@ use ffi; use {cvt, cvt_p}; use bio::{MemBio, MemBioSlice}; use dsa::Dsa; -use rsa::{Rsa, RsaRef}; +use rsa::Rsa; use error::ErrorStack; use util::{CallbackState, invoke_passwd_cb}; use types::{OpenSslType, Ref}; @@ -139,7 +139,7 @@ impl PKey { } /// Assign an RSA key to this pkey. - pub fn set_rsa(&mut self, rsa: &RsaRef) -> Result<(), ErrorStack> { + pub fn set_rsa(&mut self, rsa: &Ref) -> Result<(), ErrorStack> { unsafe { // this needs to be a reference as the set1_RSA ups the reference count let rsa_ptr = rsa.as_ptr(); diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs index a12dc4d1..57a07bd1 100644 --- a/openssl/src/rsa.rs +++ b/openssl/src/rsa.rs @@ -2,7 +2,6 @@ use ffi; use std::fmt; use std::ptr; use std::mem; -use std::ops::Deref; use libc::{c_int, c_void, c_char}; use {cvt, cvt_p, cvt_n}; @@ -11,7 +10,6 @@ use bio::{MemBio, MemBioSlice}; use error::ErrorStack; use util::{CallbackState, invoke_passwd_cb}; use types::{OpenSslType, Ref}; -use opaque::Opaque; /// Type of encryption padding to use. #[derive(Copy, Clone)] @@ -21,17 +19,9 @@ pub const NO_PADDING: Padding = Padding(ffi::RSA_NO_PADDING); pub const PKCS1_PADDING: Padding = Padding(ffi::RSA_PKCS1_PADDING); pub const PKCS1_OAEP_PADDING: Padding = Padding(ffi::RSA_PKCS1_OAEP_PADDING); -pub struct RsaRef(Opaque); - -impl RsaRef { - pub unsafe fn from_ptr<'a>(ptr: *mut ffi::RSA) -> &'a RsaRef { - &*(ptr as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::RSA { - self as *const _ as *mut _ - } +type_!(Rsa, ffi::RSA, ffi::RSA_free); +impl Ref { /// Writes an RSA private key as unencrypted PEM formatted data pub fn private_key_to_pem(&self) -> Result, ErrorStack> { let mem_bio = try!(MemBio::new()); @@ -219,16 +209,6 @@ impl RsaRef { } } -pub struct Rsa(*mut ffi::RSA); - -impl Drop for Rsa { - fn drop(&mut self) { - unsafe { - ffi::RSA_free(self.0); - } - } -} - impl Rsa { /// only useful for associating the key material directly with the key, it's safer to use /// the supplied load and save methods for DER formatted keys. @@ -266,10 +246,6 @@ impl Rsa { } } - pub unsafe fn from_ptr(rsa: *mut ffi::RSA) -> Rsa { - Rsa(rsa) - } - /// Generates a public/private key pair with the specified size. /// /// The public exponent will be 65537. @@ -330,14 +306,6 @@ impl fmt::Debug for Rsa { } } -impl Deref for Rsa { - type Target = RsaRef; - - fn deref(&self) -> &RsaRef { - unsafe { RsaRef::from_ptr(self.0) } - } -} - #[cfg(ossl110)] mod compat { use std::ptr; From 16e398e005803e0796f7033497179d689b3df265 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 20:19:59 -0700 Subject: [PATCH 09/13] Update verify --- openssl-sys/src/lib.rs | 2 ++ openssl/src/sign.rs | 9 +++++---- openssl/src/ssl/mod.rs | 8 ++++---- openssl/src/verify.rs | 14 +++----------- 4 files changed, 14 insertions(+), 19 deletions(-) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 755277e4..7f92f3a3 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1675,6 +1675,8 @@ extern { pub fn X509_REQ_add_extensions(req: *mut X509_REQ, exts: *mut stack_st_X509_EXTENSION) -> c_int; pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int; + #[cfg(not(ossl101))] + pub fn X509_VERIFY_PARAM_free(param: *mut X509_VERIFY_PARAM); #[cfg(not(ossl101))] pub fn X509_VERIFY_PARAM_set_hostflags(param: *mut X509_VERIFY_PARAM, flags: c_uint); #[cfg(not(ossl101))] diff --git a/openssl/src/sign.rs b/openssl/src/sign.rs index eeee5cc7..aebfcca7 100644 --- a/openssl/src/sign.rs +++ b/openssl/src/sign.rs @@ -63,13 +63,14 @@ use {cvt, cvt_p}; use hash::MessageDigest; use pkey::PKey; use error::ErrorStack; +use types::Ref; #[cfg(ossl110)] use ffi::{EVP_MD_CTX_new, EVP_MD_CTX_free}; #[cfg(any(ossl101, ossl102))] use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; -pub struct Signer<'a>(*mut ffi::EVP_MD_CTX, PhantomData<&'a PKey>); +pub struct Signer<'a>(*mut ffi::EVP_MD_CTX, PhantomData<&'a Ref>); impl<'a> Drop for Signer<'a> { fn drop(&mut self) { @@ -80,7 +81,7 @@ impl<'a> Drop for Signer<'a> { } impl<'a> Signer<'a> { - pub fn new(type_: MessageDigest, pkey: &'a PKey) -> Result, ErrorStack> { + pub fn new(type_: MessageDigest, pkey: &'a Ref) -> Result, ErrorStack> { unsafe { ffi::init(); @@ -128,7 +129,7 @@ impl<'a> Write for Signer<'a> { } } -pub struct Verifier<'a>(*mut ffi::EVP_MD_CTX, PhantomData<&'a PKey>); +pub struct Verifier<'a>(*mut ffi::EVP_MD_CTX, PhantomData<&'a Ref>); impl<'a> Drop for Verifier<'a> { fn drop(&mut self) { @@ -139,7 +140,7 @@ impl<'a> Drop for Verifier<'a> { } impl<'a> Verifier<'a> { - pub fn new(type_: MessageDigest, pkey: &'a PKey) -> Result, ErrorStack> { + pub fn new(type_: MessageDigest, pkey: &'a Ref) -> Result, ErrorStack> { unsafe { ffi::init(); diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 6a6916fc..8101ad01 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -95,7 +95,7 @@ use dh::Dh; use ec_key::EcKey; use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError}; #[cfg(any(ossl102, ossl110))] -use verify::X509VerifyParamRef; +use verify::X509VerifyParam; use pkey::PKey; use error::ErrorStack; use opaque::Opaque; @@ -1109,13 +1109,13 @@ impl SslRef { /// /// 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(&mut self) -> &mut X509VerifyParamRef { + pub fn param_mut(&mut self) -> &mut Ref { self._param_mut() } #[cfg(any(ossl102, ossl110))] - fn _param_mut(&mut self) -> &mut X509VerifyParamRef { - unsafe { X509VerifyParamRef::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) } + fn _param_mut(&mut self) -> &mut Ref { + unsafe { Ref::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) } } /// Returns the result of X509 certificate verification. diff --git a/openssl/src/verify.rs b/openssl/src/verify.rs index ceb3a6c8..c067e08e 100644 --- a/openssl/src/verify.rs +++ b/openssl/src/verify.rs @@ -3,7 +3,7 @@ use ffi; use cvt; use error::ErrorStack; -use opaque::Opaque; +use types::Ref; bitflags! { pub flags X509CheckFlags: c_uint { @@ -19,17 +19,9 @@ bitflags! { } } -pub struct X509VerifyParamRef(Opaque); - -impl X509VerifyParamRef { - pub unsafe fn from_ptr_mut<'a>(ptr: *mut ffi::X509_VERIFY_PARAM) -> &'a mut X509VerifyParamRef { - &mut *(ptr as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::X509_VERIFY_PARAM { - self as *const _ as *mut _ - } +type_!(X509VerifyParam, ffi::X509_VERIFY_PARAM, ffi::X509_VERIFY_PARAM_free); +impl Ref { pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) { unsafe { ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits); From ff12d37aefd597d41af9fa478570a4e3e588b67e Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 20:32:55 -0700 Subject: [PATCH 10/13] Update ssl --- openssl/src/ssl/mod.rs | 145 ++++++++--------------------------------- 1 file changed, 27 insertions(+), 118 deletions(-) diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 8101ad01..42c38980 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -80,7 +80,6 @@ use std::fmt; use std::io; use std::io::prelude::*; use std::mem; -use std::ops::{Deref, DerefMut}; use std::path::Path; use std::ptr; use std::str; @@ -98,8 +97,7 @@ use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError}; use verify::X509VerifyParam; use pkey::PKey; use error::ErrorStack; -use opaque::Opaque; -use types::Ref; +use types::{OpenSslType, Ref}; mod error; mod connector; @@ -295,13 +293,13 @@ extern "C" fn ssl_raw_verify(preverify_ok: c_int, x509_ctx: *mut ffi::X509_ST } extern "C" fn raw_sni(ssl: *mut ffi::SSL, al: *mut c_int, _arg: *mut c_void) -> c_int - where F: Fn(&mut SslRef) -> Result<(), SniError> + Any + 'static + Sync + Send + where F: Fn(&mut Ref) -> Result<(), SniError> + Any + 'static + Sync + Send { unsafe { let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl); let callback = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::()); let callback: &F = &*(callback as *mut F); - let ssl = SslRef::from_ptr_mut(ssl); + let ssl = Ref::from_ptr_mut(ssl); match callback(ssl) { Ok(()) => ffi::SSL_TLSEXT_ERR_OK, @@ -481,7 +479,7 @@ impl SslContextBuilder { /// Obtain the server name with `servername` then set the corresponding context /// with `set_ssl_context` pub fn set_servername_callback(&mut self, callback: F) - where F: Fn(&mut SslRef) -> Result<(), SniError> + Any + 'static + Sync + Send + where F: Fn(&mut Ref) -> Result<(), SniError> + Any + 'static + Sync + Send { unsafe { let callback = Box::new(callback); @@ -735,25 +733,7 @@ impl SslContextBuilder { } } -/// A borrowed SSL context object. -pub struct SslContextRef(Opaque); - -impl SslContextRef { - pub unsafe fn from_ptr<'a>(ctx: *mut ffi::SSL_CTX) -> &'a SslContextRef { - &*(ctx as *mut _) - } - - pub unsafe fn from_ptr_mut<'a>(ctx: *mut ffi::SSL_CTX) -> &'a mut SslContextRef { - &mut *(ctx as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::SSL_CTX { - self as *const _ as *mut _ - } -} - -/// An owned SSL context object. -pub struct SslContext(*mut ffi::SSL_CTX); +type_!(SslContext, ffi::SSL_CTX, ffi::SSL_CTX_free); unsafe impl Send for SslContext {} unsafe impl Sync for SslContext {} @@ -774,38 +754,10 @@ impl fmt::Debug for SslContext { } } -impl Drop for SslContext { - fn drop(&mut self) { - unsafe { ffi::SSL_CTX_free(self.as_ptr()) } - } -} - -impl Deref for SslContext { - type Target = SslContextRef; - - fn deref(&self) -> &SslContextRef { - unsafe { SslContextRef::from_ptr(self.0) } - } -} - -impl DerefMut for SslContext { - fn deref_mut(&mut self) -> &mut SslContextRef { - unsafe { SslContextRef::from_ptr_mut(self.0) } - } -} - impl SslContext { pub fn builder(method: SslMethod) -> Result { SslContextBuilder::new(method) } - - pub unsafe fn from_ptr(ctx: *mut ffi::SSL_CTX) -> SslContext { - SslContext(ctx) - } - - pub fn as_ptr(&self) -> *mut ffi::SSL_CTX { - self.0 - } } @@ -817,17 +769,21 @@ pub struct CipherBits { pub algorithm: i32, } -pub struct SslCipherRef(Opaque); +pub struct SslCipher(*mut ffi::SSL_CIPHER); -impl SslCipherRef { - pub unsafe fn from_ptr<'a>(ptr: *const ffi::SSL_CIPHER) -> &'a SslCipherRef { - &*(ptr as *const _) +unsafe impl OpenSslType for SslCipher { + type CType = ffi::SSL_CIPHER; + + unsafe fn from_ptr(ptr: *mut ffi::SSL_CIPHER) -> SslCipher { + SslCipher(ptr) } - pub fn as_ptr(&self) -> *const ffi::SSL_CIPHER { - self as *const _ as *const _ + fn as_ptr(&self) -> *mut ffi::SSL_CIPHER { + self.0 } +} +impl Ref { /// Returns the name of cipher. pub fn name(&self) -> &'static str { let name = unsafe { @@ -871,15 +827,11 @@ impl SslCipherRef { } } -/// A reference to an `Ssl`. -pub struct SslRef(Opaque); +type_!(Ssl, ffi::SSL, ffi::SSL_free); -unsafe impl Send for SslRef {} -unsafe impl Sync for SslRef {} - -impl fmt::Debug for SslRef { +impl fmt::Debug for Ref { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let mut builder = fmt.debug_struct("SslRef"); + let mut builder = fmt.debug_struct("Ssl"); builder.field("state", &self.state_string_long()); if let Some(err) = self.verify_result() { builder.field("verify_result", &err); @@ -888,19 +840,7 @@ impl fmt::Debug for SslRef { } } -impl SslRef { - pub unsafe fn from_ptr<'a>(ssl: *mut ffi::SSL) -> &'a SslRef { - &*(ssl as *mut _) - } - - pub unsafe fn from_ptr_mut<'a>(ssl: *mut ffi::SSL) -> &'a mut SslRef { - &mut *(ssl as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::SSL { - self as *const _ as *mut _ - } - +impl Ref { fn get_raw_rbio(&self) -> *mut ffi::BIO { unsafe { ffi::SSL_get_rbio(self.as_ptr()) } } @@ -945,14 +885,14 @@ impl SslRef { } } - pub fn current_cipher(&self) -> Option<&SslCipherRef> { + pub fn current_cipher(&self) -> Option<&Ref> { unsafe { let ptr = ffi::SSL_get_current_cipher(self.as_ptr()); if ptr.is_null() { None } else { - Some(SslCipherRef::from_ptr(ptr)) + Some(Ref::from_ptr(ptr as *mut _)) } } } @@ -1093,15 +1033,15 @@ impl SslRef { } /// Changes the context corresponding to the current connection. - pub fn set_ssl_context(&mut self, ctx: &SslContextRef) -> Result<(), ErrorStack> { + pub fn set_ssl_context(&mut self, ctx: &Ref) -> Result<(), ErrorStack> { unsafe { cvt_p(ffi::SSL_set_SSL_CTX(self.as_ptr(), ctx.as_ptr())).map(|_| ()) } } /// Returns the context corresponding to the current connection - pub fn ssl_context(&self) -> &SslContextRef { + pub fn ssl_context(&self) -> &Ref { unsafe { let ssl_ctx = ffi::SSL_get_SSL_CTX(self.as_ptr()); - SslContextRef::from_ptr(ssl_ctx) + Ref::from_ptr(ssl_ctx) } } @@ -1124,39 +1064,12 @@ impl SslRef { } } -pub struct Ssl(*mut ffi::SSL); - unsafe impl Sync for Ssl {} unsafe impl Send for Ssl {} impl fmt::Debug for Ssl { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let mut builder = fmt.debug_struct("Ssl"); - builder.field("state", &self.state_string_long()); - if let Some(err) = self.verify_result() { - builder.field("verify_result", &err); - } - builder.finish() - } -} - -impl Drop for Ssl { - fn drop(&mut self) { - unsafe { ffi::SSL_free(self.as_ptr()) } - } -} - -impl Deref for Ssl { - type Target = SslRef; - - fn deref(&self) -> &SslRef { - unsafe { SslRef::from_ptr(self.0) } - } -} - -impl DerefMut for Ssl { - fn deref_mut(&mut self) -> &mut SslRef { - unsafe { SslRef::from_ptr_mut(self.0) } + fmt::Debug::fmt(&**self, fmt) } } @@ -1168,10 +1081,6 @@ impl Ssl { } } - pub unsafe fn from_ptr(ssl: *mut ffi::SSL) -> Ssl { - Ssl(ssl) - } - /// Creates an SSL/TLS client operating over the provided stream. /// /// # Warning @@ -1256,7 +1165,7 @@ impl MidHandshakeSslStream { } /// Returns a shared reference to the `Ssl` of the stream. - pub fn ssl(&self) -> &SslRef { + pub fn ssl(&self) -> &Ref { self.stream.ssl() } @@ -1438,7 +1347,7 @@ impl SslStream { } /// Returns the OpenSSL `Ssl` object associated with this stream. - pub fn ssl(&self) -> &SslRef { + pub fn ssl(&self) -> &Ref { &self.ssl } } From cd7fa9fca29296adebe37dfc20d3cebc96010534 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 20:54:34 -0700 Subject: [PATCH 11/13] Update x509 --- openssl-sys/src/lib.rs | 4 +- openssl/src/ssl/connector.rs | 23 +++--- openssl/src/ssl/mod.rs | 16 ++--- openssl/src/ssl/tests/mod.rs | 23 +----- openssl/src/x509/mod.rs | 135 ++++++++++------------------------- 5 files changed, 62 insertions(+), 139 deletions(-) diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 7f92f3a3..ae423099 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -1658,12 +1658,14 @@ extern { pub fn X509_EXTENSION_free(ext: *mut X509_EXTENSION); + pub fn X509_NAME_free(x: *mut X509_NAME); pub fn X509_NAME_add_entry_by_txt(x: *mut X509_NAME, field: *const c_char, ty: c_int, bytes: *const c_uchar, len: c_int, loc: c_int, set: c_int) -> c_int; pub fn X509_NAME_get_index_by_NID(n: *mut X509_NAME, nid: c_int, last_pos: c_int) ->c_int; pub fn ASN1_STRING_length(x: *const ASN1_STRING) -> c_int; - pub fn X509_STORE_CTX_get_current_cert(ct: *mut X509_STORE_CTX) -> *mut X509; + pub fn X509_STORE_CTX_free(ctx: *mut X509_STORE_CTX); + pub fn X509_STORE_CTX_get_current_cert(ctx: *mut X509_STORE_CTX) -> *mut X509; pub fn X509_STORE_CTX_get_error(ctx: *mut X509_STORE_CTX) -> c_int; pub fn X509_STORE_CTX_get_ex_data(ctx: *mut X509_STORE_CTX, idx: c_int) -> *mut c_void; pub fn X509_STORE_CTX_get_error_depth(ctx: *mut X509_STORE_CTX) -> c_int; diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs index 752126e0..a1bcfa77 100644 --- a/openssl/src/ssl/connector.rs +++ b/openssl/src/ssl/connector.rs @@ -5,7 +5,7 @@ use error::ErrorStack; use ssl::{self, SslMethod, SslContextBuilder, SslContext, Ssl, SSL_VERIFY_PEER, SslStream, HandshakeError}; use pkey::PKey; -use x509::X509Ref; +use x509::X509; use types::Ref; // apps/dh2048.pem @@ -118,11 +118,11 @@ impl SslAcceptorBuilder { /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS pub fn mozilla_intermediate(method: SslMethod, private_key: &Ref, - certificate: &X509Ref, + certificate: &Ref, chain: I) -> Result where I: IntoIterator, - I::Item: AsRef + I::Item: AsRef> { let mut ctx = try!(ctx(method)); let dh = try!(Dh::from_pem(DHPARAM_PEM.as_bytes())); @@ -153,11 +153,11 @@ impl SslAcceptorBuilder { /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS pub fn mozilla_modern(method: SslMethod, private_key: &Ref, - certificate: &X509Ref, + certificate: &Ref, chain: I) -> Result where I: IntoIterator, - I::Item: AsRef + I::Item: AsRef> { let mut ctx = try!(ctx(method)); try!(setup_curves(&mut ctx)); @@ -171,11 +171,11 @@ impl SslAcceptorBuilder { fn finish_setup(mut ctx: SslContextBuilder, private_key: &Ref, - certificate: &X509Ref, + certificate: &Ref, chain: I) -> Result where I: IntoIterator, - I::Item: AsRef + I::Item: AsRef> { try!(ctx.set_private_key(private_key)); try!(ctx.set_certificate(certificate)); @@ -255,11 +255,12 @@ mod verify { use std::net::IpAddr; use nid; - use x509::{X509StoreContextRef, X509Ref, GeneralNames, X509NameRef}; + use x509::{X509StoreContext, X509, GeneralNames, X509Name}; + use types::Ref; pub fn verify_callback(domain: &str, preverify_ok: bool, - x509_ctx: &X509StoreContextRef) + x509_ctx: &Ref) -> bool { if !preverify_ok || x509_ctx.error_depth() != 0 { return preverify_ok; @@ -271,7 +272,7 @@ mod verify { } } - fn verify_hostname(domain: &str, cert: &X509Ref) -> bool { + fn verify_hostname(domain: &str, cert: &Ref) -> bool { match cert.subject_alt_names() { Some(names) => verify_subject_alt_names(domain, &names), None => verify_subject_name(domain, &cert.subject_name()), @@ -303,7 +304,7 @@ mod verify { false } - fn verify_subject_name(domain: &str, subject_name: &X509NameRef) -> bool { + fn verify_subject_name(domain: &str, subject_name: &Ref) -> bool { if let Some(pattern) = subject_name.text_by_nid(nid::COMMONNAME) { // Unlike with SANs, IP addresses in the subject name don't have a // different encoding. We need to pass this down to matches_dns to diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 42c38980..68d411c7 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -92,7 +92,7 @@ use ffi; use {init, cvt, cvt_p}; use dh::Dh; use ec_key::EcKey; -use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError}; +use x509::{X509StoreContext, X509FileType, X509, X509VerifyError}; #[cfg(any(ossl102, ossl110))] use verify::X509VerifyParam; use pkey::PKey; @@ -262,7 +262,7 @@ fn get_new_ssl_idx() -> c_int { } extern "C" fn raw_verify(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int - where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send + where F: Fn(bool, &Ref) -> bool + Any + 'static + Sync + Send { unsafe { let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx(); @@ -271,14 +271,14 @@ extern "C" fn raw_verify(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_ let verify = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::()); let verify: &F = &*(verify as *mut F); - let ctx = X509StoreContextRef::from_ptr(x509_ctx); + let ctx = Ref::from_ptr(x509_ctx); verify(preverify_ok != 0, ctx) as c_int } } extern "C" fn ssl_raw_verify(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int - where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send + where F: Fn(bool, &Ref) -> bool + Any + 'static + Sync + Send { unsafe { let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx(); @@ -286,7 +286,7 @@ extern "C" fn ssl_raw_verify(preverify_ok: c_int, x509_ctx: *mut ffi::X509_ST let verify = ffi::SSL_get_ex_data(ssl as *const _, get_ssl_verify_data_idx::()); let verify: &F = &*(verify as *mut F); - let ctx = X509StoreContextRef::from_ptr(x509_ctx); + let ctx = Ref::from_ptr(x509_ctx); verify(preverify_ok != 0, ctx) as c_int } @@ -463,7 +463,7 @@ impl SslContextBuilder { /// Configures the certificate verification method for new connections and /// registers a verification callback. pub fn set_verify_callback(&mut self, mode: SslVerifyMode, verify: F) - where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send + where F: Fn(bool, &Ref) -> bool + Any + 'static + Sync + Send { unsafe { let verify = Box::new(verify); @@ -584,7 +584,7 @@ impl SslContextBuilder { } /// Specifies the certificate - pub fn set_certificate(&mut self, cert: &X509Ref) -> Result<(), ErrorStack> { + pub fn set_certificate(&mut self, cert: &Ref) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_use_certificate(self.as_ptr(), cert.as_ptr())).map(|_| ()) } } @@ -874,7 +874,7 @@ impl Ref { /// to the certificate chain. It should return `true` if the certificate /// chain is valid and `false` otherwise. pub fn set_verify_callback(&mut self, mode: SslVerifyMode, verify: F) - where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send + where F: Fn(bool, &Ref) -> bool + Any + 'static + Sync + Send { unsafe { let verify = Box::new(verify); diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index a874fe3b..13b3a8a7 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -20,7 +20,7 @@ use ssl::SSL_VERIFY_PEER; use ssl::{SslMethod, HandshakeError}; use ssl::{SslContext, SslStream, Ssl, ShutdownResult, SslConnectorBuilder, SslAcceptorBuilder, Error}; -use x509::X509StoreContextRef; +use x509::X509StoreContext; use x509::X509FileType; use x509::X509; #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] @@ -171,8 +171,9 @@ macro_rules! run_test( use ssl::{SslContext, Ssl, SslStream}; use ssl::SSL_VERIFY_PEER; use hash::MessageDigest; - use x509::X509StoreContextRef; + use x509::X509StoreContext; use serialize::hex::FromHex; + use types::Ref; use super::Server; #[test] @@ -771,24 +772,6 @@ fn test_alpn_server_select_none() { assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_err()); } -#[cfg(test)] -mod dtlsv1 { - use serialize::hex::FromHex; - use std::net::TcpStream; - use std::thread; - - use hash::MessageDigest; - use ssl::SslMethod; - use ssl::{SslContext, SslStream}; - use ssl::SSL_VERIFY_PEER; - use x509::X509StoreContextRef; - - #[test] - fn test_new_ctx() { - SslContext::builder(SslMethod::dtls()).unwrap(); - } -} - #[test] #[cfg_attr(any(windows, target_arch = "arm"), ignore)] // FIXME(#467) fn test_read_dtlsv1() { diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index d3f7fbc0..bb2c7544 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -7,7 +7,6 @@ use std::ffi::{CStr, CString}; use std::fmt; use std::marker::PhantomData; use std::mem; -use std::ops::Deref; use std::ptr; use std::slice; use std::str; @@ -22,7 +21,6 @@ use rand::rand_bytes; use error::ErrorStack; use ffi; use nid::Nid; -use opaque::Opaque; use types::{OpenSslType, Ref}; #[cfg(ossl10x)] @@ -49,28 +47,20 @@ pub enum X509FileType { Default = ffi::X509_FILETYPE_DEFAULT, } -pub struct X509StoreContextRef(Opaque); - -impl X509StoreContextRef { - pub unsafe fn from_ptr<'a>(ctx: *mut ffi::X509_STORE_CTX) -> &'a X509StoreContextRef { - &*(ctx as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::X509_STORE_CTX { - self as *const _ as *mut _ - } +type_!(X509StoreContext, ffi::X509_STORE_CTX, ffi::X509_STORE_CTX_free); +impl Ref { pub fn error(&self) -> Option { unsafe { X509VerifyError::from_raw(ffi::X509_STORE_CTX_get_error(self.as_ptr()) as c_long) } } - pub fn current_cert(&self) -> Option<&X509Ref> { + pub fn current_cert(&self) -> Option<&Ref> { unsafe { let ptr = ffi::X509_STORE_CTX_get_current_cert(self.as_ptr()); if ptr.is_null() { None } else { - Some(X509Ref::from_ptr(ptr)) + Some(Ref::from_ptr(ptr)) } } } @@ -346,23 +336,13 @@ impl X509Generator { } } -/// A borrowed public key certificate. -pub struct X509Ref(Opaque); +type_!(X509, ffi::X509, ffi::X509_free); -impl X509Ref { - /// Creates a new `X509Ref` wrapping the provided handle. - pub unsafe fn from_ptr<'a>(x509: *mut ffi::X509) -> &'a X509Ref { - &*(x509 as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::X509 { - self as *const _ as *mut _ - } - - pub fn subject_name(&self) -> &X509NameRef { +impl Ref { + pub fn subject_name(&self) -> &Ref { unsafe { let name = ffi::X509_get_subject_name(self.as_ptr()); - X509NameRef::from_ptr(name) + Ref::from_ptr(name) } } @@ -437,7 +417,7 @@ impl X509Ref { } } -impl ToOwned for X509Ref { +impl ToOwned for Ref { type Owned = X509; fn to_owned(&self) -> X509 { @@ -448,15 +428,7 @@ impl ToOwned for X509Ref { } } -/// An owned public key certificate. -pub struct X509(*mut ffi::X509); - impl X509 { - /// Returns a new `X509`, taking ownership of the handle. - pub unsafe fn from_ptr(x509: *mut ffi::X509) -> X509 { - X509(x509) - } - /// Reads a certificate from DER. pub fn from_der(buf: &[u8]) -> Result { unsafe { @@ -480,49 +452,27 @@ impl X509 { } } -impl Deref for X509 { - type Target = X509Ref; - - fn deref(&self) -> &X509Ref { - unsafe { X509Ref::from_ptr(self.0) } - } -} - impl Clone for X509 { fn clone(&self) -> X509 { self.to_owned() } } -impl Drop for X509 { - fn drop(&mut self) { - unsafe { ffi::X509_free(self.as_ptr()) }; - } -} - -impl AsRef for X509 { - fn as_ref(&self) -> &X509Ref { +impl AsRef> for X509 { + fn as_ref(&self) -> &Ref { &*self } } -impl Borrow for X509 { - fn borrow(&self) -> &X509Ref { +impl Borrow> for X509 { + fn borrow(&self) -> &Ref { &*self } } -pub struct X509NameRef(Opaque); - -impl X509NameRef { - pub unsafe fn from_ptr<'a>(ptr: *mut ffi::X509_NAME) -> &'a X509NameRef { - &*(ptr as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::X509_NAME { - self as *const _ as *mut _ - } +type_!(X509Name, ffi::X509_NAME, ffi::X509_NAME_free); +impl Ref { pub fn text_by_nid(&self, nid: Nid) -> Option { unsafe { let loc = ffi::X509_NAME_get_index_by_NID(self.as_ptr(), nid.as_raw(), -1); @@ -554,18 +504,29 @@ impl X509NameRef { } } -/// A certificate signing request -pub struct X509Req(*mut ffi::X509_REQ); +type_!(X509Req, ffi::X509_REQ, ffi::X509_REQ_free); + +impl Ref { + /// Writes CSR as PEM + pub fn to_pem(&self) -> Result, ErrorStack> { + let mem_bio = try!(MemBio::new()); + if unsafe { ffi::PEM_write_bio_X509_REQ(mem_bio.as_ptr(), self.as_ptr()) } != 1 { + return Err(ErrorStack::get()); + } + Ok(mem_bio.get_buf().to_owned()) + } + + /// Returns a DER serialized form of the CSR + pub fn to_der(&self) -> Result, ErrorStack> { + let mem_bio = try!(MemBio::new()); + unsafe { + ffi::i2d_X509_REQ_bio(mem_bio.as_ptr(), self.as_ptr()); + } + Ok(mem_bio.get_buf().to_owned()) + } +} impl X509Req { - pub unsafe fn from_ptr(handle: *mut ffi::X509_REQ) -> X509Req { - X509Req(handle) - } - - pub fn as_ptr(&self) -> *mut ffi::X509_REQ { - self.0 - } - /// Reads CSR from PEM pub fn from_pem(buf: &[u8]) -> Result { let mem_bio = try!(MemBioSlice::new(buf)); @@ -577,30 +538,6 @@ impl X509Req { Ok(X509Req::from_ptr(handle)) } } - - /// Writes CSR as PEM - pub fn to_pem(&self) -> Result, ErrorStack> { - let mem_bio = try!(MemBio::new()); - if unsafe { ffi::PEM_write_bio_X509_REQ(mem_bio.as_ptr(), self.0) } != 1 { - return Err(ErrorStack::get()); - } - Ok(mem_bio.get_buf().to_owned()) - } - - /// Returns a DER serialized form of the CSR - pub fn to_der(&self) -> Result, ErrorStack> { - let mem_bio = try!(MemBio::new()); - unsafe { - ffi::i2d_X509_REQ_bio(mem_bio.as_ptr(), self.0); - } - Ok(mem_bio.get_buf().to_owned()) - } -} - -impl Drop for X509Req { - fn drop(&mut self) { - unsafe { ffi::X509_REQ_free(self.0) }; - } } /// A collection of X.509 extensions. From 96a77cf5a8388cea89e61e5d610f78bae1842d3a Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 20:56:51 -0700 Subject: [PATCH 12/13] Remove Opaque --- openssl/src/lib.rs | 1 - openssl/src/opaque.rs | 6 ------ openssl/src/types.rs | 5 ++--- 3 files changed, 2 insertions(+), 10 deletions(-) delete mode 100644 openssl/src/opaque.rs diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index 8fa53f3b..d053606f 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -59,7 +59,6 @@ macro_rules! type_ { } mod bio; -mod opaque; mod util; pub mod asn1; pub mod bn; diff --git a/openssl/src/opaque.rs b/openssl/src/opaque.rs deleted file mode 100644 index 9545471c..00000000 --- a/openssl/src/opaque.rs +++ /dev/null @@ -1,6 +0,0 @@ -use std::cell::UnsafeCell; - -/// This is intended to be used as the inner type for types designed to be pointed to by references -/// converted from raw C pointers. It has an `UnsafeCell` internally to inform the compiler about -/// aliasability and doesn't implement `Copy`, so it can't be dereferenced. -pub struct Opaque(UnsafeCell<()>); diff --git a/openssl/src/types.rs b/openssl/src/types.rs index 16829ea4..7302bca9 100644 --- a/openssl/src/types.rs +++ b/openssl/src/types.rs @@ -1,7 +1,6 @@ +use std::cell::UnsafeCell; use std::marker::PhantomData; -use opaque::Opaque; - pub unsafe trait OpenSslType { type CType; @@ -10,7 +9,7 @@ pub unsafe trait OpenSslType { fn as_ptr(&self) -> *mut Self::CType; } -pub struct Ref(Opaque, PhantomData); +pub struct Ref(UnsafeCell<()>, PhantomData); impl Ref { pub unsafe fn from_ptr<'a>(ptr: *mut T::CType) -> &'a Ref { From ab30ad0ce76ee6fd8cc14ecff2186171c7f610e3 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 20:59:38 -0700 Subject: [PATCH 13/13] Documentation --- openssl/src/types.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/openssl/src/types.rs b/openssl/src/types.rs index 7302bca9..40831ee8 100644 --- a/openssl/src/types.rs +++ b/openssl/src/types.rs @@ -1,25 +1,38 @@ +//! Items used by other types. + use std::cell::UnsafeCell; use std::marker::PhantomData; +/// A type implemented by wrappers over OpenSSL types. +/// +/// This should not be implemented by anything outside of this crate; new methods may be added at +/// any time. pub unsafe trait OpenSslType { + /// The raw C type. type CType; + /// Constructs an instance of this type from its raw type. unsafe fn from_ptr(ptr: *mut Self::CType) -> Self; + /// Returns a pointer to its raw type. fn as_ptr(&self) -> *mut Self::CType; } +/// A reference to an OpenSSL type. pub struct Ref(UnsafeCell<()>, PhantomData); impl Ref { + /// Constructs a shared reference to this type from its raw type. pub unsafe fn from_ptr<'a>(ptr: *mut T::CType) -> &'a Ref { &*(ptr as *mut _) } + /// Constructs a mutable reference to this type from its raw type. pub unsafe fn from_ptr_mut<'a>(ptr: *mut T::CType) -> &'a mut Ref { &mut *(ptr as *mut _) } + /// Returns a pointer to its raw type. pub fn as_ptr(&self) -> *mut T::CType { self as *const _ as *mut _ }