diff --git a/src/asn1/mod.rs b/src/asn1/mod.rs index d302d6b7d0cf358f146820426864a56b2663d4b3..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/src/asn1/mod.rs +++ b/src/asn1/mod.rs @@ -1,23 +0,0 @@ -pub mod ffi { - #![allow(dead_code)] - #![allow(non_camel_case_types)] - use libc::{c_int, c_long, c_void}; - - pub type ASN1_INTEGER = c_void; - pub type ASN1_TIME = c_void; - pub type ASN1_STRING = c_void; - - pub static MBSTRING_FLAG: c_int = 0x1000; - pub static MBSTRING_UTF8: c_int = MBSTRING_FLAG; - pub static MBSTRING_ASC: c_int = MBSTRING_FLAG | 1; - pub static MBSTRING_BMP: c_int = MBSTRING_FLAG | 2; - pub static MBSTRING_UNIV: c_int = MBSTRING_FLAG | 4; - - pub static V_ASN1_UTCTIME: c_int = 23; - pub static V_ASN1_GENERALIZEDTIME: c_int = 24; - - extern "C" { - pub fn ASN1_STRING_type_new(ty: c_int) -> *mut ASN1_STRING; - pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int; - } -} diff --git a/src/bio/mod.rs b/src/bio/mod.rs index f81114de614a8478e9490f073a908c1deb2fa210..5c5e8df0e66e0d7c49ae95396032e414228486e1 100644 --- a/src/bio/mod.rs +++ b/src/bio/mod.rs @@ -3,6 +3,7 @@ use std::io::{IoResult, IoError, OtherIoError}; use std::io::{Reader, Writer}; use std::ptr; +use ffi; use ssl::error::{SslError}; pub struct MemBio { @@ -84,20 +85,3 @@ impl Writer for MemBio { } } } - -pub mod ffi { - #![allow(non_camel_case_types)] - - use libc::{c_int, c_void}; - - pub type BIO = c_void; - pub type BIO_METHOD = c_void; - - extern "C" { - pub fn BIO_s_mem() -> *const BIO_METHOD; - pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO; - pub fn BIO_free_all(a: *mut BIO); - pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int; - pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int; - } -} diff --git a/src/bn/mod.rs b/src/bn/mod.rs index cc64d8cda2dacfe1d05a1c7a6ffd00c67ed227ef..29ffd413e95e5cc20b2eec715faa15423825b41c 100644 --- a/src/bn/mod.rs +++ b/src/bn/mod.rs @@ -1,88 +1,12 @@ - -use libc::{c_void, c_int, c_ulong, c_char}; +use libc::{c_int, c_ulong}; use std::{fmt, ptr}; use std::c_str::CString; use std::num::{One, Zero}; +use ffi; use ssl::error::SslError; -#[allow(dead_code)] -#[repr(C)] -struct BIGNUM { - d: *mut c_void, - top: c_int, - dmax: c_int, - neg: c_int, - flags: c_int, -} - -#[allow(non_camel_case_types)] -type BN_CTX = *mut c_void; - -#[link(name = "crypto")] -extern { - fn BN_new() -> *mut BIGNUM; - fn BN_clear_free(bn: *mut BIGNUM); - - fn BN_CTX_new() -> *mut BN_CTX; - fn BN_CTX_free(ctx: *mut BN_CTX); - - fn BN_set_word(bn: *mut BIGNUM, n: c_ulong) -> c_int; - fn BN_set_negative(bn: *mut BIGNUM, n: c_int); - fn BN_num_bits(bn: *mut BIGNUM) -> c_int; - - /* Arithmetic operations on BIGNUMs */ - fn BN_add(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM) -> c_int; - fn BN_sub(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM) -> c_int; - fn BN_mul(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; - fn BN_sqr(r: *mut BIGNUM, a: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; - fn BN_div(dv: *mut BIGNUM, rem: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; - fn BN_nnmod(rem: *mut BIGNUM, a: *mut BIGNUM, m: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; - fn BN_mod_add(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, m: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; - fn BN_mod_sub(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, m: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; - fn BN_mod_mul(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, m: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; - fn BN_mod_sqr(r: *mut BIGNUM, a: *mut BIGNUM, m: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; - fn BN_exp(r: *mut BIGNUM, a: *mut BIGNUM, p: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; - fn BN_mod_exp(r: *mut BIGNUM, a: *mut BIGNUM, p: *mut BIGNUM, m: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; - fn BN_mod_inverse(r: *mut BIGNUM, a: *mut BIGNUM, n: *mut BIGNUM, ctx: *mut BN_CTX) -> *const BIGNUM; - fn BN_gcd(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; - - /* Bit operations on BIGNUMs */ - fn BN_set_bit(a: *mut BIGNUM, n: c_int) -> c_int; - fn BN_clear_bit(a: *mut BIGNUM, n: c_int) -> c_int; - fn BN_is_bit_set(a: *mut BIGNUM, n: c_int) -> c_int; - fn BN_mask_bits(a: *mut BIGNUM, n: c_int) -> c_int; - fn BN_lshift(r: *mut BIGNUM, a: *mut BIGNUM, n: c_int) -> c_int; - fn BN_lshift1(r: *mut BIGNUM, a: *mut BIGNUM) -> c_int; - fn BN_rshift(r: *mut BIGNUM, a: *mut BIGNUM, n: c_int) -> c_int; - fn BN_rshift1(r: *mut BIGNUM, a: *mut BIGNUM) -> c_int; - - /* Comparisons on BIGNUMs */ - fn BN_cmp(a: *mut BIGNUM, b: *mut BIGNUM) -> c_int; - fn BN_ucmp(a: *mut BIGNUM, b: *mut BIGNUM) -> c_int; - fn BN_is_zero(a: *mut BIGNUM) -> c_int; - - /* Prime handling */ - fn BN_generate_prime_ex(r: *mut BIGNUM, bits: c_int, safe: c_int, add: *mut BIGNUM, rem: *mut BIGNUM, cb: *const c_void) -> c_int; - fn BN_is_prime_ex(p: *mut BIGNUM, checks: c_int, ctx: *mut BN_CTX, cb: *const c_void) -> c_int; - fn BN_is_prime_fasttest_ex(p: *mut BIGNUM, checks: c_int, ctx: *mut BN_CTX, do_trial_division: c_int, cb: *const c_void) -> c_int; - - /* Random number handling */ - fn BN_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int; - fn BN_pseudo_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int; - fn BN_rand_range(r: *mut BIGNUM, range: *mut BIGNUM) -> c_int; - fn BN_pseudo_rand_range(r: *mut BIGNUM, range: *mut BIGNUM) -> c_int; - - /* Conversion from/to binary representation */ - fn BN_bn2bin(a: *mut BIGNUM, to: *mut u8) -> c_int; - fn BN_bin2bn(s: *const u8, size: c_int, ret: *mut BIGNUM) -> *mut BIGNUM; - - /* Conversion from/to string representation */ - fn BN_bn2dec(a: *mut BIGNUM) -> *const c_char; - fn CRYPTO_free(buf: *const c_char); -} - -pub struct BigNum(*mut BIGNUM); +pub struct BigNum(*mut ffi::BIGNUM); #[repr(C)] pub enum RNGProperty { @@ -93,12 +17,12 @@ pub enum RNGProperty { macro_rules! with_ctx( ($name:ident, $action:block) => ({ - let $name = BN_CTX_new(); + let $name = ffi::BN_CTX_new(); if ($name).is_null() { Err(SslError::get()) } else { let r = $action; - BN_CTX_free($name); + ffi::BN_CTX_free($name); r } }); @@ -125,7 +49,7 @@ macro_rules! with_bn_in_ctx( let tmp = BigNum::new(); match tmp { Ok($name) => { - let $ctx_name = BN_CTX_new(); + let $ctx_name = ffi::BN_CTX_new(); if ($ctx_name).is_null() { Err(SslError::get()) } else { @@ -135,7 +59,7 @@ macro_rules! with_bn_in_ctx( } else { Err(SslError::get()) }; - BN_CTX_free($ctx_name); + ffi::BN_CTX_free($ctx_name); r } }, @@ -147,7 +71,7 @@ macro_rules! with_bn_in_ctx( impl BigNum { pub fn new() -> Result { unsafe { - let v = BN_new(); + let v = ffi::BN_new(); if v.is_null() { Err(SslError::get()) } else { @@ -158,8 +82,8 @@ impl BigNum { pub fn new_from(n: u64) -> Result { unsafe { - let bn = BN_new(); - if bn.is_null() || BN_set_word(bn, n as c_ulong) == 0 { + let bn = ffi::BN_new(); + if bn.is_null() || ffi::BN_set_word(bn, n as c_ulong) == 0 { Err(SslError::get()) } else { Ok(BigNum(bn)) @@ -169,8 +93,8 @@ impl BigNum { pub fn new_from_slice(n: &[u8]) -> Result { unsafe { - let bn = BN_new(); - if bn.is_null() || BN_bin2bn(n.as_ptr(), n.len() as c_int, bn).is_null() { + let bn = ffi::BN_new(); + if bn.is_null() || ffi::BN_bin2bn(n.as_ptr(), n.len() as c_int, bn).is_null() { Err(SslError::get()) } else { Ok(BigNum(bn)) @@ -180,61 +104,61 @@ impl BigNum { pub fn checked_sqr(&self) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_sqr(r.raw(), self.raw(), ctx) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_sqr(r.raw(), self.raw(), ctx) == 1 }) } } pub fn checked_nnmod(&self, n: &BigNum) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_nnmod(r.raw(), self.raw(), n.raw(), ctx) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_nnmod(r.raw(), self.raw(), n.raw(), ctx) == 1 }) } } pub fn checked_mod_add(&self, a: &BigNum, n: &BigNum) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_mod_add(r.raw(), self.raw(), a.raw(), n.raw(), ctx) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_mod_add(r.raw(), self.raw(), a.raw(), n.raw(), ctx) == 1 }) } } pub fn checked_mod_sub(&self, a: &BigNum, n: &BigNum) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_mod_sub(r.raw(), self.raw(), a.raw(), n.raw(), ctx) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_mod_sub(r.raw(), self.raw(), a.raw(), n.raw(), ctx) == 1 }) } } pub fn checked_mod_mul(&self, a: &BigNum, n: &BigNum) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_mod_mul(r.raw(), self.raw(), a.raw(), n.raw(), ctx) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_mod_mul(r.raw(), self.raw(), a.raw(), n.raw(), ctx) == 1 }) } } pub fn checked_mod_sqr(&self, n: &BigNum) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_mod_sqr(r.raw(), self.raw(), n.raw(), ctx) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_mod_sqr(r.raw(), self.raw(), n.raw(), ctx) == 1 }) } } pub fn checked_exp(&self, p: &BigNum) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_exp(r.raw(), self.raw(), p.raw(), ctx) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_exp(r.raw(), self.raw(), p.raw(), ctx) == 1 }) } } pub fn checked_mod_exp(&self, p: &BigNum, n: &BigNum) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_mod_exp(r.raw(), self.raw(), p.raw(), n.raw(), ctx) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_mod_exp(r.raw(), self.raw(), p.raw(), n.raw(), ctx) == 1 }) } } pub fn checked_mod_inv(&self, n: &BigNum) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { !BN_mod_inverse(r.raw(), self.raw(), n.raw(), ctx).is_null() }) + with_bn_in_ctx!(r, ctx, { !ffi::BN_mod_inverse(r.raw(), self.raw(), n.raw(), ctx).is_null() }) } } pub fn checked_gcd(&self, a: &BigNum) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_gcd(r.raw(), self.raw(), a.raw(), ctx) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_gcd(r.raw(), self.raw(), a.raw(), ctx) == 1 }) } } @@ -244,7 +168,7 @@ impl BigNum { let add_arg = add.map(|a| a.raw()).unwrap_or(ptr::mut_null()); let rem_arg = rem.map(|r| r.raw()).unwrap_or(ptr::mut_null()); - BN_generate_prime_ex(r.raw(), bits as c_int, safe as c_int, add_arg, rem_arg, ptr::null()) == 1 + ffi::BN_generate_prime_ex(r.raw(), bits as c_int, safe as c_int, add_arg, rem_arg, ptr::null()) == 1 }) } } @@ -252,7 +176,7 @@ impl BigNum { pub fn is_prime(&self, checks: i32) -> Result { unsafe { with_ctx!(ctx, { - Ok(BN_is_prime_ex(self.raw(), checks as c_int, ctx, ptr::null()) == 1) + Ok(ffi::BN_is_prime_ex(self.raw(), checks as c_int, ctx, ptr::null()) == 1) }) } } @@ -260,38 +184,38 @@ impl BigNum { pub fn is_prime_fast(&self, checks: i32, do_trial_division: bool) -> Result { unsafe { with_ctx!(ctx, { - Ok(BN_is_prime_fasttest_ex(self.raw(), checks as c_int, ctx, do_trial_division as c_int, ptr::null()) == 1) + Ok(ffi::BN_is_prime_fasttest_ex(self.raw(), checks as c_int, ctx, do_trial_division as c_int, ptr::null()) == 1) }) } } pub fn checked_new_random(bits: i32, prop: RNGProperty, odd: bool) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_rand(r.raw(), bits as c_int, prop as c_int, odd as c_int) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_rand(r.raw(), bits as c_int, prop as c_int, odd as c_int) == 1 }) } } pub fn checked_new_pseudo_random(bits: i32, prop: RNGProperty, odd: bool) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_pseudo_rand(r.raw(), bits as c_int, prop as c_int, odd as c_int) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_pseudo_rand(r.raw(), bits as c_int, prop as c_int, odd as c_int) == 1 }) } } pub fn checked_rand_in_range(&self) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_rand_range(r.raw(), self.raw()) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_rand_range(r.raw(), self.raw()) == 1 }) } } pub fn checked_pseudo_rand_in_range(&self) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_pseudo_rand_range(r.raw(), self.raw()) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_pseudo_rand_range(r.raw(), self.raw()) == 1 }) } } pub fn set_bit(&mut self, n: i32) -> Result<(), SslError> { unsafe { - if BN_set_bit(self.raw(), n as c_int) == 1 { + if ffi::BN_set_bit(self.raw(), n as c_int) == 1 { Ok(()) } else { Err(SslError::get()) @@ -301,7 +225,7 @@ impl BigNum { pub fn clear_bit(&mut self, n: i32) -> Result<(), SslError> { unsafe { - if BN_clear_bit(self.raw(), n as c_int) == 1 { + if ffi::BN_clear_bit(self.raw(), n as c_int) == 1 { Ok(()) } else { Err(SslError::get()) @@ -311,13 +235,13 @@ impl BigNum { pub fn is_bit_set(&self, n: i32) -> bool { unsafe { - BN_is_bit_set(self.raw(), n as c_int) == 1 + ffi::BN_is_bit_set(self.raw(), n as c_int) == 1 } } pub fn mask_bits(&mut self, n: i32) -> Result<(), SslError> { unsafe { - if BN_mask_bits(self.raw(), n as c_int) == 1 { + if ffi::BN_mask_bits(self.raw(), n as c_int) == 1 { Ok(()) } else { Err(SslError::get()) @@ -327,67 +251,67 @@ impl BigNum { pub fn checked_shl1(&self) -> Result { unsafe { - with_bn!(r, { BN_lshift1(r.raw(), self.raw()) == 1 }) + with_bn!(r, { ffi::BN_lshift1(r.raw(), self.raw()) == 1 }) } } pub fn checked_shr1(&self) -> Result { unsafe { - with_bn!(r, { BN_rshift1(r.raw(), self.raw()) == 1 }) + with_bn!(r, { ffi::BN_rshift1(r.raw(), self.raw()) == 1 }) } } pub fn checked_add(&self, a: &BigNum) -> Result { unsafe { - with_bn!(r, { BN_add(r.raw(), self.raw(), a.raw()) == 1 }) + with_bn!(r, { ffi::BN_add(r.raw(), self.raw(), a.raw()) == 1 }) } } pub fn checked_sub(&self, a: &BigNum) -> Result { unsafe { - with_bn!(r, { BN_sub(r.raw(), self.raw(), a.raw()) == 1 }) + with_bn!(r, { ffi::BN_sub(r.raw(), self.raw(), a.raw()) == 1 }) } } pub fn checked_mul(&self, a: &BigNum) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_mul(r.raw(), self.raw(), a.raw(), ctx) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_mul(r.raw(), self.raw(), a.raw(), ctx) == 1 }) } } pub fn checked_div(&self, a: &BigNum) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_div(r.raw(), ptr::mut_null(), self.raw(), a.raw(), ctx) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_div(r.raw(), ptr::mut_null(), self.raw(), a.raw(), ctx) == 1 }) } } pub fn checked_mod(&self, a: &BigNum) -> Result { unsafe { - with_bn_in_ctx!(r, ctx, { BN_div(ptr::mut_null(), r.raw(), self.raw(), a.raw(), ctx) == 1 }) + with_bn_in_ctx!(r, ctx, { ffi::BN_div(ptr::mut_null(), r.raw(), self.raw(), a.raw(), ctx) == 1 }) } } pub fn checked_shl(&self, a: &i32) -> Result { unsafe { - with_bn!(r, { BN_lshift(r.raw(), self.raw(), *a as c_int) == 1 }) + with_bn!(r, { ffi::BN_lshift(r.raw(), self.raw(), *a as c_int) == 1 }) } } pub fn checked_shr(&self, a: &i32) -> Result { unsafe { - with_bn!(r, { BN_rshift(r.raw(), self.raw(), *a as c_int) == 1 }) + with_bn!(r, { ffi::BN_rshift(r.raw(), self.raw(), *a as c_int) == 1 }) } } pub fn negate(&mut self) { unsafe { - BN_set_negative(self.raw(), !self.is_negative() as c_int) + ffi::BN_set_negative(self.raw(), !self.is_negative() as c_int) } } pub fn abs_cmp(&self, oth: BigNum) -> Ordering { unsafe { - let res = BN_ucmp(self.raw(), oth.raw()) as i32; + let res = ffi::BN_ucmp(self.raw(), oth.raw()) as i32; if res < 0 { Less } else if res > 0 { @@ -406,7 +330,7 @@ impl BigNum { pub fn num_bits(&self) -> i32 { unsafe { - BN_num_bits(self.raw()) as i32 + ffi::BN_num_bits(self.raw()) as i32 } } @@ -414,7 +338,7 @@ impl BigNum { (self.num_bits() + 7) / 8 } - unsafe fn raw(&self) -> *mut BIGNUM { + unsafe fn raw(&self) -> *mut ffi::BIGNUM { let BigNum(n) = *self; n } @@ -423,7 +347,7 @@ impl BigNum { let size = self.num_bytes() as uint; let mut v = Vec::with_capacity(size); unsafe { - BN_bn2bin(self.raw(), v.as_mut_ptr()); + ffi::BN_bn2bin(self.raw(), v.as_mut_ptr()); v.set_len(size); } v @@ -431,11 +355,11 @@ impl BigNum { pub fn to_dec_str(&self) -> String { unsafe { - let buf = BN_bn2dec(self.raw()); + let buf = ffi::BN_bn2dec(self.raw()); assert!(!buf.is_null()); let c_str = CString::new(buf, false); let str = c_str.as_str().unwrap().to_string(); - CRYPTO_free(buf); + ffi::CRYPTO_free(buf); str } } @@ -459,7 +383,7 @@ impl Zero for BigNum { } fn is_zero(&self) -> bool { unsafe { - BN_is_zero(self.raw()) == 1 + ffi::BN_is_zero(self.raw()) == 1 } } } @@ -468,7 +392,7 @@ impl Eq for BigNum { } impl PartialEq for BigNum { fn eq(&self, oth: &BigNum) -> bool { unsafe { - BN_cmp(self.raw(), oth.raw()) == 0 + ffi::BN_cmp(self.raw(), oth.raw()) == 0 } } } @@ -482,7 +406,7 @@ impl Ord for BigNum { impl PartialOrd for BigNum { fn partial_cmp(&self, oth: &BigNum) -> Option { unsafe { - let v = BN_cmp(self.raw(), oth.raw()); + let v = ffi::BN_cmp(self.raw(), oth.raw()); let ret = if v == 0 { Equal @@ -500,18 +424,15 @@ impl Drop for BigNum { fn drop(&mut self) { unsafe { if !self.raw().is_null() { - BN_clear_free(self.raw()); + ffi::BN_clear_free(self.raw()); } } } } pub mod unchecked { - use super::{BIGNUM, BigNum}; - - extern { - fn BN_dup(n: *mut BIGNUM) -> *mut BIGNUM; - } + use ffi; + use super::{BigNum}; impl Add for BigNum { fn add(&self, oth: &BigNum) -> BigNum { @@ -558,7 +479,7 @@ pub mod unchecked { impl Clone for BigNum { fn clone(&self) -> BigNum { unsafe { - let r = BN_dup(self.raw()); + let r = ffi::BN_dup(self.raw()); if r.is_null() { fail!("Unexpected null pointer from BN_dup(..)") } else { diff --git a/src/crypto/hash.rs b/src/crypto/hash.rs index 4a4031e22c642b56529e0b1aca3d53683087fd3b..03d0f097f0479a70d6a7bfffa0af69c789cd9c9b 100644 --- a/src/crypto/hash.rs +++ b/src/crypto/hash.rs @@ -1,7 +1,8 @@ -use libc; use libc::c_uint; use std::ptr; +use ffi; + pub enum HashType { MD5, SHA1, @@ -12,71 +13,33 @@ pub enum HashType { RIPEMD160 } -#[allow(dead_code)] -#[allow(non_camel_case_types)] -#[repr(C)] -pub struct EVP_MD_CTX { - digest: *mut EVP_MD, - engine: *mut libc::c_void, - flags: libc::c_ulong, - md_data: *mut libc::c_void, - pctx: *mut EVP_PKEY_CTX, - update: *mut libc::c_void -} - -#[allow(non_camel_case_types)] -#[repr(C)] -pub struct EVP_MD; - -#[allow(non_camel_case_types)] -#[repr(C)] -pub struct EVP_PKEY_CTX; - -#[link(name = "crypto")] -extern { - fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX; - fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX); - - fn EVP_md5() -> *const EVP_MD; - fn EVP_sha1() -> *const EVP_MD; - fn EVP_sha224() -> *const EVP_MD; - fn EVP_sha256() -> *const EVP_MD; - fn EVP_sha384() -> *const EVP_MD; - fn EVP_sha512() -> *const EVP_MD; - fn EVP_ripemd160() -> *const EVP_MD; - - fn EVP_DigestInit(ctx: *mut EVP_MD_CTX, typ: *const EVP_MD); - fn EVP_DigestUpdate(ctx: *mut EVP_MD_CTX, data: *const u8, n: c_uint); - fn EVP_DigestFinal(ctx: *mut EVP_MD_CTX, res: *mut u8, n: *mut u32); -} - -pub fn evpmd(t: HashType) -> (*const EVP_MD, uint) { +pub fn evpmd(t: HashType) -> (*const ffi::EVP_MD, uint) { unsafe { match t { - MD5 => (EVP_md5(), 16u), - SHA1 => (EVP_sha1(), 20u), - SHA224 => (EVP_sha224(), 28u), - SHA256 => (EVP_sha256(), 32u), - SHA384 => (EVP_sha384(), 48u), - SHA512 => (EVP_sha512(), 64u), - RIPEMD160 => (EVP_ripemd160(), 20u), + MD5 => (ffi::EVP_md5(), 16u), + SHA1 => (ffi::EVP_sha1(), 20u), + SHA224 => (ffi::EVP_sha224(), 28u), + SHA256 => (ffi::EVP_sha256(), 32u), + SHA384 => (ffi::EVP_sha384(), 48u), + SHA512 => (ffi::EVP_sha512(), 64u), + RIPEMD160 => (ffi::EVP_ripemd160(), 20u), } } } #[allow(dead_code)] pub struct Hasher { - evp: *const EVP_MD, - ctx: *mut EVP_MD_CTX, + evp: *const ffi::EVP_MD, + ctx: *mut ffi::EVP_MD_CTX, len: uint, } impl Hasher { pub fn new(ht: HashType) -> Hasher { - let ctx = unsafe { EVP_MD_CTX_create() }; + let ctx = unsafe { ffi::EVP_MD_CTX_create() }; let (evp, mdlen) = evpmd(ht); unsafe { - EVP_DigestInit(ctx, evp); + ffi::EVP_DigestInit(ctx, evp); } Hasher { evp: evp, ctx: ctx, len: mdlen } @@ -85,7 +48,7 @@ impl Hasher { /// Update this hasher with more input bytes pub fn update(&self, data: &[u8]) { unsafe { - EVP_DigestUpdate(self.ctx, data.as_ptr(), data.len() as c_uint) + ffi::EVP_DigestUpdate(self.ctx, data.as_ptr(), data.len() as c_uint) } } @@ -96,7 +59,7 @@ impl Hasher { pub fn final(&self) -> Vec { unsafe { let mut res = Vec::from_elem(self.len, 0u8); - EVP_DigestFinal(self.ctx, res.as_mut_ptr(), ptr::null_mut()); + ffi::EVP_DigestFinal(self.ctx, res.as_mut_ptr(), ptr::null_mut()); res } } @@ -105,7 +68,7 @@ impl Hasher { impl Drop for Hasher { fn drop(&mut self) { unsafe { - EVP_MD_CTX_destroy(self.ctx); + ffi::EVP_MD_CTX_destroy(self.ctx); } } } diff --git a/src/crypto/hmac.rs b/src/crypto/hmac.rs index 5bf625865ca755f54d914cdb0fa280c05fb004dd..0d9452008db8443086a0cf1b3b0c3c76ff25b9b2 100644 --- a/src/crypto/hmac.rs +++ b/src/crypto/hmac.rs @@ -14,35 +14,13 @@ * limitations under the License. */ -use libc::{c_uchar, c_int, c_uint}; -use crypto::hash; - -#[allow(dead_code)] -#[allow(non_camel_case_types)] -#[repr(C)] -pub struct HMAC_CTX { - md: *mut hash::EVP_MD, - md_ctx: hash::EVP_MD_CTX, - i_ctx: hash::EVP_MD_CTX, - o_ctx: hash::EVP_MD_CTX, - key_length: c_uint, - key: [c_uchar, ..128] -} +use libc::{c_int, c_uint}; -#[link(name = "crypto")] -extern { - fn HMAC_CTX_init(ctx: *mut HMAC_CTX); - fn HMAC_Init_ex(ctx: *mut HMAC_CTX, key: *const u8, keylen: c_int, md: *const hash::EVP_MD, imple: *const ENGINE); - fn HMAC_Update(ctx: *mut HMAC_CTX, input: *const u8, len: c_uint); - fn HMAC_Final(ctx: *mut HMAC_CTX, output: *mut u8, len: *mut c_uint); -} - -#[allow(non_camel_case_types)] -#[repr(C)] -struct ENGINE; +use crypto::hash; +use ffi; pub struct HMAC { - ctx: HMAC_CTX, + ctx: ffi::HMAC_CTX, len: uint, } @@ -51,13 +29,13 @@ pub fn HMAC(ht: hash::HashType, key: &[u8]) -> HMAC { unsafe { let (evp, mdlen) = hash::evpmd(ht); - let mut ctx : HMAC_CTX = ::std::mem::uninitialized(); + let mut ctx : ffi::HMAC_CTX = ::std::mem::uninitialized(); - HMAC_CTX_init(&mut ctx); - HMAC_Init_ex(&mut ctx, - key.as_ptr(), - key.len() as c_int, - evp, 0 as *const _); + ffi::HMAC_CTX_init(&mut ctx); + ffi::HMAC_Init_ex(&mut ctx, + key.as_ptr(), + key.len() as c_int, + evp, 0 as *const _); HMAC { ctx: ctx, len: mdlen } } @@ -66,7 +44,7 @@ pub fn HMAC(ht: hash::HashType, key: &[u8]) -> HMAC { impl HMAC { pub fn update(&mut self, data: &[u8]) { unsafe { - HMAC_Update(&mut self.ctx, data.as_ptr(), data.len() as c_uint) + ffi::HMAC_Update(&mut self.ctx, data.as_ptr(), data.len() as c_uint) } } @@ -74,7 +52,7 @@ impl HMAC { unsafe { let mut res = Vec::from_elem(self.len, 0u8); let mut outlen = 0; - HMAC_Final(&mut self.ctx, res.as_mut_ptr(), &mut outlen); + ffi::HMAC_Final(&mut self.ctx, res.as_mut_ptr(), &mut outlen); assert!(self.len == outlen as uint) res } diff --git a/src/crypto/pkcs5.rs b/src/crypto/pkcs5.rs index b795d84af6bdc6721b9f9f4b498eb71291cad86d..ec6e0cefcafd34806f46aeba9a92da5d6eca06ae 100644 --- a/src/crypto/pkcs5.rs +++ b/src/crypto/pkcs5.rs @@ -1,12 +1,5 @@ use libc::c_int; - -#[link(name = "crypto")] -extern { - fn PKCS5_PBKDF2_HMAC_SHA1(pass: *const u8, passlen: c_int, - salt: *const u8, saltlen: c_int, - iter: c_int, keylen: c_int, - out: *mut u8) -> c_int; -} +use ffi; /// Derives a key from a password and salt using the PBKDF2-HMAC-SHA1 algorithm. pub fn pbkdf2_hmac_sha1(pass: &str, salt: &[u8], iter: uint, keylen: uint) -> Vec { @@ -16,7 +9,7 @@ pub fn pbkdf2_hmac_sha1(pass: &str, salt: &[u8], iter: uint, keylen: uint) -> Ve let mut out = Vec::with_capacity(keylen); - let r = PKCS5_PBKDF2_HMAC_SHA1( + let r = ffi::PKCS5_PBKDF2_HMAC_SHA1( pass.as_ptr(), pass.len() as c_int, salt.as_ptr(), salt.len() as c_int, iter as c_int, keylen as c_int, diff --git a/src/crypto/pkey.rs b/src/crypto/pkey.rs index 5c4b108febb03a65414f69fc97e36ab86f148090..d95e77384499f0dc99aea48b4930904060096fe2 100644 --- a/src/crypto/pkey.rs +++ b/src/crypto/pkey.rs @@ -1,50 +1,11 @@ -use libc::{c_char, c_int, c_uint, c_void}; -use libc; +use libc::{c_int, c_uint}; use std::mem; use std::ptr; -use bio::{mod, MemBio}; +use bio::{MemBio}; use crypto::hash::{HashType, MD5, SHA1, SHA224, SHA256, SHA384, SHA512, RIPEMD160}; -use crypto::symm::{EVP_CIPHER}; +use ffi; use ssl::error::{SslError, StreamError}; -#[allow(non_camel_case_types)] -pub type EVP_PKEY = *mut libc::c_void; - -#[allow(non_camel_case_types)] -pub type RSA = *mut libc::c_void; - -pub type PrivateKeyWriteCallback = extern "C" fn(buf: *mut c_char, size: c_int, rwflag: c_int, user_data: *mut c_void) -> c_int; - -#[link(name = "crypto")] -extern { - fn EVP_PKEY_new() -> *mut EVP_PKEY; - fn EVP_PKEY_free(k: *mut EVP_PKEY); - fn EVP_PKEY_assign(pkey: *mut EVP_PKEY, typ: c_int, key: *const c_char) -> c_int; - fn EVP_PKEY_get1_RSA(k: *mut EVP_PKEY) -> *mut RSA; - fn EVP_PKEY_set1_RSA(k: *mut EVP_PKEY, r: *mut RSA) -> c_int; - - fn i2d_RSA_PUBKEY(k: *mut RSA, buf: *const *mut u8) -> c_int; - fn d2i_RSA_PUBKEY(k: *const *mut RSA, buf: *const *const u8, len: c_uint) -> *mut RSA; - fn i2d_RSAPrivateKey(k: *mut RSA, buf: *const *mut u8) -> c_int; - fn d2i_RSAPrivateKey(k: *const *mut RSA, buf: *const *const u8, len: c_uint) -> *mut RSA; - - fn RSA_generate_key(modsz: c_uint, e: c_uint, cb: *const u8, cbarg: *const u8) -> *mut RSA; - fn RSA_size(k: *mut RSA) -> c_uint; - - fn RSA_public_encrypt(flen: c_uint, from: *const u8, to: *mut u8, k: *mut RSA, - pad: c_int) -> c_int; - fn RSA_private_decrypt(flen: c_uint, from: *const u8, to: *mut u8, k: *mut RSA, - pad: c_int) -> c_int; - fn RSA_sign(t: c_int, m: *const u8, mlen: c_uint, sig: *mut u8, siglen: *mut c_uint, - k: *mut RSA) -> c_int; - fn RSA_verify(t: c_int, m: *const u8, mlen: c_uint, sig: *const u8, siglen: c_uint, - k: *mut RSA) -> c_int; - - fn PEM_write_bio_PrivateKey(bio: *mut bio::ffi::BIO, pkey: *mut EVP_PKEY, cipher: *const EVP_CIPHER, - kstr: *mut c_char, klen: c_int, - callback: *mut c_void, - user_data: *mut c_void) -> c_int; -} enum Parts { Neither, @@ -86,7 +47,7 @@ fn openssl_hash_nid(hash: HashType) -> c_int { } pub struct PKey { - evp: *mut EVP_PKEY, + evp: *mut ffi::EVP_PKEY, parts: Parts, } @@ -95,15 +56,15 @@ impl PKey { pub fn new() -> PKey { unsafe { PKey { - evp: EVP_PKEY_new(), + evp: ffi::EVP_PKEY_new(), parts: Neither, } } } - fn _tostr(&self, f: unsafe extern "C" fn(*mut RSA, *const *mut u8) -> c_int) -> Vec { + fn _tostr(&self, f: unsafe extern "C" fn(*mut ffi::RSA, *const *mut u8) -> c_int) -> Vec { unsafe { - let rsa = EVP_PKEY_get1_RSA(self.evp); + let rsa = ffi::EVP_PKEY_get1_RSA(self.evp); let len = f(rsa, ptr::null()); if len < 0 as c_int { return vec!(); } let mut s = Vec::from_elem(len as uint, 0u8); @@ -115,17 +76,17 @@ impl PKey { } } - fn _fromstr(&mut self, s: &[u8], f: unsafe extern "C" fn(*const *mut RSA, *const *const u8, c_uint) -> *mut RSA) { + fn _fromstr(&mut self, s: &[u8], f: unsafe extern "C" fn(*const *mut ffi::RSA, *const *const u8, c_uint) -> *mut ffi::RSA) { unsafe { let rsa = ptr::null_mut(); f(&rsa, &s.as_ptr(), s.len() as c_uint); - EVP_PKEY_set1_RSA(self.evp, rsa); + ffi::EVP_PKEY_set1_RSA(self.evp, rsa); } } pub fn gen(&mut self, keysz: uint) { unsafe { - let rsa = RSA_generate_key( + let rsa = ffi::RSA_generate_key( keysz as c_uint, 65537u as c_uint, ptr::null(), @@ -133,7 +94,7 @@ impl PKey { ); // XXX: 6 == NID_rsaEncryption - EVP_PKEY_assign( + ffi::EVP_PKEY_assign( self.evp, 6 as c_int, mem::transmute(rsa)); @@ -146,14 +107,14 @@ impl PKey { * Returns a serialized form of the public key, suitable for load_pub(). */ pub fn save_pub(&self) -> Vec { - self._tostr(i2d_RSA_PUBKEY) + self._tostr(ffi::i2d_RSA_PUBKEY) } /** * Loads a serialized form of the public key, as produced by save_pub(). */ pub fn load_pub(&mut self, s: &[u8]) { - self._fromstr(s, d2i_RSA_PUBKEY); + self._fromstr(s, ffi::d2i_RSA_PUBKEY); self.parts = Public; } @@ -162,14 +123,14 @@ impl PKey { * load_priv(). */ pub fn save_priv(&self) -> Vec { - self._tostr(i2d_RSAPrivateKey) + self._tostr(ffi::i2d_RSAPrivateKey) } /** * Loads a serialized form of the public and private keys, as produced by * save_priv(). */ pub fn load_priv(&mut self, s: &[u8]) { - self._fromstr(s, d2i_RSAPrivateKey); + self._fromstr(s, ffi::d2i_RSAPrivateKey); self.parts = Both; } @@ -178,8 +139,8 @@ impl PKey { pub fn write_pem(&self, writer: &mut Writer/*, password: Option*/) -> Result<(), SslError> { let mut mem_bio = try!(MemBio::new()); unsafe { - try_ssl!(PEM_write_bio_PrivateKey(mem_bio.get_handle(), self.evp, ptr::null(), - ptr::null_mut(), -1, ptr::null_mut(), ptr::null_mut())); + try_ssl!(ffi::PEM_write_bio_PrivateKey(mem_bio.get_handle(), self.evp, ptr::null(), + ptr::null_mut(), -1, ptr::null_mut(), ptr::null_mut())); } let buf = try!(mem_bio.read_to_end().map_err(StreamError)); @@ -191,7 +152,7 @@ impl PKey { */ pub fn size(&self) -> uint { unsafe { - RSA_size(EVP_PKEY_get1_RSA(self.evp)) as uint + ffi::RSA_size(ffi::EVP_PKEY_get1_RSA(self.evp)) as uint } } @@ -229,8 +190,8 @@ impl PKey { */ pub fn max_data(&self) -> uint { unsafe { - let rsa = EVP_PKEY_get1_RSA(self.evp); - let len = RSA_size(rsa); + let rsa = ffi::EVP_PKEY_get1_RSA(self.evp); + let len = ffi::RSA_size(rsa); // 41 comes from RSA_public_encrypt(3) for OAEP len as uint - 41u @@ -239,14 +200,14 @@ impl PKey { pub fn encrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> Vec { unsafe { - let rsa = EVP_PKEY_get1_RSA(self.evp); - let len = RSA_size(rsa); + let rsa = ffi::EVP_PKEY_get1_RSA(self.evp); + let len = ffi::RSA_size(rsa); assert!(s.len() < self.max_data()); let mut r = Vec::from_elem(len as uint + 1u, 0u8); - let rv = RSA_public_encrypt( + let rv = ffi::RSA_public_encrypt( s.len() as c_uint, s.as_ptr(), r.as_mut_ptr(), @@ -264,14 +225,14 @@ impl PKey { pub fn decrypt_with_padding(&self, s: &[u8], padding: EncryptionPadding) -> Vec { unsafe { - let rsa = EVP_PKEY_get1_RSA(self.evp); - let len = RSA_size(rsa); + let rsa = ffi::EVP_PKEY_get1_RSA(self.evp); + let len = ffi::RSA_size(rsa); - assert_eq!(s.len() as c_uint, RSA_size(rsa)); + assert_eq!(s.len() as c_uint, ffi::RSA_size(rsa)); let mut r = Vec::from_elem(len as uint + 1u, 0u8); - let rv = RSA_private_decrypt( + let rv = ffi::RSA_private_decrypt( s.len() as c_uint, s.as_ptr(), r.as_mut_ptr(), @@ -312,11 +273,11 @@ impl PKey { pub fn sign_with_hash(&self, s: &[u8], hash: HashType) -> Vec { unsafe { - let rsa = EVP_PKEY_get1_RSA(self.evp); - let mut len = RSA_size(rsa); + let rsa = ffi::EVP_PKEY_get1_RSA(self.evp); + let mut len = ffi::RSA_size(rsa); let mut r = Vec::from_elem(len as uint + 1u, 0u8); - let rv = RSA_sign( + let rv = ffi::RSA_sign( openssl_hash_nid(hash), s.as_ptr(), s.len() as c_uint, @@ -335,9 +296,9 @@ impl PKey { pub fn verify_with_hash(&self, m: &[u8], s: &[u8], hash: HashType) -> bool { unsafe { - let rsa = EVP_PKEY_get1_RSA(self.evp); + let rsa = ffi::EVP_PKEY_get1_RSA(self.evp); - let rv = RSA_verify( + let rv = ffi::RSA_verify( openssl_hash_nid(hash), m.as_ptr(), m.len() as c_uint, @@ -350,7 +311,7 @@ impl PKey { } } - pub unsafe fn get_handle(&self) -> *mut EVP_PKEY { + pub unsafe fn get_handle(&self) -> *mut ffi::EVP_PKEY { return self.evp } } @@ -358,7 +319,7 @@ impl PKey { impl Drop for PKey { fn drop(&mut self) { unsafe { - EVP_PKEY_free(self.evp); + ffi::EVP_PKEY_free(self.evp); } } } diff --git a/src/crypto/rand.rs b/src/crypto/rand.rs index 9db87fcd551ae2779367ef59f8f5f64ae4c9eaa2..dffddee71dc645d9e4b9f05fa97bc85360b12b1f 100644 --- a/src/crypto/rand.rs +++ b/src/crypto/rand.rs @@ -1,15 +1,11 @@ use libc::c_int; - -#[link(name = "crypto")] -extern { - fn RAND_bytes(buf: *mut u8, num: c_int) -> c_int; -} +use ffi; pub fn rand_bytes(len: uint) -> Vec { unsafe { let mut out = Vec::with_capacity(len); - let r = RAND_bytes(out.as_mut_ptr(), len as c_int); + let r = ffi::RAND_bytes(out.as_mut_ptr(), len as c_int); if r != 1 as c_int { fail!() } out.set_len(len); diff --git a/src/crypto/symm.rs b/src/crypto/symm.rs index 6bba7267f525aec0f9a235f3071fda7dfa4ef1d7..a3664bc0a06e0eecf50bfb08f2746656e0a77244 100644 --- a/src/crypto/symm.rs +++ b/src/crypto/symm.rs @@ -1,36 +1,6 @@ -use libc::{c_int, c_uint}; -use libc; +use libc::{c_int}; -#[allow(non_camel_case_types)] -pub type EVP_CIPHER_CTX = *mut libc::c_void; - -#[allow(non_camel_case_types)] -pub type EVP_CIPHER = *mut libc::c_void; - -#[link(name = "crypto")] -extern { - fn EVP_CIPHER_CTX_new() -> EVP_CIPHER_CTX; - fn EVP_CIPHER_CTX_set_padding(ctx: EVP_CIPHER_CTX, padding: c_int); - fn EVP_CIPHER_CTX_free(ctx: EVP_CIPHER_CTX); - - fn EVP_aes_128_ecb() -> EVP_CIPHER; - fn EVP_aes_128_cbc() -> EVP_CIPHER; - // fn EVP_aes_128_ctr() -> EVP_CIPHER; - // fn EVP_aes_128_gcm() -> EVP_CIPHER; - - fn EVP_aes_256_ecb() -> EVP_CIPHER; - fn EVP_aes_256_cbc() -> EVP_CIPHER; - // fn EVP_aes_256_ctr() -> EVP_CIPHER; - // fn EVP_aes_256_gcm() -> EVP_CIPHER; - - fn EVP_rc4() -> EVP_CIPHER; - - fn EVP_CipherInit(ctx: EVP_CIPHER_CTX, evp: EVP_CIPHER, - key: *const u8, iv: *const u8, mode: c_int); - fn EVP_CipherUpdate(ctx: EVP_CIPHER_CTX, outbuf: *mut u8, - outlen: &mut c_uint, inbuf: *const u8, inlen: c_int); - fn EVP_CipherFinal(ctx: EVP_CIPHER_CTX, res: *mut u8, len: &mut c_int); -} +use ffi; pub enum Mode { Encrypt, @@ -52,35 +22,35 @@ pub enum Type { RC4_128, } -fn evpc(t: Type) -> (EVP_CIPHER, uint, uint) { +fn evpc(t: Type) -> (ffi::EVP_CIPHER, uint, uint) { unsafe { match t { - AES_128_ECB => (EVP_aes_128_ecb(), 16u, 16u), - AES_128_CBC => (EVP_aes_128_cbc(), 16u, 16u), + AES_128_ECB => (ffi::EVP_aes_128_ecb(), 16u, 16u), + AES_128_CBC => (ffi::EVP_aes_128_cbc(), 16u, 16u), // AES_128_CTR => (EVP_aes_128_ctr(), 16u, 0u), //AES_128_GCM => (EVP_aes_128_gcm(), 16u, 16u), - AES_256_ECB => (EVP_aes_256_ecb(), 32u, 16u), - AES_256_CBC => (EVP_aes_256_cbc(), 32u, 16u), + AES_256_ECB => (ffi::EVP_aes_256_ecb(), 32u, 16u), + AES_256_CBC => (ffi::EVP_aes_256_cbc(), 32u, 16u), // AES_256_CTR => (EVP_aes_256_ctr(), 32u, 0u), //AES_256_GCM => (EVP_aes_256_gcm(), 32u, 16u), - RC4_128 => (EVP_rc4(), 16u, 0u), + RC4_128 => (ffi::EVP_rc4(), 16u, 0u), } } } /// Represents a symmetric cipher context. pub struct Crypter { - evp: EVP_CIPHER, - ctx: EVP_CIPHER_CTX, + evp: ffi::EVP_CIPHER, + ctx: ffi::EVP_CIPHER_CTX, keylen: uint, blocksize: uint } impl Crypter { pub fn new(t: Type) -> Crypter { - let ctx = unsafe { EVP_CIPHER_CTX_new() }; + let ctx = unsafe { ffi::EVP_CIPHER_CTX_new() }; let (evp, keylen, blocksz) = evpc(t); Crypter { evp: evp, ctx: ctx, keylen: keylen, blocksize: blocksz } } @@ -93,7 +63,7 @@ impl Crypter { if self.blocksize > 0 { unsafe { let v = if padding { 1 as c_int } else { 0 }; - EVP_CIPHER_CTX_set_padding(self.ctx, v); + ffi::EVP_CIPHER_CTX_set_padding(self.ctx, v); } } } @@ -109,7 +79,7 @@ impl Crypter { }; assert_eq!(key.len(), self.keylen); - EVP_CipherInit( + ffi::EVP_CipherInit( self.ctx, self.evp, key.as_ptr(), @@ -128,7 +98,7 @@ impl Crypter { let mut res = Vec::from_elem(data.len() + self.blocksize, 0u8); let mut reslen = (data.len() + self.blocksize) as u32; - EVP_CipherUpdate( + ffi::EVP_CipherUpdate( self.ctx, res.as_mut_ptr(), &mut reslen, @@ -149,7 +119,7 @@ impl Crypter { let mut res = Vec::from_elem(self.blocksize, 0u8); let mut reslen = self.blocksize as c_int; - EVP_CipherFinal(self.ctx, + ffi::EVP_CipherFinal(self.ctx, res.as_mut_ptr(), &mut reslen); @@ -162,7 +132,7 @@ impl Crypter { impl Drop for Crypter { fn drop(&mut self) { unsafe { - EVP_CIPHER_CTX_free(self.ctx); + ffi::EVP_CIPHER_CTX_free(self.ctx); } } } diff --git a/src/ffi.rs b/src/ffi.rs new file mode 100755 index 0000000000000000000000000000000000000000..020948d1fcb4e0a5c200b525c9ab188eb96b3a61 --- /dev/null +++ b/src/ffi.rs @@ -0,0 +1,418 @@ +#![allow(non_camel_case_types)] +#![allow(dead_code)] +use libc::{c_void, c_int, c_char, c_ulong, c_long, c_uint, c_uchar}; + +pub type ASN1_INTEGER = c_void; +pub type ASN1_STRING = c_void; +pub type ASN1_TIME = c_void; +pub type BIO = c_void; +pub type BIO_METHOD = c_void; +pub type BN_CTX = *mut c_void; +pub type COMP_METHOD = c_void; +pub type CRYPTO_EX_DATA = c_void; +pub type ENGINE = c_void; +pub type EVP_CIPHER = *mut c_void; +pub type EVP_CIPHER_CTX = *mut c_void; +pub type EVP_MD = c_void; +pub type EVP_PKEY = *mut c_void; +pub type EVP_PKEY_CTX = c_void; +pub type RSA = *mut c_void; +pub type SSL = c_void; +pub type SSL_CTX = c_void; +pub type SSL_METHOD = c_void; +pub type X509 = c_void; +pub type X509_CRL = c_void; +pub type X509_EXTENSION = c_void; +pub type X509_NAME = c_void; +pub type X509_REQ = c_void; +pub type X509_STORE_CTX = c_void; + +#[allow(dead_code)] +#[repr(C)] +pub struct BIGNUM { + d: *mut c_void, + top: c_int, + dmax: c_int, + pub neg: c_int, + flags: c_int, +} + +#[repr(C)] +pub struct EVP_MD_CTX { + digest: *mut EVP_MD, + engine: *mut c_void, + flags: c_ulong, + md_data: *mut c_void, + pctx: *mut EVP_PKEY_CTX, + update: *mut c_void +} + +#[repr(C)] +pub struct HMAC_CTX { + md: *mut EVP_MD, + md_ctx: EVP_MD_CTX, + i_ctx: EVP_MD_CTX, + o_ctx: EVP_MD_CTX, + key_length: c_uint, + key: [c_uchar, ..128] +} + +#[repr(C)] +pub struct X509V3_CTX { + flags: c_int, + issuer_cert: *mut c_void, + subject_cert: *mut c_void, + subject_req: *mut c_void, + crl: *mut c_void, + db_meth: *mut c_void, + db: *mut c_void, + // I like the last comment line, it is copied from OpenSSL sources: + // Maybe more here +} + +pub type CRYPTO_EX_new = extern "C" fn(parent: *mut c_void, ptr: *mut c_void, + ad: *const CRYPTO_EX_DATA, idx: c_int, + argl: c_long, argp: *const c_void) -> c_int; +pub type CRYPTO_EX_dup = extern "C" fn(to: *mut CRYPTO_EX_DATA, + from: *mut CRYPTO_EX_DATA, from_d: *mut c_void, + idx: c_int, argl: c_long, argp: *mut c_void) + -> c_int; +pub type CRYPTO_EX_free = extern "C" fn(parent: *mut c_void, ptr: *mut c_void, + ad: *mut CRYPTO_EX_DATA, idx: c_int, + argl: c_long, argp: *mut c_void); +pub type PrivateKeyWriteCallback = extern "C" fn(buf: *mut c_char, size: c_int, + rwflag: c_int, user_data: *mut c_void) + -> c_int; + + +pub static CRYPTO_LOCK: c_int = 1; + +pub static MBSTRING_ASC: c_int = MBSTRING_FLAG | 1; +pub static MBSTRING_BMP: c_int = MBSTRING_FLAG | 2; +pub static MBSTRING_FLAG: c_int = 0x1000; +pub static MBSTRING_UNIV: c_int = MBSTRING_FLAG | 4; +pub static MBSTRING_UTF8: c_int = MBSTRING_FLAG; + +pub static NID_ext_key_usage: c_int = 126; +pub static NID_key_usage: c_int = 83; + +pub static SSL_CTRL_SET_TLSEXT_HOSTNAME: c_int = 55; +pub static SSL_ERROR_NONE: c_int = 0; +pub static SSL_ERROR_SSL: c_int = 1; +pub static SSL_ERROR_SYSCALL: c_int = 5; +pub static SSL_ERROR_WANT_ACCEPT: c_int = 8; +pub static SSL_ERROR_WANT_CONNECT: c_int = 7; +pub static SSL_ERROR_WANT_READ: c_int = 2; +pub static SSL_ERROR_WANT_WRITE: c_int = 3; +pub static SSL_ERROR_WANT_X509_LOOKUP: c_int = 4; +pub static SSL_ERROR_ZERO_RETURN: c_int = 6; +pub static SSL_VERIFY_NONE: c_int = 0; +pub static SSL_VERIFY_PEER: c_int = 1; + +pub static TLSEXT_NAMETYPE_host_name: c_long = 0; + +pub static V_ASN1_GENERALIZEDTIME: c_int = 24; +pub static V_ASN1_UTCTIME: c_int = 23; + +pub static X509_FILETYPE_ASN1: c_int = 2; +pub static X509_FILETYPE_DEFAULT: c_int = 3; +pub static X509_FILETYPE_PEM: c_int = 1; +pub static X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: c_int = 31; +pub static X509_V_ERR_AKID_SKID_MISMATCH: c_int = 30; +pub static X509_V_ERR_APPLICATION_VERIFICATION: c_int = 50; +pub static X509_V_ERR_CERT_CHAIN_TOO_LONG: c_int = 22; +pub static X509_V_ERR_CERT_HAS_EXPIRED: c_int = 10; +pub static X509_V_ERR_CERT_NOT_YET_VALID: c_int = 9; +pub static X509_V_ERR_CERT_REJECTED: c_int = 28; +pub static X509_V_ERR_CERT_REVOKED: c_int = 23; +pub static X509_V_ERR_CERT_SIGNATURE_FAILURE: c_int = 7; +pub static X509_V_ERR_CERT_UNTRUSTED: c_int = 27; +pub static X509_V_ERR_CRL_HAS_EXPIRED: c_int = 12; +pub static X509_V_ERR_CRL_NOT_YET_VALID: c_int = 11; +pub static X509_V_ERR_CRL_PATH_VALIDATION_ERROR: c_int = 54; +pub static X509_V_ERR_CRL_SIGNATURE_FAILURE: c_int = 8; +pub static X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: c_int = 18; +pub static X509_V_ERR_DIFFERENT_CRL_SCOPE: c_int = 44; +pub static X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: c_int = 14; +pub static X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: c_int = 13; +pub static X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: c_int = 15; +pub static X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: c_int = 16; +pub static X509_V_ERR_EXCLUDED_VIOLATION: c_int = 48; +pub static X509_V_ERR_INVALID_CA: c_int = 24; +pub static X509_V_ERR_INVALID_EXTENSION: c_int = 41; +pub static X509_V_ERR_INVALID_NON_CA: c_int = 37; +pub static X509_V_ERR_INVALID_POLICY_EXTENSION: c_int = 42; +pub static X509_V_ERR_INVALID_PURPOSE: c_int = 26; +pub static X509_V_ERR_KEYUSAGE_NO_CERTSIGN: c_int = 32; +pub static X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: c_int = 35; +pub static X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: c_int = 39; +pub static X509_V_ERR_NO_EXPLICIT_POLICY: c_int = 43; +pub static X509_V_ERR_OUT_OF_MEM: c_int = 17; +pub static X509_V_ERR_PATH_LENGTH_EXCEEDED: c_int = 25; +pub static X509_V_ERR_PERMITTED_VIOLATION: c_int = 47; +pub static X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: c_int = 40; +pub static X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: c_int = 38; +pub static X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: c_int = 19; +pub static X509_V_ERR_SUBJECT_ISSUER_MISMATCH: c_int = 29; +pub static X509_V_ERR_SUBTREE_MINMAX: c_int = 49; +pub static X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: c_int = 6; +pub static X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: c_int = 4; +pub static X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: c_int = 5; +pub static X509_V_ERR_UNABLE_TO_GET_CRL: c_int = 3; +pub static X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: c_int = 33; +pub static X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: c_int = 2; +pub static X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: c_int = 20; +pub static X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: c_int = 21; +pub static X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: c_int = 36; +pub static X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: c_int = 34; +pub static X509_V_ERR_UNNESTED_RESOURCE: c_int = 46; +pub static X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: c_int = 52; +pub static X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: c_int = 51; +pub static X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: c_int = 45; +pub static X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: c_int = 53; +pub static X509_V_OK: c_int = 0; + +#[cfg(target_os = "macos", feature = "tlsv1_1")] +#[cfg(target_os = "macos", feature = "tlsv1_2")] +#[link(name="ssl.1.0.0")] +#[link(name="crypto.1.0.0")] +extern {} + +#[cfg(not(target_os = "macos"))] +#[cfg(target_os = "macos", not(feature = "tlsv1_1"), not(feature = "tlsv1_2"))] +#[link(name="ssl")] +#[link(name="crypto")] +extern {} + +#[cfg(target_os = "win32")] +#[link(name="gdi32")] +#[link(name="wsock32")] +extern { } + +extern "C" { + pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int; + pub fn ASN1_STRING_type_new(ty: c_int) -> *mut ASN1_STRING; + + pub fn BIO_free_all(a: *mut BIO); + pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO; + pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int; + pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int; + pub fn BIO_s_mem() -> *const BIO_METHOD; + + pub fn BN_new() -> *mut BIGNUM; + pub fn BN_dup(n: *mut BIGNUM) -> *mut BIGNUM; + pub fn BN_clear_free(bn: *mut BIGNUM); + + pub fn BN_CTX_new() -> *mut BN_CTX; + pub fn BN_CTX_free(ctx: *mut BN_CTX); + + pub fn BN_num_bits(bn: *mut BIGNUM) -> c_int; + pub fn BN_set_negative(bn: *mut BIGNUM, n: c_int); + pub fn BN_set_word(bn: *mut BIGNUM, n: c_ulong) -> c_int; + + /* Arithmetic operations on BIGNUMs */ + pub fn BN_add(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM) -> c_int; + pub fn BN_div(dv: *mut BIGNUM, rem: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_exp(r: *mut BIGNUM, a: *mut BIGNUM, p: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_gcd(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_mod_add(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, m: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_mod_exp(r: *mut BIGNUM, a: *mut BIGNUM, p: *mut BIGNUM, m: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_mod_inverse(r: *mut BIGNUM, a: *mut BIGNUM, n: *mut BIGNUM, ctx: *mut BN_CTX) -> *const BIGNUM; + pub fn BN_mod_mul(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, m: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_mod_sqr(r: *mut BIGNUM, a: *mut BIGNUM, m: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_mod_sub(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, m: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_mul(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_nnmod(rem: *mut BIGNUM, a: *mut BIGNUM, m: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_sqr(r: *mut BIGNUM, a: *mut BIGNUM, ctx: *mut BN_CTX) -> c_int; + pub fn BN_sub(r: *mut BIGNUM, a: *mut BIGNUM, b: *mut BIGNUM) -> c_int; + + /* Bit operations on BIGNUMs */ + pub fn BN_clear_bit(a: *mut BIGNUM, n: c_int) -> c_int; + pub fn BN_is_bit_set(a: *mut BIGNUM, n: c_int) -> c_int; + pub fn BN_lshift(r: *mut BIGNUM, a: *mut BIGNUM, n: c_int) -> c_int; + pub fn BN_lshift1(r: *mut BIGNUM, a: *mut BIGNUM) -> c_int; + pub fn BN_mask_bits(a: *mut BIGNUM, n: c_int) -> c_int; + pub fn BN_rshift(r: *mut BIGNUM, a: *mut BIGNUM, n: c_int) -> c_int; + pub fn BN_set_bit(a: *mut BIGNUM, n: c_int) -> c_int; + pub fn BN_rshift1(r: *mut BIGNUM, a: *mut BIGNUM) -> c_int; + + /* Comparisons on BIGNUMs */ + pub fn BN_cmp(a: *mut BIGNUM, b: *mut BIGNUM) -> c_int; + pub fn BN_ucmp(a: *mut BIGNUM, b: *mut BIGNUM) -> c_int; + pub fn BN_is_zero(a: *mut BIGNUM) -> c_int; + + /* Prime handling */ + pub fn BN_generate_prime_ex(r: *mut BIGNUM, bits: c_int, safe: c_int, add: *mut BIGNUM, rem: *mut BIGNUM, cb: *const c_void) -> c_int; + pub fn BN_is_prime_ex(p: *mut BIGNUM, checks: c_int, ctx: *mut BN_CTX, cb: *const c_void) -> c_int; + pub fn BN_is_prime_fasttest_ex(p: *mut BIGNUM, checks: c_int, ctx: *mut BN_CTX, do_trial_division: c_int, cb: *const c_void) -> c_int; + + /* Random number handling */ + pub fn BN_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int; + pub fn BN_pseudo_rand(r: *mut BIGNUM, bits: c_int, top: c_int, bottom: c_int) -> c_int; + pub fn BN_rand_range(r: *mut BIGNUM, range: *mut BIGNUM) -> c_int; + pub fn BN_pseudo_rand_range(r: *mut BIGNUM, range: *mut BIGNUM) -> c_int; + + /* Conversion from/to binary representation */ + pub fn BN_bin2bn(s: *const u8, size: c_int, ret: *mut BIGNUM) -> *mut BIGNUM; + pub fn BN_bn2bin(a: *mut BIGNUM, to: *mut u8) -> c_int; + + /* Conversion from/to string representation */ + pub fn BN_bn2dec(a: *mut BIGNUM) -> *const c_char; + + pub fn CRYPTO_num_locks() -> c_int; + pub fn CRYPTO_set_locking_callback(func: extern "C" fn(mode: c_int, + n: c_int, + file: *const c_char, + line: c_int)); + pub fn CRYPTO_free(buf: *const c_char); + + pub fn ERR_get_error() -> c_ulong; + + pub fn EVP_md5() -> *const EVP_MD; + pub fn EVP_ripemd160() -> *const EVP_MD; + pub fn EVP_sha1() -> *const EVP_MD; + pub fn EVP_sha224() -> *const EVP_MD; + pub fn EVP_sha256() -> *const EVP_MD; + pub fn EVP_sha384() -> *const EVP_MD; + pub fn EVP_sha512() -> *const EVP_MD; + + pub fn EVP_aes_128_cbc() -> EVP_CIPHER; + pub fn EVP_aes_128_ecb() -> EVP_CIPHER; + // fn EVP_aes_128_ctr() -> EVP_CIPHER; + // fn EVP_aes_128_gcm() -> EVP_CIPHER; + pub fn EVP_aes_256_cbc() -> EVP_CIPHER; + pub fn EVP_aes_256_ecb() -> EVP_CIPHER; + // fn EVP_aes_256_ctr() -> EVP_CIPHER; + // fn EVP_aes_256_gcm() -> EVP_CIPHER; + pub fn EVP_rc4() -> EVP_CIPHER; + + pub fn EVP_CIPHER_CTX_new() -> EVP_CIPHER_CTX; + pub fn EVP_CIPHER_CTX_set_padding(ctx: EVP_CIPHER_CTX, padding: c_int); + pub fn EVP_CIPHER_CTX_free(ctx: EVP_CIPHER_CTX); + + pub fn EVP_CipherInit(ctx: EVP_CIPHER_CTX, evp: EVP_CIPHER, + key: *const u8, iv: *const u8, mode: c_int); + pub fn EVP_CipherUpdate(ctx: EVP_CIPHER_CTX, outbuf: *mut u8, + outlen: &mut c_uint, inbuf: *const u8, inlen: c_int); + pub fn EVP_CipherFinal(ctx: EVP_CIPHER_CTX, res: *mut u8, len: &mut c_int); + + pub fn EVP_DigestInit(ctx: *mut EVP_MD_CTX, typ: *const EVP_MD); + pub fn EVP_DigestUpdate(ctx: *mut EVP_MD_CTX, data: *const u8, n: c_uint); + pub fn EVP_DigestFinal(ctx: *mut EVP_MD_CTX, res: *mut u8, n: *mut u32); + + pub fn EVP_MD_CTX_create() -> *mut EVP_MD_CTX; + pub fn EVP_MD_CTX_destroy(ctx: *mut EVP_MD_CTX); + + pub fn EVP_PKEY_new() -> *mut EVP_PKEY; + pub fn EVP_PKEY_free(k: *mut EVP_PKEY); + pub fn EVP_PKEY_assign(pkey: *mut EVP_PKEY, typ: c_int, key: *const c_char) -> c_int; + pub fn EVP_PKEY_get1_RSA(k: *mut EVP_PKEY) -> *mut RSA; + pub fn EVP_PKEY_set1_RSA(k: *mut EVP_PKEY, r: *mut RSA) -> c_int; + + pub fn HMAC_CTX_init(ctx: *mut HMAC_CTX); + pub fn HMAC_Init_ex(ctx: *mut HMAC_CTX, key: *const u8, keylen: c_int, md: *const EVP_MD, imple: *const ENGINE); + pub fn HMAC_Final(ctx: *mut HMAC_CTX, output: *mut u8, len: *mut c_uint); + pub fn HMAC_Update(ctx: *mut HMAC_CTX, input: *const u8, len: c_uint); + + pub fn PEM_write_bio_PrivateKey(bio: *mut BIO, pkey: *mut EVP_PKEY, cipher: *const EVP_CIPHER, + kstr: *mut c_char, klen: c_int, + callback: *mut c_void, + user_data: *mut c_void) -> c_int; + pub fn PEM_write_bio_X509(bio: *mut BIO, x509: *mut X509) -> c_int; + + pub fn PKCS5_PBKDF2_HMAC_SHA1(pass: *const u8, passlen: c_int, + salt: *const u8, saltlen: c_int, + iter: c_int, keylen: c_int, + out: *mut u8) -> c_int; + + + pub fn RAND_bytes(buf: *mut u8, num: c_int) -> c_int; + + pub fn RSA_generate_key(modsz: c_uint, e: c_uint, cb: *const u8, cbarg: *const u8) -> *mut RSA; + pub fn RSA_private_decrypt(flen: c_uint, from: *const u8, to: *mut u8, k: *mut RSA, + pad: c_int) -> c_int; + pub fn RSA_public_encrypt(flen: c_uint, from: *const u8, to: *mut u8, k: *mut RSA, + pad: c_int) -> c_int; + pub fn RSA_sign(t: c_int, m: *const u8, mlen: c_uint, sig: *mut u8, siglen: *mut c_uint, + k: *mut RSA) -> c_int; + pub fn RSA_size(k: *mut RSA) -> c_uint; + pub fn RSA_verify(t: c_int, m: *const u8, mlen: c_uint, sig: *const u8, siglen: c_uint, + k: *mut RSA) -> c_int; + + pub fn SSL_library_init() -> c_int; + + #[cfg(feature = "sslv2")] + pub fn SSLv2_method() -> *const SSL_METHOD; + pub fn SSLv3_method() -> *const SSL_METHOD; + pub fn TLSv1_method() -> *const SSL_METHOD; + #[cfg(feature = "tlsv1_1")] + pub fn TLSv1_1_method() -> *const SSL_METHOD; + #[cfg(feature = "tlsv1_2")] + pub fn TLSv1_2_method() -> *const SSL_METHOD; + pub fn SSLv23_method() -> *const SSL_METHOD; + + pub fn SSL_new(ctx: *mut SSL_CTX) -> *mut SSL; + pub fn SSL_free(ssl: *mut SSL); + pub fn SSL_set_bio(ssl: *mut SSL, rbio: *mut BIO, wbio: *mut BIO); + pub fn SSL_get_rbio(ssl: *mut SSL) -> *mut BIO; + pub fn SSL_get_wbio(ssl: *mut SSL) -> *mut BIO; + pub fn SSL_connect(ssl: *mut SSL) -> c_int; + pub fn SSL_ctrl(ssl: *mut SSL, cmd: c_int, larg: c_long, + parg: *mut c_void) -> c_long; + pub fn SSL_get_error(ssl: *mut SSL, ret: c_int) -> c_int; + pub fn SSL_read(ssl: *mut SSL, buf: *mut c_void, num: c_int) -> c_int; + pub fn SSL_write(ssl: *mut SSL, buf: *const c_void, num: c_int) -> c_int; + pub fn SSL_get_ex_data_X509_STORE_CTX_idx() -> c_int; + pub fn SSL_get_SSL_CTX(ssl: *mut SSL) -> *mut SSL_CTX; + pub fn SSL_get_current_compression(ssl: *mut SSL) -> *const COMP_METHOD; + + pub fn SSL_COMP_get_name(comp: *const COMP_METHOD) -> *const c_char; + + pub fn SSL_CTX_new(method: *const SSL_METHOD) -> *mut SSL_CTX; + pub fn SSL_CTX_free(ctx: *mut SSL_CTX); + pub fn SSL_CTX_set_verify(ctx: *mut SSL_CTX, mode: c_int, + verify_callback: Option c_int>); + pub fn SSL_CTX_load_verify_locations(ctx: *mut SSL_CTX, CAfile: *const c_char, + CApath: *const c_char) -> c_int; + pub fn SSL_CTX_get_ex_new_index(argl: c_long, argp: *const c_void, + new_func: Option, + dup_func: Option, + free_func: Option) + -> c_int; + pub fn SSL_CTX_set_ex_data(ctx: *mut SSL_CTX, idx: c_int, data: *mut c_void) + -> c_int; + pub fn SSL_CTX_get_ex_data(ctx: *mut SSL_CTX, idx: c_int) -> *mut c_void; + + pub fn SSL_CTX_use_certificate_file(ctx: *mut SSL_CTX, cert_file: *const c_char, file_type: c_int) -> c_int; + pub fn SSL_CTX_use_PrivateKey_file(ctx: *mut SSL_CTX, key_file: *const c_char, file_type: c_int) -> c_int; + + + pub fn X509_add_ext(x: *mut X509, ext: *mut X509_EXTENSION, loc: c_int) -> c_int; + pub fn X509_digest(x: *mut X509, digest: *const EVP_MD, buf: *mut c_char, len: *mut c_uint) -> c_int; + pub fn X509_get_serialNumber(x: *mut X509) -> *mut ASN1_INTEGER; + pub fn X509_get_subject_name(x: *mut X509) -> *mut X509_NAME; + pub fn X509_gmtime_adj(time: *mut ASN1_TIME, adj: c_long) -> *mut ASN1_TIME; + pub fn X509_new() -> *mut X509; + pub fn X509_set_issuer_name(x: *mut X509, name: *mut X509_NAME) -> c_int; + pub fn X509_set_notAfter(x: *mut X509, tm: *const ASN1_TIME) -> c_int; + pub fn X509_set_notBefore(x: *mut X509, tm: *const ASN1_TIME) -> c_int; + pub fn X509_set_version(x: *mut X509, version: c_ulong) -> c_int; + pub fn X509_set_pubkey(x: *mut X509, pkey: *mut EVP_PKEY) -> c_int; + pub fn X509_sign(x: *mut X509, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int; + + pub fn X509_EXTENSION_free(ext: *mut X509_EXTENSION); + + pub fn X509_NAME_add_entry_by_txt(x: *mut X509, field: *const c_char, ty: c_int, bytes: *const c_char, len: c_int, loc: c_int, set: c_int) -> c_int; + + pub fn X509_STORE_CTX_get_current_cert(ct: *mut X509_STORE_CTX) -> *mut X509; + pub fn X509_STORE_CTX_get_error(ctx: *mut X509_STORE_CTX) -> c_int; + pub fn X509_STORE_CTX_get_ex_data(ctx: *mut X509_STORE_CTX, idx: c_int) -> *mut c_void; + + pub fn X509V3_EXT_conf_nid(conf: *mut c_void, ctx: *mut X509V3_CTX, ext_nid: c_int, value: *mut c_char) -> *mut X509_EXTENSION; + pub fn X509V3_set_ctx(ctx: *mut X509V3_CTX, issuer: *mut X509, subject: *mut X509, req: *mut X509_REQ, crl: *mut X509_CRL, flags: c_int); + + pub fn i2d_RSA_PUBKEY(k: *mut RSA, buf: *const *mut u8) -> c_int; + pub fn d2i_RSA_PUBKEY(k: *const *mut RSA, buf: *const *const u8, len: c_uint) -> *mut RSA; + pub fn i2d_RSAPrivateKey(k: *mut RSA, buf: *const *mut u8) -> c_int; + pub fn d2i_RSAPrivateKey(k: *const *mut RSA, buf: *const *const u8, len: c_uint) -> *mut RSA; +} diff --git a/src/lib.rs b/src/lib.rs index d142f86574d4213df3d7102fd554d9928451773c..9aee977d1dfc2b32b6c5c6c9fd03cfd5d898c02f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,5 +15,6 @@ mod asn1; pub mod bn; pub mod bio; pub mod crypto; +pub mod ffi; pub mod ssl; pub mod x509; diff --git a/src/ssl/error.rs b/src/ssl/error.rs index 9af14dd9cde4e787df490a49c342d93cf138ba78..452f8aad8716c8697d6a1be2dc46409fb4278acb 100644 --- a/src/ssl/error.rs +++ b/src/ssl/error.rs @@ -1,7 +1,7 @@ use libc::c_ulong; use std::io::IoError; -use ssl::ffi; +use ffi; /// An SSL error #[deriving(Show, Clone, PartialEq, Eq)] diff --git a/src/ssl/ffi.rs b/src/ssl/ffi.rs deleted file mode 100755 index 02392f748f86a821e0893afb11ddad8a8bf69455..0000000000000000000000000000000000000000 --- a/src/ssl/ffi.rs +++ /dev/null @@ -1,117 +0,0 @@ -#![allow(non_camel_case_types)] - -use libc::{c_int, c_void, c_long, c_ulong, c_char}; - -use bio; -use x509; - -pub type SSL_CTX = c_void; -pub type SSL_METHOD = c_void; -pub type COMP_METHOD = c_void; -pub type SSL = c_void; -pub type CRYPTO_EX_DATA = c_void; - -pub type CRYPTO_EX_new = extern "C" fn(parent: *mut c_void, ptr: *mut c_void, - ad: *const CRYPTO_EX_DATA, idx: c_int, - argl: c_long, argp: *const c_void) -> c_int; -pub type CRYPTO_EX_dup = extern "C" fn(to: *mut CRYPTO_EX_DATA, - from: *mut CRYPTO_EX_DATA, from_d: *mut c_void, - idx: c_int, argl: c_long, argp: *mut c_void) - -> c_int; -pub type CRYPTO_EX_free = extern "C" fn(parent: *mut c_void, ptr: *mut c_void, - ad: *mut CRYPTO_EX_DATA, idx: c_int, - argl: c_long, argp: *mut c_void); - -pub static CRYPTO_LOCK: c_int = 1; - -pub static SSL_ERROR_NONE: c_int = 0; -pub static SSL_ERROR_SSL: c_int = 1; -pub static SSL_ERROR_WANT_READ: c_int = 2; -pub static SSL_ERROR_WANT_WRITE: c_int = 3; -pub static SSL_ERROR_WANT_X509_LOOKUP: c_int = 4; -pub static SSL_ERROR_SYSCALL: c_int = 5; -pub static SSL_ERROR_ZERO_RETURN: c_int = 6; -pub static SSL_ERROR_WANT_CONNECT: c_int = 7; -pub static SSL_ERROR_WANT_ACCEPT: c_int = 8; - -pub static SSL_VERIFY_NONE: c_int = 0; -pub static SSL_VERIFY_PEER: c_int = 1; - -pub static SSL_CTRL_SET_TLSEXT_HOSTNAME: c_int = 55; - -pub static TLSEXT_NAMETYPE_host_name: c_long = 0; - - -#[cfg(target_os = "macos", feature = "tlsv1_1")] -#[cfg(target_os = "macos", feature = "tlsv1_2")] -#[link(name="ssl.1.0.0")] -#[link(name="crypto.1.0.0")] -extern {} - -#[cfg(not(target_os = "macos"))] -#[cfg(target_os = "macos", not(feature = "tlsv1_1"), not(feature = "tlsv1_2"))] -#[link(name="ssl")] -#[link(name="crypto")] -extern {} - -extern "C" { - pub fn CRYPTO_num_locks() -> c_int; - pub fn CRYPTO_set_locking_callback(func: extern "C" fn(mode: c_int, - n: c_int, - file: *const c_char, - line: c_int)); - - pub fn ERR_get_error() -> c_ulong; - - pub fn SSL_library_init() -> c_int; - - #[cfg(feature = "sslv2")] - pub fn SSLv2_method() -> *const SSL_METHOD; - pub fn SSLv3_method() -> *const SSL_METHOD; - pub fn TLSv1_method() -> *const SSL_METHOD; - #[cfg(feature = "tlsv1_1")] - pub fn TLSv1_1_method() -> *const SSL_METHOD; - #[cfg(feature = "tlsv1_2")] - pub fn TLSv1_2_method() -> *const SSL_METHOD; - pub fn SSLv23_method() -> *const SSL_METHOD; - - pub fn SSL_CTX_new(method: *const SSL_METHOD) -> *mut SSL_CTX; - pub fn SSL_CTX_free(ctx: *mut SSL_CTX); - pub fn SSL_CTX_set_verify(ctx: *mut SSL_CTX, mode: c_int, - verify_callback: Option c_int>); - pub fn SSL_CTX_load_verify_locations(ctx: *mut SSL_CTX, CAfile: *const c_char, - CApath: *const c_char) -> c_int; - pub fn SSL_CTX_get_ex_new_index(argl: c_long, argp: *const c_void, - new_func: Option, - dup_func: Option, - free_func: Option) - -> c_int; - pub fn SSL_CTX_set_ex_data(ctx: *mut SSL_CTX, idx: c_int, data: *mut c_void) - -> c_int; - pub fn SSL_CTX_get_ex_data(ctx: *mut SSL_CTX, idx: c_int) -> *mut c_void; - - pub fn SSL_CTX_use_certificate_file(ctx: *mut SSL_CTX, cert_file: *const c_char, file_type: c_int) -> c_int; - pub fn SSL_CTX_use_PrivateKey_file(ctx: *mut SSL_CTX, key_file: *const c_char, file_type: c_int) -> c_int; - - pub fn SSL_new(ctx: *mut SSL_CTX) -> *mut SSL; - pub fn SSL_free(ssl: *mut SSL); - pub fn SSL_set_bio(ssl: *mut SSL, rbio: *mut bio::ffi::BIO, wbio: *mut bio::ffi::BIO); - pub fn SSL_get_rbio(ssl: *mut SSL) -> *mut bio::ffi::BIO; - pub fn SSL_get_wbio(ssl: *mut SSL) -> *mut bio::ffi::BIO; - pub fn SSL_connect(ssl: *mut SSL) -> c_int; - pub fn SSL_ctrl(ssl: *mut SSL, cmd: c_int, larg: c_long, - parg: *mut c_void) -> c_long; - pub fn SSL_get_error(ssl: *mut SSL, ret: c_int) -> c_int; - pub fn SSL_read(ssl: *mut SSL, buf: *mut c_void, num: c_int) -> c_int; - pub fn SSL_write(ssl: *mut SSL, buf: *const c_void, num: c_int) -> c_int; - pub fn SSL_get_ex_data_X509_STORE_CTX_idx() -> c_int; - pub fn SSL_get_SSL_CTX(ssl: *mut SSL) -> *mut SSL_CTX; - pub fn SSL_get_current_compression(ssl: *mut SSL) -> *const COMP_METHOD; - - pub fn SSL_COMP_get_name(comp: *const COMP_METHOD) -> *const c_char; -} - -#[cfg(target_os = "win32")] -#[link(name="gdi32")] -#[link(name="wsock32")] -extern { } diff --git a/src/ssl/mod.rs b/src/ssl/mod.rs index d13972d2fa86b2c270e1d995188739052fd7d04c..1198aa4ad141fa79ed89e6ff9cdb845fb4db591f 100644 --- a/src/ssl/mod.rs +++ b/src/ssl/mod.rs @@ -6,12 +6,12 @@ use std::rt::mutex::NativeMutex; use std::string; use sync::one::{Once, ONCE_INIT}; -use bio::{mod, MemBio}; +use bio::{MemBio}; +use ffi; use ssl::error::{SslError, SslSessionClosed, StreamError}; -use x509::{mod, X509StoreContext, X509FileType}; +use x509::{X509StoreContext, X509FileType}; pub mod error; -mod ffi; #[cfg(test)] mod tests; @@ -95,11 +95,11 @@ extern fn locking_function(mode: c_int, n: c_int, _file: *const c_char, } } -extern fn raw_verify(preverify_ok: c_int, x509_ctx: *mut x509::ffi::X509_STORE_CTX) +extern fn raw_verify(preverify_ok: c_int, x509_ctx: *mut ffi::X509_STORE_CTX) -> c_int { unsafe { let idx = ffi::SSL_get_ex_data_X509_STORE_CTX_idx(); - let ssl = x509::ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx); + let ssl = ffi::X509_STORE_CTX_get_ex_data(x509_ctx, idx); let ssl_ctx = ffi::SSL_get_SSL_CTX(ssl); let verify = ffi::SSL_CTX_get_ex_data(ssl_ctx, VERIFY_IDX); let verify: Option = mem::transmute(verify); @@ -241,7 +241,7 @@ impl Ssl { unsafe { self.wrap_bio(ffi::SSL_get_wbio(self.ssl)) } } - fn wrap_bio<'a>(&'a self, bio: *mut bio::ffi::BIO) -> MemBioRef<'a> { + fn wrap_bio<'a>(&'a self, bio: *mut ffi::BIO) -> MemBioRef<'a> { assert!(bio != ptr::mut_null()); MemBioRef { ssl: self, diff --git a/src/x509/mod.rs b/src/x509/mod.rs index cc911afeb020ccab3b76e574a0005da7f2faff59..c46edc3df09cab5f752e47e76fc62bb5db3efed3 100755 --- a/src/x509/mod.rs +++ b/src/x509/mod.rs @@ -2,11 +2,11 @@ use libc::{c_int, c_long, c_uint}; use std::mem; use std::ptr; -use asn1; use bio::{MemBio}; use crypto::hash::{HashType, evpmd, SHA1}; use crypto::pkey::{PKey}; use crypto::rand::rand_bytes; +use ffi; use ssl::error::{SslError, StreamError}; @@ -200,7 +200,7 @@ impl X509Generator { let value_len = value.len() as c_int; lift_ssl!(key.with_c_str(|key| { value.with_c_str(|value| unsafe { - ffi::X509_NAME_add_entry_by_txt(name, key, asn1::ffi::MBSTRING_UTF8, + ffi::X509_NAME_add_entry_by_txt(name, key, ffi::MBSTRING_UTF8, value, value_len, -1, 0) }) })) @@ -227,7 +227,7 @@ impl X509Generator { let x509 = ffi::X509_new(); try_ssl_null!(x509); try_ssl!(ffi::X509_set_version(x509, 2)); - try_ssl!(asn1::ffi::ASN1_INTEGER_set(ffi::X509_get_serialNumber(x509), X509Generator::random_serial())); + try_ssl!(ffi::ASN1_INTEGER_set(ffi::X509_get_serialNumber(x509), X509Generator::random_serial())); let not_before = ffi::X509_gmtime_adj(ptr::null_mut(), 0); try_ssl_null!(not_before); @@ -317,129 +317,6 @@ pub struct X509Name<'x> { name: *mut ffi::X509_NAME } - -pub mod ffi { - #![allow(non_camel_case_types)] - use libc::{c_void, c_int, c_char, c_ulong, c_long, c_uint}; - - use asn1::ffi::{ASN1_INTEGER, ASN1_TIME}; - use bio::ffi::{BIO}; - use crypto::hash::{EVP_MD}; - use crypto::pkey::{EVP_PKEY}; - - pub type X509_STORE_CTX = c_void; - pub type X509 = c_void; - pub type X509_NAME = c_void; - pub type X509_CRL = c_void; - pub type X509_REQ = c_void; - pub type X509_EXTENSION = c_void; - - #[repr(C)] - pub struct X509V3_CTX { - flags: c_int, - issuer_cert: *mut c_void, - subject_cert: *mut c_void, - subject_req: *mut c_void, - crl: *mut c_void, - db_meth: *mut c_void, - db: *mut c_void, - // I like the last comment line, it is copied from OpenSSL sources: - // Maybe more here - } - - pub static X509_V_OK: c_int = 0; - pub static X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: c_int = 2; - pub static X509_V_ERR_UNABLE_TO_GET_CRL: c_int = 3; - pub static X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: c_int = 4; - pub static X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: c_int = 5; - pub static X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: c_int = 6; - pub static X509_V_ERR_CERT_SIGNATURE_FAILURE: c_int = 7; - pub static X509_V_ERR_CRL_SIGNATURE_FAILURE: c_int = 8; - pub static X509_V_ERR_CERT_NOT_YET_VALID: c_int = 9; - pub static X509_V_ERR_CERT_HAS_EXPIRED: c_int = 10; - pub static X509_V_ERR_CRL_NOT_YET_VALID: c_int = 11; - pub static X509_V_ERR_CRL_HAS_EXPIRED: c_int = 12; - pub static X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: c_int = 13; - pub static X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: c_int = 14; - pub static X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: c_int = 15; - pub static X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: c_int = 16; - pub static X509_V_ERR_OUT_OF_MEM: c_int = 17; - pub static X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: c_int = 18; - pub static X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: c_int = 19; - pub static X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: c_int = 20; - pub static X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: c_int = 21; - pub static X509_V_ERR_CERT_CHAIN_TOO_LONG: c_int = 22; - pub static X509_V_ERR_CERT_REVOKED: c_int = 23; - pub static X509_V_ERR_INVALID_CA: c_int = 24; - pub static X509_V_ERR_PATH_LENGTH_EXCEEDED: c_int = 25; - pub static X509_V_ERR_INVALID_PURPOSE: c_int = 26; - pub static X509_V_ERR_CERT_UNTRUSTED: c_int = 27; - pub static X509_V_ERR_CERT_REJECTED: c_int = 28; - pub static X509_V_ERR_SUBJECT_ISSUER_MISMATCH: c_int = 29; - pub static X509_V_ERR_AKID_SKID_MISMATCH: c_int = 30; - pub static X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: c_int = 31; - pub static X509_V_ERR_KEYUSAGE_NO_CERTSIGN: c_int = 32; - pub static X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: c_int = 33; - pub static X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: c_int = 34; - pub static X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: c_int = 35; - pub static X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: c_int = 36; - pub static X509_V_ERR_INVALID_NON_CA: c_int = 37; - pub static X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: c_int = 38; - pub static X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: c_int = 39; - pub static X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: c_int = 40; - pub static X509_V_ERR_INVALID_EXTENSION: c_int = 41; - pub static X509_V_ERR_INVALID_POLICY_EXTENSION: c_int = 42; - pub static X509_V_ERR_NO_EXPLICIT_POLICY: c_int = 43; - pub static X509_V_ERR_DIFFERENT_CRL_SCOPE: c_int = 44; - pub static X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: c_int = 45; - pub static X509_V_ERR_UNNESTED_RESOURCE: c_int = 46; - pub static X509_V_ERR_PERMITTED_VIOLATION: c_int = 47; - pub static X509_V_ERR_EXCLUDED_VIOLATION: c_int = 48; - pub static X509_V_ERR_SUBTREE_MINMAX: c_int = 49; - pub static X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: c_int = 51; - pub static X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: c_int = 52; - pub static X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: c_int = 53; - pub static X509_V_ERR_CRL_PATH_VALIDATION_ERROR: c_int = 54; - pub static X509_V_ERR_APPLICATION_VERIFICATION: c_int = 50; - - pub static X509_FILETYPE_PEM: c_int = 1; - pub static X509_FILETYPE_ASN1: c_int = 2; - pub static X509_FILETYPE_DEFAULT: c_int = 3; - - pub static NID_key_usage: c_int = 83; - pub static NID_ext_key_usage: c_int = 126; - - - - extern "C" { - 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_current_cert(ct: *mut X509_STORE_CTX) -> *mut X509; - pub fn X509_STORE_CTX_get_error(ctx: *mut X509_STORE_CTX) -> c_int; - - pub fn X509_add_ext(x: *mut X509, ext: *mut X509_EXTENSION, loc: c_int) -> c_int; - pub fn X509_digest(x: *mut X509, digest: *const EVP_MD, buf: *mut c_char, len: *mut c_uint) -> c_int; - pub fn X509_get_serialNumber(x: *mut X509) -> *mut ASN1_INTEGER; - pub fn X509_get_subject_name(x: *mut X509) -> *mut X509_NAME; - pub fn X509_gmtime_adj(time: *mut ASN1_TIME, adj: c_long) -> *mut ASN1_TIME; - pub fn X509_new() -> *mut X509; - pub fn X509_set_issuer_name(x: *mut X509, name: *mut X509_NAME) -> c_int; - pub fn X509_set_notAfter(x: *mut X509, tm: *const ASN1_TIME) -> c_int; - pub fn X509_set_notBefore(x: *mut X509, tm: *const ASN1_TIME) -> c_int; - pub fn X509_set_version(x: *mut X509, version: c_ulong) -> c_int; - pub fn X509_set_pubkey(x: *mut X509, pkey: *mut EVP_PKEY) -> c_int; - pub fn X509_sign(x: *mut X509, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int; - - pub fn X509_NAME_add_entry_by_txt(x: *mut X509, field: *const c_char, ty: c_int, bytes: *const c_char, len: c_int, loc: c_int, set: c_int) -> c_int; - - pub fn X509V3_EXT_conf_nid(conf: *mut c_void, ctx: *mut X509V3_CTX, ext_nid: c_int, value: *mut c_char) -> *mut X509_EXTENSION; - pub fn X509V3_set_ctx(ctx: *mut X509V3_CTX, issuer: *mut X509, subject: *mut X509, req: *mut X509_REQ, crl: *mut X509_CRL, flags: c_int); - - pub fn X509_EXTENSION_free(ext: *mut X509_EXTENSION); - - pub fn PEM_write_bio_X509(bio: *mut BIO, x509: *mut X509) -> c_int; - } -} - macro_rules! make_validation_error( ($ok_val:ident, $($name:ident = $val:ident,)+) => ( pub enum X509ValidationError { @@ -451,8 +328,8 @@ macro_rules! make_validation_error( #[doc(hidden)] pub fn from_raw(err: c_int) -> Option { match err { - self::ffi::$ok_val => None, - $(self::ffi::$val => Some($name),)+ + ffi::$ok_val => None, + $(ffi::$val => Some($name),)+ err => Some(X509UnknownError(err)) } }