commit
36977c2aa3
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
191
src/bn/mod.rs
191
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<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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -15,5 +15,6 @@ mod asn1;
|
|||
pub mod bn;
|
||||
pub mod bio;
|
||||
pub mod crypto;
|
||||
pub mod ffi;
|
||||
pub mod ssl;
|
||||
pub mod x509;
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
117
src/ssl/ffi.rs
117
src/ssl/ffi.rs
|
|
@ -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 { }
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
133
src/x509/mod.rs
133
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<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))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue