diff options
author | Steven Fackler <sfackler@gmail.com> | 2016-10-31 21:23:36 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-10-31 21:23:36 -0700 |
commit | 50d8cca640d4919474605810179f2800f7242722 (patch) | |
tree | f855b70ba26f82e6545e8e2557cc5eb0c5574fae /openssl/src | |
parent | f22955315839a2aa03fcfc1f0c3e00da4844915b (diff) | |
parent | ab30ad0ce76ee6fd8cc14ecff2186171c7f610e3 (diff) | |
download | rust-openssl-50d8cca640d4919474605810179f2800f7242722.zip |
Merge pull request #507 from sfackler/ref
Add a unified Ref type
Diffstat (limited to 'openssl/src')
-rw-r--r-- | openssl/src/asn1.rs | 44 | ||||
-rw-r--r-- | openssl/src/bn.rs | 246 | ||||
-rw-r--r-- | openssl/src/dh.rs | 31 | ||||
-rw-r--r-- | openssl/src/dsa.rs | 61 | ||||
-rw-r--r-- | openssl/src/ec_key.rs | 36 | ||||
-rw-r--r-- | openssl/src/lib.rs | 40 | ||||
-rw-r--r-- | openssl/src/opaque.rs | 6 | ||||
-rw-r--r-- | openssl/src/pkcs12.rs | 1 | ||||
-rw-r--r-- | openssl/src/pkey.rs | 45 | ||||
-rw-r--r-- | openssl/src/rsa.rs | 59 | ||||
-rw-r--r-- | openssl/src/sign.rs | 9 | ||||
-rw-r--r-- | openssl/src/ssl/connector.rs | 32 | ||||
-rw-r--r-- | openssl/src/ssl/mod.rs | 180 | ||||
-rw-r--r-- | openssl/src/ssl/tests/mod.rs | 23 | ||||
-rw-r--r-- | openssl/src/types.rs | 39 | ||||
-rw-r--r-- | openssl/src/verify.rs | 14 | ||||
-rw-r--r-- | openssl/src/x509/mod.rs | 139 |
17 files changed, 324 insertions, 681 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); - -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 _) - } +type_!(Asn1Time, ffi::ASN1_TIME, ffi::ASN1_TIME_free); - /// 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<Asn1Time> { 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<Asn1Time, ErrorStack> { 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/bn.rs b/openssl/src/bn.rs index 78684d0a..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)] @@ -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,25 +31,21 @@ 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, - a: &BigNumRef, - b: &BigNumRef) + r: &mut Ref<BigNum>, + a: &Ref<BigNum>, + b: &Ref<BigNum>) -> 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<BigNum>>, + rem: Option<&mut Ref<BigNum>>, + a: &Ref<BigNum>, + b: &Ref<BigNum>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_div(dv.map(|b| b.as_ptr()).unwrap_or(ptr::null_mut()), @@ -71,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<BigNum>, a: &Ref<BigNum>) -> 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<BigNum>, + a: &Ref<BigNum>, + m: &Ref<BigNum>) -> 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<BigNum>, + a: &Ref<BigNum>, + b: &Ref<BigNum>, + m: &Ref<BigNum>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_mod_add(r.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) @@ -98,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<BigNum>, + a: &Ref<BigNum>, + b: &Ref<BigNum>, + m: &Ref<BigNum>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_mod_sub(r.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) @@ -110,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<BigNum>, + a: &Ref<BigNum>, + b: &Ref<BigNum>, + m: &Ref<BigNum>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_mod_mul(r.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) @@ -122,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<BigNum>, + a: &Ref<BigNum>, + m: &Ref<BigNum>) -> 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<BigNum>, + a: &Ref<BigNum>, + p: &Ref<BigNum>) -> 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<BigNum>, + a: &Ref<BigNum>, + p: &Ref<BigNum>, + m: &Ref<BigNum>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_mod_exp(r.as_ptr(), a.as_ptr(), p.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) @@ -152,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<BigNum>, + a: &Ref<BigNum>, + n: &Ref<BigNum>) -> Result<(), ErrorStack> { unsafe { cvt_p(ffi::BN_mod_inverse(r.as_ptr(), a.as_ptr(), n.as_ptr(), self.as_ptr())) @@ -164,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<BigNum>, + a: &Ref<BigNum>, + b: &Ref<BigNum>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_gcd(r.as_ptr(), a.as_ptr(), b.as_ptr(), self.as_ptr())).map(|_| ()) } } @@ -176,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<bool, ErrorStack> { + pub fn is_prime(&mut self, p: &Ref<BigNum>, checks: i32) -> Result<bool, ErrorStack> { unsafe { cvt_n(ffi::BN_is_prime_ex(p.as_ptr(), checks.into(), self.as_ptr(), ptr::null_mut())) .map(|r| r != 0) @@ -193,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<BigNum>, checks: i32, do_trial_division: bool) -> Result<bool, ErrorStack> { @@ -214,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<BigNum>, bits: i32, prop: RNGProperty, odd: bool) @@ -225,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<BigNum>, bits: i32, prop: RNGProperty, odd: bool) @@ -237,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<BigNum> { /// 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(|_| ()) } @@ -294,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<BigNum>) -> 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<BigNum>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_pseudo_rand_range(self.as_ptr(), rnd.as_ptr())).map(|_| ()) } } @@ -330,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<BigNum>) -> 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<BigNum>) -> 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<BigNum>, b: &Ref<BigNum>) -> 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<BigNum>, b: &Ref<BigNum>) -> 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<BigNum>, 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<BigNum>, n: i32) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_rshift(r.as_ptr(), self.as_ptr(), n.into())).map(|_| ()) } } @@ -378,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<BigNum>) -> Ordering { unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) } } @@ -459,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. @@ -504,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. /// /// ``` @@ -532,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<BigNum>, bits: i32, safe: bool, - add: Option<&BigNumRef>, - rem: Option<&BigNumRef>) + add: Option<&Ref<BigNum>>, + rem: Option<&Ref<BigNum>>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::BN_generate_prime_ex(r.as_ptr(), @@ -550,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<BigNumRef> for BigNum { - fn as_ref(&self) -> &BigNumRef { +impl AsRef<Ref<BigNum>> for BigNum { + fn as_ref(&self) -> &Ref<BigNum> { self.deref() } } -impl fmt::Debug for BigNumRef { +impl fmt::Debug for Ref<BigNum> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.to_dec_str() { Ok(s) => f.write_str(&s), @@ -596,7 +536,7 @@ impl fmt::Debug for BigNum { } } -impl fmt::Display for BigNumRef { +impl fmt::Display for Ref<BigNum> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.to_dec_str() { Ok(s) => f.write_str(&s), @@ -614,19 +554,19 @@ impl fmt::Display for BigNum { } } -impl PartialEq<BigNumRef> for BigNumRef { - fn eq(&self, oth: &BigNumRef) -> bool { +impl PartialEq<Ref<BigNum>> for Ref<BigNum> { + fn eq(&self, oth: &Ref<BigNum>) -> bool { self.cmp(oth) == Ordering::Equal } } -impl PartialEq<BigNum> for BigNumRef { +impl PartialEq<BigNum> for Ref<BigNum> { fn eq(&self, oth: &BigNum) -> bool { self.eq(oth.deref()) } } -impl Eq for BigNumRef {} +impl Eq for Ref<BigNum> {} impl PartialEq for BigNum { fn eq(&self, oth: &BigNum) -> bool { @@ -634,28 +574,28 @@ impl PartialEq for BigNum { } } -impl PartialEq<BigNumRef> for BigNum { - fn eq(&self, oth: &BigNumRef) -> bool { +impl PartialEq<Ref<BigNum>> for BigNum { + fn eq(&self, oth: &Ref<BigNum>) -> bool { self.deref().eq(oth) } } impl Eq for BigNum {} -impl PartialOrd<BigNumRef> for BigNumRef { - fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> { +impl PartialOrd<Ref<BigNum>> for Ref<BigNum> { + fn partial_cmp(&self, oth: &Ref<BigNum>) -> Option<Ordering> { Some(self.cmp(oth)) } } -impl PartialOrd<BigNum> for BigNumRef { +impl PartialOrd<BigNum> for Ref<BigNum> { fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> { Some(self.cmp(oth.deref())) } } -impl Ord for BigNumRef { - fn cmp(&self, oth: &BigNumRef) -> Ordering { +impl Ord for Ref<BigNum> { + fn cmp(&self, oth: &Ref<BigNum>) -> Ordering { unsafe { ffi::BN_cmp(self.as_ptr(), oth.as_ptr()).cmp(&0) } } } @@ -666,8 +606,8 @@ impl PartialOrd for BigNum { } } -impl PartialOrd<BigNumRef> for BigNum { - fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> { +impl PartialOrd<Ref<BigNum>> for BigNum { + fn partial_cmp(&self, oth: &Ref<BigNum>) -> Option<Ordering> { self.deref().partial_cmp(oth) } } @@ -680,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<BigNum> { type Output = BigNum; fn $m(self, oth: &BigNum) -> BigNum { @@ -688,10 +628,10 @@ macro_rules! delegate { } } - impl<'a, 'b> $t<&'b BigNumRef> for &'a BigNum { + impl<'a, 'b> $t<&'b Ref<BigNum>> for &'a BigNum { type Output = BigNum; - fn $m(self, oth: &BigNumRef) -> BigNum { + fn $m(self, oth: &Ref<BigNum>) -> BigNum { $t::$m(self.deref(), oth) } } @@ -706,10 +646,10 @@ macro_rules! delegate { } } -impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef { +impl<'a, 'b> Add<&'b Ref<BigNum>> for &'a Ref<BigNum> { type Output = BigNum; - fn add(self, oth: &BigNumRef) -> BigNum { + fn add(self, oth: &Ref<BigNum>) -> BigNum { let mut r = BigNum::new().unwrap(); self.add(&mut r, oth).unwrap(); r @@ -718,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<BigNum>> for &'a Ref<BigNum> { type Output = BigNum; - fn sub(self, oth: &BigNumRef) -> BigNum { + fn sub(self, oth: &Ref<BigNum>) -> BigNum { let mut r = BigNum::new().unwrap(); self.sub(&mut r, oth).unwrap(); r @@ -730,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<BigNum>> for &'a Ref<BigNum> { type Output = BigNum; - fn mul(self, oth: &BigNumRef) -> BigNum { + fn mul(self, oth: &Ref<BigNum>) -> BigNum { let mut ctx = BnCtx::new().unwrap(); let mut r = BigNum::new().unwrap(); ctx.mul(&mut r, self, oth).unwrap(); @@ -743,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<BigNum>> for &'a Ref<BigNum> { type Output = BigNum; - fn div(self, oth: &'b BigNumRef) -> BigNum { + fn div(self, oth: &'b Ref<BigNum>) -> BigNum { let mut ctx = BnCtx::new().unwrap(); let mut dv = BigNum::new().unwrap(); ctx.div(Some(&mut dv), None, self, oth).unwrap(); @@ -756,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<BigNum>> for &'a Ref<BigNum> { type Output = BigNum; - fn rem(self, oth: &'b BigNumRef) -> BigNum { + fn rem(self, oth: &'b Ref<BigNum>) -> BigNum { let mut ctx = BnCtx::new().unwrap(); let mut rem = BigNum::new().unwrap(); ctx.div(None, Some(&mut rem), self, oth).unwrap(); @@ -769,7 +709,7 @@ impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef { delegate!(Rem, rem); -impl<'a> Shl<i32> for &'a BigNumRef { +impl<'a> Shl<i32> for &'a Ref<BigNum> { type Output = BigNum; fn shl(self, n: i32) -> BigNum { @@ -787,7 +727,7 @@ impl<'a> Shl<i32> for &'a BigNum { } } -impl<'a> Shr<i32> for &'a BigNumRef { +impl<'a> Shr<i32> for &'a Ref<BigNum> { type Output = BigNum; fn shr(self, n: i32) -> BigNum { @@ -805,7 +745,7 @@ impl<'a> Shr<i32> for &'a BigNum { } } -impl<'a> Neg for &'a BigNumRef { +impl<'a> Neg for &'a Ref<BigNum> { type Output = BigNum; fn neg(self) -> BigNum { 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<Dh, ErrorStack> { @@ -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/dsa.rs b/openssl/src/dsa.rs index e92b8ca3..6efa7050 100644 --- a/openssl/src/dsa.rs +++ b/openssl/src/dsa.rs @@ -2,26 +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 {cvt, cvt_p}; -use bn::BigNumRef; use bio::{MemBio, MemBioSlice}; +use bn::BigNum; +use {cvt, cvt_p}; +use types::Ref; use util::{CallbackState, invoke_passwd_cb}; -use opaque::Opaque; - -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<Dsa> { /// Writes an DSA private key as unencrypted PEM formatted data pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> { assert!(self.has_private_key()); @@ -53,35 +44,35 @@ impl DsaRef { } } - pub fn p(&self) -> Option<&BigNumRef> { + pub fn p(&self) -> Option<&Ref<BigNum>> { unsafe { let p = compat::pqg(self.as_ptr())[0]; if p.is_null() { None } else { - Some(BigNumRef::from_ptr(p as *mut _)) + Some(Ref::<BigNum>::from_ptr(p as *mut _)) } } } - pub fn q(&self) -> Option<&BigNumRef> { + pub fn q(&self) -> Option<&Ref<BigNum>> { unsafe { let q = compat::pqg(self.as_ptr())[1]; if q.is_null() { None } else { - Some(BigNumRef::from_ptr(q as *mut _)) + Some(Ref::<BigNum>::from_ptr(q as *mut _)) } } } - pub fn g(&self) -> Option<&BigNumRef> { + pub fn g(&self) -> Option<&Ref<BigNum>> { unsafe { let g = compat::pqg(self.as_ptr())[2]; if g.is_null() { None } else { - Some(BigNumRef::from_ptr(g as *mut _)) + Some(Ref::<BigNum>::from_ptr(g as *mut _)) } } } @@ -95,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<Dsa, ErrorStack> { unsafe { @@ -121,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) } } @@ -177,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") } } @@ -216,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; 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<EcKey, ErrorStack> { 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/lib.rs b/openssl/src/lib.rs index f335c097..d053606f 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -20,8 +20,45 @@ 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; pub mod asn1; pub mod bn; @@ -37,6 +74,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/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/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..6236b642 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -1,29 +1,19 @@ use libc::{c_void, c_char, c_int}; use std::ptr; use std::mem; -use std::ops::Deref; 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 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<PKey> { /// Get a reference to the interal RSA key for direct access to the key components pub fn rsa(&self) -> Result<Rsa, ErrorStack> { 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<PKey>) -> 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<PKey, ErrorStack> { ffi::init(); @@ -156,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<Rsa>) -> Result<(), ErrorStack> { unsafe { // this needs to be a reference as the set1_RSA ups the reference count let rsa_ptr = rsa.as_ptr(); @@ -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/rsa.rs b/openssl/src/rsa.rs index c6c96223..57a07bd1 100644 --- a/openssl/src/rsa.rs +++ b/openssl/src/rsa.rs @@ -2,15 +2,14 @@ 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}; -use bn::{BigNum, BigNumRef}; +use bn::BigNum; use bio::{MemBio, MemBioSlice}; use error::ErrorStack; use util::{CallbackState, invoke_passwd_cb}; -use opaque::Opaque; +use types::{OpenSslType, Ref}; /// Type of encryption padding to use. #[derive(Copy, Clone)] @@ -20,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<Rsa> { /// Writes an RSA private key as unencrypted PEM formatted data pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> { let mem_bio = try!(MemBio::new()); @@ -162,72 +153,62 @@ impl RsaRef { } } - pub fn n(&self) -> Option<&BigNumRef> { + pub fn n(&self) -> Option<&Ref<BigNum>> { unsafe { let n = compat::key(self.as_ptr())[0]; if n.is_null() { None } else { - Some(BigNumRef::from_ptr(n as *mut _)) + Some(Ref::<BigNum>::from_ptr(n as *mut _)) } } } - pub fn d(&self) -> Option<&BigNumRef> { + pub fn d(&self) -> Option<&Ref<BigNum>> { unsafe { let d = compat::key(self.as_ptr())[2]; if d.is_null() { None } else { - Some(BigNumRef::from_ptr(d as *mut _)) + Some(Ref::<BigNum>::from_ptr(d as *mut _)) } } } - pub fn e(&self) -> Option<&BigNumRef> { + pub fn e(&self) -> Option<&Ref<BigNum>> { unsafe { let e = compat::key(self.as_ptr())[1]; if e.is_null() { None } else { - Some(BigNumRef::from_ptr(e as *mut _)) + Some(Ref::<BigNum>::from_ptr(e as *mut _)) } } } - pub fn p(&self) -> Option<&BigNumRef> { + pub fn p(&self) -> Option<&Ref<BigNum>> { unsafe { let p = compat::factors(self.as_ptr())[0]; if p.is_null() { None } else { - Some(BigNumRef::from_ptr(p as *mut _)) + Some(Ref::<BigNum>::from_ptr(p as *mut _)) } } } - pub fn q(&self) -> Option<&BigNumRef> { + pub fn q(&self) -> Option<&Ref<BigNum>> { unsafe { let q = compat::factors(self.as_ptr())[1]; if q.is_null() { None } else { - Some(BigNumRef::from_ptr(q as *mut _)) + Some(Ref::<BigNum>::from_ptr(q as *mut _)) } } } } -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. @@ -265,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. @@ -329,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; 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<PKey>>); 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<Signer<'a>, ErrorStack> { + pub fn new(type_: MessageDigest, pkey: &'a Ref<PKey>) -> Result<Signer<'a>, 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<PKey>>); 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<Verifier<'a>, ErrorStack> { + pub fn new(type_: MessageDigest, pkey: &'a Ref<PKey>) -> Result<Verifier<'a>, ErrorStack> { unsafe { ffi::init(); diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs index c7bfb209..a1bcfa77 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 x509::X509Ref; +use pkey::PKey; +use x509::X509; +use types::Ref; // apps/dh2048.pem const DHPARAM_PEM: &'static str = r#" @@ -116,12 +117,12 @@ impl SslAcceptorBuilder { /// /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS pub fn mozilla_intermediate<I>(method: SslMethod, - private_key: &PKeyRef, - certificate: &X509Ref, + private_key: &Ref<PKey>, + certificate: &Ref<X509>, chain: I) -> Result<SslAcceptorBuilder, ErrorStack> where I: IntoIterator, - I::Item: AsRef<X509Ref> + I::Item: AsRef<Ref<X509>> { let mut ctx = try!(ctx(method)); let dh = try!(Dh::from_pem(DHPARAM_PEM.as_bytes())); @@ -151,12 +152,12 @@ impl SslAcceptorBuilder { /// /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS pub fn mozilla_modern<I>(method: SslMethod, - private_key: &PKeyRef, - certificate: &X509Ref, + private_key: &Ref<PKey>, + certificate: &Ref<X509>, chain: I) -> Result<SslAcceptorBuilder, ErrorStack> where I: IntoIterator, - I::Item: AsRef<X509Ref> + I::Item: AsRef<Ref<X509>> { let mut ctx = try!(ctx(method)); try!(setup_curves(&mut ctx)); @@ -169,12 +170,12 @@ impl SslAcceptorBuilder { } fn finish_setup<I>(mut ctx: SslContextBuilder, - private_key: &PKeyRef, - certificate: &X509Ref, + private_key: &Ref<PKey>, + certificate: &Ref<X509>, chain: I) -> Result<SslAcceptorBuilder, ErrorStack> where I: IntoIterator, - I::Item: AsRef<X509Ref> + I::Item: AsRef<Ref<X509>> { try!(ctx.set_private_key(private_key)); try!(ctx.set_certificate(certificate)); @@ -254,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<X509StoreContext>) -> bool { if !preverify_ok || x509_ctx.error_depth() != 0 { return preverify_ok; @@ -270,7 +272,7 @@ mod verify { } } - fn verify_hostname(domain: &str, cert: &X509Ref) -> bool { + fn verify_hostname(domain: &str, cert: &Ref<X509>) -> bool { match cert.subject_alt_names() { Some(names) => verify_subject_alt_names(domain, &names), None => verify_subject_name(domain, &cert.subject_name()), @@ -302,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<X509Name>) -> 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 5466f26e..68d411c7 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; @@ -91,14 +90,14 @@ use std::marker::PhantomData; use ffi; use {init, cvt, cvt_p}; -use dh::DhRef; -use ec_key::EcKeyRef; -use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError}; +use dh::Dh; +use ec_key::EcKey; +use x509::{X509StoreContext, X509FileType, X509, X509VerifyError}; #[cfg(any(ossl102, ossl110))] -use verify::X509VerifyParamRef; -use pkey::PKeyRef; +use verify::X509VerifyParam; +use pkey::PKey; use error::ErrorStack; -use opaque::Opaque; +use types::{OpenSslType, Ref}; mod error; mod connector; @@ -263,7 +262,7 @@ fn get_new_ssl_idx<T>() -> c_int { } extern "C" fn raw_verify<F>(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<X509StoreContext>) -> bool + Any + 'static + Sync + Send { unsafe { let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx(); @@ -272,14 +271,14 @@ extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_ let verify = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::<F>()); 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<F>(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<X509StoreContext>) -> bool + Any + 'static + Sync + Send { unsafe { let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx(); @@ -287,20 +286,20 @@ extern "C" fn ssl_raw_verify<F>(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::<F>()); 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 raw_sni<F>(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<Ssl>) -> 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::<F>()); 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, @@ -464,7 +463,7 @@ impl SslContextBuilder { /// Configures the certificate verification method for new connections and /// registers a verification callback. pub fn set_verify_callback<F>(&mut self, mode: SslVerifyMode, verify: F) - where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send + where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send { unsafe { let verify = Box::new(verify); @@ -480,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<F>(&mut self, callback: F) - where F: Fn(&mut SslRef) -> Result<(), SniError> + Any + 'static + Sync + Send + where F: Fn(&mut Ref<Ssl>) -> Result<(), SniError> + Any + 'static + Sync + Send { unsafe { let callback = Box::new(callback); @@ -513,11 +512,11 @@ impl SslContextBuilder { } } - pub fn set_tmp_dh(&mut self, dh: &DhRef) -> Result<(), ErrorStack> { + pub fn set_tmp_dh(&mut self, dh: &Ref<Dh>) -> Result<(), ErrorStack> { 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<EcKey>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_set_tmp_ecdh(self.as_ptr(), key.as_ptr()) as c_int).map(|_| ()) } } @@ -585,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<X509>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_use_certificate(self.as_ptr(), cert.as_ptr())).map(|_| ()) } } @@ -614,7 +613,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<PKey>) -> Result<(), ErrorStack> { unsafe { cvt(ffi::SSL_CTX_use_PrivateKey(self.as_ptr(), key.as_ptr())).map(|_| ()) } } @@ -734,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 {} @@ -773,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, ErrorStack> { 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 - } } @@ -816,17 +769,21 @@ pub struct CipherBits { pub algorithm: i32, } -pub struct SslCipherRef(Opaque); +pub struct SslCipher(*mut ffi::SSL_CIPHER); + +unsafe impl OpenSslType for SslCipher { + type CType = ffi::SSL_CIPHER; -impl SslCipherRef { - pub unsafe fn from_ptr<'a>(ptr: *const ffi::SSL_CIPHER) -> &'a SslCipherRef { - &*(ptr as *const _) + 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<SslCipher> { /// Returns the name of cipher. pub fn name(&self) -> &'static str { let name = unsafe { @@ -870,15 +827,11 @@ impl SslCipherRef { } } -/// A reference to an `Ssl`. -pub struct SslRef(Opaque); - -unsafe impl Send for SslRef {} -unsafe impl Sync for SslRef {} +type_!(Ssl, ffi::SSL, ffi::SSL_free); -impl fmt::Debug for SslRef { +impl fmt::Debug for Ref<Ssl> { 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); @@ -887,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<Ssl> { fn get_raw_rbio(&self) -> *mut ffi::BIO { unsafe { ffi::SSL_get_rbio(self.as_ptr()) } } @@ -933,7 +874,7 @@ impl SslRef { /// to the certificate chain. It should return `true` if the certificate /// chain is valid and `false` otherwise. pub fn set_verify_callback<F>(&mut self, mode: SslVerifyMode, verify: F) - where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send + where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send { unsafe { let verify = Box::new(verify); @@ -944,14 +885,14 @@ impl SslRef { } } - pub fn current_cipher(&self) -> Option<&SslCipherRef> { + pub fn current_cipher(&self) -> Option<&Ref<SslCipher>> { 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 _)) } } } @@ -1092,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<SslContext>) -> 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<SslContext> { unsafe { let ssl_ctx = ffi::SSL_get_SSL_CTX(self.as_ptr()); - SslContextRef::from_ptr(ssl_ctx) + Ref::from_ptr(ssl_ctx) } } @@ -1108,13 +1049,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<X509VerifyParam> { 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<X509VerifyParam> { + unsafe { Ref::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) } } /// Returns the result of X509 certificate verification. @@ -1123,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) } } @@ -1167,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 @@ -1255,7 +1165,7 @@ impl<S> MidHandshakeSslStream<S> { } /// Returns a shared reference to the `Ssl` of the stream. - pub fn ssl(&self) -> &SslRef { + pub fn ssl(&self) -> &Ref<Ssl> { self.stream.ssl() } @@ -1437,7 +1347,7 @@ impl<S> SslStream<S> { } /// Returns the OpenSSL `Ssl` object associated with this stream. - pub fn ssl(&self) -> &SslRef { + pub fn ssl(&self) -> &Ref<Ssl> { &self.ssl } } 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/types.rs b/openssl/src/types.rs new file mode 100644 index 00000000..40831ee8 --- /dev/null +++ b/openssl/src/types.rs @@ -0,0 +1,39 @@ +//! 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<T>(UnsafeCell<()>, PhantomData<T>); + +impl<T: OpenSslType> Ref<T> { + /// Constructs a shared reference to this type from its raw type. + pub unsafe fn from_ptr<'a>(ptr: *mut T::CType) -> &'a Ref<T> { + &*(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<T> { + &mut *(ptr as *mut _) + } + + /// Returns a pointer to its raw type. + pub fn as_ptr(&self) -> *mut T::CType { + self as *const _ as *mut _ + } +} 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<X509VerifyParam> { pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) { unsafe { ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits); diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index b49a9848..bb2c7544 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -7,23 +7,21 @@ 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; use {cvt, cvt_p}; use asn1::Asn1Time; -use asn1::Asn1TimeRef; 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::{OpenSslType, Ref}; #[cfg(ossl10x)] use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data}; @@ -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<X509StoreContext> { pub fn error(&self) -> Option<X509VerifyError> { 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<X509>> { 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)) } } } @@ -269,7 +259,7 @@ impl X509Generator { } /// Sets the certificate public-key, then self-sign and return it - pub fn sign(&self, p_key: &PKeyRef) -> Result<X509, ErrorStack> { + pub fn sign(&self, p_key: &Ref<PKey>) -> Result<X509, ErrorStack> { ffi::init(); unsafe { @@ -321,7 +311,7 @@ impl X509Generator { } /// Obtain a certificate signing request (CSR) - pub fn request(&self, p_key: &PKeyRef) -> Result<X509Req, ErrorStack> { + pub fn request(&self, p_key: &Ref<PKey>) -> Result<X509Req, ErrorStack> { let cert = match self.sign(p_key) { Ok(c) => c, Err(x) => return Err(x), @@ -346,23 +336,13 @@ impl X509Generator { } } -/// A borrowed public key certificate. -pub struct X509Ref(Opaque); - -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 _ - } +type_!(X509, ffi::X509, ffi::X509_free); - pub fn subject_name(&self) -> &X509NameRef { +impl Ref<X509> { + pub fn subject_name(&self) -> &Ref<X509Name> { unsafe { let name = ffi::X509_get_subject_name(self.as_ptr()); - X509NameRef::from_ptr(name) + Ref::from_ptr(name) } } @@ -401,20 +381,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<Asn1Time> { 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<Asn1Time> { unsafe { let date = compat::X509_get_notBefore(self.as_ptr()); assert!(!date.is_null()); - Asn1TimeRef::from_ptr(date) + Ref::from_ptr(date) } } @@ -437,7 +417,7 @@ impl X509Ref { } } -impl ToOwned for X509Ref { +impl ToOwned for Ref<X509> { 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<X509, ErrorStack> { 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<X509Ref> for X509 { - fn as_ref(&self) -> &X509Ref { +impl AsRef<Ref<X509>> for X509 { + fn as_ref(&self) -> &Ref<X509> { &*self } } -impl Borrow<X509Ref> for X509 { - fn borrow(&self) -> &X509Ref { +impl Borrow<Ref<X509>> for X509 { + fn borrow(&self) -> &Ref<X509> { &*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<X509Name> { pub fn text_by_nid(&self, nid: Nid) -> Option<CryptoString> { unsafe { let loc = ffi::X509_NAME_get_index_by_NID(self.as_ptr(), nid.as_raw(), -1); @@ -554,34 +504,13 @@ impl X509NameRef { } } -/// A certificate signing request -pub struct X509Req(*mut ffi::X509_REQ); - -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<X509Req, ErrorStack> { - let mem_bio = try!(MemBioSlice::new(buf)); - unsafe { - let handle = try!(cvt_p(ffi::PEM_read_bio_X509_REQ(mem_bio.as_ptr(), - ptr::null_mut(), - None, - ptr::null_mut()))); - Ok(X509Req::from_ptr(handle)) - } - } +type_!(X509Req, ffi::X509_REQ, ffi::X509_REQ_free); +impl Ref<X509Req> { /// Writes CSR as PEM pub fn to_pem(&self) -> Result<Vec<u8>, ErrorStack> { let mem_bio = try!(MemBio::new()); - if unsafe { ffi::PEM_write_bio_X509_REQ(mem_bio.as_ptr(), self.0) } != 1 { + 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()) @@ -591,15 +520,23 @@ impl X509Req { pub fn to_der(&self) -> Result<Vec<u8>, ErrorStack> { let mem_bio = try!(MemBio::new()); unsafe { - ffi::i2d_X509_REQ_bio(mem_bio.as_ptr(), self.0); + ffi::i2d_X509_REQ_bio(mem_bio.as_ptr(), self.as_ptr()); } Ok(mem_bio.get_buf().to_owned()) } } -impl Drop for X509Req { - fn drop(&mut self) { - unsafe { ffi::X509_REQ_free(self.0) }; +impl X509Req { + /// Reads CSR from PEM + pub fn from_pem(buf: &[u8]) -> Result<X509Req, ErrorStack> { + let mem_bio = try!(MemBioSlice::new(buf)); + unsafe { + let handle = try!(cvt_p(ffi::PEM_read_bio_X509_REQ(mem_bio.as_ptr(), + ptr::null_mut(), + None, + ptr::null_mut()))); + Ok(X509Req::from_ptr(handle)) + } } } |