Merge pull request #512 from sfackler/no-ref

Get rid of Ref
This commit is contained in:
Steven Fackler 2016-11-04 18:40:43 -07:00 committed by GitHub
commit 1108db74ec
17 changed files with 317 additions and 299 deletions

View File

@ -9,11 +9,11 @@ use {cvt, cvt_p};
use bio::MemBio; use bio::MemBio;
use crypto::CryptoString; use crypto::CryptoString;
use error::ErrorStack; use error::ErrorStack;
use types::{OpenSslType, Ref}; use types::{OpenSslType, OpenSslTypeRef};
type_!(Asn1Time, ffi::ASN1_TIME, ffi::ASN1_TIME_free); type_!(Asn1Time, Asn1TimeRef, ffi::ASN1_TIME, ffi::ASN1_TIME_free);
impl fmt::Display for Ref<Asn1Time> { impl fmt::Display for Asn1TimeRef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
unsafe { unsafe {
let mem_bio = try!(MemBio::new()); let mem_bio = try!(MemBio::new());
@ -39,9 +39,9 @@ impl Asn1Time {
} }
} }
type_!(Asn1String, ffi::ASN1_STRING, ffi::ASN1_STRING_free); type_!(Asn1String, Asn1StringRef, ffi::ASN1_STRING, ffi::ASN1_STRING_free);
impl Ref<Asn1String> { impl Asn1StringRef {
pub fn as_utf8(&self) -> Result<CryptoString, ErrorStack> { pub fn as_utf8(&self) -> Result<CryptoString, ErrorStack> {
unsafe { unsafe {
let mut ptr = ptr::null_mut(); let mut ptr = ptr::null_mut();

View File

@ -8,7 +8,7 @@ use std::ops::{Add, Div, Mul, Neg, Rem, Shl, Shr, Sub, Deref};
use {cvt, cvt_p, cvt_n}; use {cvt, cvt_p, cvt_n};
use crypto::CryptoString; use crypto::CryptoString;
use error::ErrorStack; use error::ErrorStack;
use types::{Ref, OpenSslType}; use types::{OpenSslType, OpenSslTypeRef};
/// Options for the most significant bits of a randomly generated `BigNum`. /// Options for the most significant bits of a randomly generated `BigNum`.
pub struct MsbOption(c_int); pub struct MsbOption(c_int);
@ -25,7 +25,7 @@ pub const MSB_ONE: MsbOption = MsbOption(0);
/// of bits in the original numbers. /// of bits in the original numbers.
pub const TWO_MSB_ONE: MsbOption = MsbOption(1); pub const TWO_MSB_ONE: MsbOption = MsbOption(1);
type_!(BigNumContext, ffi::BN_CTX, ffi::BN_CTX_free); type_!(BigNumContext, BigNumContextRef, ffi::BN_CTX, ffi::BN_CTX_free);
impl BigNumContext { impl BigNumContext {
/// Returns a new `BigNumContext`. /// Returns a new `BigNumContext`.
@ -35,19 +35,19 @@ impl BigNumContext {
/// Places the result of `a * b` in `r`. /// Places the result of `a * b` in `r`.
pub fn mul(&mut self, pub fn mul(&mut self,
r: &mut Ref<BigNum>, r: &mut BigNumRef,
a: &Ref<BigNum>, a: &BigNumRef,
b: &Ref<BigNum>) b: &BigNumRef)
-> Result<(), ErrorStack> { -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_mul(r.as_ptr(), a.as_ptr(), b.as_ptr(), self.as_ptr())).map(|_| ()) } 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`. /// Places the result of `a / b` in `dv` and `a mod b` in `rem`.
pub fn div(&mut self, pub fn div(&mut self,
dv: Option<&mut Ref<BigNum>>, dv: Option<&mut BigNumRef>,
rem: Option<&mut Ref<BigNum>>, rem: Option<&mut BigNumRef>,
a: &Ref<BigNum>, a: &BigNumRef,
b: &Ref<BigNum>) b: &BigNumRef)
-> Result<(), ErrorStack> { -> Result<(), ErrorStack> {
unsafe { unsafe {
cvt(ffi::BN_div(dv.map(|b| b.as_ptr()).unwrap_or(ptr::null_mut()), cvt(ffi::BN_div(dv.map(|b| b.as_ptr()).unwrap_or(ptr::null_mut()),
@ -60,25 +60,25 @@ impl BigNumContext {
} }
/// Places the result of `a²` in `r`. /// Places the result of `a²` in `r`.
pub fn sqr(&mut self, r: &mut Ref<BigNum>, a: &Ref<BigNum>) -> Result<(), ErrorStack> { pub fn sqr(&mut self, r: &mut BigNumRef, a: &BigNumRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_sqr(r.as_ptr(), a.as_ptr(), self.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_sqr(r.as_ptr(), a.as_ptr(), self.as_ptr())).map(|_| ()) }
} }
/// Places the result of `a mod m` in `r`. /// Places the result of `a mod m` in `r`.
pub fn nnmod(&mut self, pub fn nnmod(&mut self,
r: &mut Ref<BigNum>, r: &mut BigNumRef,
a: &Ref<BigNum>, a: &BigNumRef,
m: &Ref<BigNum>) m: &BigNumRef)
-> Result<(), ErrorStack> { -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_nnmod(r.as_ptr(), a.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) } 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`. /// Places the result of `(a + b) mod m` in `r`.
pub fn mod_add(&mut self, pub fn mod_add(&mut self,
r: &mut Ref<BigNum>, r: &mut BigNumRef,
a: &Ref<BigNum>, a: &BigNumRef,
b: &Ref<BigNum>, b: &BigNumRef,
m: &Ref<BigNum>) m: &BigNumRef)
-> Result<(), ErrorStack> { -> Result<(), ErrorStack> {
unsafe { unsafe {
cvt(ffi::BN_mod_add(r.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) cvt(ffi::BN_mod_add(r.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), self.0)).map(|_| ())
@ -87,10 +87,10 @@ impl BigNumContext {
/// Places the result of `(a - b) mod m` in `r`. /// Places the result of `(a - b) mod m` in `r`.
pub fn mod_sub(&mut self, pub fn mod_sub(&mut self,
r: &mut Ref<BigNum>, r: &mut BigNumRef,
a: &Ref<BigNum>, a: &BigNumRef,
b: &Ref<BigNum>, b: &BigNumRef,
m: &Ref<BigNum>) m: &BigNumRef)
-> Result<(), ErrorStack> { -> Result<(), ErrorStack> {
unsafe { unsafe {
cvt(ffi::BN_mod_sub(r.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) cvt(ffi::BN_mod_sub(r.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), self.0)).map(|_| ())
@ -99,10 +99,10 @@ impl BigNumContext {
/// Places the result of `(a * b) mod m` in `r`. /// Places the result of `(a * b) mod m` in `r`.
pub fn mod_mul(&mut self, pub fn mod_mul(&mut self,
r: &mut Ref<BigNum>, r: &mut BigNumRef,
a: &Ref<BigNum>, a: &BigNumRef,
b: &Ref<BigNum>, b: &BigNumRef,
m: &Ref<BigNum>) m: &BigNumRef)
-> Result<(), ErrorStack> { -> Result<(), ErrorStack> {
unsafe { unsafe {
cvt(ffi::BN_mod_mul(r.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) cvt(ffi::BN_mod_mul(r.as_ptr(), a.as_ptr(), b.as_ptr(), m.as_ptr(), self.0)).map(|_| ())
@ -111,28 +111,28 @@ impl BigNumContext {
/// Places the result of `a² mod m` in `r`. /// Places the result of `a² mod m` in `r`.
pub fn mod_sqr(&mut self, pub fn mod_sqr(&mut self,
r: &mut Ref<BigNum>, r: &mut BigNumRef,
a: &Ref<BigNum>, a: &BigNumRef,
m: &Ref<BigNum>) m: &BigNumRef)
-> Result<(), ErrorStack> { -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_mod_sqr(r.as_ptr(), a.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) } 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`. /// Places the result of `a^p` in `r`.
pub fn exp(&mut self, pub fn exp(&mut self,
r: &mut Ref<BigNum>, r: &mut BigNumRef,
a: &Ref<BigNum>, a: &BigNumRef,
p: &Ref<BigNum>) p: &BigNumRef)
-> Result<(), ErrorStack> { -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_exp(r.as_ptr(), a.as_ptr(), p.as_ptr(), self.0)).map(|_| ()) } 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`. /// Places the result of `a^p mod m` in `r`.
pub fn mod_exp(&mut self, pub fn mod_exp(&mut self,
r: &mut Ref<BigNum>, r: &mut BigNumRef,
a: &Ref<BigNum>, a: &BigNumRef,
p: &Ref<BigNum>, p: &BigNumRef,
m: &Ref<BigNum>) m: &BigNumRef)
-> Result<(), ErrorStack> { -> Result<(), ErrorStack> {
unsafe { unsafe {
cvt(ffi::BN_mod_exp(r.as_ptr(), a.as_ptr(), p.as_ptr(), m.as_ptr(), self.0)).map(|_| ()) cvt(ffi::BN_mod_exp(r.as_ptr(), a.as_ptr(), p.as_ptr(), m.as_ptr(), self.0)).map(|_| ())
@ -141,9 +141,9 @@ impl BigNumContext {
/// Places the inverse of `a` modulo `n` in `r`. /// Places the inverse of `a` modulo `n` in `r`.
pub fn mod_inverse(&mut self, pub fn mod_inverse(&mut self,
r: &mut Ref<BigNum>, r: &mut BigNumRef,
a: &Ref<BigNum>, a: &BigNumRef,
n: &Ref<BigNum>) n: &BigNumRef)
-> Result<(), ErrorStack> { -> Result<(), ErrorStack> {
unsafe { unsafe {
cvt_p(ffi::BN_mod_inverse(r.as_ptr(), a.as_ptr(), n.as_ptr(), self.as_ptr())) cvt_p(ffi::BN_mod_inverse(r.as_ptr(), a.as_ptr(), n.as_ptr(), self.as_ptr()))
@ -153,9 +153,9 @@ impl BigNumContext {
/// Places the greatest common denominator of `a` and `b` in `r`. /// Places the greatest common denominator of `a` and `b` in `r`.
pub fn gcd(&mut self, pub fn gcd(&mut self,
r: &mut Ref<BigNum>, r: &mut BigNumRef,
a: &Ref<BigNum>, a: &BigNumRef,
b: &Ref<BigNum>) b: &BigNumRef)
-> Result<(), ErrorStack> { -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_gcd(r.as_ptr(), a.as_ptr(), b.as_ptr(), self.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_gcd(r.as_ptr(), a.as_ptr(), b.as_ptr(), self.as_ptr())).map(|_| ()) }
} }
@ -165,7 +165,7 @@ impl BigNumContext {
/// Performs a Miller-Rabin probabilistic primality test with `checks` iterations. /// 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`. /// Returns `true` if `p` is prime with an error probability of less than `0.25 ^ checks`.
pub fn is_prime(&mut self, p: &Ref<BigNum>, checks: i32) -> Result<bool, ErrorStack> { pub fn is_prime(&mut self, p: &BigNumRef, checks: i32) -> Result<bool, ErrorStack> {
unsafe { unsafe {
cvt_n(ffi::BN_is_prime_ex(p.as_ptr(), checks.into(), self.as_ptr(), ptr::null_mut())) cvt_n(ffi::BN_is_prime_ex(p.as_ptr(), checks.into(), self.as_ptr(), ptr::null_mut()))
.map(|r| r != 0) .map(|r| r != 0)
@ -182,7 +182,7 @@ impl BigNumContext {
/// ///
/// Returns `true` if `p` is prime with an error probability of less than `0.25 ^ checks`. /// Returns `true` if `p` is prime with an error probability of less than `0.25 ^ checks`.
pub fn is_prime_fasttest(&mut self, pub fn is_prime_fasttest(&mut self,
p: &Ref<BigNum>, p: &BigNumRef,
checks: i32, checks: i32,
do_trial_division: bool) do_trial_division: bool)
-> Result<bool, ErrorStack> { -> Result<bool, ErrorStack> {
@ -197,7 +197,7 @@ impl BigNumContext {
} }
} }
impl Ref<BigNum> { impl BigNumRef {
/// Erases the memory used by this `BigNum`, resetting its value to 0. /// Erases the memory used by this `BigNum`, resetting its value to 0.
/// ///
/// This can be used to destroy sensitive data such as keys when they are no longer needed. /// This can be used to destroy sensitive data such as keys when they are no longer needed.
@ -246,12 +246,12 @@ impl Ref<BigNum> {
/// Places a cryptographically-secure pseudo-random number nonnegative /// Places a cryptographically-secure pseudo-random number nonnegative
/// number less than `self` in `rnd`. /// number less than `self` in `rnd`.
pub fn rand_in_range(&self, rnd: &mut Ref<BigNum>) -> Result<(), ErrorStack> { pub fn rand_in_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_rand_range(self.as_ptr(), rnd.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_rand_range(self.as_ptr(), rnd.as_ptr())).map(|_| ()) }
} }
/// The cryptographically weak counterpart to `rand_in_range`. /// The cryptographically weak counterpart to `rand_in_range`.
pub fn pseudo_rand_in_range(&self, rnd: &mut Ref<BigNum>) -> Result<(), ErrorStack> { pub fn pseudo_rand_in_range(&self, rnd: &mut BigNumRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_pseudo_rand_range(self.as_ptr(), rnd.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_pseudo_rand_range(self.as_ptr(), rnd.as_ptr())).map(|_| ()) }
} }
@ -282,32 +282,32 @@ impl Ref<BigNum> {
} }
/// Places `self << 1` in `r`. /// Places `self << 1` in `r`.
pub fn lshift1(&self, r: &mut Ref<BigNum>) -> Result<(), ErrorStack> { pub fn lshift1(&self, r: &mut BigNumRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_lshift1(r.as_ptr(), self.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_lshift1(r.as_ptr(), self.as_ptr())).map(|_| ()) }
} }
/// Places `self >> 1` in `r`. /// Places `self >> 1` in `r`.
pub fn rshift1(&self, r: &mut Ref<BigNum>) -> Result<(), ErrorStack> { pub fn rshift1(&self, r: &mut BigNumRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_rshift1(r.as_ptr(), self.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_rshift1(r.as_ptr(), self.as_ptr())).map(|_| ()) }
} }
/// Places `self + b` in `r`. /// Places `self + b` in `r`.
pub fn add(&self, r: &mut Ref<BigNum>, b: &Ref<BigNum>) -> Result<(), ErrorStack> { pub fn add(&self, r: &mut BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_add(r.as_ptr(), self.as_ptr(), b.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_add(r.as_ptr(), self.as_ptr(), b.as_ptr())).map(|_| ()) }
} }
/// Places `self - b` in `r`. /// Places `self - b` in `r`.
pub fn sub(&self, r: &mut Ref<BigNum>, b: &Ref<BigNum>) -> Result<(), ErrorStack> { pub fn sub(&self, r: &mut BigNumRef, b: &BigNumRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_sub(r.as_ptr(), self.as_ptr(), b.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::BN_sub(r.as_ptr(), self.as_ptr(), b.as_ptr())).map(|_| ()) }
} }
/// Places `self << n` in `r`. /// Places `self << n` in `r`.
pub fn lshift(&self, r: &mut Ref<BigNum>, b: i32) -> Result<(), ErrorStack> { pub fn lshift(&self, r: &mut BigNumRef, b: i32) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_lshift(r.as_ptr(), self.as_ptr(), b.into())).map(|_| ()) } unsafe { cvt(ffi::BN_lshift(r.as_ptr(), self.as_ptr(), b.into())).map(|_| ()) }
} }
/// Places `self >> n` in `r`. /// Places `self >> n` in `r`.
pub fn rshift(&self, r: &mut Ref<BigNum>, n: i32) -> Result<(), ErrorStack> { pub fn rshift(&self, r: &mut BigNumRef, n: i32) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::BN_rshift(r.as_ptr(), self.as_ptr(), n.into())).map(|_| ()) } unsafe { cvt(ffi::BN_rshift(r.as_ptr(), self.as_ptr(), n.into())).map(|_| ()) }
} }
@ -330,7 +330,7 @@ impl Ref<BigNum> {
/// ///
/// assert_eq!(s.ucmp(&o), Ordering::Equal); /// assert_eq!(s.ucmp(&o), Ordering::Equal);
/// ``` /// ```
pub fn ucmp(&self, oth: &Ref<BigNum>) -> Ordering { pub fn ucmp(&self, oth: &BigNumRef) -> Ordering {
unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) } unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
} }
@ -397,8 +397,8 @@ impl Ref<BigNum> {
pub fn generate_prime(&mut self, pub fn generate_prime(&mut self,
bits: i32, bits: i32,
safe: bool, safe: bool,
add: Option<&Ref<BigNum>>, add: Option<&BigNumRef>,
rem: Option<&Ref<BigNum>>) rem: Option<&BigNumRef>)
-> Result<(), ErrorStack> { -> Result<(), ErrorStack> {
unsafe { unsafe {
cvt(ffi::BN_generate_prime_ex(self.as_ptr(), cvt(ffi::BN_generate_prime_ex(self.as_ptr(),
@ -464,7 +464,7 @@ impl Ref<BigNum> {
} }
} }
type_!(BigNum, ffi::BIGNUM, ffi::BN_free); type_!(BigNum, BigNumRef, ffi::BIGNUM, ffi::BN_free);
impl BigNum { impl BigNum {
/// Creates a new `BigNum` with the value 0. /// Creates a new `BigNum` with the value 0.
@ -520,13 +520,13 @@ impl BigNum {
} }
} }
impl AsRef<Ref<BigNum>> for BigNum { impl AsRef<BigNumRef> for BigNum {
fn as_ref(&self) -> &Ref<BigNum> { fn as_ref(&self) -> &BigNumRef {
self.deref() self.deref()
} }
} }
impl fmt::Debug for Ref<BigNum> { impl fmt::Debug for BigNumRef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.to_dec_str() { match self.to_dec_str() {
Ok(s) => f.write_str(&s), Ok(s) => f.write_str(&s),
@ -544,7 +544,7 @@ impl fmt::Debug for BigNum {
} }
} }
impl fmt::Display for Ref<BigNum> { impl fmt::Display for BigNumRef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.to_dec_str() { match self.to_dec_str() {
Ok(s) => f.write_str(&s), Ok(s) => f.write_str(&s),
@ -562,19 +562,19 @@ impl fmt::Display for BigNum {
} }
} }
impl PartialEq<Ref<BigNum>> for Ref<BigNum> { impl PartialEq<BigNumRef> for BigNumRef {
fn eq(&self, oth: &Ref<BigNum>) -> bool { fn eq(&self, oth: &BigNumRef) -> bool {
self.cmp(oth) == Ordering::Equal self.cmp(oth) == Ordering::Equal
} }
} }
impl PartialEq<BigNum> for Ref<BigNum> { impl PartialEq<BigNum> for BigNumRef {
fn eq(&self, oth: &BigNum) -> bool { fn eq(&self, oth: &BigNum) -> bool {
self.eq(oth.deref()) self.eq(oth.deref())
} }
} }
impl Eq for Ref<BigNum> {} impl Eq for BigNumRef {}
impl PartialEq for BigNum { impl PartialEq for BigNum {
fn eq(&self, oth: &BigNum) -> bool { fn eq(&self, oth: &BigNum) -> bool {
@ -582,28 +582,28 @@ impl PartialEq for BigNum {
} }
} }
impl PartialEq<Ref<BigNum>> for BigNum { impl PartialEq<BigNumRef> for BigNum {
fn eq(&self, oth: &Ref<BigNum>) -> bool { fn eq(&self, oth: &BigNumRef) -> bool {
self.deref().eq(oth) self.deref().eq(oth)
} }
} }
impl Eq for BigNum {} impl Eq for BigNum {}
impl PartialOrd<Ref<BigNum>> for Ref<BigNum> { impl PartialOrd<BigNumRef> for BigNumRef {
fn partial_cmp(&self, oth: &Ref<BigNum>) -> Option<Ordering> { fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> {
Some(self.cmp(oth)) Some(self.cmp(oth))
} }
} }
impl PartialOrd<BigNum> for Ref<BigNum> { impl PartialOrd<BigNum> for BigNumRef {
fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> { fn partial_cmp(&self, oth: &BigNum) -> Option<Ordering> {
Some(self.cmp(oth.deref())) Some(self.cmp(oth.deref()))
} }
} }
impl Ord for Ref<BigNum> { impl Ord for BigNumRef {
fn cmp(&self, oth: &Ref<BigNum>) -> Ordering { fn cmp(&self, oth: &BigNumRef) -> Ordering {
unsafe { ffi::BN_cmp(self.as_ptr(), oth.as_ptr()).cmp(&0) } unsafe { ffi::BN_cmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
} }
} }
@ -614,8 +614,8 @@ impl PartialOrd for BigNum {
} }
} }
impl PartialOrd<Ref<BigNum>> for BigNum { impl PartialOrd<BigNumRef> for BigNum {
fn partial_cmp(&self, oth: &Ref<BigNum>) -> Option<Ordering> { fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> {
self.deref().partial_cmp(oth) self.deref().partial_cmp(oth)
} }
} }
@ -628,7 +628,7 @@ impl Ord for BigNum {
macro_rules! delegate { macro_rules! delegate {
($t:ident, $m:ident) => { ($t:ident, $m:ident) => {
impl<'a, 'b> $t<&'b BigNum> for &'a Ref<BigNum> { impl<'a, 'b> $t<&'b BigNum> for &'a BigNumRef {
type Output = BigNum; type Output = BigNum;
fn $m(self, oth: &BigNum) -> BigNum { fn $m(self, oth: &BigNum) -> BigNum {
@ -636,10 +636,10 @@ macro_rules! delegate {
} }
} }
impl<'a, 'b> $t<&'b Ref<BigNum>> for &'a BigNum { impl<'a, 'b> $t<&'b BigNumRef> for &'a BigNum {
type Output = BigNum; type Output = BigNum;
fn $m(self, oth: &Ref<BigNum>) -> BigNum { fn $m(self, oth: &BigNumRef) -> BigNum {
$t::$m(self.deref(), oth) $t::$m(self.deref(), oth)
} }
} }
@ -654,10 +654,10 @@ macro_rules! delegate {
} }
} }
impl<'a, 'b> Add<&'b Ref<BigNum>> for &'a Ref<BigNum> { impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef {
type Output = BigNum; type Output = BigNum;
fn add(self, oth: &Ref<BigNum>) -> BigNum { fn add(self, oth: &BigNumRef) -> BigNum {
let mut r = BigNum::new().unwrap(); let mut r = BigNum::new().unwrap();
self.add(&mut r, oth).unwrap(); self.add(&mut r, oth).unwrap();
r r
@ -666,10 +666,10 @@ impl<'a, 'b> Add<&'b Ref<BigNum>> for &'a Ref<BigNum> {
delegate!(Add, add); delegate!(Add, add);
impl<'a, 'b> Sub<&'b Ref<BigNum>> for &'a Ref<BigNum> { impl<'a, 'b> Sub<&'b BigNumRef> for &'a BigNumRef {
type Output = BigNum; type Output = BigNum;
fn sub(self, oth: &Ref<BigNum>) -> BigNum { fn sub(self, oth: &BigNumRef) -> BigNum {
let mut r = BigNum::new().unwrap(); let mut r = BigNum::new().unwrap();
self.sub(&mut r, oth).unwrap(); self.sub(&mut r, oth).unwrap();
r r
@ -678,10 +678,10 @@ impl<'a, 'b> Sub<&'b Ref<BigNum>> for &'a Ref<BigNum> {
delegate!(Sub, sub); delegate!(Sub, sub);
impl<'a, 'b> Mul<&'b Ref<BigNum>> for &'a Ref<BigNum> { impl<'a, 'b> Mul<&'b BigNumRef> for &'a BigNumRef {
type Output = BigNum; type Output = BigNum;
fn mul(self, oth: &Ref<BigNum>) -> BigNum { fn mul(self, oth: &BigNumRef) -> BigNum {
let mut ctx = BigNumContext::new().unwrap(); let mut ctx = BigNumContext::new().unwrap();
let mut r = BigNum::new().unwrap(); let mut r = BigNum::new().unwrap();
ctx.mul(&mut r, self, oth).unwrap(); ctx.mul(&mut r, self, oth).unwrap();
@ -691,10 +691,10 @@ impl<'a, 'b> Mul<&'b Ref<BigNum>> for &'a Ref<BigNum> {
delegate!(Mul, mul); delegate!(Mul, mul);
impl<'a, 'b> Div<&'b Ref<BigNum>> for &'a Ref<BigNum> { impl<'a, 'b> Div<&'b BigNumRef> for &'a BigNumRef {
type Output = BigNum; type Output = BigNum;
fn div(self, oth: &'b Ref<BigNum>) -> BigNum { fn div(self, oth: &'b BigNumRef) -> BigNum {
let mut ctx = BigNumContext::new().unwrap(); let mut ctx = BigNumContext::new().unwrap();
let mut dv = BigNum::new().unwrap(); let mut dv = BigNum::new().unwrap();
ctx.div(Some(&mut dv), None, self, oth).unwrap(); ctx.div(Some(&mut dv), None, self, oth).unwrap();
@ -704,10 +704,10 @@ impl<'a, 'b> Div<&'b Ref<BigNum>> for &'a Ref<BigNum> {
delegate!(Div, div); delegate!(Div, div);
impl<'a, 'b> Rem<&'b Ref<BigNum>> for &'a Ref<BigNum> { impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef {
type Output = BigNum; type Output = BigNum;
fn rem(self, oth: &'b Ref<BigNum>) -> BigNum { fn rem(self, oth: &'b BigNumRef) -> BigNum {
let mut ctx = BigNumContext::new().unwrap(); let mut ctx = BigNumContext::new().unwrap();
let mut rem = BigNum::new().unwrap(); let mut rem = BigNum::new().unwrap();
ctx.div(None, Some(&mut rem), self, oth).unwrap(); ctx.div(None, Some(&mut rem), self, oth).unwrap();
@ -717,7 +717,7 @@ impl<'a, 'b> Rem<&'b Ref<BigNum>> for &'a Ref<BigNum> {
delegate!(Rem, rem); delegate!(Rem, rem);
impl<'a> Shl<i32> for &'a Ref<BigNum> { impl<'a> Shl<i32> for &'a BigNumRef {
type Output = BigNum; type Output = BigNum;
fn shl(self, n: i32) -> BigNum { fn shl(self, n: i32) -> BigNum {
@ -735,7 +735,7 @@ impl<'a> Shl<i32> for &'a BigNum {
} }
} }
impl<'a> Shr<i32> for &'a Ref<BigNum> { impl<'a> Shr<i32> for &'a BigNumRef {
type Output = BigNum; type Output = BigNum;
fn shr(self, n: i32) -> BigNum { fn shr(self, n: i32) -> BigNum {
@ -753,7 +753,7 @@ impl<'a> Shr<i32> for &'a BigNum {
} }
} }
impl<'a> Neg for &'a Ref<BigNum> { impl<'a> Neg for &'a BigNumRef {
type Output = BigNum; type Output = BigNum;
fn neg(self) -> BigNum { fn neg(self) -> BigNum {

View File

@ -7,11 +7,11 @@ use std::mem;
use {cvt, cvt_p}; use {cvt, cvt_p};
use bio::MemBio; use bio::MemBio;
use bn::BigNum; use bn::BigNum;
use types::{OpenSslType, Ref}; use types::OpenSslTypeRef;
type_!(Dh, ffi::DH, ffi::DH_free); type_!(Dh, DhRef, ffi::DH, ffi::DH_free);
impl Ref<Dh> { impl DhRef {
/// Encodes the parameters to PEM. /// Encodes the parameters to PEM.
pub fn to_pem(&self) -> Result<Vec<u8>, ErrorStack> { pub fn to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
let mem_bio = try!(MemBio::new()); let mem_bio = try!(MemBio::new());

View File

@ -5,14 +5,14 @@ use std::fmt;
use std::ptr; use std::ptr;
use bio::{MemBio, MemBioSlice}; use bio::{MemBio, MemBioSlice};
use bn::BigNum; use bn::BigNumRef;
use {cvt, cvt_p}; use {cvt, cvt_p};
use types::Ref; use types::OpenSslTypeRef;
use util::{CallbackState, invoke_passwd_cb}; use util::{CallbackState, invoke_passwd_cb};
type_!(Dsa, ffi::DSA, ffi::DSA_free); type_!(Dsa, DsaRef, ffi::DSA, ffi::DSA_free);
impl Ref<Dsa> { impl DsaRef {
/// Writes an DSA private key as unencrypted PEM formatted data /// Writes an DSA private key as unencrypted PEM formatted data
pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> { pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
assert!(self.has_private_key()); assert!(self.has_private_key());
@ -44,35 +44,35 @@ impl Ref<Dsa> {
} }
} }
pub fn p(&self) -> Option<&Ref<BigNum>> { pub fn p(&self) -> Option<&BigNumRef> {
unsafe { unsafe {
let p = compat::pqg(self.as_ptr())[0]; let p = compat::pqg(self.as_ptr())[0];
if p.is_null() { if p.is_null() {
None None
} else { } else {
Some(Ref::<BigNum>::from_ptr(p as *mut _)) Some(BigNumRef::from_ptr(p as *mut _))
} }
} }
} }
pub fn q(&self) -> Option<&Ref<BigNum>> { pub fn q(&self) -> Option<&BigNumRef> {
unsafe { unsafe {
let q = compat::pqg(self.as_ptr())[1]; let q = compat::pqg(self.as_ptr())[1];
if q.is_null() { if q.is_null() {
None None
} else { } else {
Some(Ref::<BigNum>::from_ptr(q as *mut _)) Some(BigNumRef::from_ptr(q as *mut _))
} }
} }
} }
pub fn g(&self) -> Option<&Ref<BigNum>> { pub fn g(&self) -> Option<&BigNumRef> {
unsafe { unsafe {
let g = compat::pqg(self.as_ptr())[2]; let g = compat::pqg(self.as_ptr())[2];
if g.is_null() { if g.is_null() {
None None
} else { } else {
Some(Ref::<BigNum>::from_ptr(g as *mut _)) Some(BigNumRef::from_ptr(g as *mut _))
} }
} }
} }

View File

@ -4,7 +4,7 @@ use cvt_p;
use error::ErrorStack; use error::ErrorStack;
use nid::Nid; use nid::Nid;
type_!(EcKey, ffi::EC_KEY, ffi::EC_KEY_free); type_!(EcKey, EcKeyRef, ffi::EC_KEY, ffi::EC_KEY_free);
impl EcKey { impl EcKey {
pub fn new_by_curve_name(nid: Nid) -> Result<EcKey, ErrorStack> { pub fn new_by_curve_name(nid: Nid) -> Result<EcKey, ErrorStack> {

View File

@ -21,19 +21,16 @@ use libc::c_int;
use error::ErrorStack; use error::ErrorStack;
macro_rules! type_ { macro_rules! type_ {
($n:ident, $c:path, $d:path) => { ($n:ident, $r:ident, $c:path, $d:path) => {
pub struct $n(*mut $c); pub struct $n(*mut $c);
unsafe impl ::types::OpenSslType for $n { impl ::types::OpenSslType for $n {
type CType = $c; type CType = $c;
type Ref = $r;
unsafe fn from_ptr(ptr: *mut $c) -> $n { unsafe fn from_ptr(ptr: *mut $c) -> $n {
$n(ptr) $n(ptr)
} }
fn as_ptr(&self) -> *mut $c {
self.0
}
} }
impl Drop for $n { impl Drop for $n {
@ -43,18 +40,24 @@ macro_rules! type_ {
} }
impl ::std::ops::Deref for $n { impl ::std::ops::Deref for $n {
type Target = ::types::Ref<$n>; type Target = $r;
fn deref(&self) -> &::types::Ref<$n> { fn deref(&self) -> &$r {
unsafe { ::types::Ref::from_ptr(self.0) } unsafe { ::types::OpenSslTypeRef::from_ptr(self.0) }
} }
} }
impl ::std::ops::DerefMut for $n { impl ::std::ops::DerefMut for $n {
fn deref_mut(&mut self) -> &mut ::types::Ref<$n> { fn deref_mut(&mut self) -> &mut $r {
unsafe { ::types::Ref::from_ptr_mut(self.0) } unsafe { ::types::OpenSslTypeRef::from_ptr_mut(self.0) }
} }
} }
pub struct $r(::util::Opaque);
impl ::types::OpenSslTypeRef for $r {
type CType = $c;
}
} }
} }

View File

@ -6,14 +6,14 @@ use ffi;
use {cvt, cvt_p}; use {cvt, cvt_p};
use bio::{MemBio, MemBioSlice}; use bio::{MemBio, MemBioSlice};
use dsa::Dsa; use dsa::Dsa;
use rsa::Rsa; use rsa::{Rsa, RsaRef};
use error::ErrorStack; use error::ErrorStack;
use util::{CallbackState, invoke_passwd_cb}; use util::{CallbackState, invoke_passwd_cb};
use types::{OpenSslType, Ref}; use types::{OpenSslType, OpenSslTypeRef};
type_!(PKey, ffi::EVP_PKEY, ffi::EVP_PKEY_free); type_!(PKey, PKeyRef, ffi::EVP_PKEY, ffi::EVP_PKEY_free);
impl Ref<PKey> { impl PKeyRef {
/// Get a reference to the interal RSA key for direct access to the key components /// Get a reference to the interal RSA key for direct access to the key components
pub fn rsa(&self) -> Result<Rsa, ErrorStack> { pub fn rsa(&self) -> Result<Rsa, ErrorStack> {
unsafe { unsafe {
@ -58,7 +58,7 @@ impl Ref<PKey> {
Ok(mem_bio.get_buf().to_owned()) Ok(mem_bio.get_buf().to_owned())
} }
pub fn public_eq(&self, other: &Ref<PKey>) -> bool { pub fn public_eq(&self, other: &PKeyRef) -> bool {
unsafe { ffi::EVP_PKEY_cmp(self.as_ptr(), other.as_ptr()) == 1 } unsafe { ffi::EVP_PKEY_cmp(self.as_ptr(), other.as_ptr()) == 1 }
} }
} }
@ -148,7 +148,7 @@ impl PKey {
} }
/// Assign an RSA key to this pkey. /// Assign an RSA key to this pkey.
pub fn set_rsa(&mut self, rsa: &Ref<Rsa>) -> Result<(), ErrorStack> { pub fn set_rsa(&mut self, rsa: &RsaRef) -> Result<(), ErrorStack> {
unsafe { unsafe {
// this needs to be a reference as the set1_RSA ups the reference count // this needs to be a reference as the set1_RSA ups the reference count
let rsa_ptr = rsa.as_ptr(); let rsa_ptr = rsa.as_ptr();

View File

@ -5,11 +5,11 @@ use std::mem;
use libc::{c_int, c_void, c_char}; use libc::{c_int, c_void, c_char};
use {cvt, cvt_p, cvt_n}; use {cvt, cvt_p, cvt_n};
use bn::BigNum; use bn::{BigNum, BigNumRef};
use bio::{MemBio, MemBioSlice}; use bio::{MemBio, MemBioSlice};
use error::ErrorStack; use error::ErrorStack;
use util::{CallbackState, invoke_passwd_cb}; use util::{CallbackState, invoke_passwd_cb};
use types::{OpenSslType, Ref}; use types::OpenSslTypeRef;
/// Type of encryption padding to use. /// Type of encryption padding to use.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@ -19,9 +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_PADDING: Padding = Padding(ffi::RSA_PKCS1_PADDING);
pub const PKCS1_OAEP_PADDING: Padding = Padding(ffi::RSA_PKCS1_OAEP_PADDING); pub const PKCS1_OAEP_PADDING: Padding = Padding(ffi::RSA_PKCS1_OAEP_PADDING);
type_!(Rsa, ffi::RSA, ffi::RSA_free); type_!(Rsa, RsaRef, ffi::RSA, ffi::RSA_free);
impl Ref<Rsa> { impl RsaRef {
/// Writes an RSA private key as unencrypted PEM formatted data /// Writes an RSA private key as unencrypted PEM formatted data
pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> { pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
let mem_bio = try!(MemBio::new()); let mem_bio = try!(MemBio::new());
@ -153,57 +153,57 @@ impl Ref<Rsa> {
} }
} }
pub fn n(&self) -> Option<&Ref<BigNum>> { pub fn n(&self) -> Option<&BigNumRef> {
unsafe { unsafe {
let n = compat::key(self.as_ptr())[0]; let n = compat::key(self.as_ptr())[0];
if n.is_null() { if n.is_null() {
None None
} else { } else {
Some(Ref::<BigNum>::from_ptr(n as *mut _)) Some(BigNumRef::from_ptr(n as *mut _))
} }
} }
} }
pub fn d(&self) -> Option<&Ref<BigNum>> { pub fn d(&self) -> Option<&BigNumRef> {
unsafe { unsafe {
let d = compat::key(self.as_ptr())[2]; let d = compat::key(self.as_ptr())[2];
if d.is_null() { if d.is_null() {
None None
} else { } else {
Some(Ref::<BigNum>::from_ptr(d as *mut _)) Some(BigNumRef::from_ptr(d as *mut _))
} }
} }
} }
pub fn e(&self) -> Option<&Ref<BigNum>> { pub fn e(&self) -> Option<&BigNumRef> {
unsafe { unsafe {
let e = compat::key(self.as_ptr())[1]; let e = compat::key(self.as_ptr())[1];
if e.is_null() { if e.is_null() {
None None
} else { } else {
Some(Ref::<BigNum>::from_ptr(e as *mut _)) Some(BigNumRef::from_ptr(e as *mut _))
} }
} }
} }
pub fn p(&self) -> Option<&Ref<BigNum>> { pub fn p(&self) -> Option<&BigNumRef> {
unsafe { unsafe {
let p = compat::factors(self.as_ptr())[0]; let p = compat::factors(self.as_ptr())[0];
if p.is_null() { if p.is_null() {
None None
} else { } else {
Some(Ref::<BigNum>::from_ptr(p as *mut _)) Some(BigNumRef::from_ptr(p as *mut _))
} }
} }
} }
pub fn q(&self) -> Option<&Ref<BigNum>> { pub fn q(&self) -> Option<&BigNumRef> {
unsafe { unsafe {
let q = compat::factors(self.as_ptr())[1]; let q = compat::factors(self.as_ptr())[1];
if q.is_null() { if q.is_null() {
None None
} else { } else {
Some(Ref::<BigNum>::from_ptr(q as *mut _)) Some(BigNumRef::from_ptr(q as *mut _))
} }
} }
} }

View File

@ -61,16 +61,16 @@ use std::ptr;
use {cvt, cvt_p}; use {cvt, cvt_p};
use hash::MessageDigest; use hash::MessageDigest;
use pkey::PKey; use pkey::PKeyRef;
use error::ErrorStack; use error::ErrorStack;
use types::Ref; use types::OpenSslTypeRef;
#[cfg(ossl110)] #[cfg(ossl110)]
use ffi::{EVP_MD_CTX_new, EVP_MD_CTX_free}; use ffi::{EVP_MD_CTX_new, EVP_MD_CTX_free};
#[cfg(any(ossl101, ossl102))] #[cfg(any(ossl101, ossl102))]
use ffi::{EVP_MD_CTX_create as EVP_MD_CTX_new, EVP_MD_CTX_destroy as EVP_MD_CTX_free}; 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 Ref<PKey>>); pub struct Signer<'a>(*mut ffi::EVP_MD_CTX, PhantomData<&'a PKeyRef>);
impl<'a> Drop for Signer<'a> { impl<'a> Drop for Signer<'a> {
fn drop(&mut self) { fn drop(&mut self) {
@ -81,7 +81,7 @@ impl<'a> Drop for Signer<'a> {
} }
impl<'a> Signer<'a> { impl<'a> Signer<'a> {
pub fn new(type_: MessageDigest, pkey: &'a Ref<PKey>) -> Result<Signer<'a>, ErrorStack> { pub fn new(type_: MessageDigest, pkey: &'a PKeyRef) -> Result<Signer<'a>, ErrorStack> {
unsafe { unsafe {
ffi::init(); ffi::init();
@ -129,7 +129,7 @@ impl<'a> Write for Signer<'a> {
} }
} }
pub struct Verifier<'a>(*mut ffi::EVP_MD_CTX, PhantomData<&'a Ref<PKey>>); pub struct Verifier<'a>(*mut ffi::EVP_MD_CTX, PhantomData<&'a PKeyRef>);
impl<'a> Drop for Verifier<'a> { impl<'a> Drop for Verifier<'a> {
fn drop(&mut self) { fn drop(&mut self) {
@ -140,7 +140,7 @@ impl<'a> Drop for Verifier<'a> {
} }
impl<'a> Verifier<'a> { impl<'a> Verifier<'a> {
pub fn new(type_: MessageDigest, pkey: &'a Ref<PKey>) -> Result<Verifier<'a>, ErrorStack> { pub fn new(type_: MessageDigest, pkey: &'a PKeyRef) -> Result<Verifier<'a>, ErrorStack> {
unsafe { unsafe {
ffi::init(); ffi::init();

View File

@ -4,9 +4,8 @@ use dh::Dh;
use error::ErrorStack; use error::ErrorStack;
use ssl::{self, SslMethod, SslContextBuilder, SslContext, Ssl, SSL_VERIFY_PEER, SslStream, use ssl::{self, SslMethod, SslContextBuilder, SslContext, Ssl, SSL_VERIFY_PEER, SslStream,
HandshakeError}; HandshakeError};
use pkey::PKey; use pkey::PKeyRef;
use x509::X509; use x509::X509Ref;
use types::Ref;
// Serialized form of DH_get_2048_256 // Serialized form of DH_get_2048_256
#[cfg(any(ossl101, all(test, any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))))] #[cfg(any(ossl101, all(test, any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))))]
@ -118,12 +117,12 @@ impl SslAcceptorBuilder {
/// ///
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
pub fn mozilla_intermediate<I>(method: SslMethod, pub fn mozilla_intermediate<I>(method: SslMethod,
private_key: &Ref<PKey>, private_key: &PKeyRef,
certificate: &Ref<X509>, certificate: &X509Ref,
chain: I) chain: I)
-> Result<SslAcceptorBuilder, ErrorStack> -> Result<SslAcceptorBuilder, ErrorStack>
where I: IntoIterator, where I: IntoIterator,
I::Item: AsRef<Ref<X509>> I::Item: AsRef<X509Ref>
{ {
let mut ctx = try!(ctx(method)); let mut ctx = try!(ctx(method));
let dh = try!(get_dh()); let dh = try!(get_dh());
@ -153,12 +152,12 @@ impl SslAcceptorBuilder {
/// ///
/// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS /// [docs]: https://wiki.mozilla.org/Security/Server_Side_TLS
pub fn mozilla_modern<I>(method: SslMethod, pub fn mozilla_modern<I>(method: SslMethod,
private_key: &Ref<PKey>, private_key: &PKeyRef,
certificate: &Ref<X509>, certificate: &X509Ref,
chain: I) chain: I)
-> Result<SslAcceptorBuilder, ErrorStack> -> Result<SslAcceptorBuilder, ErrorStack>
where I: IntoIterator, where I: IntoIterator,
I::Item: AsRef<Ref<X509>> I::Item: AsRef<X509Ref>
{ {
let mut ctx = try!(ctx(method)); let mut ctx = try!(ctx(method));
try!(setup_curves(&mut ctx)); try!(setup_curves(&mut ctx));
@ -171,12 +170,12 @@ impl SslAcceptorBuilder {
} }
fn finish_setup<I>(mut ctx: SslContextBuilder, fn finish_setup<I>(mut ctx: SslContextBuilder,
private_key: &Ref<PKey>, private_key: &PKeyRef,
certificate: &Ref<X509>, certificate: &X509Ref,
chain: I) chain: I)
-> Result<SslAcceptorBuilder, ErrorStack> -> Result<SslAcceptorBuilder, ErrorStack>
where I: IntoIterator, where I: IntoIterator,
I::Item: AsRef<Ref<X509>> I::Item: AsRef<X509Ref>
{ {
try!(ctx.set_private_key(private_key)); try!(ctx.set_private_key(private_key));
try!(ctx.set_certificate(certificate)); try!(ctx.set_certificate(certificate));
@ -278,13 +277,13 @@ mod verify {
use std::str; use std::str;
use nid; use nid;
use x509::{X509StoreContext, X509, X509Name, GeneralName}; use x509::{X509StoreContextRef, X509Ref, X509NameRef, GeneralName};
use stack::Stack; use stack::Stack;
use types::Ref; use types::OpenSslTypeRef;
pub fn verify_callback(domain: &str, pub fn verify_callback(domain: &str,
preverify_ok: bool, preverify_ok: bool,
x509_ctx: &Ref<X509StoreContext>) x509_ctx: &X509StoreContextRef)
-> bool { -> bool {
if !preverify_ok || x509_ctx.error_depth() != 0 { if !preverify_ok || x509_ctx.error_depth() != 0 {
return preverify_ok; return preverify_ok;
@ -296,7 +295,7 @@ mod verify {
} }
} }
fn verify_hostname(domain: &str, cert: &Ref<X509>) -> bool { fn verify_hostname(domain: &str, cert: &X509Ref) -> bool {
match cert.subject_alt_names() { match cert.subject_alt_names() {
Some(names) => verify_subject_alt_names(domain, names), Some(names) => verify_subject_alt_names(domain, names),
None => verify_subject_name(domain, &cert.subject_name()), None => verify_subject_name(domain, &cert.subject_name()),
@ -329,7 +328,7 @@ mod verify {
false false
} }
fn verify_subject_name(domain: &str, subject_name: &Ref<X509Name>) -> bool { fn verify_subject_name(domain: &str, subject_name: &X509NameRef) -> bool {
if let Some(pattern) = subject_name.entries_by_nid(nid::COMMONNAME).next() { if let Some(pattern) = subject_name.entries_by_nid(nid::COMMONNAME).next() {
let pattern = match str::from_utf8(pattern.data().as_slice()) { let pattern = match str::from_utf8(pattern.data().as_slice()) {
Ok(pattern) => pattern, Ok(pattern) => pattern,

View File

@ -90,14 +90,15 @@ use std::marker::PhantomData;
use ffi; use ffi;
use {init, cvt, cvt_p}; use {init, cvt, cvt_p};
use dh::Dh; use dh::DhRef;
use ec_key::EcKey; use ec_key::EcKeyRef;
use x509::{X509StoreContext, X509FileType, X509, X509VerifyError}; use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError};
#[cfg(any(ossl102, ossl110))] #[cfg(any(ossl102, ossl110))]
use verify::X509VerifyParam; use verify::X509VerifyParamRef;
use pkey::PKey; use pkey::PKeyRef;
use error::ErrorStack; use error::ErrorStack;
use types::{OpenSslType, Ref}; use types::{OpenSslType, OpenSslTypeRef};
use util::Opaque;
mod error; mod error;
mod connector; mod connector;
@ -262,7 +263,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 extern "C" fn raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int
where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send
{ {
unsafe { unsafe {
let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx(); let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx();
@ -271,14 +272,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 = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::<F>());
let verify: &F = &*(verify as *mut F); let verify: &F = &*(verify as *mut F);
let ctx = Ref::from_ptr(x509_ctx); let ctx = X509StoreContextRef::from_ptr(x509_ctx);
verify(preverify_ok != 0, ctx) as c_int 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 extern "C" fn ssl_raw_verify<F>(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int
where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send
{ {
unsafe { unsafe {
let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx(); let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx();
@ -286,20 +287,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 = ffi::SSL_get_ex_data(ssl as *const _, get_ssl_verify_data_idx::<F>());
let verify: &F = &*(verify as *mut F); let verify: &F = &*(verify as *mut F);
let ctx = Ref::from_ptr(x509_ctx); let ctx = X509StoreContextRef::from_ptr(x509_ctx);
verify(preverify_ok != 0, ctx) as c_int 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 extern "C" fn raw_sni<F>(ssl: *mut ffi::SSL, al: *mut c_int, _arg: *mut c_void) -> c_int
where F: Fn(&mut Ref<Ssl>) -> Result<(), SniError> + Any + 'static + Sync + Send where F: Fn(&mut SslRef) -> Result<(), SniError> + Any + 'static + Sync + Send
{ {
unsafe { unsafe {
let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl); 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 = ffi::SSL_CTX_get_ex_data(ssl_ctx, get_verify_data_idx::<F>());
let callback: &F = &*(callback as *mut F); let callback: &F = &*(callback as *mut F);
let ssl = Ref::from_ptr_mut(ssl); let ssl = SslRef::from_ptr_mut(ssl);
match callback(ssl) { match callback(ssl) {
Ok(()) => ffi::SSL_TLSEXT_ERR_OK, Ok(()) => ffi::SSL_TLSEXT_ERR_OK,
@ -463,7 +464,7 @@ impl SslContextBuilder {
/// Configures the certificate verification method for new connections and /// Configures the certificate verification method for new connections and
/// registers a verification callback. /// registers a verification callback.
pub fn set_verify_callback<F>(&mut self, mode: SslVerifyMode, verify: F) pub fn set_verify_callback<F>(&mut self, mode: SslVerifyMode, verify: F)
where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send
{ {
unsafe { unsafe {
let verify = Box::new(verify); let verify = Box::new(verify);
@ -479,7 +480,7 @@ impl SslContextBuilder {
/// Obtain the server name with `servername` then set the corresponding context /// Obtain the server name with `servername` then set the corresponding context
/// with `set_ssl_context` /// with `set_ssl_context`
pub fn set_servername_callback<F>(&mut self, callback: F) pub fn set_servername_callback<F>(&mut self, callback: F)
where F: Fn(&mut Ref<Ssl>) -> Result<(), SniError> + Any + 'static + Sync + Send where F: Fn(&mut SslRef) -> Result<(), SniError> + Any + 'static + Sync + Send
{ {
unsafe { unsafe {
let callback = Box::new(callback); let callback = Box::new(callback);
@ -512,11 +513,11 @@ impl SslContextBuilder {
} }
} }
pub fn set_tmp_dh(&mut self, dh: &Ref<Dh>) -> Result<(), ErrorStack> { pub fn set_tmp_dh(&mut self, dh: &DhRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_CTX_set_tmp_dh(self.as_ptr(), dh.as_ptr()) as c_int).map(|_| ()) } 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: &Ref<EcKey>) -> Result<(), ErrorStack> { pub fn set_tmp_ecdh(&mut self, key: &EcKeyRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_CTX_set_tmp_ecdh(self.as_ptr(), key.as_ptr()) as c_int).map(|_| ()) } unsafe { cvt(ffi::SSL_CTX_set_tmp_ecdh(self.as_ptr(), key.as_ptr()) as c_int).map(|_| ()) }
} }
@ -584,7 +585,7 @@ impl SslContextBuilder {
} }
/// Specifies the certificate /// Specifies the certificate
pub fn set_certificate(&mut self, cert: &Ref<X509>) -> Result<(), ErrorStack> { pub fn set_certificate(&mut self, cert: &X509Ref) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_CTX_use_certificate(self.as_ptr(), cert.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::SSL_CTX_use_certificate(self.as_ptr(), cert.as_ptr())).map(|_| ()) }
} }
@ -613,7 +614,7 @@ impl SslContextBuilder {
} }
/// Specifies the private key /// Specifies the private key
pub fn set_private_key(&mut self, key: &Ref<PKey>) -> Result<(), ErrorStack> { pub fn set_private_key(&mut self, key: &PKeyRef) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_CTX_use_PrivateKey(self.as_ptr(), key.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::SSL_CTX_use_PrivateKey(self.as_ptr(), key.as_ptr())).map(|_| ()) }
} }
@ -733,7 +734,7 @@ impl SslContextBuilder {
} }
} }
type_!(SslContext, ffi::SSL_CTX, ffi::SSL_CTX_free); type_!(SslContext, SslContextRef, ffi::SSL_CTX, ffi::SSL_CTX_free);
unsafe impl Send for SslContext {} unsafe impl Send for SslContext {}
unsafe impl Sync for SslContext {} unsafe impl Sync for SslContext {}
@ -771,19 +772,22 @@ pub struct CipherBits {
pub struct SslCipher(*mut ffi::SSL_CIPHER); pub struct SslCipher(*mut ffi::SSL_CIPHER);
unsafe impl OpenSslType for SslCipher { impl OpenSslType for SslCipher {
type CType = ffi::SSL_CIPHER; type CType = ffi::SSL_CIPHER;
type Ref = SslCipherRef;
unsafe fn from_ptr(ptr: *mut ffi::SSL_CIPHER) -> SslCipher { unsafe fn from_ptr(ptr: *mut ffi::SSL_CIPHER) -> SslCipher {
SslCipher(ptr) SslCipher(ptr)
} }
fn as_ptr(&self) -> *mut ffi::SSL_CIPHER {
self.0
}
} }
impl Ref<SslCipher> { pub struct SslCipherRef(Opaque);
impl OpenSslTypeRef for SslCipherRef {
type CType = ffi::SSL_CIPHER;
}
impl SslCipherRef {
/// Returns the name of cipher. /// Returns the name of cipher.
pub fn name(&self) -> &'static str { pub fn name(&self) -> &'static str {
let name = unsafe { let name = unsafe {
@ -827,9 +831,9 @@ impl Ref<SslCipher> {
} }
} }
type_!(Ssl, ffi::SSL, ffi::SSL_free); type_!(Ssl, SslRef, ffi::SSL, ffi::SSL_free);
impl fmt::Debug for Ref<Ssl> { impl fmt::Debug for SslRef {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let mut builder = fmt.debug_struct("Ssl"); let mut builder = fmt.debug_struct("Ssl");
builder.field("state", &self.state_string_long()); builder.field("state", &self.state_string_long());
@ -840,7 +844,7 @@ impl fmt::Debug for Ref<Ssl> {
} }
} }
impl Ref<Ssl> { impl SslRef {
fn get_raw_rbio(&self) -> *mut ffi::BIO { fn get_raw_rbio(&self) -> *mut ffi::BIO {
unsafe { ffi::SSL_get_rbio(self.as_ptr()) } unsafe { ffi::SSL_get_rbio(self.as_ptr()) }
} }
@ -874,7 +878,7 @@ impl Ref<Ssl> {
/// to the certificate chain. It should return `true` if the certificate /// to the certificate chain. It should return `true` if the certificate
/// chain is valid and `false` otherwise. /// chain is valid and `false` otherwise.
pub fn set_verify_callback<F>(&mut self, mode: SslVerifyMode, verify: F) pub fn set_verify_callback<F>(&mut self, mode: SslVerifyMode, verify: F)
where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send where F: Fn(bool, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send
{ {
unsafe { unsafe {
let verify = Box::new(verify); let verify = Box::new(verify);
@ -885,14 +889,14 @@ impl Ref<Ssl> {
} }
} }
pub fn current_cipher(&self) -> Option<&Ref<SslCipher>> { pub fn current_cipher(&self) -> Option<&SslCipherRef> {
unsafe { unsafe {
let ptr = ffi::SSL_get_current_cipher(self.as_ptr()); let ptr = ffi::SSL_get_current_cipher(self.as_ptr());
if ptr.is_null() { if ptr.is_null() {
None None
} else { } else {
Some(Ref::from_ptr(ptr as *mut _)) Some(SslCipherRef::from_ptr(ptr as *mut _))
} }
} }
} }
@ -1033,15 +1037,15 @@ impl Ref<Ssl> {
} }
/// Changes the context corresponding to the current connection. /// Changes the context corresponding to the current connection.
pub fn set_ssl_context(&mut self, ctx: &Ref<SslContext>) -> Result<(), ErrorStack> { pub fn set_ssl_context(&mut self, ctx: &SslContextRef) -> Result<(), ErrorStack> {
unsafe { cvt_p(ffi::SSL_set_SSL_CTX(self.as_ptr(), ctx.as_ptr())).map(|_| ()) } unsafe { cvt_p(ffi::SSL_set_SSL_CTX(self.as_ptr(), ctx.as_ptr())).map(|_| ()) }
} }
/// Returns the context corresponding to the current connection /// Returns the context corresponding to the current connection
pub fn ssl_context(&self) -> &Ref<SslContext> { pub fn ssl_context(&self) -> &SslContextRef {
unsafe { unsafe {
let ssl_ctx = ffi::SSL_get_SSL_CTX(self.as_ptr()); let ssl_ctx = ffi::SSL_get_SSL_CTX(self.as_ptr());
Ref::from_ptr(ssl_ctx) SslContextRef::from_ptr(ssl_ctx)
} }
} }
@ -1049,13 +1053,13 @@ impl Ref<Ssl> {
/// ///
/// Requires the `v102` or `v110` features and OpenSSL 1.0.2 or 1.1.0. /// 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)))] #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))]
pub fn param_mut(&mut self) -> &mut Ref<X509VerifyParam> { pub fn param_mut(&mut self) -> &mut X509VerifyParamRef {
self._param_mut() self._param_mut()
} }
#[cfg(any(ossl102, ossl110))] #[cfg(any(ossl102, ossl110))]
fn _param_mut(&mut self) -> &mut Ref<X509VerifyParam> { fn _param_mut(&mut self) -> &mut X509VerifyParamRef {
unsafe { Ref::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) } unsafe { X509VerifyParamRef::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) }
} }
/// Returns the result of X509 certificate verification. /// Returns the result of X509 certificate verification.
@ -1165,7 +1169,7 @@ impl<S> MidHandshakeSslStream<S> {
} }
/// Returns a shared reference to the `Ssl` of the stream. /// Returns a shared reference to the `Ssl` of the stream.
pub fn ssl(&self) -> &Ref<Ssl> { pub fn ssl(&self) -> &SslRef {
self.stream.ssl() self.stream.ssl()
} }
@ -1347,7 +1351,7 @@ impl<S> SslStream<S> {
} }
/// Returns the OpenSSL `Ssl` object associated with this stream. /// Returns the OpenSSL `Ssl` object associated with this stream.
pub fn ssl(&self) -> &Ref<Ssl> { pub fn ssl(&self) -> &SslRef {
&self.ssl &self.ssl
} }
} }

View File

@ -171,7 +171,7 @@ macro_rules! run_test(
use hash::MessageDigest; use hash::MessageDigest;
use x509::X509StoreContext; use x509::X509StoreContext;
use serialize::hex::FromHex; use serialize::hex::FromHex;
use types::Ref; use types::OpenSslTypeRef;
use super::Server; use super::Server;
#[test] #[test]

View File

@ -2,10 +2,12 @@ use std::ops::{Deref, DerefMut, Index, IndexMut};
use std::iter; use std::iter;
use std::borrow::Borrow; use std::borrow::Borrow;
use std::convert::AsRef; use std::convert::AsRef;
use std::marker::PhantomData;
use libc::c_int; use libc::c_int;
use ffi; use ffi;
use types::{OpenSslType, Ref}; use types::{OpenSslType, OpenSslTypeRef};
use util::Opaque;
#[cfg(ossl10x)] #[cfg(ossl10x)]
use ffi::{sk_pop as OPENSSL_sk_pop,sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num, use ffi::{sk_pop as OPENSSL_sk_pop,sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num,
@ -55,45 +57,49 @@ impl<T: Stackable> Drop for Stack<T> {
} }
} }
impl<T: Stackable> AsRef<Ref<Stack<T>>> for Stack<T> { impl<T: Stackable> AsRef<StackRef<T>> for Stack<T> {
fn as_ref(&self) -> &Ref<Stack<T>> { fn as_ref(&self) -> &StackRef<T> {
&*self &*self
} }
} }
impl<T: Stackable> Borrow<Ref<Stack<T>>> for Stack<T> { impl<T: Stackable> Borrow<StackRef<T>> for Stack<T> {
fn borrow(&self) -> &Ref<Stack<T>> { fn borrow(&self) -> &StackRef<T> {
&*self &*self
} }
} }
unsafe impl<T: Stackable> OpenSslType for Stack<T> { impl<T: Stackable> OpenSslType for Stack<T> {
type CType = T::StackType; type CType = T::StackType;
type Ref = StackRef<T>;
unsafe fn from_ptr(ptr: *mut T::StackType) -> Stack<T> { unsafe fn from_ptr(ptr: *mut T::StackType) -> Stack<T> {
Stack(ptr) Stack(ptr)
} }
fn as_ptr(&self) -> *mut T::StackType {
self.0
}
} }
impl<T: Stackable> Deref for Stack<T> { impl<T: Stackable> Deref for Stack<T> {
type Target = Ref<Stack<T>>; type Target = StackRef<T>;
fn deref(&self) -> &Ref<Stack<T>> { fn deref(&self) -> &StackRef<T> {
unsafe { Ref::from_ptr(self.0) } unsafe { StackRef::from_ptr(self.0) }
} }
} }
impl<T: Stackable> DerefMut for Stack<T> { impl<T: Stackable> DerefMut for Stack<T> {
fn deref_mut(&mut self) -> &mut ::types::Ref<Stack<T>> { fn deref_mut(&mut self) -> &mut StackRef<T> {
unsafe { Ref::from_ptr_mut(self.0) } unsafe { StackRef::from_ptr_mut(self.0) }
} }
} }
impl<T: Stackable> Ref<Stack<T>> { pub struct StackRef<T: Stackable>(Opaque, PhantomData<T>);
impl<T: Stackable> OpenSslTypeRef for StackRef<T> {
type CType = T::StackType;
}
impl<T: Stackable> StackRef<T> {
/// OpenSSL stack types are just a (kinda) typesafe wrapper around /// OpenSSL stack types are just a (kinda) typesafe wrapper around
/// a `_STACK` object. We can therefore safely cast it and access /// a `_STACK` object. We can therefore safely cast it and access
/// the `_STACK` members without having to worry about the real /// the `_STACK` members without having to worry about the real
@ -141,25 +147,25 @@ impl<T: Stackable> Ref<Stack<T>> {
/// Returns a reference to the element at the given index in the /// Returns a reference to the element at the given index in the
/// stack or `None` if the index is out of bounds /// stack or `None` if the index is out of bounds
pub fn get(&self, idx: usize) -> Option<&Ref<T>> { pub fn get(&self, idx: usize) -> Option<&T::Ref> {
unsafe { unsafe {
if idx >= self.len() { if idx >= self.len() {
return None; return None;
} }
Some(Ref::from_ptr(self._get(idx))) Some(T::Ref::from_ptr(self._get(idx)))
} }
} }
/// Returns a mutable reference to the element at the given index in the /// Returns a mutable reference to the element at the given index in the
/// stack or `None` if the index is out of bounds /// stack or `None` if the index is out of bounds
pub fn get_mut(&mut self, idx: usize) -> Option<&mut Ref<T>> { pub fn get_mut(&mut self, idx: usize) -> Option<&mut T::Ref> {
unsafe { unsafe {
if idx >= self.len() { if idx >= self.len() {
return None; return None;
} }
Some(Ref::from_ptr_mut(self._get(idx))) Some(T::Ref::from_ptr_mut(self._get(idx)))
} }
} }
@ -168,22 +174,22 @@ impl<T: Stackable> Ref<Stack<T>> {
} }
} }
impl<T: Stackable> Index<usize> for Ref<Stack<T>> { impl<T: Stackable> Index<usize> for StackRef<T> {
type Output = Ref<T>; type Output = T::Ref;
fn index(&self, index: usize) -> &Ref<T> { fn index(&self, index: usize) -> &T::Ref {
self.get(index).unwrap() self.get(index).unwrap()
} }
} }
impl<T: Stackable> IndexMut<usize> for Ref<Stack<T>> { impl<T: Stackable> IndexMut<usize> for StackRef<T> {
fn index_mut(&mut self, index: usize) -> &mut Ref<T> { fn index_mut(&mut self, index: usize) -> &mut T::Ref {
self.get_mut(index).unwrap() self.get_mut(index).unwrap()
} }
} }
impl<'a, T: Stackable> iter::IntoIterator for &'a Ref<Stack<T>> { impl<'a, T: Stackable> iter::IntoIterator for &'a StackRef<T> {
type Item = &'a Ref<T>; type Item = &'a T::Ref;
type IntoIter = Iter<'a, T>; type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> { fn into_iter(self) -> Iter<'a, T> {
@ -191,8 +197,8 @@ impl<'a, T: Stackable> iter::IntoIterator for &'a Ref<Stack<T>> {
} }
} }
impl<'a, T: Stackable> iter::IntoIterator for &'a mut Ref<Stack<T>> { impl<'a, T: Stackable> iter::IntoIterator for &'a mut StackRef<T> {
type Item = &'a mut Ref<T>; type Item = &'a mut T::Ref;
type IntoIter = IterMut<'a, T>; type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> IterMut<'a, T> { fn into_iter(self) -> IterMut<'a, T> {
@ -201,7 +207,7 @@ impl<'a, T: Stackable> iter::IntoIterator for &'a mut Ref<Stack<T>> {
} }
impl<'a, T: Stackable> iter::IntoIterator for &'a Stack<T> { impl<'a, T: Stackable> iter::IntoIterator for &'a Stack<T> {
type Item = &'a Ref<T>; type Item = &'a T::Ref;
type IntoIter = Iter<'a, T>; type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> { fn into_iter(self) -> Iter<'a, T> {
@ -210,7 +216,7 @@ impl<'a, T: Stackable> iter::IntoIterator for &'a Stack<T> {
} }
impl<'a, T: Stackable> iter::IntoIterator for &'a mut Stack<T> { impl<'a, T: Stackable> iter::IntoIterator for &'a mut Stack<T> {
type Item = &'a mut Ref<T>; type Item = &'a mut T::Ref;
type IntoIter = IterMut<'a, T>; type IntoIter = IterMut<'a, T>;
fn into_iter(self) -> IterMut<'a, T> { fn into_iter(self) -> IterMut<'a, T> {
@ -221,14 +227,14 @@ impl<'a, T: Stackable> iter::IntoIterator for &'a mut Stack<T> {
/// An iterator over the stack's contents. /// An iterator over the stack's contents.
pub struct Iter<'a, T: Stackable> pub struct Iter<'a, T: Stackable>
where T: 'a { where T: 'a {
stack: &'a Ref<Stack<T>>, stack: &'a StackRef<T>,
pos: usize, pos: usize,
} }
impl<'a, T: Stackable> iter::Iterator for Iter<'a, T> { impl<'a, T: Stackable> iter::Iterator for Iter<'a, T> {
type Item = &'a Ref<T>; type Item = &'a T::Ref;
fn next(&mut self) -> Option<&'a Ref<T>> { fn next(&mut self) -> Option<&'a T::Ref> {
let n = self.stack.get(self.pos); let n = self.stack.get(self.pos);
if n.is_some() { if n.is_some() {
@ -250,14 +256,14 @@ impl<'a, T: Stackable> iter::ExactSizeIterator for Iter<'a, T> {
/// A mutable iterator over the stack's contents. /// A mutable iterator over the stack's contents.
pub struct IterMut<'a, T: Stackable + 'a> { pub struct IterMut<'a, T: Stackable + 'a> {
stack: &'a mut Ref<Stack<T>>, stack: &'a mut StackRef<T>,
pos: usize, pos: usize,
} }
impl<'a, T: Stackable> iter::Iterator for IterMut<'a, T> { impl<'a, T: Stackable> iter::Iterator for IterMut<'a, T> {
type Item = &'a mut Ref<T>; type Item = &'a mut T::Ref;
fn next(&mut self) -> Option<&'a mut Ref<T>> { fn next(&mut self) -> Option<&'a mut T::Ref> {
if self.pos >= self.stack.len() { if self.pos >= self.stack.len() {
None None
} else { } else {
@ -267,7 +273,7 @@ impl<'a, T: Stackable> iter::Iterator for IterMut<'a, T> {
// the same object, so we have to use unsafe code for // the same object, so we have to use unsafe code for
// mutable iterators. // mutable iterators.
let n = unsafe { let n = unsafe {
Some(Ref::from_ptr_mut(self.stack._get(self.pos))) Some(T::Ref::from_ptr_mut(self.stack._get(self.pos)))
}; };
self.pos += 1; self.pos += 1;

View File

@ -1,39 +1,40 @@
//! Items used by other types. //! Items used by other types.
use std::cell::UnsafeCell;
use std::marker::PhantomData;
/// A type implemented by wrappers over OpenSSL types. /// 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 /// This should not be implemented by anything outside of this crate; new methods may be added at
/// any time. /// any time.
pub unsafe trait OpenSslType { pub trait OpenSslType: Sized {
/// The raw C type. /// The raw C type.
type CType; type CType;
/// The type representing a reference to this type.
type Ref: OpenSslTypeRef<CType = Self::CType>;
/// Constructs an instance of this type from its raw type. /// Constructs an instance of this type from its raw type.
unsafe fn from_ptr(ptr: *mut Self::CType) -> Self; 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. /// A trait implemented by types which reference borrowed OpenSSL types.
pub struct Ref<T>(UnsafeCell<()>, PhantomData<T>); ///
/// This should not be implemented by anything outside of this crate; new methods may be added at
/// any time.
pub trait OpenSslTypeRef: Sized {
/// The raw C type.
type CType;
impl<T: OpenSslType> Ref<T> { /// Constructs a shared instance of this type from its raw type.
/// Constructs a shared reference to this type from its raw type. unsafe fn from_ptr<'a>(ptr: *mut Self::CType) -> &'a Self {
pub unsafe fn from_ptr<'a>(ptr: *mut T::CType) -> &'a Ref<T> {
&*(ptr as *mut _) &*(ptr as *mut _)
} }
/// Constructs a mutable reference to this type from its raw type. /// Constructs a mutable reference of this type from its raw type.
pub unsafe fn from_ptr_mut<'a>(ptr: *mut T::CType) -> &'a mut Ref<T> { unsafe fn from_ptr_mut<'a>(ptr: *mut Self::CType) -> &'a mut Self {
&mut *(ptr as *mut _) &mut *(ptr as *mut _)
} }
/// Returns a pointer to its raw type. /// Returns a raw pointer to the wrapped value.
pub fn as_ptr(&self) -> *mut T::CType { fn as_ptr(&self) -> *mut Self::CType {
self as *const _ as *mut _ self as *const _ as *mut _
} }
} }

View File

@ -1,6 +1,6 @@
use libc::{c_int, c_char, c_void}; use libc::{c_int, c_char, c_void};
use std::any::Any; use std::any::Any;
use std::cell::UnsafeCell;
use std::panic::{self, AssertUnwindSafe}; use std::panic::{self, AssertUnwindSafe};
use std::slice; use std::slice;
@ -60,3 +60,8 @@ pub unsafe extern "C" fn invoke_passwd_cb<F>(buf: *mut c_char,
} }
} }
} }
/// This is intended to be used as the inner type for `FooRef` types 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<()>);

View File

@ -3,7 +3,7 @@ use ffi;
use cvt; use cvt;
use error::ErrorStack; use error::ErrorStack;
use types::Ref; use types::OpenSslTypeRef;
bitflags! { bitflags! {
pub flags X509CheckFlags: c_uint { pub flags X509CheckFlags: c_uint {
@ -19,9 +19,9 @@ bitflags! {
} }
} }
type_!(X509VerifyParam, ffi::X509_VERIFY_PARAM, ffi::X509_VERIFY_PARAM_free); type_!(X509VerifyParam, X509VerifyParamRef, ffi::X509_VERIFY_PARAM, ffi::X509_VERIFY_PARAM_free);
impl Ref<X509VerifyParam> { impl X509VerifyParamRef {
pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) { pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) {
unsafe { unsafe {
ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits); ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits);

View File

@ -11,16 +11,16 @@ use std::slice;
use std::str; use std::str;
use {cvt, cvt_p}; use {cvt, cvt_p};
use asn1::{Asn1String, Asn1Time}; use asn1::{Asn1StringRef, Asn1Time, Asn1TimeRef};
use bio::{MemBio, MemBioSlice}; use bio::{MemBio, MemBioSlice};
use hash::MessageDigest; use hash::MessageDigest;
use pkey::PKey; use pkey::{PKey, PKeyRef};
use rand::rand_bytes; use rand::rand_bytes;
use error::ErrorStack; use error::ErrorStack;
use ffi; use ffi;
use nid::Nid; use nid::Nid;
use types::{OpenSslType, Ref}; use types::{OpenSslType, OpenSslTypeRef};
use stack::{Stack, Stackable}; use stack::{Stack, StackRef, Stackable};
#[cfg(ossl10x)] #[cfg(ossl10x)]
use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data, X509_STORE_CTX_get_chain}; use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data, X509_STORE_CTX_get_chain};
@ -51,20 +51,20 @@ pub const X509_FILETYPE_PEM: X509FileType = X509FileType(ffi::X509_FILETYPE_PEM)
pub const X509_FILETYPE_ASN1: X509FileType = X509FileType(ffi::X509_FILETYPE_ASN1); pub const X509_FILETYPE_ASN1: X509FileType = X509FileType(ffi::X509_FILETYPE_ASN1);
pub const X509_FILETYPE_DEFAULT: X509FileType = X509FileType(ffi::X509_FILETYPE_DEFAULT); pub const X509_FILETYPE_DEFAULT: X509FileType = X509FileType(ffi::X509_FILETYPE_DEFAULT);
type_!(X509StoreContext, ffi::X509_STORE_CTX, ffi::X509_STORE_CTX_free); type_!(X509StoreContext, X509StoreContextRef, ffi::X509_STORE_CTX, ffi::X509_STORE_CTX_free);
impl Ref<X509StoreContext> { impl X509StoreContextRef {
pub fn error(&self) -> Option<X509VerifyError> { pub fn error(&self) -> Option<X509VerifyError> {
unsafe { X509VerifyError::from_raw(ffi::X509_STORE_CTX_get_error(self.as_ptr()) as c_long) } unsafe { X509VerifyError::from_raw(ffi::X509_STORE_CTX_get_error(self.as_ptr()) as c_long) }
} }
pub fn current_cert(&self) -> Option<&Ref<X509>> { pub fn current_cert(&self) -> Option<&X509Ref> {
unsafe { unsafe {
let ptr = ffi::X509_STORE_CTX_get_current_cert(self.as_ptr()); let ptr = ffi::X509_STORE_CTX_get_current_cert(self.as_ptr());
if ptr.is_null() { if ptr.is_null() {
None None
} else { } else {
Some(Ref::from_ptr(ptr)) Some(X509Ref::from_ptr(ptr))
} }
} }
} }
@ -73,7 +73,7 @@ impl Ref<X509StoreContext> {
unsafe { ffi::X509_STORE_CTX_get_error_depth(self.as_ptr()) as u32 } unsafe { ffi::X509_STORE_CTX_get_error_depth(self.as_ptr()) as u32 }
} }
pub fn chain(&self) -> Option<&Ref<Stack<X509>>> { pub fn chain(&self) -> Option<&StackRef<X509>> {
unsafe { unsafe {
let chain = X509_STORE_CTX_get_chain(self.as_ptr()); let chain = X509_STORE_CTX_get_chain(self.as_ptr());
@ -81,7 +81,7 @@ impl Ref<X509StoreContext> {
return None; return None;
} }
Some(Ref::from_ptr(chain)) Some(StackRef::from_ptr(chain))
} }
} }
} }
@ -275,7 +275,7 @@ impl X509Generator {
} }
/// Sets the certificate public-key, then self-sign and return it /// Sets the certificate public-key, then self-sign and return it
pub fn sign(&self, p_key: &Ref<PKey>) -> Result<X509, ErrorStack> { pub fn sign(&self, p_key: &PKeyRef) -> Result<X509, ErrorStack> {
ffi::init(); ffi::init();
unsafe { unsafe {
@ -327,7 +327,7 @@ impl X509Generator {
} }
/// Obtain a certificate signing request (CSR) /// Obtain a certificate signing request (CSR)
pub fn request(&self, p_key: &Ref<PKey>) -> Result<X509Req, ErrorStack> { pub fn request(&self, p_key: &PKeyRef) -> Result<X509Req, ErrorStack> {
let cert = match self.sign(p_key) { let cert = match self.sign(p_key) {
Ok(c) => c, Ok(c) => c,
Err(x) => return Err(x), Err(x) => return Err(x),
@ -352,13 +352,13 @@ impl X509Generator {
} }
} }
type_!(X509, ffi::X509, ffi::X509_free); type_!(X509, X509Ref, ffi::X509, ffi::X509_free);
impl Ref<X509> { impl X509Ref {
pub fn subject_name(&self) -> &Ref<X509Name> { pub fn subject_name(&self) -> &X509NameRef {
unsafe { unsafe {
let name = ffi::X509_get_subject_name(self.as_ptr()); let name = ffi::X509_get_subject_name(self.as_ptr());
Ref::from_ptr(name) X509NameRef::from_ptr(name)
} }
} }
@ -397,20 +397,20 @@ impl Ref<X509> {
} }
/// Returns certificate Not After validity period. /// Returns certificate Not After validity period.
pub fn not_after<'a>(&'a self) -> &'a Ref<Asn1Time> { pub fn not_after<'a>(&'a self) -> &'a Asn1TimeRef {
unsafe { unsafe {
let date = compat::X509_get_notAfter(self.as_ptr()); let date = compat::X509_get_notAfter(self.as_ptr());
assert!(!date.is_null()); assert!(!date.is_null());
Ref::from_ptr(date) Asn1TimeRef::from_ptr(date)
} }
} }
/// Returns certificate Not Before validity period. /// Returns certificate Not Before validity period.
pub fn not_before<'a>(&'a self) -> &'a Ref<Asn1Time> { pub fn not_before<'a>(&'a self) -> &'a Asn1TimeRef {
unsafe { unsafe {
let date = compat::X509_get_notBefore(self.as_ptr()); let date = compat::X509_get_notBefore(self.as_ptr());
assert!(!date.is_null()); assert!(!date.is_null());
Ref::from_ptr(date) Asn1TimeRef::from_ptr(date)
} }
} }
@ -433,7 +433,7 @@ impl Ref<X509> {
} }
} }
impl ToOwned for Ref<X509> { impl ToOwned for X509Ref {
type Owned = X509; type Owned = X509;
fn to_owned(&self) -> X509 { fn to_owned(&self) -> X509 {
@ -474,14 +474,14 @@ impl Clone for X509 {
} }
} }
impl AsRef<Ref<X509>> for X509 { impl AsRef<X509Ref> for X509 {
fn as_ref(&self) -> &Ref<X509> { fn as_ref(&self) -> &X509Ref {
&*self &*self
} }
} }
impl Borrow<Ref<X509>> for X509 { impl Borrow<X509Ref> for X509 {
fn borrow(&self) -> &Ref<X509> { fn borrow(&self) -> &X509Ref {
&*self &*self
} }
} }
@ -490,9 +490,9 @@ impl Stackable for X509 {
type StackType = ffi::stack_st_X509; type StackType = ffi::stack_st_X509;
} }
type_!(X509Name, ffi::X509_NAME, ffi::X509_NAME_free); type_!(X509Name, X509NameRef, ffi::X509_NAME, ffi::X509_NAME_free);
impl Ref<X509Name> { impl X509NameRef {
pub fn entries_by_nid<'a>(&'a self, nid: Nid) -> X509NameEntries<'a> { pub fn entries_by_nid<'a>(&'a self, nid: Nid) -> X509NameEntries<'a> {
X509NameEntries { X509NameEntries {
name: self, name: self,
@ -503,15 +503,15 @@ impl Ref<X509Name> {
} }
pub struct X509NameEntries<'a> { pub struct X509NameEntries<'a> {
name: &'a Ref<X509Name>, name: &'a X509NameRef,
nid: Nid, nid: Nid,
loc: c_int, loc: c_int,
} }
impl<'a> Iterator for X509NameEntries<'a> { impl<'a> Iterator for X509NameEntries<'a> {
type Item = &'a Ref<X509NameEntry>; type Item = &'a X509NameEntryRef;
fn next(&mut self) -> Option<&'a Ref<X509NameEntry>> { fn next(&mut self) -> Option<&'a X509NameEntryRef> {
unsafe { unsafe {
self.loc = ffi::X509_NAME_get_index_by_NID(self.name.as_ptr(), self.loc = ffi::X509_NAME_get_index_by_NID(self.name.as_ptr(),
self.nid.as_raw(), self.nid.as_raw(),
@ -524,25 +524,25 @@ impl<'a> Iterator for X509NameEntries<'a> {
let entry = ffi::X509_NAME_get_entry(self.name.as_ptr(), self.loc); let entry = ffi::X509_NAME_get_entry(self.name.as_ptr(), self.loc);
assert!(!entry.is_null()); assert!(!entry.is_null());
Some(Ref::from_ptr(entry)) Some(X509NameEntryRef::from_ptr(entry))
} }
} }
} }
type_!(X509NameEntry, ffi::X509_NAME_ENTRY, ffi::X509_NAME_ENTRY_free); type_!(X509NameEntry, X509NameEntryRef, ffi::X509_NAME_ENTRY, ffi::X509_NAME_ENTRY_free);
impl Ref<X509NameEntry> { impl X509NameEntryRef {
pub fn data(&self) -> &Ref<Asn1String> { pub fn data(&self) -> &Asn1StringRef {
unsafe { unsafe {
let data = ffi::X509_NAME_ENTRY_get_data(self.as_ptr()); let data = ffi::X509_NAME_ENTRY_get_data(self.as_ptr());
Ref::from_ptr(data) Asn1StringRef::from_ptr(data)
} }
} }
} }
type_!(X509Req, ffi::X509_REQ, ffi::X509_REQ_free); type_!(X509Req, X509ReqRef, ffi::X509_REQ, ffi::X509_REQ_free);
impl Ref<X509Req> { impl X509ReqRef {
/// Writes CSR as PEM /// Writes CSR as PEM
pub fn to_pem(&self) -> Result<Vec<u8>, ErrorStack> { pub fn to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
let mem_bio = try!(MemBio::new()); let mem_bio = try!(MemBio::new());
@ -699,9 +699,9 @@ impl X509VerifyError {
} }
} }
type_!(GeneralName, ffi::GENERAL_NAME, ffi::GENERAL_NAME_free); type_!(GeneralName, GeneralNameRef, ffi::GENERAL_NAME, ffi::GENERAL_NAME_free);
impl Ref<GeneralName> { impl GeneralNameRef {
/// Returns the contents of this `GeneralName` if it is a `dNSName`. /// Returns the contents of this `GeneralName` if it is a `dNSName`.
pub fn dnsname(&self) -> Option<&str> { pub fn dnsname(&self) -> Option<&str> {
unsafe { unsafe {