Merge pull request #56 from vhbit/single-ffi

Single `ffi` module
This commit is contained in:
Steven Fackler 2014-09-30 02:15:40 -04:00
commit 36977c2aa3
15 changed files with 571 additions and 649 deletions

View File

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

View File

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

View File

@ -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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<bool, SslError> {
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<bool, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<BigNum, SslError> {
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<Ordering> {
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<BigNum, BigNum> 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 {

View File

@ -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<u8> {
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);
}
}
}

View File

@ -14,35 +14,13 @@
* limitations under the License.
*/
use libc::{c_uchar, c_int, c_uint};
use libc::{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]
}
#[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 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
}

View File

@ -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<u8> {
@ -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,

View File

@ -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<u8> {
fn _tostr(&self, f: unsafe extern "C" fn(*mut ffi::RSA, *const *mut u8) -> c_int) -> Vec<u8> {
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<u8> {
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<u8> {
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<String>*/) -> 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<u8> {
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<u8> {
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<u8> {
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);
}
}
}

View File

@ -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<u8> {
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);

View File

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

418
src/ffi.rs Executable file
View File

@ -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<extern fn(c_int, *mut X509_STORE_CTX) -> 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<CRYPTO_EX_new>,
dup_func: Option<CRYPTO_EX_dup>,
free_func: Option<CRYPTO_EX_free>)
-> 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;
}

View File

@ -15,5 +15,6 @@ mod asn1;
pub mod bn;
pub mod bio;
pub mod crypto;
pub mod ffi;
pub mod ssl;
pub mod x509;

View File

@ -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)]

View File

@ -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<extern fn(c_int, *mut x509::ffi::X509_STORE_CTX) -> 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<CRYPTO_EX_new>,
dup_func: Option<CRYPTO_EX_dup>,
free_func: Option<CRYPTO_EX_free>)
-> 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 { }

View File

@ -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<VerifyCallback> = 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,

View File

@ -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<X509ValidationError> {
match err {
self::ffi::$ok_val => None,
$(self::ffi::$val => Some($name),)+
ffi::$ok_val => None,
$(ffi::$val => Some($name),)+
err => Some(X509UnknownError(err))
}
}