Merge pull request #507 from sfackler/ref

Add a unified Ref type
This commit is contained in:
Steven Fackler 2016-10-31 21:23:36 -07:00 committed by GitHub
commit 50d8cca640
18 changed files with 335 additions and 688 deletions

View File

@ -1658,12 +1658,14 @@ extern {
pub fn X509_EXTENSION_free(ext: *mut X509_EXTENSION); pub fn X509_EXTENSION_free(ext: *mut X509_EXTENSION);
pub fn X509_NAME_free(x: *mut X509_NAME);
pub fn X509_NAME_add_entry_by_txt(x: *mut X509_NAME, field: *const c_char, ty: c_int, bytes: *const c_uchar, len: c_int, loc: c_int, set: c_int) -> c_int; pub fn X509_NAME_add_entry_by_txt(x: *mut X509_NAME, field: *const c_char, ty: c_int, bytes: *const c_uchar, len: c_int, loc: c_int, set: c_int) -> c_int;
pub fn X509_NAME_get_index_by_NID(n: *mut X509_NAME, nid: c_int, last_pos: c_int) ->c_int; pub fn X509_NAME_get_index_by_NID(n: *mut X509_NAME, nid: c_int, last_pos: c_int) ->c_int;
pub fn ASN1_STRING_length(x: *const ASN1_STRING) -> c_int; pub fn ASN1_STRING_length(x: *const ASN1_STRING) -> c_int;
pub fn X509_STORE_CTX_get_current_cert(ct: *mut X509_STORE_CTX) -> *mut X509; pub fn X509_STORE_CTX_free(ctx: *mut X509_STORE_CTX);
pub fn X509_STORE_CTX_get_current_cert(ctx: *mut X509_STORE_CTX) -> *mut X509;
pub fn X509_STORE_CTX_get_error(ctx: *mut X509_STORE_CTX) -> c_int; pub fn X509_STORE_CTX_get_error(ctx: *mut X509_STORE_CTX) -> c_int;
pub fn X509_STORE_CTX_get_ex_data(ctx: *mut X509_STORE_CTX, idx: c_int) -> *mut c_void; pub fn X509_STORE_CTX_get_ex_data(ctx: *mut X509_STORE_CTX, idx: c_int) -> *mut c_void;
pub fn X509_STORE_CTX_get_error_depth(ctx: *mut X509_STORE_CTX) -> c_int; pub fn X509_STORE_CTX_get_error_depth(ctx: *mut X509_STORE_CTX) -> c_int;
@ -1675,6 +1677,8 @@ extern {
pub fn X509_REQ_add_extensions(req: *mut X509_REQ, exts: *mut stack_st_X509_EXTENSION) -> c_int; pub fn X509_REQ_add_extensions(req: *mut X509_REQ, exts: *mut stack_st_X509_EXTENSION) -> c_int;
pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int; pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int;
#[cfg(not(ossl101))]
pub fn X509_VERIFY_PARAM_free(param: *mut X509_VERIFY_PARAM);
#[cfg(not(ossl101))] #[cfg(not(ossl101))]
pub fn X509_VERIFY_PARAM_set_hostflags(param: *mut X509_VERIFY_PARAM, flags: c_uint); pub fn X509_VERIFY_PARAM_set_hostflags(param: *mut X509_VERIFY_PARAM, flags: c_uint);
#[cfg(not(ossl101))] #[cfg(not(ossl101))]

View File

@ -1,30 +1,15 @@
use libc::c_long; use libc::c_long;
use std::{ptr, fmt}; use std::{ptr, fmt};
use std::ops::Deref;
use ffi; use ffi;
use opaque::Opaque;
use {cvt, cvt_p}; use {cvt, cvt_p};
use bio::MemBio; use bio::MemBio;
use error::ErrorStack; use error::ErrorStack;
use types::{OpenSslType, Ref};
/// A borrowed Asn1Time type_!(Asn1Time, ffi::ASN1_TIME, ffi::ASN1_TIME_free);
pub struct Asn1TimeRef(Opaque);
impl Asn1TimeRef { impl fmt::Display for Ref<Asn1Time> {
/// Creates a new `Asn1TimeRef` wrapping the provided handle.
pub unsafe fn from_ptr<'a>(handle: *mut ffi::ASN1_TIME) -> &'a Asn1TimeRef {
&*(handle as *mut _)
}
/// Returns the raw handle
pub fn as_ptr(&self) -> *mut ffi::ASN1_TIME {
self as *const _ as *mut _
}
}
impl fmt::Display for Asn1TimeRef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mem_bio = try!(MemBio::new()); let mem_bio = try!(MemBio::new());
let as_str = unsafe { 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 { 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> { fn from_period(period: c_long) -> Result<Asn1Time, ErrorStack> {
ffi::init(); ffi::init();
@ -59,17 +35,3 @@ impl Asn1Time {
Asn1Time::from_period(days as c_long * 60 * 60 * 24) 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()) };
}
}

View File

@ -3,12 +3,12 @@ use libc::c_int;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::ffi::CString; use std::ffi::CString;
use std::{fmt, ptr}; 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 {cvt, cvt_p, cvt_n};
use crypto::CryptoString; use crypto::CryptoString;
use error::ErrorStack; use error::ErrorStack;
use opaque::Opaque; use types::{Ref, OpenSslType};
/// Specifies the desired properties of a randomly generated `BigNum`. /// Specifies the desired properties of a randomly generated `BigNum`.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@ -23,16 +23,7 @@ pub enum RNGProperty {
TwoMsbOne = 1, TwoMsbOne = 1,
} }
/// A context object for `BigNum` operations. type_!(BnCtx, ffi::BN_CTX, ffi::BN_CTX_free);
pub struct BnCtx(*mut ffi::BN_CTX);
impl Drop for BnCtx {
fn drop(&mut self) {
unsafe {
ffi::BN_CTX_free(self.0);
}
}
}
impl BnCtx { impl BnCtx {
/// Returns a new `BnCtx`. /// Returns a new `BnCtx`.
@ -40,25 +31,21 @@ impl BnCtx {
unsafe { cvt_p(ffi::BN_CTX_new()).map(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`. /// Places the result of `a * b` in `r`.
pub fn mul(&mut self, pub fn mul(&mut self,
r: &mut BigNumRef, r: &mut Ref<BigNum>,
a: &BigNumRef, a: &Ref<BigNum>,
b: &BigNumRef) b: &Ref<BigNum>)
-> 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 BigNumRef>, dv: Option<&mut Ref<BigNum>>,
rem: Option<&mut BigNumRef>, rem: Option<&mut Ref<BigNum>>,
a: &BigNumRef, a: &Ref<BigNum>,
b: &BigNumRef) b: &Ref<BigNum>)
-> 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()),
@ -71,25 +58,25 @@ impl BnCtx {
} }
/// Places the result of `a²` in `r`. /// 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(|_| ()) } 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 BigNumRef, r: &mut Ref<BigNum>,
a: &BigNumRef, a: &Ref<BigNum>,
m: &BigNumRef) m: &Ref<BigNum>)
-> 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 BigNumRef, r: &mut Ref<BigNum>,
a: &BigNumRef, a: &Ref<BigNum>,
b: &BigNumRef, b: &Ref<BigNum>,
m: &BigNumRef) m: &Ref<BigNum>)
-> 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(|_| ())
@ -98,10 +85,10 @@ impl BnCtx {
/// 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 BigNumRef, r: &mut Ref<BigNum>,
a: &BigNumRef, a: &Ref<BigNum>,
b: &BigNumRef, b: &Ref<BigNum>,
m: &BigNumRef) m: &Ref<BigNum>)
-> 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(|_| ())
@ -110,10 +97,10 @@ impl BnCtx {
/// 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 BigNumRef, r: &mut Ref<BigNum>,
a: &BigNumRef, a: &Ref<BigNum>,
b: &BigNumRef, b: &Ref<BigNum>,
m: &BigNumRef) m: &Ref<BigNum>)
-> 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(|_| ())
@ -122,28 +109,28 @@ impl BnCtx {
/// 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 BigNumRef, r: &mut Ref<BigNum>,
a: &BigNumRef, a: &Ref<BigNum>,
m: &BigNumRef) m: &Ref<BigNum>)
-> 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 BigNumRef, r: &mut Ref<BigNum>,
a: &BigNumRef, a: &Ref<BigNum>,
p: &BigNumRef) p: &Ref<BigNum>)
-> 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 BigNumRef, r: &mut Ref<BigNum>,
a: &BigNumRef, a: &Ref<BigNum>,
p: &BigNumRef, p: &Ref<BigNum>,
m: &BigNumRef) m: &Ref<BigNum>)
-> 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(|_| ())
@ -152,9 +139,9 @@ impl BnCtx {
/// 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 BigNumRef, r: &mut Ref<BigNum>,
a: &BigNumRef, a: &Ref<BigNum>,
n: &BigNumRef) n: &Ref<BigNum>)
-> 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()))
@ -164,9 +151,9 @@ impl BnCtx {
/// 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 BigNumRef, r: &mut Ref<BigNum>,
a: &BigNumRef, a: &Ref<BigNum>,
b: &BigNumRef) b: &Ref<BigNum>)
-> 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(|_| ()) }
} }
@ -176,7 +163,7 @@ impl BnCtx {
/// 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: &BigNumRef, checks: i32) -> Result<bool, ErrorStack> { pub fn is_prime(&mut self, p: &Ref<BigNum>, 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)
@ -193,7 +180,7 @@ impl BnCtx {
/// ///
/// 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: &BigNumRef, p: &Ref<BigNum>,
checks: i32, checks: i32,
do_trial_division: bool) do_trial_division: bool)
-> Result<bool, ErrorStack> { -> Result<bool, ErrorStack> {
@ -214,7 +201,7 @@ impl BnCtx {
/// * `bits`: Length of the number in bits. /// * `bits`: Length of the number in bits.
/// * `prop`: The desired properties of the number. /// * `prop`: The desired properties of the number.
/// * `odd`: If `true`, the generated number will be odd. /// * `odd`: If `true`, the generated number will be odd.
pub fn rand(r: &mut BigNumRef, pub fn rand(r: &mut Ref<BigNum>,
bits: i32, bits: i32,
prop: RNGProperty, prop: RNGProperty,
odd: bool) odd: bool)
@ -225,7 +212,7 @@ impl BnCtx {
} }
/// The cryptographically weak counterpart to `checked_new_random`. /// 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, bits: i32,
prop: RNGProperty, prop: RNGProperty,
odd: bool) odd: bool)
@ -237,22 +224,7 @@ impl BnCtx {
} }
} }
/// A borrowed, signed, arbitrary-precision integer. impl Ref<BigNum> {
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 _
}
/// Adds a `u32` to `self`. /// Adds a `u32` to `self`.
pub fn add_word(&mut self, w: u32) -> Result<(), ErrorStack> { 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(|_| ()) } 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 /// 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 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(|_| ()) } 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 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(|_| ()) } 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`. /// 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(|_| ()) } 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 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(|_| ()) } 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 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(|_| ()) } 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 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(|_| ()) } 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 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(|_| ()) } 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 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(|_| ()) } 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); /// 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) } unsafe { ffi::BN_ucmp(self.as_ptr(), oth.as_ptr()).cmp(&0) }
} }
@ -459,13 +431,7 @@ impl BigNumRef {
} }
} }
/// An owned, signed, arbitrary-precision integer. type_!(BigNum, ffi::BIGNUM, ffi::BN_clear_free);
///
/// `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);
impl BigNum { impl BigNum {
/// Creates a new `BigNum` with the value 0. /// 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. /// 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. /// * `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 /// * `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`). /// 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, bits: i32,
safe: bool, safe: bool,
add: Option<&BigNumRef>, add: Option<&Ref<BigNum>>,
rem: Option<&BigNumRef>) rem: Option<&Ref<BigNum>>)
-> Result<(), ErrorStack> { -> Result<(), ErrorStack> {
unsafe { unsafe {
cvt(ffi::BN_generate_prime_ex(r.as_ptr(), cvt(ffi::BN_generate_prime_ex(r.as_ptr(),
@ -550,35 +512,13 @@ impl BigNum {
} }
} }
impl Drop for BigNum { impl AsRef<Ref<BigNum>> for BigNum {
fn drop(&mut self) { fn as_ref(&self) -> &Ref<BigNum> {
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 {
self.deref() self.deref()
} }
} }
impl fmt::Debug for BigNumRef { impl fmt::Debug for Ref<BigNum> {
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),
@ -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 { 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),
@ -614,19 +554,19 @@ impl fmt::Display for BigNum {
} }
} }
impl PartialEq<BigNumRef> for BigNumRef { impl PartialEq<Ref<BigNum>> for Ref<BigNum> {
fn eq(&self, oth: &BigNumRef) -> bool { fn eq(&self, oth: &Ref<BigNum>) -> bool {
self.cmp(oth) == Ordering::Equal self.cmp(oth) == Ordering::Equal
} }
} }
impl PartialEq<BigNum> for BigNumRef { impl PartialEq<BigNum> for Ref<BigNum> {
fn eq(&self, oth: &BigNum) -> bool { fn eq(&self, oth: &BigNum) -> bool {
self.eq(oth.deref()) self.eq(oth.deref())
} }
} }
impl Eq for BigNumRef {} impl Eq for Ref<BigNum> {}
impl PartialEq for BigNum { impl PartialEq for BigNum {
fn eq(&self, oth: &BigNum) -> bool { fn eq(&self, oth: &BigNum) -> bool {
@ -634,28 +574,28 @@ impl PartialEq for BigNum {
} }
} }
impl PartialEq<BigNumRef> for BigNum { impl PartialEq<Ref<BigNum>> for BigNum {
fn eq(&self, oth: &BigNumRef) -> bool { fn eq(&self, oth: &Ref<BigNum>) -> bool {
self.deref().eq(oth) self.deref().eq(oth)
} }
} }
impl Eq for BigNum {} impl Eq for BigNum {}
impl PartialOrd<BigNumRef> for BigNumRef { impl PartialOrd<Ref<BigNum>> for Ref<BigNum> {
fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> { fn partial_cmp(&self, oth: &Ref<BigNum>) -> Option<Ordering> {
Some(self.cmp(oth)) Some(self.cmp(oth))
} }
} }
impl PartialOrd<BigNum> for BigNumRef { impl PartialOrd<BigNum> for Ref<BigNum> {
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 BigNumRef { impl Ord for Ref<BigNum> {
fn cmp(&self, oth: &BigNumRef) -> Ordering { fn cmp(&self, oth: &Ref<BigNum>) -> 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) }
} }
} }
@ -666,8 +606,8 @@ impl PartialOrd for BigNum {
} }
} }
impl PartialOrd<BigNumRef> for BigNum { impl PartialOrd<Ref<BigNum>> for BigNum {
fn partial_cmp(&self, oth: &BigNumRef) -> Option<Ordering> { fn partial_cmp(&self, oth: &Ref<BigNum>) -> Option<Ordering> {
self.deref().partial_cmp(oth) self.deref().partial_cmp(oth)
} }
} }
@ -680,7 +620,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 BigNumRef { impl<'a, 'b> $t<&'b BigNum> for &'a Ref<BigNum> {
type Output = BigNum; type Output = BigNum;
fn $m(self, oth: &BigNum) -> 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; type Output = BigNum;
fn $m(self, oth: &BigNumRef) -> BigNum { fn $m(self, oth: &Ref<BigNum>) -> BigNum {
$t::$m(self.deref(), oth) $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; type Output = BigNum;
fn add(self, oth: &BigNumRef) -> BigNum { fn add(self, oth: &Ref<BigNum>) -> 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
@ -718,10 +658,10 @@ impl<'a, 'b> Add<&'b BigNumRef> for &'a BigNumRef {
delegate!(Add, add); 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; type Output = BigNum;
fn sub(self, oth: &BigNumRef) -> BigNum { fn sub(self, oth: &Ref<BigNum>) -> 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
@ -730,10 +670,10 @@ impl<'a, 'b> Sub<&'b BigNumRef> for &'a BigNumRef {
delegate!(Sub, sub); 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; type Output = BigNum;
fn mul(self, oth: &BigNumRef) -> BigNum { fn mul(self, oth: &Ref<BigNum>) -> BigNum {
let mut ctx = BnCtx::new().unwrap(); let mut ctx = BnCtx::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();
@ -743,10 +683,10 @@ impl<'a, 'b> Mul<&'b BigNumRef> for &'a BigNumRef {
delegate!(Mul, mul); 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; 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 ctx = BnCtx::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();
@ -756,10 +696,10 @@ impl<'a, 'b> Div<&'b BigNumRef> for &'a BigNumRef {
delegate!(Div, div); 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; 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 ctx = BnCtx::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();
@ -769,7 +709,7 @@ impl<'a, 'b> Rem<&'b BigNumRef> for &'a BigNumRef {
delegate!(Rem, rem); delegate!(Rem, rem);
impl<'a> Shl<i32> for &'a BigNumRef { impl<'a> Shl<i32> for &'a Ref<BigNum> {
type Output = BigNum; type Output = BigNum;
fn shl(self, n: i32) -> 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; type Output = BigNum;
fn shr(self, n: i32) -> 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; type Output = BigNum;
fn neg(self) -> BigNum { fn neg(self) -> BigNum {

View File

@ -3,25 +3,12 @@ use error::ErrorStack;
use bio::MemBioSlice; use bio::MemBioSlice;
use std::ptr; use std::ptr;
use std::mem; use std::mem;
use std::ops::Deref;
use {cvt, cvt_p}; use {cvt, cvt_p};
use bn::BigNum; use bn::BigNum;
use opaque::Opaque; use types::OpenSslType;
pub struct DhRef(Opaque); type_!(Dh, ffi::DH, ffi::DH_free);
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);
impl Dh { impl Dh {
pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<Dh, ErrorStack> { 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)] #[cfg(ossl110)]
mod compat { mod compat {
pub use ffi::DH_set0_pqg; pub use ffi::DH_set0_pqg;

View File

@ -2,26 +2,17 @@ use error::ErrorStack;
use ffi; use ffi;
use libc::{c_int, c_char, c_void}; use libc::{c_int, c_char, c_void};
use std::fmt; use std::fmt;
use std::ops::Deref;
use std::ptr; use std::ptr;
use {cvt, cvt_p};
use bn::BigNumRef;
use bio::{MemBio, MemBioSlice}; use bio::{MemBio, MemBioSlice};
use bn::BigNum;
use {cvt, cvt_p};
use types::Ref;
use util::{CallbackState, invoke_passwd_cb}; use util::{CallbackState, invoke_passwd_cb};
use opaque::Opaque;
pub struct DsaRef(Opaque); type_!(Dsa, ffi::DSA, ffi::DSA_free);
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 _
}
impl Ref<Dsa> {
/// 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());
@ -53,35 +44,35 @@ impl DsaRef {
} }
} }
pub fn p(&self) -> Option<&BigNumRef> { pub fn p(&self) -> Option<&Ref<BigNum>> {
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(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 { 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(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 { 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(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 { impl Dsa {
pub unsafe fn from_ptr(dsa: *mut ffi::DSA) -> Dsa {
Dsa(dsa)
}
/// Generate a DSA key pair. /// Generate a DSA key pair.
pub fn generate(bits: u32) -> Result<Dsa, ErrorStack> { pub fn generate(bits: u32) -> Result<Dsa, ErrorStack> {
unsafe { unsafe {
@ -121,7 +98,7 @@ impl Dsa {
ptr::null_mut(), ptr::null_mut(),
ptr::null_mut(), 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) Ok(dsa)
} }
} }
@ -177,11 +154,9 @@ impl Dsa {
} }
} }
impl Deref for Dsa { impl fmt::Debug for Dsa {
type Target = DsaRef; fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "DSA")
fn deref(&self) -> &DsaRef {
unsafe { DsaRef::from_ptr(self.0) }
} }
} }
@ -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)] #[cfg(test)]
mod test { mod test {
use libc::c_char; use libc::c_char;

View File

@ -1,49 +1,15 @@
use ffi; use ffi;
use std::ops::Deref;
use cvt_p; use cvt_p;
use error::ErrorStack; use error::ErrorStack;
use nid::Nid; use nid::Nid;
use opaque::Opaque;
pub struct EcKeyRef(Opaque); type_!(EcKey, ffi::EC_KEY, ffi::EC_KEY_free);
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);
}
}
}
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> {
unsafe { cvt_p(ffi::EC_KEY_new_by_curve_name(nid.as_raw())).map(EcKey) } 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)] #[cfg(test)]

View File

@ -20,8 +20,45 @@ use libc::c_int;
use error::ErrorStack; 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 bio;
mod opaque;
mod util; mod util;
pub mod asn1; pub mod asn1;
pub mod bn; pub mod bn;
@ -37,6 +74,7 @@ pub mod pkcs12;
pub mod pkcs5; pub mod pkcs5;
pub mod pkey; pub mod pkey;
pub mod rand; pub mod rand;
pub mod types;
pub mod rsa; pub mod rsa;
pub mod sign; pub mod sign;
pub mod ssl; pub mod ssl;

View File

@ -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<()>);

View File

@ -10,6 +10,7 @@ use {cvt, cvt_p};
use pkey::PKey; use pkey::PKey;
use error::ErrorStack; use error::ErrorStack;
use x509::X509; use x509::X509;
use types::OpenSslType;
/// A PKCS #12 archive. /// A PKCS #12 archive.
pub struct Pkcs12(*mut ffi::PKCS12); pub struct Pkcs12(*mut ffi::PKCS12);

View File

@ -1,29 +1,19 @@
use libc::{c_void, c_char, c_int}; use libc::{c_void, c_char, c_int};
use std::ptr; use std::ptr;
use std::mem; use std::mem;
use std::ops::Deref;
use ffi; 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, RsaRef}; use rsa::Rsa;
use error::ErrorStack; use error::ErrorStack;
use util::{CallbackState, invoke_passwd_cb}; use util::{CallbackState, invoke_passwd_cb};
use opaque::Opaque; use types::{OpenSslType, Ref};
/// A borrowed `PKey`. type_!(PKey, ffi::EVP_PKEY, ffi::EVP_PKEY_free);
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 _
}
impl Ref<PKey> {
/// 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 {
@ -59,14 +49,11 @@ impl PKeyRef {
Ok(mem_bio.get_buf().to_owned()) 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 } 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 Send for PKey {}
unsafe impl Sync 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 /// Reads private key from PEM, takes ownership of handle
pub fn private_key_from_pem(buf: &[u8]) -> Result<PKey, ErrorStack> { pub fn private_key_from_pem(buf: &[u8]) -> Result<PKey, ErrorStack> {
ffi::init(); ffi::init();
@ -156,7 +139,7 @@ impl PKey {
} }
/// Assign an RSA key to this 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 { 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();
@ -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)] #[cfg(test)]
mod tests { mod tests {
#[test] #[test]

View File

@ -2,15 +2,14 @@ use ffi;
use std::fmt; use std::fmt;
use std::ptr; use std::ptr;
use std::mem; use std::mem;
use std::ops::Deref;
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, BigNumRef}; use bn::BigNum;
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 opaque::Opaque; use types::{OpenSslType, Ref};
/// Type of encryption padding to use. /// Type of encryption padding to use.
#[derive(Copy, Clone)] #[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_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);
pub struct RsaRef(Opaque); type_!(Rsa, ffi::RSA, ffi::RSA_free);
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 _
}
impl Ref<Rsa> {
/// 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());
@ -162,72 +153,62 @@ impl RsaRef {
} }
} }
pub fn n(&self) -> Option<&BigNumRef> { pub fn n(&self) -> Option<&Ref<BigNum>> {
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(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 { 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(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 { 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(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 { 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(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 { 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(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 { impl Rsa {
/// only useful for associating the key material directly with the key, it's safer to use /// 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. /// 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. /// Generates a public/private key pair with the specified size.
/// ///
/// The public exponent will be 65537. /// 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)] #[cfg(ossl110)]
mod compat { mod compat {
use std::ptr; use std::ptr;

View File

@ -63,13 +63,14 @@ use {cvt, cvt_p};
use hash::MessageDigest; use hash::MessageDigest;
use pkey::PKey; use pkey::PKey;
use error::ErrorStack; use error::ErrorStack;
use types::Ref;
#[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 PKey>); pub struct Signer<'a>(*mut ffi::EVP_MD_CTX, PhantomData<&'a Ref<PKey>>);
impl<'a> Drop for Signer<'a> { impl<'a> Drop for Signer<'a> {
fn drop(&mut self) { fn drop(&mut self) {
@ -80,7 +81,7 @@ impl<'a> Drop for Signer<'a> {
} }
impl<'a> 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 { unsafe {
ffi::init(); 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> { impl<'a> Drop for Verifier<'a> {
fn drop(&mut self) { fn drop(&mut self) {
@ -139,7 +140,7 @@ impl<'a> Drop for Verifier<'a> {
} }
impl<'a> 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 { unsafe {
ffi::init(); ffi::init();

View File

@ -4,8 +4,9 @@ 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::PKeyRef; use pkey::PKey;
use x509::X509Ref; use x509::X509;
use types::Ref;
// apps/dh2048.pem // apps/dh2048.pem
const DHPARAM_PEM: &'static str = r#" const DHPARAM_PEM: &'static str = r#"
@ -116,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: &PKeyRef, private_key: &Ref<PKey>,
certificate: &X509Ref, certificate: &Ref<X509>,
chain: I) chain: I)
-> Result<SslAcceptorBuilder, ErrorStack> -> Result<SslAcceptorBuilder, ErrorStack>
where I: IntoIterator, where I: IntoIterator,
I::Item: AsRef<X509Ref> I::Item: AsRef<Ref<X509>>
{ {
let mut ctx = try!(ctx(method)); let mut ctx = try!(ctx(method));
let dh = try!(Dh::from_pem(DHPARAM_PEM.as_bytes())); 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 /// [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: &PKeyRef, private_key: &Ref<PKey>,
certificate: &X509Ref, certificate: &Ref<X509>,
chain: I) chain: I)
-> Result<SslAcceptorBuilder, ErrorStack> -> Result<SslAcceptorBuilder, ErrorStack>
where I: IntoIterator, where I: IntoIterator,
I::Item: AsRef<X509Ref> I::Item: AsRef<Ref<X509>>
{ {
let mut ctx = try!(ctx(method)); let mut ctx = try!(ctx(method));
try!(setup_curves(&mut ctx)); try!(setup_curves(&mut ctx));
@ -169,12 +170,12 @@ impl SslAcceptorBuilder {
} }
fn finish_setup<I>(mut ctx: SslContextBuilder, fn finish_setup<I>(mut ctx: SslContextBuilder,
private_key: &PKeyRef, private_key: &Ref<PKey>,
certificate: &X509Ref, certificate: &Ref<X509>,
chain: I) chain: I)
-> Result<SslAcceptorBuilder, ErrorStack> -> Result<SslAcceptorBuilder, ErrorStack>
where I: IntoIterator, where I: IntoIterator,
I::Item: AsRef<X509Ref> I::Item: AsRef<Ref<X509>>
{ {
try!(ctx.set_private_key(private_key)); try!(ctx.set_private_key(private_key));
try!(ctx.set_certificate(certificate)); try!(ctx.set_certificate(certificate));
@ -254,11 +255,12 @@ mod verify {
use std::net::IpAddr; use std::net::IpAddr;
use nid; use nid;
use x509::{X509StoreContextRef, X509Ref, GeneralNames, X509NameRef}; use x509::{X509StoreContext, X509, GeneralNames, X509Name};
use types::Ref;
pub fn verify_callback(domain: &str, pub fn verify_callback(domain: &str,
preverify_ok: bool, preverify_ok: bool,
x509_ctx: &X509StoreContextRef) x509_ctx: &Ref<X509StoreContext>)
-> bool { -> bool {
if !preverify_ok || x509_ctx.error_depth() != 0 { if !preverify_ok || x509_ctx.error_depth() != 0 {
return preverify_ok; 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() { 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()),
@ -302,7 +304,7 @@ mod verify {
false 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) { if let Some(pattern) = subject_name.text_by_nid(nid::COMMONNAME) {
// Unlike with SANs, IP addresses in the subject name don't have a // 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 // different encoding. We need to pass this down to matches_dns to

View File

@ -80,7 +80,6 @@ use std::fmt;
use std::io; use std::io;
use std::io::prelude::*; use std::io::prelude::*;
use std::mem; use std::mem;
use std::ops::{Deref, DerefMut};
use std::path::Path; use std::path::Path;
use std::ptr; use std::ptr;
use std::str; use std::str;
@ -91,14 +90,14 @@ use std::marker::PhantomData;
use ffi; use ffi;
use {init, cvt, cvt_p}; use {init, cvt, cvt_p};
use dh::DhRef; use dh::Dh;
use ec_key::EcKeyRef; use ec_key::EcKey;
use x509::{X509StoreContextRef, X509FileType, X509, X509Ref, X509VerifyError}; use x509::{X509StoreContext, X509FileType, X509, X509VerifyError};
#[cfg(any(ossl102, ossl110))] #[cfg(any(ossl102, ossl110))]
use verify::X509VerifyParamRef; use verify::X509VerifyParam;
use pkey::PKeyRef; use pkey::PKey;
use error::ErrorStack; use error::ErrorStack;
use opaque::Opaque; use types::{OpenSslType, Ref};
mod error; mod error;
mod connector; 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 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 { unsafe {
let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx(); 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 = 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 = X509StoreContextRef::from_ptr(x509_ctx); let ctx = Ref::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, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send where F: Fn(bool, &Ref<X509StoreContext>) -> 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();
@ -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 = 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 = X509StoreContextRef::from_ptr(x509_ctx); let ctx = Ref::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 SslRef) -> Result<(), SniError> + Any + 'static + Sync + Send where F: Fn(&mut Ref<Ssl>) -> 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 = SslRef::from_ptr_mut(ssl); let ssl = Ref::from_ptr_mut(ssl);
match callback(ssl) { match callback(ssl) {
Ok(()) => ffi::SSL_TLSEXT_ERR_OK, Ok(()) => ffi::SSL_TLSEXT_ERR_OK,
@ -464,7 +463,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, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send
{ {
unsafe { unsafe {
let verify = Box::new(verify); let verify = Box::new(verify);
@ -480,7 +479,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 SslRef) -> Result<(), SniError> + Any + 'static + Sync + Send where F: Fn(&mut Ref<Ssl>) -> Result<(), SniError> + Any + 'static + Sync + Send
{ {
unsafe { unsafe {
let callback = Box::new(callback); 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(|_| ()) } 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(|_| ()) } 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 /// 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(|_| ()) } unsafe { cvt(ffi::SSL_CTX_use_certificate(self.as_ptr(), cert.as_ptr())).map(|_| ()) }
} }
@ -614,7 +613,7 @@ impl SslContextBuilder {
} }
/// Specifies the private key /// 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(|_| ()) } 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. type_!(SslContext, ffi::SSL_CTX, ffi::SSL_CTX_free);
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);
unsafe impl Send for SslContext {} unsafe impl Send for SslContext {}
unsafe impl Sync 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 { impl SslContext {
pub fn builder(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> { pub fn builder(method: SslMethod) -> Result<SslContextBuilder, ErrorStack> {
SslContextBuilder::new(method) 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 algorithm: i32,
} }
pub struct SslCipherRef(Opaque); pub struct SslCipher(*mut ffi::SSL_CIPHER);
impl SslCipherRef { unsafe impl OpenSslType for SslCipher {
pub unsafe fn from_ptr<'a>(ptr: *const ffi::SSL_CIPHER) -> &'a SslCipherRef { type CType = ffi::SSL_CIPHER;
&*(ptr as *const _)
unsafe fn from_ptr(ptr: *mut ffi::SSL_CIPHER) -> SslCipher {
SslCipher(ptr)
} }
pub fn as_ptr(&self) -> *const ffi::SSL_CIPHER { fn as_ptr(&self) -> *mut ffi::SSL_CIPHER {
self as *const _ as *const _ self.0
} }
}
impl Ref<SslCipher> {
/// 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 {
@ -870,15 +827,11 @@ impl SslCipherRef {
} }
} }
/// A reference to an `Ssl`. type_!(Ssl, ffi::SSL, ffi::SSL_free);
pub struct SslRef(Opaque);
unsafe impl Send for SslRef {} impl fmt::Debug for Ref<Ssl> {
unsafe impl Sync for SslRef {}
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("SslRef"); let mut builder = fmt.debug_struct("Ssl");
builder.field("state", &self.state_string_long()); builder.field("state", &self.state_string_long());
if let Some(err) = self.verify_result() { if let Some(err) = self.verify_result() {
builder.field("verify_result", &err); builder.field("verify_result", &err);
@ -887,19 +840,7 @@ impl fmt::Debug for SslRef {
} }
} }
impl SslRef { impl Ref<Ssl> {
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 _
}
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()) }
} }
@ -933,7 +874,7 @@ impl SslRef {
/// 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, &X509StoreContextRef) -> bool + Any + 'static + Sync + Send where F: Fn(bool, &Ref<X509StoreContext>) -> bool + Any + 'static + Sync + Send
{ {
unsafe { unsafe {
let verify = Box::new(verify); 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 { 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(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. /// 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(|_| ()) } 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) -> &SslContextRef { pub fn ssl_context(&self) -> &Ref<SslContext> {
unsafe { unsafe {
let ssl_ctx = ffi::SSL_get_SSL_CTX(self.as_ptr()); 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. /// 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 X509VerifyParamRef { pub fn param_mut(&mut self) -> &mut Ref<X509VerifyParam> {
self._param_mut() self._param_mut()
} }
#[cfg(any(ossl102, ossl110))] #[cfg(any(ossl102, ossl110))]
fn _param_mut(&mut self) -> &mut X509VerifyParamRef { fn _param_mut(&mut self) -> &mut Ref<X509VerifyParam> {
unsafe { X509VerifyParamRef::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) } unsafe { Ref::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) }
} }
/// Returns the result of X509 certificate verification. /// 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 Sync for Ssl {}
unsafe impl Send for Ssl {} unsafe impl Send for Ssl {}
impl fmt::Debug for Ssl { impl fmt::Debug for Ssl {
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"); fmt::Debug::fmt(&**self, fmt)
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) }
} }
} }
@ -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. /// Creates an SSL/TLS client operating over the provided stream.
/// ///
/// # Warning /// # Warning
@ -1255,7 +1165,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) -> &SslRef { pub fn ssl(&self) -> &Ref<Ssl> {
self.stream.ssl() self.stream.ssl()
} }
@ -1437,7 +1347,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) -> &SslRef { pub fn ssl(&self) -> &Ref<Ssl> {
&self.ssl &self.ssl
} }
} }

View File

@ -20,7 +20,7 @@ use ssl::SSL_VERIFY_PEER;
use ssl::{SslMethod, HandshakeError}; use ssl::{SslMethod, HandshakeError};
use ssl::{SslContext, SslStream, Ssl, ShutdownResult, SslConnectorBuilder, SslAcceptorBuilder, use ssl::{SslContext, SslStream, Ssl, ShutdownResult, SslConnectorBuilder, SslAcceptorBuilder,
Error}; Error};
use x509::X509StoreContextRef; use x509::X509StoreContext;
use x509::X509FileType; use x509::X509FileType;
use x509::X509; use x509::X509;
#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] #[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::{SslContext, Ssl, SslStream};
use ssl::SSL_VERIFY_PEER; use ssl::SSL_VERIFY_PEER;
use hash::MessageDigest; use hash::MessageDigest;
use x509::X509StoreContextRef; use x509::X509StoreContext;
use serialize::hex::FromHex; use serialize::hex::FromHex;
use types::Ref;
use super::Server; use super::Server;
#[test] #[test]
@ -771,24 +772,6 @@ fn test_alpn_server_select_none() {
assert!(Ssl::new(&ctx.build()).unwrap().connect(stream).is_err()); 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] #[test]
#[cfg_attr(any(windows, target_arch = "arm"), ignore)] // FIXME(#467) #[cfg_attr(any(windows, target_arch = "arm"), ignore)] // FIXME(#467)
fn test_read_dtlsv1() { fn test_read_dtlsv1() {

39
openssl/src/types.rs Normal file
View File

@ -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 _
}
}

View File

@ -3,7 +3,7 @@ use ffi;
use cvt; use cvt;
use error::ErrorStack; use error::ErrorStack;
use opaque::Opaque; use types::Ref;
bitflags! { bitflags! {
pub flags X509CheckFlags: c_uint { pub flags X509CheckFlags: c_uint {
@ -19,17 +19,9 @@ bitflags! {
} }
} }
pub struct X509VerifyParamRef(Opaque); type_!(X509VerifyParam, ffi::X509_VERIFY_PARAM, ffi::X509_VERIFY_PARAM_free);
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 _
}
impl Ref<X509VerifyParam> {
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

@ -7,23 +7,21 @@ use std::ffi::{CStr, CString};
use std::fmt; use std::fmt;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::mem; use std::mem;
use std::ops::Deref;
use std::ptr; use std::ptr;
use std::slice; use std::slice;
use std::str; use std::str;
use {cvt, cvt_p}; use {cvt, cvt_p};
use asn1::Asn1Time; use asn1::Asn1Time;
use asn1::Asn1TimeRef;
use bio::{MemBio, MemBioSlice}; use bio::{MemBio, MemBioSlice};
use crypto::CryptoString; use crypto::CryptoString;
use hash::MessageDigest; use hash::MessageDigest;
use pkey::{PKey, PKeyRef}; use pkey::PKey;
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 opaque::Opaque; use types::{OpenSslType, Ref};
#[cfg(ossl10x)] #[cfg(ossl10x)]
use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data}; use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data};
@ -49,28 +47,20 @@ pub enum X509FileType {
Default = ffi::X509_FILETYPE_DEFAULT, Default = ffi::X509_FILETYPE_DEFAULT,
} }
pub struct X509StoreContextRef(Opaque); type_!(X509StoreContext, ffi::X509_STORE_CTX, ffi::X509_STORE_CTX_free);
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 _
}
impl Ref<X509StoreContext> {
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<&X509Ref> { pub fn current_cert(&self) -> Option<&Ref<X509>> {
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(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 /// 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(); ffi::init();
unsafe { unsafe {
@ -321,7 +311,7 @@ impl X509Generator {
} }
/// Obtain a certificate signing request (CSR) /// 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) { let cert = match self.sign(p_key) {
Ok(c) => c, Ok(c) => c,
Err(x) => return Err(x), Err(x) => return Err(x),
@ -346,23 +336,13 @@ impl X509Generator {
} }
} }
/// A borrowed public key certificate. type_!(X509, ffi::X509, ffi::X509_free);
pub struct X509Ref(Opaque);
impl X509Ref { impl Ref<X509> {
/// Creates a new `X509Ref` wrapping the provided handle. pub fn subject_name(&self) -> &Ref<X509Name> {
pub unsafe fn from_ptr<'a>(x509: *mut ffi::X509) -> &'a X509Ref {
&*(x509 as *mut _)
}
pub fn as_ptr(&self) -> *mut ffi::X509 {
self as *const _ as *mut _
}
pub fn subject_name(&self) -> &X509NameRef {
unsafe { unsafe {
let name = ffi::X509_get_subject_name(self.as_ptr()); 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. /// 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 { 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());
Asn1TimeRef::from_ptr(date) Ref::from_ptr(date)
} }
} }
/// Returns certificate Not Before validity period. /// 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 { 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());
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; type Owned = X509;
fn to_owned(&self) -> 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 { 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. /// Reads a certificate from DER.
pub fn from_der(buf: &[u8]) -> Result<X509, ErrorStack> { pub fn from_der(buf: &[u8]) -> Result<X509, ErrorStack> {
unsafe { 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 { impl Clone for X509 {
fn clone(&self) -> X509 { fn clone(&self) -> X509 {
self.to_owned() self.to_owned()
} }
} }
impl Drop for X509 { impl AsRef<Ref<X509>> for X509 {
fn drop(&mut self) { fn as_ref(&self) -> &Ref<X509> {
unsafe { ffi::X509_free(self.as_ptr()) };
}
}
impl AsRef<X509Ref> for X509 {
fn as_ref(&self) -> &X509Ref {
&*self &*self
} }
} }
impl Borrow<X509Ref> for X509 { impl Borrow<Ref<X509>> for X509 {
fn borrow(&self) -> &X509Ref { fn borrow(&self) -> &Ref<X509> {
&*self &*self
} }
} }
pub struct X509NameRef(Opaque); type_!(X509Name, ffi::X509_NAME, ffi::X509_NAME_free);
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 _
}
impl Ref<X509Name> {
pub fn text_by_nid(&self, nid: Nid) -> Option<CryptoString> { pub fn text_by_nid(&self, nid: Nid) -> Option<CryptoString> {
unsafe { unsafe {
let loc = ffi::X509_NAME_get_index_by_NID(self.as_ptr(), nid.as_raw(), -1); let loc = ffi::X509_NAME_get_index_by_NID(self.as_ptr(), nid.as_raw(), -1);
@ -554,18 +504,29 @@ impl X509NameRef {
} }
} }
/// A certificate signing request type_!(X509Req, ffi::X509_REQ, ffi::X509_REQ_free);
pub struct X509Req(*mut ffi::X509_REQ);
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.as_ptr()) } != 1 {
return Err(ErrorStack::get());
}
Ok(mem_bio.get_buf().to_owned())
}
/// Returns a DER serialized form of the CSR
pub fn to_der(&self) -> Result<Vec<u8>, ErrorStack> {
let mem_bio = try!(MemBio::new());
unsafe {
ffi::i2d_X509_REQ_bio(mem_bio.as_ptr(), self.as_ptr());
}
Ok(mem_bio.get_buf().to_owned())
}
}
impl X509Req { 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 /// Reads CSR from PEM
pub fn from_pem(buf: &[u8]) -> Result<X509Req, ErrorStack> { pub fn from_pem(buf: &[u8]) -> Result<X509Req, ErrorStack> {
let mem_bio = try!(MemBioSlice::new(buf)); let mem_bio = try!(MemBioSlice::new(buf));
@ -577,30 +538,6 @@ impl X509Req {
Ok(X509Req::from_ptr(handle)) Ok(X509Req::from_ptr(handle))
} }
} }
/// 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 {
return Err(ErrorStack::get());
}
Ok(mem_bio.get_buf().to_owned())
}
/// Returns a DER serialized form of the CSR
pub fn to_der(&self) -> Result<Vec<u8>, ErrorStack> {
let mem_bio = try!(MemBio::new());
unsafe {
ffi::i2d_X509_REQ_bio(mem_bio.as_ptr(), self.0);
}
Ok(mem_bio.get_buf().to_owned())
}
}
impl Drop for X509Req {
fn drop(&mut self) {
unsafe { ffi::X509_REQ_free(self.0) };
}
} }
/// A collection of X.509 extensions. /// A collection of X.509 extensions.