Merge remote-tracking branch 'origin/breaks'
This commit is contained in:
commit
c5b2ede282
|
|
@ -6,7 +6,7 @@ addons:
|
|||
- gcc-arm-linux-gnueabihf
|
||||
rust:
|
||||
- nightly
|
||||
- 1.8.0
|
||||
- 1.9.0
|
||||
os:
|
||||
- osx
|
||||
- linux
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ environment:
|
|||
install:
|
||||
- ps: Start-FileDownload "http://slproweb.com/download/Win${env:BITS}OpenSSL-1_0_2h.exe"
|
||||
- Win%BITS%OpenSSL-1_0_2h.exe /SILENT /VERYSILENT /SP- /DIR="C:\OpenSSL"
|
||||
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-1.8.0-${env:TARGET}.exe"
|
||||
- rust-1.8.0-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
|
||||
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-1.9.0-${env:TARGET}.exe"
|
||||
- rust-1.9.0-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
|
||||
- SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin
|
||||
- SET PATH=%PATH%;C:\MinGW\bin
|
||||
- rustc -V
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@ pub type PasswordCallback = extern "C" fn(buf: *mut c_char, size: c_int,
|
|||
pub const BIO_TYPE_NONE: c_int = 0;
|
||||
|
||||
pub const BIO_CTRL_EOF: c_int = 2;
|
||||
pub const BIO_CTRL_INFO: c_int = 3;
|
||||
pub const BIO_CTRL_FLUSH: c_int = 11;
|
||||
pub const BIO_C_SET_BUF_MEM_EOF_RETURN: c_int = 130;
|
||||
|
||||
|
|
@ -453,6 +454,11 @@ fn set_id_callback() {
|
|||
#[cfg(not(unix))]
|
||||
fn set_id_callback() {}
|
||||
|
||||
// macros
|
||||
pub unsafe fn BIO_get_mem_data(b: *mut BIO, pp: *mut *mut c_char) -> c_long {
|
||||
BIO_ctrl(b, BIO_CTRL_INFO, 0, pp as *mut c_void)
|
||||
}
|
||||
|
||||
// True functions
|
||||
extern "C" {
|
||||
pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int;
|
||||
|
|
@ -466,6 +472,7 @@ extern "C" {
|
|||
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 BIO_new_mem_buf(buf: *const c_void, len: c_int) -> *mut BIO;
|
||||
|
||||
pub fn BN_new() -> *mut BIGNUM;
|
||||
pub fn BN_dup(n: *mut BIGNUM) -> *mut BIGNUM;
|
||||
|
|
@ -741,6 +748,7 @@ extern "C" {
|
|||
pub fn SSL_get_wbio(ssl: *mut SSL) -> *mut BIO;
|
||||
pub fn SSL_accept(ssl: *mut SSL) -> c_int;
|
||||
pub fn SSL_connect(ssl: *mut SSL) -> c_int;
|
||||
pub fn SSL_do_handshake(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;
|
||||
|
|
|
|||
|
|
@ -26,9 +26,6 @@ rfc5114 = ["openssl-sys/rfc5114"]
|
|||
ecdh_auto = ["openssl-sys-extras/ecdh_auto"]
|
||||
pkcs5_pbkdf2_hmac = ["openssl-sys/pkcs5_pbkdf2_hmac"]
|
||||
|
||||
nightly = []
|
||||
catch_unwind = []
|
||||
|
||||
[dependencies]
|
||||
bitflags = ">= 0.5.0, < 0.8.0"
|
||||
lazy_static = "0.2"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ use libc::c_long;
|
|||
use std::ptr;
|
||||
|
||||
use ffi;
|
||||
use ssl::error::SslError;
|
||||
|
||||
use error::ErrorStack;
|
||||
|
||||
pub struct Asn1Time {
|
||||
handle: *mut ffi::ASN1_TIME,
|
||||
|
|
@ -19,7 +18,7 @@ impl Asn1Time {
|
|||
}
|
||||
}
|
||||
|
||||
fn new_with_period(period: u64) -> Result<Asn1Time, SslError> {
|
||||
fn new_with_period(period: u64) -> Result<Asn1Time, ErrorStack> {
|
||||
ffi::init();
|
||||
|
||||
let handle = unsafe {
|
||||
|
|
@ -29,7 +28,7 @@ impl Asn1Time {
|
|||
}
|
||||
|
||||
/// Creates a new time on specified interval in days from now
|
||||
pub fn days_from_now(days: u32) -> Result<Asn1Time, SslError> {
|
||||
pub fn days_from_now(days: u32) -> Result<Asn1Time, ErrorStack> {
|
||||
Asn1Time::new_with_period(days as u64 * 60 * 60 * 24)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
use libc::c_int;
|
||||
use ffi;
|
||||
|
||||
use error::ErrorStack;
|
||||
|
||||
pub struct MemBioSlice<'a>(*mut ffi::BIO, PhantomData<&'a [u8]>);
|
||||
|
||||
impl<'a> Drop for MemBioSlice<'a> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
ffi::BIO_free_all(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> MemBioSlice<'a> {
|
||||
pub fn new(buf: &'a [u8]) -> Result<MemBioSlice<'a>, ErrorStack> {
|
||||
ffi::init();
|
||||
|
||||
assert!(buf.len() <= c_int::max_value() as usize);
|
||||
let bio = unsafe {
|
||||
try_ssl_null!(ffi::BIO_new_mem_buf(buf.as_ptr() as *const _, buf.len() as c_int))
|
||||
};
|
||||
|
||||
Ok(MemBioSlice(bio, PhantomData))
|
||||
}
|
||||
|
||||
pub fn get_handle(&self) -> *mut ffi::BIO {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MemBio(*mut ffi::BIO);
|
||||
|
||||
impl Drop for MemBio {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
ffi::BIO_free_all(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MemBio {
|
||||
pub fn new() -> Result<MemBio, ErrorStack> {
|
||||
ffi::init();
|
||||
|
||||
let bio = unsafe {
|
||||
try_ssl_null!(ffi::BIO_new(ffi::BIO_s_mem()))
|
||||
};
|
||||
Ok(MemBio(bio))
|
||||
}
|
||||
|
||||
pub fn get_handle(&self) -> *mut ffi::BIO {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn get_buf(&self) -> &[u8] {
|
||||
unsafe {
|
||||
let mut ptr = ptr::null_mut();
|
||||
let len = ffi::BIO_get_mem_data(self.0, &mut ptr);
|
||||
slice::from_raw_parts(ptr as *const _ as *const _, len as usize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
use libc::{c_void, c_int};
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::ptr;
|
||||
use std::cmp;
|
||||
|
||||
use ffi;
|
||||
use ffi_extras;
|
||||
use ssl::error::SslError;
|
||||
|
||||
pub struct MemBio {
|
||||
bio: *mut ffi::BIO,
|
||||
owned: bool,
|
||||
}
|
||||
|
||||
impl Drop for MemBio {
|
||||
fn drop(&mut self) {
|
||||
if self.owned {
|
||||
unsafe {
|
||||
ffi::BIO_free_all(self.bio);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MemBio {
|
||||
/// Creates a new owned memory based BIO
|
||||
pub fn new() -> Result<MemBio, SslError> {
|
||||
ffi::init();
|
||||
|
||||
let bio = unsafe { ffi::BIO_new(ffi::BIO_s_mem()) };
|
||||
try_ssl_null!(bio);
|
||||
|
||||
Ok(MemBio {
|
||||
bio: bio,
|
||||
owned: true,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a "borrow", i.e. it has no ownership
|
||||
pub fn borrowed(bio: *mut ffi::BIO) -> MemBio {
|
||||
MemBio {
|
||||
bio: bio,
|
||||
owned: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes current bio and returns wrapped value
|
||||
/// Note that data ownership is lost and
|
||||
/// should be managed manually
|
||||
pub unsafe fn unwrap(mut self) -> *mut ffi::BIO {
|
||||
self.owned = false;
|
||||
self.bio
|
||||
}
|
||||
|
||||
/// Temporarily gets wrapped value
|
||||
pub unsafe fn get_handle(&self) -> *mut ffi::BIO {
|
||||
self.bio
|
||||
}
|
||||
|
||||
/// Sets the BIO's EOF state.
|
||||
pub fn set_eof(&self, eof: bool) {
|
||||
let v = if eof {
|
||||
0
|
||||
} else {
|
||||
-1
|
||||
};
|
||||
unsafe {
|
||||
ffi_extras::BIO_set_mem_eof_return(self.bio, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Read for MemBio {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let len = cmp::min(c_int::max_value() as usize, buf.len()) as c_int;
|
||||
let ret = unsafe { ffi::BIO_read(self.bio, buf.as_ptr() as *mut c_void, len) };
|
||||
|
||||
if ret <= 0 {
|
||||
let is_eof = unsafe { ffi_extras::BIO_eof(self.bio) };
|
||||
if is_eof != 0 {
|
||||
Ok(0)
|
||||
} else {
|
||||
Err(io::Error::new(io::ErrorKind::Other, SslError::get()))
|
||||
}
|
||||
} else {
|
||||
Ok(ret as usize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for MemBio {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
let len = cmp::min(c_int::max_value() as usize, buf.len()) as c_int;
|
||||
let ret = unsafe { ffi::BIO_write(self.bio, buf.as_ptr() as *const c_void, len) };
|
||||
|
||||
if ret < 0 {
|
||||
Err(io::Error::new(io::ErrorKind::Other, SslError::get()))
|
||||
} else {
|
||||
Ok(ret as usize)
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ use std::cmp::Ordering;
|
|||
use std::{fmt, ptr, mem};
|
||||
|
||||
use ffi;
|
||||
use ssl::error::SslError;
|
||||
use error::ErrorStack;
|
||||
|
||||
/// A signed arbitrary-precision integer.
|
||||
///
|
||||
|
|
@ -30,7 +30,7 @@ macro_rules! with_ctx(
|
|||
($name:ident, $action:block) => ({
|
||||
let $name = ffi::BN_CTX_new();
|
||||
if ($name).is_null() {
|
||||
Err(SslError::get())
|
||||
Err(ErrorStack::get())
|
||||
} else {
|
||||
let r = $action;
|
||||
ffi::BN_CTX_free($name);
|
||||
|
|
@ -47,7 +47,7 @@ macro_rules! with_bn(
|
|||
if $action {
|
||||
Ok($name)
|
||||
} else {
|
||||
Err(SslError::get())
|
||||
Err(ErrorStack::get())
|
||||
}
|
||||
},
|
||||
Err(err) => Err(err),
|
||||
|
|
@ -62,13 +62,13 @@ macro_rules! with_bn_in_ctx(
|
|||
Ok($name) => {
|
||||
let $ctx_name = ffi::BN_CTX_new();
|
||||
if ($ctx_name).is_null() {
|
||||
Err(SslError::get())
|
||||
Err(ErrorStack::get())
|
||||
} else {
|
||||
let r =
|
||||
if $action {
|
||||
Ok($name)
|
||||
} else {
|
||||
Err(SslError::get())
|
||||
Err(ErrorStack::get())
|
||||
};
|
||||
ffi::BN_CTX_free($ctx_name);
|
||||
r
|
||||
|
|
@ -81,7 +81,7 @@ macro_rules! with_bn_in_ctx(
|
|||
|
||||
impl BigNum {
|
||||
/// Creates a new `BigNum` with the value 0.
|
||||
pub fn new() -> Result<BigNum, SslError> {
|
||||
pub fn new() -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
ffi::init();
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ impl BigNum {
|
|||
}
|
||||
|
||||
/// Creates a new `BigNum` with the given value.
|
||||
pub fn new_from(n: u64) -> Result<BigNum, SslError> {
|
||||
pub fn new_from(n: u64) -> Result<BigNum, ErrorStack> {
|
||||
BigNum::new().and_then(|v| unsafe {
|
||||
try_ssl!(ffi::BN_set_word(v.raw(), n as c_ulong));
|
||||
Ok(v)
|
||||
|
|
@ -99,7 +99,7 @@ impl BigNum {
|
|||
}
|
||||
|
||||
/// Creates a `BigNum` from a decimal string.
|
||||
pub fn from_dec_str(s: &str) -> Result<BigNum, SslError> {
|
||||
pub fn from_dec_str(s: &str) -> Result<BigNum, ErrorStack> {
|
||||
BigNum::new().and_then(|v| unsafe {
|
||||
let c_str = CString::new(s.as_bytes()).unwrap();
|
||||
try_ssl!(ffi::BN_dec2bn(v.raw_ptr(), c_str.as_ptr() as *const _));
|
||||
|
|
@ -108,7 +108,7 @@ impl BigNum {
|
|||
}
|
||||
|
||||
/// Creates a `BigNum` from a hexadecimal string.
|
||||
pub fn from_hex_str(s: &str) -> Result<BigNum, SslError> {
|
||||
pub fn from_hex_str(s: &str) -> Result<BigNum, ErrorStack> {
|
||||
BigNum::new().and_then(|v| unsafe {
|
||||
let c_str = CString::new(s.as_bytes()).unwrap();
|
||||
try_ssl!(ffi::BN_hex2bn(v.raw_ptr(), c_str.as_ptr() as *const _));
|
||||
|
|
@ -116,13 +116,13 @@ impl BigNum {
|
|||
})
|
||||
}
|
||||
|
||||
pub unsafe fn new_from_ffi(orig: *mut ffi::BIGNUM) -> Result<BigNum, SslError> {
|
||||
pub unsafe fn new_from_ffi(orig: *mut ffi::BIGNUM) -> Result<BigNum, ErrorStack> {
|
||||
if orig.is_null() {
|
||||
panic!("Null Pointer was supplied to BigNum::new_from_ffi");
|
||||
}
|
||||
let r = ffi::BN_dup(orig);
|
||||
if r.is_null() {
|
||||
Err(SslError::get())
|
||||
Err(ErrorStack::get())
|
||||
} else {
|
||||
Ok(BigNum(r))
|
||||
}
|
||||
|
|
@ -136,7 +136,7 @@ impl BigNum {
|
|||
///
|
||||
/// assert_eq!(bignum, BigNum::new_from(0x120034).unwrap());
|
||||
/// ```
|
||||
pub fn new_from_slice(n: &[u8]) -> Result<BigNum, SslError> {
|
||||
pub fn new_from_slice(n: &[u8]) -> Result<BigNum, ErrorStack> {
|
||||
BigNum::new().and_then(|v| unsafe {
|
||||
try_ssl_null!(ffi::BN_bin2bn(n.as_ptr(), n.len() as c_int, v.raw()));
|
||||
Ok(v)
|
||||
|
|
@ -153,7 +153,7 @@ impl BigNum {
|
|||
/// assert_eq!(n.checked_sqr().unwrap(), squared);
|
||||
/// assert_eq!(n * n, squared);
|
||||
/// ```
|
||||
pub fn checked_sqr(&self) -> Result<BigNum, SslError> {
|
||||
pub fn checked_sqr(&self) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_sqr(r.raw(), self.raw(), ctx) == 1
|
||||
|
|
@ -162,7 +162,7 @@ impl BigNum {
|
|||
}
|
||||
|
||||
/// Returns the unsigned remainder of the division `self / n`.
|
||||
pub fn checked_nnmod(&self, n: &BigNum) -> Result<BigNum, SslError> {
|
||||
pub fn checked_nnmod(&self, n: &BigNum) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_nnmod(r.raw(), self.raw(), n.raw(), ctx) == 1
|
||||
|
|
@ -181,7 +181,7 @@ impl BigNum {
|
|||
///
|
||||
/// assert_eq!(s.checked_mod_add(a, n).unwrap(), result);
|
||||
/// ```
|
||||
pub fn checked_mod_add(&self, a: &BigNum, n: &BigNum) -> Result<BigNum, SslError> {
|
||||
pub fn checked_mod_add(&self, a: &BigNum, n: &BigNum) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_mod_add(r.raw(), self.raw(), a.raw(), n.raw(), ctx) == 1
|
||||
|
|
@ -190,7 +190,7 @@ impl BigNum {
|
|||
}
|
||||
|
||||
/// Equivalent to `(self - a) mod n`.
|
||||
pub fn checked_mod_sub(&self, a: &BigNum, n: &BigNum) -> Result<BigNum, SslError> {
|
||||
pub fn checked_mod_sub(&self, a: &BigNum, n: &BigNum) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_mod_sub(r.raw(), self.raw(), a.raw(), n.raw(), ctx) == 1
|
||||
|
|
@ -199,7 +199,7 @@ impl BigNum {
|
|||
}
|
||||
|
||||
/// Equivalent to `(self * a) mod n`.
|
||||
pub fn checked_mod_mul(&self, a: &BigNum, n: &BigNum) -> Result<BigNum, SslError> {
|
||||
pub fn checked_mod_mul(&self, a: &BigNum, n: &BigNum) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_mod_mul(r.raw(), self.raw(), a.raw(), n.raw(), ctx) == 1
|
||||
|
|
@ -208,7 +208,7 @@ impl BigNum {
|
|||
}
|
||||
|
||||
/// Equivalent to `self² mod n`.
|
||||
pub fn checked_mod_sqr(&self, n: &BigNum) -> Result<BigNum, SslError> {
|
||||
pub fn checked_mod_sqr(&self, n: &BigNum) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_mod_sqr(r.raw(), self.raw(), n.raw(), ctx) == 1
|
||||
|
|
@ -217,7 +217,7 @@ impl BigNum {
|
|||
}
|
||||
|
||||
/// Raises `self` to the `p`th power.
|
||||
pub fn checked_exp(&self, p: &BigNum) -> Result<BigNum, SslError> {
|
||||
pub fn checked_exp(&self, p: &BigNum) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_exp(r.raw(), self.raw(), p.raw(), ctx) == 1
|
||||
|
|
@ -226,7 +226,7 @@ impl BigNum {
|
|||
}
|
||||
|
||||
/// Equivalent to `self.checked_exp(p) mod n`.
|
||||
pub fn checked_mod_exp(&self, p: &BigNum, n: &BigNum) -> Result<BigNum, SslError> {
|
||||
pub fn checked_mod_exp(&self, p: &BigNum, n: &BigNum) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_mod_exp(r.raw(), self.raw(), p.raw(), n.raw(), ctx) == 1
|
||||
|
|
@ -236,7 +236,7 @@ impl BigNum {
|
|||
|
||||
/// Calculates the modular multiplicative inverse of `self` modulo `n`, that is, an integer `r`
|
||||
/// such that `(self * r) % n == 1`.
|
||||
pub fn checked_mod_inv(&self, n: &BigNum) -> Result<BigNum, SslError> {
|
||||
pub fn checked_mod_inv(&self, n: &BigNum) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
!ffi::BN_mod_inverse(r.raw(), self.raw(), n.raw(), ctx).is_null()
|
||||
|
|
@ -245,60 +245,60 @@ impl BigNum {
|
|||
}
|
||||
|
||||
/// Add an `unsigned long` to `self`. This is more efficient than adding a `BigNum`.
|
||||
pub fn add_word(&mut self, w: c_ulong) -> Result<(), SslError> {
|
||||
pub fn add_word(&mut self, w: c_ulong) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
if ffi::BN_add_word(self.raw(), w) == 1 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(SslError::get())
|
||||
Err(ErrorStack::get())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sub_word(&mut self, w: c_ulong) -> Result<(), SslError> {
|
||||
pub fn sub_word(&mut self, w: c_ulong) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
if ffi::BN_sub_word(self.raw(), w) == 1 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(SslError::get())
|
||||
Err(ErrorStack::get())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mul_word(&mut self, w: c_ulong) -> Result<(), SslError> {
|
||||
pub fn mul_word(&mut self, w: c_ulong) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
if ffi::BN_mul_word(self.raw(), w) == 1 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(SslError::get())
|
||||
Err(ErrorStack::get())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn div_word(&mut self, w: c_ulong) -> Result<c_ulong, SslError> {
|
||||
pub fn div_word(&mut self, w: c_ulong) -> Result<c_ulong, ErrorStack> {
|
||||
unsafe {
|
||||
let result = ffi::BN_div_word(self.raw(), w);
|
||||
if result != !0 as c_ulong {
|
||||
Ok(result)
|
||||
} else {
|
||||
Err(SslError::get())
|
||||
Err(ErrorStack::get())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mod_word(&self, w: c_ulong) -> Result<c_ulong, SslError> {
|
||||
pub fn mod_word(&self, w: c_ulong) -> Result<c_ulong, ErrorStack> {
|
||||
unsafe {
|
||||
let result = ffi::BN_mod_word(self.raw(), w);
|
||||
if result != !0 as c_ulong {
|
||||
Ok(result)
|
||||
} else {
|
||||
Err(SslError::get())
|
||||
Err(ErrorStack::get())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes the greatest common denominator of `self` and `a`.
|
||||
pub fn checked_gcd(&self, a: &BigNum) -> Result<BigNum, SslError> {
|
||||
pub fn checked_gcd(&self, a: &BigNum) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_gcd(r.raw(), self.raw(), a.raw(), ctx) == 1
|
||||
|
|
@ -318,7 +318,7 @@ impl BigNum {
|
|||
safe: bool,
|
||||
add: Option<&BigNum>,
|
||||
rem: Option<&BigNum>)
|
||||
-> Result<BigNum, SslError> {
|
||||
-> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
let add_arg = add.map(|a| a.raw()).unwrap_or(ptr::null_mut());
|
||||
|
|
@ -341,7 +341,7 @@ impl BigNum {
|
|||
/// # Return Value
|
||||
///
|
||||
/// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
|
||||
pub fn is_prime(&self, checks: i32) -> Result<bool, SslError> {
|
||||
pub fn is_prime(&self, checks: i32) -> Result<bool, ErrorStack> {
|
||||
unsafe {
|
||||
with_ctx!(ctx, {
|
||||
Ok(ffi::BN_is_prime_ex(self.raw(), checks as c_int, ctx, ptr::null()) == 1)
|
||||
|
|
@ -358,7 +358,7 @@ impl BigNum {
|
|||
/// # Return Value
|
||||
///
|
||||
/// Returns `true` if `self` is prime with an error probability of less than `0.25 ^ checks`.
|
||||
pub fn is_prime_fast(&self, checks: i32, do_trial_division: bool) -> Result<bool, SslError> {
|
||||
pub fn is_prime_fast(&self, checks: i32, do_trial_division: bool) -> Result<bool, ErrorStack> {
|
||||
unsafe {
|
||||
with_ctx!(ctx, {
|
||||
Ok(ffi::BN_is_prime_fasttest_ex(self.raw(),
|
||||
|
|
@ -377,7 +377,7 @@ impl BigNum {
|
|||
/// * `bits`: Length of the number in bits.
|
||||
/// * `prop`: The desired properties of the number.
|
||||
/// * `odd`: If `true`, the generated number will be odd.
|
||||
pub fn checked_new_random(bits: i32, prop: RNGProperty, odd: bool) -> Result<BigNum, SslError> {
|
||||
pub fn checked_new_random(bits: i32, prop: RNGProperty, odd: bool) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_rand(r.raw(), bits as c_int, prop as c_int, odd as c_int) == 1
|
||||
|
|
@ -389,7 +389,7 @@ impl BigNum {
|
|||
pub fn checked_new_pseudo_random(bits: i32,
|
||||
prop: RNGProperty,
|
||||
odd: bool)
|
||||
-> Result<BigNum, SslError> {
|
||||
-> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
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
|
||||
|
|
@ -399,7 +399,7 @@ impl BigNum {
|
|||
|
||||
/// Generates a cryptographically strong pseudo-random `BigNum` `r` in the range
|
||||
/// `0 <= r < self`.
|
||||
pub fn checked_rand_in_range(&self) -> Result<BigNum, SslError> {
|
||||
pub fn checked_rand_in_range(&self) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_rand_range(r.raw(), self.raw()) == 1
|
||||
|
|
@ -408,7 +408,7 @@ impl BigNum {
|
|||
}
|
||||
|
||||
/// The cryptographically weak counterpart to `checked_rand_in_range`.
|
||||
pub fn checked_pseudo_rand_in_range(&self) -> Result<BigNum, SslError> {
|
||||
pub fn checked_pseudo_rand_in_range(&self) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_pseudo_rand_range(r.raw(), self.raw()) == 1
|
||||
|
|
@ -419,12 +419,12 @@ impl BigNum {
|
|||
/// Sets bit `n`. Equivalent to `self |= (1 << n)`.
|
||||
///
|
||||
/// When setting a bit outside of `self`, it is expanded.
|
||||
pub fn set_bit(&mut self, n: i32) -> Result<(), SslError> {
|
||||
pub fn set_bit(&mut self, n: i32) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
if ffi::BN_set_bit(self.raw(), n as c_int) == 1 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(SslError::get())
|
||||
Err(ErrorStack::get())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -432,12 +432,12 @@ impl BigNum {
|
|||
/// Clears bit `n`, setting it to 0. Equivalent to `self &= ~(1 << n)`.
|
||||
///
|
||||
/// When clearing a bit outside of `self`, an error is returned.
|
||||
pub fn clear_bit(&mut self, n: i32) -> Result<(), SslError> {
|
||||
pub fn clear_bit(&mut self, n: i32) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
if ffi::BN_clear_bit(self.raw(), n as c_int) == 1 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(SslError::get())
|
||||
Err(ErrorStack::get())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -450,12 +450,12 @@ impl BigNum {
|
|||
/// Truncates `self` to the lowest `n` bits.
|
||||
///
|
||||
/// An error occurs if `self` is already shorter than `n` bits.
|
||||
pub fn mask_bits(&mut self, n: i32) -> Result<(), SslError> {
|
||||
pub fn mask_bits(&mut self, n: i32) -> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
if ffi::BN_mask_bits(self.raw(), n as c_int) == 1 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(SslError::get())
|
||||
Err(ErrorStack::get())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -478,7 +478,7 @@ impl BigNum {
|
|||
/// // (-8) << 1 == -16
|
||||
/// assert_eq!(s.checked_shl1().unwrap(), result);
|
||||
/// ```
|
||||
pub fn checked_shl1(&self) -> Result<BigNum, SslError> {
|
||||
pub fn checked_shl1(&self) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn!(r, {
|
||||
ffi::BN_lshift1(r.raw(), self.raw()) == 1
|
||||
|
|
@ -487,7 +487,7 @@ impl BigNum {
|
|||
}
|
||||
|
||||
/// Returns `self`, shifted right by 1 bit. `self` may be negative.
|
||||
pub fn checked_shr1(&self) -> Result<BigNum, SslError> {
|
||||
pub fn checked_shr1(&self) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn!(r, {
|
||||
ffi::BN_rshift1(r.raw(), self.raw()) == 1
|
||||
|
|
@ -495,7 +495,7 @@ impl BigNum {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn checked_add(&self, a: &BigNum) -> Result<BigNum, SslError> {
|
||||
pub fn checked_add(&self, a: &BigNum) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn!(r, {
|
||||
ffi::BN_add(r.raw(), self.raw(), a.raw()) == 1
|
||||
|
|
@ -503,7 +503,7 @@ impl BigNum {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn checked_sub(&self, a: &BigNum) -> Result<BigNum, SslError> {
|
||||
pub fn checked_sub(&self, a: &BigNum) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn!(r, {
|
||||
ffi::BN_sub(r.raw(), self.raw(), a.raw()) == 1
|
||||
|
|
@ -511,7 +511,7 @@ impl BigNum {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn checked_mul(&self, a: &BigNum) -> Result<BigNum, SslError> {
|
||||
pub fn checked_mul(&self, a: &BigNum) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_mul(r.raw(), self.raw(), a.raw(), ctx) == 1
|
||||
|
|
@ -519,7 +519,7 @@ impl BigNum {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn checked_div(&self, a: &BigNum) -> Result<BigNum, SslError> {
|
||||
pub fn checked_div(&self, a: &BigNum) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_div(r.raw(), ptr::null_mut(), self.raw(), a.raw(), ctx) == 1
|
||||
|
|
@ -527,7 +527,7 @@ impl BigNum {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn checked_mod(&self, a: &BigNum) -> Result<BigNum, SslError> {
|
||||
pub fn checked_mod(&self, a: &BigNum) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn_in_ctx!(r, ctx, {
|
||||
ffi::BN_div(ptr::null_mut(), r.raw(), self.raw(), a.raw(), ctx) == 1
|
||||
|
|
@ -535,7 +535,7 @@ impl BigNum {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn checked_shl(&self, a: &i32) -> Result<BigNum, SslError> {
|
||||
pub fn checked_shl(&self, a: &i32) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn!(r, {
|
||||
ffi::BN_lshift(r.raw(), self.raw(), *a as c_int) == 1
|
||||
|
|
@ -543,7 +543,7 @@ impl BigNum {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn checked_shr(&self, a: &i32) -> Result<BigNum, SslError> {
|
||||
pub fn checked_shr(&self, a: &i32) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
with_bn!(r, {
|
||||
ffi::BN_rshift(r.raw(), self.raw(), *a as c_int) == 1
|
||||
|
|
|
|||
|
|
@ -1,25 +1,21 @@
|
|||
use ffi;
|
||||
use std::fmt;
|
||||
use ssl::error::{SslError, StreamError};
|
||||
use error::ErrorStack;
|
||||
use std::ptr;
|
||||
use std::io::{self, Read, Write};
|
||||
use libc::{c_uint, c_int};
|
||||
use libc::{c_uint, c_int, c_char, c_void};
|
||||
|
||||
use bn::BigNum;
|
||||
use bio::MemBio;
|
||||
use bio::{MemBio, MemBioSlice};
|
||||
use crypto::hash;
|
||||
use crypto::HashTypeInternals;
|
||||
|
||||
#[cfg(feature = "catch_unwind")]
|
||||
use libc::{c_char, c_void};
|
||||
#[cfg(feature = "catch_unwind")]
|
||||
use crypto::util::{CallbackState, invoke_passwd_cb};
|
||||
|
||||
|
||||
/// Builder for upfront DSA parameter generateration
|
||||
pub struct DSAParams(*mut ffi::DSA);
|
||||
|
||||
impl DSAParams {
|
||||
pub fn with_size(size: usize) -> Result<DSAParams, SslError> {
|
||||
pub fn with_size(size: usize) -> Result<DSAParams, ErrorStack> {
|
||||
unsafe {
|
||||
// Wrap it so that if we panic we'll call the dtor
|
||||
let dsa = DSAParams(try_ssl_null!(ffi::DSA_new()));
|
||||
|
|
@ -30,7 +26,7 @@ impl DSAParams {
|
|||
}
|
||||
|
||||
/// Generate a key pair from the initialized parameters
|
||||
pub fn generate(self) -> Result<DSA, SslError> {
|
||||
pub fn generate(self) -> Result<DSA, ErrorStack> {
|
||||
unsafe {
|
||||
try_ssl!(ffi::DSA_generate_key(self.0));
|
||||
let dsa = DSA(self.0);
|
||||
|
|
@ -66,17 +62,15 @@ impl DSA {
|
|||
|
||||
/// Generate a DSA key pair
|
||||
/// For more complicated key generation scenarios see the `DSAParams` type
|
||||
pub fn generate(size: usize) -> Result<DSA, SslError> {
|
||||
pub fn generate(size: usize) -> Result<DSA, ErrorStack> {
|
||||
let params = try!(DSAParams::with_size(size));
|
||||
params.generate()
|
||||
}
|
||||
|
||||
/// Reads a DSA private key from PEM formatted data.
|
||||
pub fn private_key_from_pem<R>(reader: &mut R) -> Result<DSA, SslError>
|
||||
where R: Read
|
||||
{
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
|
||||
pub fn private_key_from_pem(buf: &[u8]) -> Result<DSA, ErrorStack> {
|
||||
ffi::init();
|
||||
let mem_bio = try!(MemBioSlice::new(buf));
|
||||
|
||||
unsafe {
|
||||
let dsa = try_ssl_null!(ffi::PEM_read_bio_DSAPrivateKey(mem_bio.get_handle(),
|
||||
|
|
@ -94,15 +88,12 @@ impl DSA {
|
|||
///
|
||||
/// The callback will be passed the password buffer and should return the number of characters
|
||||
/// placed into the buffer.
|
||||
///
|
||||
/// Requires the `catch_unwind` feature.
|
||||
#[cfg(feature = "catch_unwind")]
|
||||
pub fn private_key_from_pem_cb<R, F>(reader: &mut R, pass_cb: F) -> Result<DSA, SslError>
|
||||
where R: Read, F: FnOnce(&mut [c_char]) -> usize
|
||||
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<DSA, ErrorStack>
|
||||
where F: FnOnce(&mut [c_char]) -> usize
|
||||
{
|
||||
ffi::init();
|
||||
let mut cb = CallbackState::new(pass_cb);
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
|
||||
let mem_bio = try!(MemBioSlice::new(buf));
|
||||
|
||||
unsafe {
|
||||
let cb_ptr = &mut cb as *mut _ as *mut c_void;
|
||||
|
|
@ -117,11 +108,10 @@ impl DSA {
|
|||
}
|
||||
|
||||
/// Writes an DSA private key as unencrypted PEM formatted data
|
||||
pub fn private_key_to_pem<W>(&self, writer: &mut W) -> Result<(), SslError>
|
||||
where W: Write
|
||||
pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack>
|
||||
{
|
||||
assert!(self.has_private_key());
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
let mem_bio = try!(MemBio::new());
|
||||
|
||||
unsafe {
|
||||
try_ssl!(ffi::PEM_write_bio_DSAPrivateKey(mem_bio.get_handle(), self.0,
|
||||
|
|
@ -129,18 +119,15 @@ impl DSA {
|
|||
None, ptr::null_mut()))
|
||||
};
|
||||
|
||||
|
||||
try!(io::copy(&mut mem_bio, writer).map_err(StreamError));
|
||||
Ok(())
|
||||
Ok(mem_bio.get_buf().to_owned())
|
||||
}
|
||||
|
||||
/// Reads an DSA public key from PEM formatted data.
|
||||
pub fn public_key_from_pem<R>(reader: &mut R) -> Result<DSA, SslError>
|
||||
where R: Read
|
||||
pub fn public_key_from_pem(buf: &[u8]) -> Result<DSA, ErrorStack>
|
||||
{
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
|
||||
ffi::init();
|
||||
|
||||
let mem_bio = try!(MemBioSlice::new(buf));
|
||||
unsafe {
|
||||
let dsa = try_ssl_null!(ffi::PEM_read_bio_DSA_PUBKEY(mem_bio.get_handle(),
|
||||
ptr::null_mut(),
|
||||
|
|
@ -151,27 +138,22 @@ impl DSA {
|
|||
}
|
||||
|
||||
/// Writes an DSA public key as PEM formatted data
|
||||
pub fn public_key_to_pem<W>(&self, writer: &mut W) -> Result<(), SslError>
|
||||
where W: Write
|
||||
{
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
|
||||
pub fn public_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mem_bio = try!(MemBio::new());
|
||||
unsafe { try_ssl!(ffi::PEM_write_bio_DSA_PUBKEY(mem_bio.get_handle(), self.0)) };
|
||||
|
||||
try!(io::copy(&mut mem_bio, writer).map_err(StreamError));
|
||||
Ok(())
|
||||
Ok(mem_bio.get_buf().to_owned())
|
||||
}
|
||||
|
||||
pub fn size(&self) -> Result<isize, SslError> {
|
||||
pub fn size(&self) -> Option<u32> {
|
||||
if self.has_q() {
|
||||
unsafe { Ok(ffi::DSA_size(self.0) as isize) }
|
||||
unsafe { Some(ffi::DSA_size(self.0) as u32) }
|
||||
} else {
|
||||
Err(SslError::OpenSslErrors(vec![]))
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sign(&self, hash: hash::Type, message: &[u8]) -> Result<Vec<u8>, SslError> {
|
||||
let k_len = try!(self.size()) as c_uint;
|
||||
pub fn sign(&self, hash: hash::Type, message: &[u8]) -> Result<Vec<u8>, ErrorStack> {
|
||||
let k_len = self.size().expect("DSA missing a q") as c_uint;
|
||||
let mut sig = vec![0; k_len as usize];
|
||||
let mut sig_len = k_len;
|
||||
assert!(self.has_private_key());
|
||||
|
|
@ -189,7 +171,7 @@ impl DSA {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn verify(&self, hash: hash::Type, message: &[u8], sig: &[u8]) -> Result<bool, SslError> {
|
||||
pub fn verify(&self, hash: hash::Type, message: &[u8], sig: &[u8]) -> Result<bool, ErrorStack> {
|
||||
unsafe {
|
||||
let result = ffi::DSA_verify(hash.as_nid() as c_int,
|
||||
message.as_ptr(),
|
||||
|
|
@ -208,7 +190,7 @@ impl DSA {
|
|||
}
|
||||
|
||||
// The following getters are unsafe, since BigNum::new_from_ffi fails upon null pointers
|
||||
pub fn p(&self) -> Result<BigNum, SslError> {
|
||||
pub fn p(&self) -> Result<BigNum, ErrorStack> {
|
||||
unsafe { BigNum::new_from_ffi((*self.0).p) }
|
||||
}
|
||||
|
||||
|
|
@ -216,7 +198,7 @@ impl DSA {
|
|||
unsafe { !(*self.0).p.is_null() }
|
||||
}
|
||||
|
||||
pub fn q(&self) -> Result<BigNum, SslError> {
|
||||
pub fn q(&self) -> Result<BigNum, ErrorStack> {
|
||||
unsafe { BigNum::new_from_ffi((*self.0).q) }
|
||||
}
|
||||
|
||||
|
|
@ -224,7 +206,7 @@ impl DSA {
|
|||
unsafe { !(*self.0).q.is_null() }
|
||||
}
|
||||
|
||||
pub fn g(&self) -> Result<BigNum, SslError> {
|
||||
pub fn g(&self) -> Result<BigNum, ErrorStack> {
|
||||
unsafe { BigNum::new_from_ffi((*self.0).g) }
|
||||
}
|
||||
|
||||
|
|
@ -249,19 +231,18 @@ impl fmt::Debug for DSA {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::fs::File;
|
||||
use std::io::{Write, Cursor};
|
||||
use std::io::Write;
|
||||
use libc::c_char;
|
||||
|
||||
use super::*;
|
||||
use crypto::hash::*;
|
||||
|
||||
#[test]
|
||||
pub fn test_generate() {
|
||||
let key = DSA::generate(1024).unwrap();
|
||||
let mut priv_buf = Cursor::new(vec![]);
|
||||
let mut pub_buf = Cursor::new(vec![]);
|
||||
|
||||
key.public_key_to_pem(&mut pub_buf).unwrap();
|
||||
key.private_key_to_pem(&mut priv_buf).unwrap();
|
||||
key.public_key_to_pem().unwrap();
|
||||
key.private_key_to_pem().unwrap();
|
||||
|
||||
let input: Vec<u8> = (0..25).cycle().take(1024).collect();
|
||||
|
||||
|
|
@ -281,13 +262,13 @@ mod test {
|
|||
let input: Vec<u8> = (0..25).cycle().take(1024).collect();
|
||||
|
||||
let private_key = {
|
||||
let mut buffer = File::open("test/dsa.pem").unwrap();
|
||||
DSA::private_key_from_pem(&mut buffer).unwrap()
|
||||
let key = include_bytes!("../../test/dsa.pem");
|
||||
DSA::private_key_from_pem(key).unwrap()
|
||||
};
|
||||
|
||||
let public_key = {
|
||||
let mut buffer = File::open("test/dsa.pem.pub").unwrap();
|
||||
DSA::public_key_from_pem(&mut buffer).unwrap()
|
||||
let key = include_bytes!("../../test/dsa.pem.pub");
|
||||
DSA::public_key_from_pem(key).unwrap()
|
||||
};
|
||||
|
||||
let digest = {
|
||||
|
|
@ -305,13 +286,13 @@ mod test {
|
|||
pub fn test_sign_verify_fail() {
|
||||
let input: Vec<u8> = (0..25).cycle().take(128).collect();
|
||||
let private_key = {
|
||||
let mut buffer = File::open("test/dsa.pem").unwrap();
|
||||
DSA::private_key_from_pem(&mut buffer).unwrap()
|
||||
let key = include_bytes!("../../test/dsa.pem");
|
||||
DSA::private_key_from_pem(key).unwrap()
|
||||
};
|
||||
|
||||
let public_key = {
|
||||
let mut buffer = File::open("test/dsa.pem.pub").unwrap();
|
||||
DSA::public_key_from_pem(&mut buffer).unwrap()
|
||||
let key = include_bytes!("../../test/dsa.pem.pub");
|
||||
DSA::public_key_from_pem(key).unwrap()
|
||||
};
|
||||
|
||||
let digest = {
|
||||
|
|
@ -331,18 +312,17 @@ mod test {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "catch_unwind")]
|
||||
pub fn test_password() {
|
||||
let mut password_queried = false;
|
||||
let mut buffer = File::open("test/dsa-encrypted.pem").unwrap();
|
||||
DSA::private_key_from_pem_cb(&mut buffer, |password| {
|
||||
let key = include_bytes!("../../test/dsa-encrypted.pem");
|
||||
DSA::private_key_from_pem_cb(key, |password| {
|
||||
password_queried = true;
|
||||
password[0] = b'm' as _;
|
||||
password[1] = b'y' as _;
|
||||
password[2] = b'p' as _;
|
||||
password[3] = b'a' as _;
|
||||
password[4] = b's' as _;
|
||||
password[5] = b's' as _;
|
||||
password[0] = b'm' as c_char;
|
||||
password[1] = b'y' as c_char;
|
||||
password[2] = b'p' as c_char;
|
||||
password[3] = b'a' as c_char;
|
||||
password[4] = b's' as c_char;
|
||||
password[5] = b's' as c_char;
|
||||
6
|
||||
}).unwrap();
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ pub mod symm;
|
|||
pub mod memcmp;
|
||||
pub mod rsa;
|
||||
pub mod dsa;
|
||||
#[cfg(feature = "catch_unwind")]
|
||||
mod util;
|
||||
|
||||
mod symm_internal;
|
||||
|
|
|
|||
|
|
@ -1,21 +1,15 @@
|
|||
use libc::{c_int, c_uint, c_ulong};
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use libc::{c_int, c_uint, c_ulong, c_void, c_char};
|
||||
use std::iter::repeat;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use bio::MemBio;
|
||||
use bio::{MemBio, MemBioSlice};
|
||||
|
||||
use crypto::HashTypeInternals;
|
||||
use crypto::hash;
|
||||
use crypto::hash::Type as HashType;
|
||||
use ffi;
|
||||
use ssl::error::{SslError, StreamError};
|
||||
use crypto::rsa::RSA;
|
||||
|
||||
#[cfg(feature = "catch_unwind")]
|
||||
use libc::{c_void, c_char};
|
||||
#[cfg(feature = "catch_unwind")]
|
||||
use error::ErrorStack;
|
||||
use crypto::util::{CallbackState, invoke_passwd_cb};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
|
@ -80,17 +74,14 @@ impl PKey {
|
|||
}
|
||||
|
||||
/// Reads private key from PEM, takes ownership of handle
|
||||
pub fn private_key_from_pem<R>(reader: &mut R) -> Result<PKey, SslError>
|
||||
where R: Read
|
||||
{
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
|
||||
|
||||
pub fn private_key_from_pem(buf: &[u8]) -> Result<PKey, ErrorStack> {
|
||||
let mem_bio = try!(MemBioSlice::new(buf));
|
||||
unsafe {
|
||||
let evp = try_ssl_null!(ffi::PEM_read_bio_PrivateKey(mem_bio.get_handle(),
|
||||
ptr::null_mut(),
|
||||
None,
|
||||
ptr::null_mut()));
|
||||
|
||||
Ok(PKey {
|
||||
evp: evp as *mut ffi::EVP_PKEY,
|
||||
parts: Parts::Both,
|
||||
|
|
@ -103,17 +94,11 @@ impl PKey {
|
|||
///
|
||||
/// The callback will be passed the password buffer and should return the number of characters
|
||||
/// placed into the buffer.
|
||||
///
|
||||
/// Requires the `catch_unwind` feature.
|
||||
#[cfg(feature = "catch_unwind")]
|
||||
pub fn private_key_from_pem_cb<R, F>(reader: &mut R, pass_cb: F) -> Result<PKey, SslError>
|
||||
where R: Read, F: FnOnce(&mut [c_char]) -> usize
|
||||
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<PKey, ErrorStack>
|
||||
where F: FnOnce(&mut [c_char]) -> usize
|
||||
{
|
||||
let mut cb = CallbackState::new(pass_cb);
|
||||
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
|
||||
|
||||
let mem_bio = try!(MemBioSlice::new(buf));
|
||||
unsafe {
|
||||
let evp = try_ssl_null!(ffi::PEM_read_bio_PrivateKey(mem_bio.get_handle(),
|
||||
ptr::null_mut(),
|
||||
|
|
@ -128,12 +113,8 @@ impl PKey {
|
|||
}
|
||||
|
||||
/// Reads public key from PEM, takes ownership of handle
|
||||
pub fn public_key_from_pem<R>(reader: &mut R) -> Result<PKey, SslError>
|
||||
where R: Read
|
||||
{
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
|
||||
|
||||
pub fn public_key_from_pem(buf: &[u8]) -> Result<PKey, ErrorStack> {
|
||||
let mem_bio = try!(MemBioSlice::new(buf));
|
||||
unsafe {
|
||||
let evp = try_ssl_null!(ffi::PEM_read_bio_PUBKEY(mem_bio.get_handle(),
|
||||
ptr::null_mut(),
|
||||
|
|
@ -147,13 +128,13 @@ impl PKey {
|
|||
}
|
||||
|
||||
/// Reads an RSA private key from PEM, takes ownership of handle
|
||||
pub fn private_rsa_key_from_pem<R>(reader: &mut R) -> Result<PKey, SslError>
|
||||
where R: Read
|
||||
{
|
||||
let rsa = try!(RSA::private_key_from_pem(reader));
|
||||
pub fn private_rsa_key_from_pem(buf: &[u8]) -> Result<PKey, ErrorStack> {
|
||||
let rsa = try!(RSA::private_key_from_pem(buf));
|
||||
unsafe {
|
||||
let evp = try_ssl_null!(ffi::EVP_PKEY_new());
|
||||
try_ssl!(ffi::EVP_PKEY_set1_RSA(evp, rsa.as_ptr()));
|
||||
if ffi::EVP_PKEY_set1_RSA(evp, rsa.as_ptr()) == 0 {
|
||||
return Err(ErrorStack::get());
|
||||
}
|
||||
|
||||
Ok(PKey {
|
||||
evp: evp,
|
||||
|
|
@ -163,13 +144,13 @@ impl PKey {
|
|||
}
|
||||
|
||||
/// Reads an RSA public key from PEM, takes ownership of handle
|
||||
pub fn public_rsa_key_from_pem<R>(reader: &mut R) -> Result<PKey, SslError>
|
||||
where R: Read
|
||||
{
|
||||
let rsa = try!(RSA::public_key_from_pem(reader));
|
||||
pub fn public_rsa_key_from_pem(buf: &[u8]) -> Result<PKey, ErrorStack> {
|
||||
let rsa = try!(RSA::public_key_from_pem(buf));
|
||||
unsafe {
|
||||
let evp = try_ssl_null!(ffi::EVP_PKEY_new());
|
||||
try_ssl!(ffi::EVP_PKEY_set1_RSA(evp, rsa.as_ptr()));
|
||||
if ffi::EVP_PKEY_set1_RSA(evp, rsa.as_ptr()) == 0 {
|
||||
return Err(ErrorStack::get());
|
||||
}
|
||||
|
||||
Ok(PKey {
|
||||
evp: evp,
|
||||
|
|
@ -282,10 +263,8 @@ impl PKey {
|
|||
|
||||
/// Stores private key as a PEM
|
||||
// FIXME: also add password and encryption
|
||||
pub fn write_pem<W: Write>(&self,
|
||||
writer: &mut W /* , password: Option<String> */)
|
||||
-> Result<(), SslError> {
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
pub fn write_pem(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mem_bio = try!(MemBio::new());
|
||||
unsafe {
|
||||
try_ssl!(ffi::PEM_write_bio_PrivateKey(mem_bio.get_handle(),
|
||||
self.evp,
|
||||
|
|
@ -296,20 +275,14 @@ impl PKey {
|
|||
ptr::null_mut()));
|
||||
|
||||
}
|
||||
let mut buf = vec![];
|
||||
try!(mem_bio.read_to_end(&mut buf).map_err(StreamError));
|
||||
writer.write_all(&buf).map_err(StreamError)
|
||||
Ok(mem_bio.get_buf().to_owned())
|
||||
}
|
||||
|
||||
/// Stores public key as a PEM
|
||||
pub fn write_pub_pem<W: Write>(&self,
|
||||
writer: &mut W /* , password: Option<String> */)
|
||||
-> Result<(), SslError> {
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
pub fn write_pub_pem(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mem_bio = try!(MemBio::new());
|
||||
unsafe { try_ssl!(ffi::PEM_write_bio_PUBKEY(mem_bio.get_handle(), self.evp)) }
|
||||
let mut buf = vec![];
|
||||
try!(mem_bio.read_to_end(&mut buf).map_err(StreamError));
|
||||
writer.write_all(&buf).map_err(StreamError)
|
||||
Ok(mem_bio.get_buf().to_owned())
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -394,7 +367,7 @@ impl PKey {
|
|||
openssl_padding_code(padding));
|
||||
|
||||
if rv < 0 as c_int {
|
||||
// println!("{:?}", SslError::get());
|
||||
// println!("{:?}", ErrorStack::get());
|
||||
vec![]
|
||||
} else {
|
||||
r.truncate(rv as usize);
|
||||
|
|
@ -650,8 +623,6 @@ impl Clone for PKey {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::Path;
|
||||
use std::fs::File;
|
||||
use crypto::hash::Type::{MD5, SHA1};
|
||||
use crypto::rsa::RSA;
|
||||
|
||||
|
|
@ -695,42 +666,26 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_private_key_from_pem() {
|
||||
let key_path = Path::new("test/key.pem");
|
||||
let mut file = File::open(&key_path)
|
||||
.ok()
|
||||
.expect("Failed to open `test/key.pem`");
|
||||
|
||||
super::PKey::private_key_from_pem(&mut file).unwrap();
|
||||
let key = include_bytes!("../../test/key.pem");
|
||||
super::PKey::private_key_from_pem(key).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_public_key_from_pem() {
|
||||
let key_path = Path::new("test/key.pem.pub");
|
||||
let mut file = File::open(&key_path)
|
||||
.ok()
|
||||
.expect("Failed to open `test/key.pem.pub`");
|
||||
|
||||
super::PKey::public_key_from_pem(&mut file).unwrap();
|
||||
let key = include_bytes!("../../test/key.pem.pub");
|
||||
super::PKey::public_key_from_pem(key).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_private_rsa_key_from_pem() {
|
||||
let key_path = Path::new("test/key.pem");
|
||||
let mut file = File::open(&key_path)
|
||||
.ok()
|
||||
.expect("Failed to open `test/key.pem`");
|
||||
|
||||
super::PKey::private_rsa_key_from_pem(&mut file).unwrap();
|
||||
let key = include_bytes!("../../test/key.pem");
|
||||
super::PKey::private_rsa_key_from_pem(key).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_public_rsa_key_from_pem() {
|
||||
let key_path = Path::new("test/key.pem.pub");
|
||||
let mut file = File::open(&key_path)
|
||||
.ok()
|
||||
.expect("Failed to open `test/key.pem.pub`");
|
||||
|
||||
super::PKey::public_rsa_key_from_pem(&mut file).unwrap();
|
||||
let key = include_bytes!("../../test/key.pem.pub");
|
||||
super::PKey::public_rsa_key_from_pem(key).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -821,18 +776,11 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_pem() {
|
||||
let key_path = Path::new("test/key.pem");
|
||||
let mut file = File::open(&key_path)
|
||||
.ok()
|
||||
.expect("Failed to open `test/key.pem`");
|
||||
let key = include_bytes!("../../test/key.pem");
|
||||
let key = super::PKey::private_key_from_pem(key).unwrap();
|
||||
|
||||
let key = super::PKey::private_key_from_pem(&mut file).unwrap();
|
||||
|
||||
let mut priv_key = Vec::new();
|
||||
let mut pub_key = Vec::new();
|
||||
|
||||
key.write_pem(&mut priv_key).unwrap();
|
||||
key.write_pub_pem(&mut pub_key).unwrap();
|
||||
let priv_key = key.write_pem().unwrap();
|
||||
let pub_key = key.write_pub_pem().unwrap();
|
||||
|
||||
// As a super-simple verification, just check that the buffers contain
|
||||
// the `PRIVATE KEY` or `PUBLIC KEY` strings.
|
||||
|
|
|
|||
|
|
@ -1,18 +1,13 @@
|
|||
use ffi;
|
||||
use std::fmt;
|
||||
use ssl::error::{SslError, StreamError};
|
||||
use std::ptr;
|
||||
use std::io::{self, Read, Write};
|
||||
use libc::c_int;
|
||||
use libc::{c_int, c_void, c_char};
|
||||
|
||||
use bn::BigNum;
|
||||
use bio::MemBio;
|
||||
use bio::{MemBio, MemBioSlice};
|
||||
use error::ErrorStack;
|
||||
use crypto::HashTypeInternals;
|
||||
use crypto::hash;
|
||||
|
||||
#[cfg(feature = "catch_unwind")]
|
||||
use libc::{c_void, c_char};
|
||||
#[cfg(feature = "catch_unwind")]
|
||||
use crypto::util::{CallbackState, invoke_passwd_cb};
|
||||
|
||||
pub struct RSA(*mut ffi::RSA);
|
||||
|
|
@ -28,7 +23,7 @@ impl Drop for RSA {
|
|||
impl RSA {
|
||||
/// only useful for associating the key material directly with the key, it's safer to use
|
||||
/// the supplied load and save methods for DER formatted keys.
|
||||
pub fn from_public_components(n: BigNum, e: BigNum) -> Result<RSA, SslError> {
|
||||
pub fn from_public_components(n: BigNum, e: BigNum) -> Result<RSA, ErrorStack> {
|
||||
unsafe {
|
||||
let rsa = try_ssl_null!(ffi::RSA_new());
|
||||
(*rsa).n = n.into_raw();
|
||||
|
|
@ -45,7 +40,7 @@ impl RSA {
|
|||
dp: BigNum,
|
||||
dq: BigNum,
|
||||
qi: BigNum)
|
||||
-> Result<RSA, SslError> {
|
||||
-> Result<RSA, ErrorStack> {
|
||||
unsafe {
|
||||
let rsa = try_ssl_null!(ffi::RSA_new());
|
||||
(*rsa).n = n.into_raw();
|
||||
|
|
@ -66,12 +61,8 @@ impl RSA {
|
|||
}
|
||||
|
||||
/// Reads an RSA private key from PEM formatted data.
|
||||
pub fn private_key_from_pem<R>(reader: &mut R) -> Result<RSA, SslError>
|
||||
where R: Read
|
||||
{
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
|
||||
|
||||
pub fn private_key_from_pem(buf: &[u8]) -> Result<RSA, ErrorStack> {
|
||||
let mem_bio = try!(MemBioSlice::new(buf));
|
||||
unsafe {
|
||||
let rsa = try_ssl_null!(ffi::PEM_read_bio_RSAPrivateKey(mem_bio.get_handle(),
|
||||
ptr::null_mut(),
|
||||
|
|
@ -82,16 +73,11 @@ impl RSA {
|
|||
}
|
||||
|
||||
/// Reads an RSA private key from PEM formatted data and supplies a password callback.
|
||||
///
|
||||
/// Requires the `catch_unwind` feature.
|
||||
#[cfg(feature = "catch_unwind")]
|
||||
pub fn private_key_from_pem_cb<R, F>(reader: &mut R, pass_cb: F) -> Result<RSA, SslError>
|
||||
where R: Read, F: FnOnce(&mut [c_char]) -> usize
|
||||
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<RSA, ErrorStack>
|
||||
where F: FnOnce(&mut [c_char]) -> usize
|
||||
{
|
||||
let mut cb = CallbackState::new(pass_cb);
|
||||
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
|
||||
let mem_bio = try!(MemBioSlice::new(buf));
|
||||
|
||||
unsafe {
|
||||
let cb_ptr = &mut cb as *mut _ as *mut c_void;
|
||||
|
|
@ -105,10 +91,8 @@ impl RSA {
|
|||
}
|
||||
|
||||
/// Writes an RSA private key as unencrypted PEM formatted data
|
||||
pub fn private_key_to_pem<W>(&self, writer: &mut W) -> Result<(), SslError>
|
||||
where W: Write
|
||||
{
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mem_bio = try!(MemBio::new());
|
||||
|
||||
unsafe {
|
||||
try_ssl!(ffi::PEM_write_bio_RSAPrivateKey(mem_bio.get_handle(),
|
||||
|
|
@ -119,17 +103,12 @@ impl RSA {
|
|||
None,
|
||||
ptr::null_mut()));
|
||||
}
|
||||
try!(io::copy(&mut mem_bio, writer).map_err(StreamError));
|
||||
Ok(())
|
||||
Ok(mem_bio.get_buf().to_owned())
|
||||
}
|
||||
|
||||
/// Reads an RSA public key from PEM formatted data.
|
||||
pub fn public_key_from_pem<R>(reader: &mut R) -> Result<RSA, SslError>
|
||||
where R: Read
|
||||
{
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
|
||||
|
||||
pub fn public_key_from_pem(buf: &[u8]) -> Result<RSA, ErrorStack> {
|
||||
let mem_bio = try!(MemBioSlice::new(buf));
|
||||
unsafe {
|
||||
let rsa = try_ssl_null!(ffi::PEM_read_bio_RSA_PUBKEY(mem_bio.get_handle(),
|
||||
ptr::null_mut(),
|
||||
|
|
@ -140,29 +119,26 @@ impl RSA {
|
|||
}
|
||||
|
||||
/// Writes an RSA public key as PEM formatted data
|
||||
pub fn public_key_to_pem<W>(&self, writer: &mut W) -> Result<(), SslError>
|
||||
where W: Write
|
||||
{
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
pub fn public_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mem_bio = try!(MemBio::new());
|
||||
|
||||
unsafe {
|
||||
try_ssl!(ffi::PEM_write_bio_RSA_PUBKEY(mem_bio.get_handle(), self.0))
|
||||
};
|
||||
|
||||
try!(io::copy(&mut mem_bio, writer).map_err(StreamError));
|
||||
Ok(())
|
||||
Ok(mem_bio.get_buf().to_owned())
|
||||
}
|
||||
|
||||
pub fn size(&self) -> Result<u32, SslError> {
|
||||
pub fn size(&self) -> Option<u32> {
|
||||
if self.has_n() {
|
||||
unsafe { Ok(ffi::RSA_size(self.0) as u32) }
|
||||
unsafe { Some(ffi::RSA_size(self.0) as u32) }
|
||||
} else {
|
||||
Err(SslError::OpenSslErrors(vec![]))
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sign(&self, hash: hash::Type, message: &[u8]) -> Result<Vec<u8>, SslError> {
|
||||
let k_len = try!(self.size());
|
||||
pub fn sign(&self, hash: hash::Type, message: &[u8]) -> Result<Vec<u8>, ErrorStack> {
|
||||
let k_len = self.size().expect("RSA missing an n");
|
||||
let mut sig = vec![0; k_len as usize];
|
||||
let mut sig_len = k_len;
|
||||
|
||||
|
|
@ -178,7 +154,7 @@ impl RSA {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn verify(&self, hash: hash::Type, message: &[u8], sig: &[u8]) -> Result<bool, SslError> {
|
||||
pub fn verify(&self, hash: hash::Type, message: &[u8], sig: &[u8]) -> Result<bool, ErrorStack> {
|
||||
unsafe {
|
||||
let result = ffi::RSA_verify(hash.as_nid() as c_int,
|
||||
message.as_ptr(),
|
||||
|
|
@ -196,32 +172,42 @@ impl RSA {
|
|||
}
|
||||
|
||||
// The following getters are unsafe, since BigNum::new_from_ffi fails upon null pointers
|
||||
pub fn n(&self) -> Result<BigNum, SslError> {
|
||||
unsafe { BigNum::new_from_ffi((*self.0).n) }
|
||||
pub fn n(&self) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
BigNum::new_from_ffi((*self.0).n)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_n(&self) -> bool {
|
||||
unsafe { !(*self.0).n.is_null() }
|
||||
}
|
||||
|
||||
pub fn d(&self) -> Result<BigNum, SslError> {
|
||||
unsafe { BigNum::new_from_ffi((*self.0).d) }
|
||||
pub fn d(&self) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
BigNum::new_from_ffi((*self.0).d)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn e(&self) -> Result<BigNum, SslError> {
|
||||
unsafe { BigNum::new_from_ffi((*self.0).e) }
|
||||
pub fn e(&self) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
BigNum::new_from_ffi((*self.0).e)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_e(&self) -> bool {
|
||||
unsafe { !(*self.0).e.is_null() }
|
||||
}
|
||||
|
||||
pub fn p(&self) -> Result<BigNum, SslError> {
|
||||
unsafe { BigNum::new_from_ffi((*self.0).p) }
|
||||
pub fn p(&self) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
BigNum::new_from_ffi((*self.0).p)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn q(&self) -> Result<BigNum, SslError> {
|
||||
unsafe { BigNum::new_from_ffi((*self.0).q) }
|
||||
pub fn q(&self) -> Result<BigNum, ErrorStack> {
|
||||
unsafe {
|
||||
BigNum::new_from_ffi((*self.0).q)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -233,8 +219,9 @@ impl fmt::Debug for RSA {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use libc::c_char;
|
||||
|
||||
use super::*;
|
||||
use crypto::hash::*;
|
||||
|
||||
|
|
@ -266,8 +253,8 @@ mod test {
|
|||
|
||||
#[test]
|
||||
pub fn test_sign() {
|
||||
let mut buffer = File::open("test/rsa.pem").unwrap();
|
||||
let private_key = RSA::private_key_from_pem(&mut buffer).unwrap();
|
||||
let key = include_bytes!("../../test/rsa.pem");
|
||||
let private_key = RSA::private_key_from_pem(key).unwrap();
|
||||
|
||||
let mut sha = Hasher::new(Type::SHA256);
|
||||
sha.write_all(&signing_input_rs256()).unwrap();
|
||||
|
|
@ -280,8 +267,8 @@ mod test {
|
|||
|
||||
#[test]
|
||||
pub fn test_verify() {
|
||||
let mut buffer = File::open("test/rsa.pem.pub").unwrap();
|
||||
let public_key = RSA::public_key_from_pem(&mut buffer).unwrap();
|
||||
let key = include_bytes!("../../test/rsa.pem.pub");
|
||||
let public_key = RSA::public_key_from_pem(key).unwrap();
|
||||
|
||||
let mut sha = Hasher::new(Type::SHA256);
|
||||
sha.write_all(&signing_input_rs256()).unwrap();
|
||||
|
|
@ -293,18 +280,17 @@ mod test {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "catch_unwind")]
|
||||
pub fn test_password() {
|
||||
let mut password_queried = false;
|
||||
let mut buffer = File::open("test/rsa-encrypted.pem").unwrap();
|
||||
RSA::private_key_from_pem_cb(&mut buffer, |password| {
|
||||
let key = include_bytes!("../../test/rsa-encrypted.pem");
|
||||
RSA::private_key_from_pem_cb(key, |password| {
|
||||
password_queried = true;
|
||||
password[0] = b'm' as _;
|
||||
password[1] = b'y' as _;
|
||||
password[2] = b'p' as _;
|
||||
password[3] = b'a' as _;
|
||||
password[4] = b's' as _;
|
||||
password[5] = b's' as _;
|
||||
password[0] = b'm' as c_char;
|
||||
password[1] = b'y' as c_char;
|
||||
password[2] = b'p' as c_char;
|
||||
password[3] = b'a' as c_char;
|
||||
password[4] = b's' as c_char;
|
||||
password[5] = b's' as c_char;
|
||||
6
|
||||
}).unwrap();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
use ffi;
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use ssl::error::{SslError, StreamError};
|
||||
use bio::MemBio;
|
||||
use error::ErrorStack;
|
||||
use bio::MemBioSlice;
|
||||
use bn::BigNum;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
|
@ -10,7 +8,7 @@ use std::ptr;
|
|||
pub struct DH(*mut ffi::DH);
|
||||
|
||||
impl DH {
|
||||
pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<DH, SslError> {
|
||||
pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<DH, ErrorStack> {
|
||||
let dh = try_ssl_null!(unsafe { ffi::DH_new_from_params(p.raw(), g.raw(), q.raw()) });
|
||||
mem::forget(p);
|
||||
mem::forget(g);
|
||||
|
|
@ -18,11 +16,8 @@ impl DH {
|
|||
Ok(DH(dh))
|
||||
}
|
||||
|
||||
pub fn from_pem<R>(reader: &mut R) -> Result<DH, SslError>
|
||||
where R: Read
|
||||
{
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
|
||||
pub fn from_pem(buf: &[u8]) -> Result<DH, ErrorStack> {
|
||||
let mem_bio = try!(MemBioSlice::new(buf));
|
||||
let dh = unsafe {
|
||||
ffi::PEM_read_bio_DHparams(mem_bio.get_handle(), ptr::null_mut(), None, ptr::null_mut())
|
||||
};
|
||||
|
|
@ -31,19 +26,19 @@ impl DH {
|
|||
}
|
||||
|
||||
#[cfg(feature = "rfc5114")]
|
||||
pub fn get_1024_160() -> Result<DH, SslError> {
|
||||
pub fn get_1024_160() -> Result<DH, ErrorStack> {
|
||||
let dh = try_ssl_null!(unsafe { ffi::DH_get_1024_160() });
|
||||
Ok(DH(dh))
|
||||
}
|
||||
|
||||
#[cfg(feature = "rfc5114")]
|
||||
pub fn get_2048_224() -> Result<DH, SslError> {
|
||||
pub fn get_2048_224() -> Result<DH, ErrorStack> {
|
||||
let dh = try_ssl_null!(unsafe { ffi::DH_get_2048_224() });
|
||||
Ok(DH(dh))
|
||||
}
|
||||
|
||||
#[cfg(feature = "rfc5114")]
|
||||
pub fn get_2048_256() -> Result<DH, SslError> {
|
||||
pub fn get_2048_256() -> Result<DH, ErrorStack> {
|
||||
let dh = try_ssl_null!(unsafe { ffi::DH_get_2048_256() });
|
||||
Ok(DH(dh))
|
||||
}
|
||||
|
|
@ -71,8 +66,6 @@ impl Drop for DH {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use super::DH;
|
||||
use bn::BigNum;
|
||||
use ssl::SslContext;
|
||||
|
|
@ -81,7 +74,7 @@ mod tests {
|
|||
#[test]
|
||||
#[cfg(feature = "rfc5114")]
|
||||
fn test_dh_rfc5114() {
|
||||
let ctx = SslContext::new(Sslv23).unwrap();
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
let dh1 = DH::get_1024_160().unwrap();
|
||||
ctx.set_tmp_dh(dh1).unwrap();
|
||||
let dh2 = DH::get_2048_224().unwrap();
|
||||
|
|
@ -92,7 +85,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_dh() {
|
||||
let ctx = SslContext::new(Sslv23).unwrap();
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
let p = BigNum::from_hex_str("87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435\
|
||||
E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF429\
|
||||
6D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C02\
|
||||
|
|
@ -122,12 +115,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_dh_from_pem() {
|
||||
let ctx = SslContext::new(Sslv23).unwrap();
|
||||
let pem_path = Path::new("test/dhparams.pem");
|
||||
let mut file = File::open(&pem_path)
|
||||
.ok()
|
||||
.expect("Failed to open `test/dhparams.pem`");
|
||||
let dh = DH::from_pem(&mut file).ok().expect("Failed to load PEM");
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
let params = include_bytes!("../../test/dhparams.pem");
|
||||
let dh = DH::from_pem(params).ok().expect("Failed to load PEM");
|
||||
ctx.set_tmp_dh(dh).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,137 @@
|
|||
use libc::c_ulong;
|
||||
use std::fmt;
|
||||
use std::error;
|
||||
use std::ffi::CStr;
|
||||
use std::io;
|
||||
use std::str;
|
||||
|
||||
use ffi;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ErrorStack(Vec<Error>);
|
||||
|
||||
impl ErrorStack {
|
||||
/// Returns the contents of the OpenSSL error stack.
|
||||
pub fn get() -> ErrorStack {
|
||||
let mut vec = vec![];
|
||||
while let Some(err) = Error::get() {
|
||||
vec.push(err);
|
||||
}
|
||||
ErrorStack(vec)
|
||||
}
|
||||
}
|
||||
|
||||
impl ErrorStack {
|
||||
/// Returns the errors in the stack.
|
||||
pub fn errors(&self) -> &[Error] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for ErrorStack {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut first = true;
|
||||
for err in &self.0 {
|
||||
if first {
|
||||
try!(fmt.write_str(", "));
|
||||
first = false;
|
||||
}
|
||||
try!(write!(fmt, "{}", err));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for ErrorStack {
|
||||
fn description(&self) -> &str {
|
||||
"An OpenSSL error stack"
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ErrorStack> for io::Error {
|
||||
fn from(e: ErrorStack) -> io::Error {
|
||||
io::Error::new(io::ErrorKind::Other, e)
|
||||
}
|
||||
}
|
||||
|
||||
/// An error reported from OpenSSL.
|
||||
pub struct Error(c_ulong);
|
||||
|
||||
impl Error {
|
||||
/// Returns the first error on the OpenSSL error stack.
|
||||
pub fn get() -> Option<Error> {
|
||||
ffi::init();
|
||||
|
||||
match unsafe { ffi::ERR_get_error() } {
|
||||
0 => None,
|
||||
err => Some((Error(err))),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the raw OpenSSL error code for this error.
|
||||
pub fn error_code(&self) -> c_ulong {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Returns the name of the library reporting the error.
|
||||
pub fn library(&self) -> &'static str {
|
||||
get_lib(self.0)
|
||||
}
|
||||
|
||||
/// Returns the name of the function reporting the error.
|
||||
pub fn function(&self) -> &'static str {
|
||||
get_func(self.0)
|
||||
}
|
||||
|
||||
/// Returns the reason for the error.
|
||||
pub fn reason(&self) -> &'static str {
|
||||
get_reason(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Error {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_struct("Error")
|
||||
.field("library", &self.library())
|
||||
.field("function", &self.function())
|
||||
.field("reason", &self.reason())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.write_str(&self.reason())
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
"An OpenSSL error"
|
||||
}
|
||||
}
|
||||
|
||||
fn get_lib(err: c_ulong) -> &'static str {
|
||||
unsafe {
|
||||
let cstr = ffi::ERR_lib_error_string(err);
|
||||
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
|
||||
str::from_utf8(bytes).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_func(err: c_ulong) -> &'static str {
|
||||
unsafe {
|
||||
let cstr = ffi::ERR_func_error_string(err);
|
||||
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
|
||||
str::from_utf8(bytes).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_reason(err: c_ulong) -> &'static str {
|
||||
unsafe {
|
||||
let cstr = ffi::ERR_reason_error_string(err);
|
||||
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
|
||||
str::from_utf8(bytes).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.7.14")]
|
||||
#![cfg_attr(feature = "nightly", feature(const_fn))]
|
||||
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
|
|
@ -18,11 +17,12 @@ extern crate net2;
|
|||
mod macros;
|
||||
|
||||
pub mod asn1;
|
||||
mod bio;
|
||||
pub mod bn;
|
||||
pub mod bio;
|
||||
pub mod crypto;
|
||||
pub mod dh;
|
||||
pub mod ssl;
|
||||
pub mod x509;
|
||||
pub mod error;
|
||||
pub mod nid;
|
||||
pub mod ssl;
|
||||
pub mod version;
|
||||
pub mod x509;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ macro_rules! try_ssl_stream {
|
|||
macro_rules! try_ssl_if {
|
||||
($e:expr) => (
|
||||
if $e {
|
||||
return Err(SslError::get())
|
||||
return Err(::error::ErrorStack::get().into())
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ macro_rules! try_ssl_null{
|
|||
macro_rules! lift_ssl_if{
|
||||
($e:expr) => ( {
|
||||
if $e {
|
||||
Err(SslError::get())
|
||||
Err(::error::ErrorStack::get().into())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use std::ptr;
|
|||
use std::slice;
|
||||
use std::sync::Arc;
|
||||
|
||||
use ssl::error::SslError;
|
||||
use error::ErrorStack;
|
||||
|
||||
pub struct StreamState<S> {
|
||||
pub stream: S,
|
||||
|
|
@ -39,7 +39,7 @@ impl BioMethod {
|
|||
|
||||
unsafe impl Send for BioMethod {}
|
||||
|
||||
pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, Arc<BioMethod>), SslError> {
|
||||
pub fn new<S: Read + Write>(stream: S) -> Result<(*mut BIO, Arc<BioMethod>), ErrorStack> {
|
||||
let method = Arc::new(BioMethod::new::<S>());
|
||||
|
||||
let state = Box::new(StreamState {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,8 @@
|
|||
pub use self::SslError::*;
|
||||
pub use self::OpensslError::*;
|
||||
|
||||
use libc::c_ulong;
|
||||
use std::error;
|
||||
use std::error::Error as StdError;
|
||||
use std::fmt;
|
||||
use std::ffi::CStr;
|
||||
use std::io;
|
||||
use std::str;
|
||||
|
||||
use ffi;
|
||||
use error::ErrorStack;
|
||||
|
||||
/// An SSL error.
|
||||
#[derive(Debug)]
|
||||
|
|
@ -27,31 +20,17 @@ pub enum Error {
|
|||
/// An error reported by the underlying stream.
|
||||
Stream(io::Error),
|
||||
/// An error in the OpenSSL library.
|
||||
Ssl(Vec<OpenSslError>),
|
||||
Ssl(ErrorStack),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(fmt.write_str(self.description()));
|
||||
match *self {
|
||||
Error::Stream(ref err) => write!(fmt, ": {}", err),
|
||||
Error::WantRead(ref err) => write!(fmt, ": {}", err),
|
||||
Error::WantWrite(ref err) => write!(fmt, ": {}", err),
|
||||
Error::Ssl(ref errs) => {
|
||||
let mut first = true;
|
||||
for err in errs {
|
||||
if first {
|
||||
try!(fmt.write_str(": "));
|
||||
first = false;
|
||||
if let Some(err) = self.cause() {
|
||||
write!(fmt, ": {}", err)
|
||||
} else {
|
||||
try!(fmt.write_str(", "));
|
||||
}
|
||||
try!(fmt.write_str(&err.reason()))
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -72,247 +51,14 @@ impl error::Error for Error {
|
|||
Error::WantRead(ref err) => Some(err),
|
||||
Error::WantWrite(ref err) => Some(err),
|
||||
Error::Stream(ref err) => Some(err),
|
||||
Error::Ssl(ref err) => Some(err),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An error reported from OpenSSL.
|
||||
pub struct OpenSslError(c_ulong);
|
||||
|
||||
impl OpenSslError {
|
||||
/// Returns the contents of the OpenSSL error stack.
|
||||
pub fn get_stack() -> Vec<OpenSslError> {
|
||||
ffi::init();
|
||||
|
||||
let mut errs = vec![];
|
||||
loop {
|
||||
match unsafe { ffi::ERR_get_error() } {
|
||||
0 => break,
|
||||
err => errs.push(OpenSslError(err)),
|
||||
impl From<ErrorStack> for Error {
|
||||
fn from(e: ErrorStack) -> Error {
|
||||
Error::Ssl(e)
|
||||
}
|
||||
}
|
||||
errs
|
||||
}
|
||||
|
||||
/// Returns the raw OpenSSL error code for this error.
|
||||
pub fn error_code(&self) -> c_ulong {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Returns the name of the library reporting the error.
|
||||
pub fn library(&self) -> &'static str {
|
||||
get_lib(self.0)
|
||||
}
|
||||
|
||||
/// Returns the name of the function reporting the error.
|
||||
pub fn function(&self) -> &'static str {
|
||||
get_func(self.0)
|
||||
}
|
||||
|
||||
/// Returns the reason for the error.
|
||||
pub fn reason(&self) -> &'static str {
|
||||
get_reason(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for OpenSslError {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_struct("OpenSslError")
|
||||
.field("library", &self.library())
|
||||
.field("function", &self.function())
|
||||
.field("reason", &self.reason())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for OpenSslError {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.write_str(&self.reason())
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for OpenSslError {
|
||||
fn description(&self) -> &str {
|
||||
"An OpenSSL error"
|
||||
}
|
||||
}
|
||||
|
||||
/// An SSL error
|
||||
#[derive(Debug)]
|
||||
pub enum SslError {
|
||||
/// The underlying stream reported an error
|
||||
StreamError(io::Error),
|
||||
/// The SSL session has been closed by the other end
|
||||
SslSessionClosed,
|
||||
/// An error in the OpenSSL library
|
||||
OpenSslErrors(Vec<OpensslError>),
|
||||
}
|
||||
|
||||
/// An error on a nonblocking stream.
|
||||
#[derive(Debug)]
|
||||
pub enum NonblockingSslError {
|
||||
/// A standard SSL error occurred.
|
||||
SslError(SslError),
|
||||
/// The OpenSSL library wants data from the remote socket;
|
||||
/// the caller should wait for read readiness.
|
||||
WantRead,
|
||||
/// The OpenSSL library wants to send data to the remote socket;
|
||||
/// the caller should wait for write readiness.
|
||||
WantWrite,
|
||||
}
|
||||
|
||||
impl fmt::Display for SslError {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(fmt.write_str(error::Error::description(self)));
|
||||
if let OpenSslErrors(ref errs) = *self {
|
||||
let mut first = true;
|
||||
for err in errs {
|
||||
if first {
|
||||
try!(fmt.write_str(": "));
|
||||
first = false;
|
||||
} else {
|
||||
try!(fmt.write_str(", "));
|
||||
}
|
||||
match *err {
|
||||
UnknownError { ref reason, .. } => try!(fmt.write_str(reason)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for SslError {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
StreamError(_) => "The underlying stream reported an error",
|
||||
SslSessionClosed => "The SSL session has been closed by the other end",
|
||||
OpenSslErrors(_) => "An error in the OpenSSL library",
|
||||
}
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
match *self {
|
||||
StreamError(ref err) => Some(err as &error::Error),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for NonblockingSslError {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.write_str(error::Error::description(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for NonblockingSslError {
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
NonblockingSslError::SslError(ref e) => e.description(),
|
||||
NonblockingSslError::WantRead => {
|
||||
"The OpenSSL library wants data from the remote socket"
|
||||
}
|
||||
NonblockingSslError::WantWrite => {
|
||||
"The OpenSSL library want to send data to the remote socket"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
match *self {
|
||||
NonblockingSslError::SslError(ref e) => e.cause(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SslError> for NonblockingSslError {
|
||||
fn from(e: SslError) -> NonblockingSslError {
|
||||
NonblockingSslError::SslError(e)
|
||||
}
|
||||
}
|
||||
|
||||
/// An error from the OpenSSL library
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum OpensslError {
|
||||
/// An unknown error
|
||||
UnknownError {
|
||||
/// The library reporting the error
|
||||
library: String,
|
||||
/// The function reporting the error
|
||||
function: String,
|
||||
/// The reason for the error
|
||||
reason: String,
|
||||
},
|
||||
}
|
||||
|
||||
impl OpensslError {
|
||||
pub fn from_error_code(err: c_ulong) -> OpensslError {
|
||||
ffi::init();
|
||||
UnknownError {
|
||||
library: get_lib(err).to_owned(),
|
||||
function: get_func(err).to_owned(),
|
||||
reason: get_reason(err).to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_lib(err: c_ulong) -> &'static str {
|
||||
unsafe {
|
||||
let cstr = ffi::ERR_lib_error_string(err);
|
||||
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
|
||||
str::from_utf8(bytes).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_func(err: c_ulong) -> &'static str {
|
||||
unsafe {
|
||||
let cstr = ffi::ERR_func_error_string(err);
|
||||
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
|
||||
str::from_utf8(bytes).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_reason(err: c_ulong) -> &'static str {
|
||||
unsafe {
|
||||
let cstr = ffi::ERR_reason_error_string(err);
|
||||
let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
|
||||
str::from_utf8(bytes).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl SslError {
|
||||
/// Creates a new `OpenSslErrors` with the current contents of the error
|
||||
/// stack.
|
||||
pub fn get() -> SslError {
|
||||
let mut errs = vec![];
|
||||
loop {
|
||||
match unsafe { ffi::ERR_get_error() } {
|
||||
0 => break,
|
||||
err => errs.push(OpensslError::from_error_code(err)),
|
||||
}
|
||||
}
|
||||
OpenSslErrors(errs)
|
||||
}
|
||||
|
||||
/// Creates an `SslError` from the raw numeric error code.
|
||||
pub fn from_error(err: c_ulong) -> SslError {
|
||||
OpenSslErrors(vec![OpensslError::from_error_code(err)])
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_uknown_error_should_have_correct_messages() {
|
||||
let errs = match SslError::from_error(336032784) {
|
||||
OpenSslErrors(errs) => errs,
|
||||
_ => panic!("This should always be an `OpenSslErrors` variant."),
|
||||
};
|
||||
|
||||
let UnknownError { ref library, ref function, ref reason } = errs[0];
|
||||
|
||||
assert_eq!(&library[..], "SSL routines");
|
||||
assert_eq!(&function[..], "SSL23_GET_SERVER_HELLO");
|
||||
assert_eq!(&reason[..], "sslv3 alert handshake failure");
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -17,9 +17,9 @@ use crypto::hash::Type::SHA256;
|
|||
use ssl;
|
||||
use ssl::SSL_VERIFY_PEER;
|
||||
use ssl::SslMethod::Sslv23;
|
||||
use ssl::SslMethod;
|
||||
use ssl::error::NonblockingSslError;
|
||||
use ssl::{SslContext, SslStream, VerifyCallback, NonblockingSslStream};
|
||||
use ssl::{SslMethod, HandshakeError};
|
||||
use ssl::error::Error;
|
||||
use ssl::{SslContext, SslStream};
|
||||
use x509::X509StoreContext;
|
||||
use x509::X509FileType;
|
||||
use x509::X509;
|
||||
|
|
@ -133,6 +133,7 @@ impl Drop for Server {
|
|||
}
|
||||
|
||||
#[cfg(feature = "dtlsv1")]
|
||||
#[derive(Debug)]
|
||||
struct UdpConnected(UdpSocket);
|
||||
|
||||
#[cfg(feature = "dtlsv1")]
|
||||
|
|
@ -194,9 +195,9 @@ macro_rules! run_test(
|
|||
use std::net::TcpStream;
|
||||
use ssl;
|
||||
use ssl::SslMethod;
|
||||
use ssl::{SslContext, Ssl, SslStream, VerifyCallback};
|
||||
use ssl::{SslContext, Ssl, SslStream};
|
||||
use ssl::SSL_VERIFY_PEER;
|
||||
use crypto::hash::Type::SHA1;
|
||||
use crypto::hash::Type::{SHA1, SHA256};
|
||||
use x509::X509StoreContext;
|
||||
use serialize::hex::FromHex;
|
||||
use super::Server;
|
||||
|
|
@ -222,19 +223,19 @@ run_test!(new_ctx, |method, _| {
|
|||
});
|
||||
|
||||
run_test!(new_sslstream, |method, stream| {
|
||||
SslStream::connect_generic(&SslContext::new(method).unwrap(), stream).unwrap();
|
||||
SslStream::connect(&SslContext::new(method).unwrap(), stream).unwrap();
|
||||
});
|
||||
|
||||
run_test!(get_ssl_method, |method, _| {
|
||||
let ssl = Ssl::new(&SslContext::new(method).unwrap()).unwrap();
|
||||
assert_eq!(ssl.get_ssl_method(), Some(method));
|
||||
assert_eq!(ssl.ssl_method(), Some(method));
|
||||
});
|
||||
|
||||
run_test!(verify_untrusted, |method, stream| {
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
|
||||
match SslStream::connect_generic(&ctx, stream) {
|
||||
match SslStream::connect(&ctx, stream) {
|
||||
Ok(_) => panic!("expected failure"),
|
||||
Err(err) => println!("error {:?}", err),
|
||||
}
|
||||
|
|
@ -242,127 +243,95 @@ run_test!(verify_untrusted, |method, stream| {
|
|||
|
||||
run_test!(verify_trusted, |method, stream| {
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
Ok(_) => {}
|
||||
Err(err) => panic!("Unexpected error {:?}", err),
|
||||
}
|
||||
match SslStream::connect_generic(&ctx, stream) {
|
||||
match SslStream::connect(&ctx, stream) {
|
||||
Ok(_) => (),
|
||||
Err(err) => panic!("Expected success, got {:?}", err),
|
||||
}
|
||||
});
|
||||
|
||||
run_test!(verify_untrusted_callback_override_ok, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, _x509_ctx: &X509StoreContext) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback));
|
||||
ctx.set_verify_callback(SSL_VERIFY_PEER, |_, _| true);
|
||||
|
||||
match SslStream::connect_generic(&ctx, stream) {
|
||||
match SslStream::connect(&ctx, stream) {
|
||||
Ok(_) => (),
|
||||
Err(err) => panic!("Expected success, got {:?}", err),
|
||||
}
|
||||
});
|
||||
|
||||
run_test!(verify_untrusted_callback_override_bad, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, _x509_ctx: &X509StoreContext) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback));
|
||||
ctx.set_verify_callback(SSL_VERIFY_PEER, |_, _| false);
|
||||
|
||||
assert!(SslStream::connect_generic(&ctx, stream).is_err());
|
||||
assert!(SslStream::connect(&ctx, stream).is_err());
|
||||
});
|
||||
|
||||
run_test!(verify_trusted_callback_override_ok, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, _x509_ctx: &X509StoreContext) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback));
|
||||
ctx.set_verify_callback(SSL_VERIFY_PEER, |_, _| true);
|
||||
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
Ok(_) => {}
|
||||
Err(err) => panic!("Unexpected error {:?}", err),
|
||||
}
|
||||
match SslStream::connect_generic(&ctx, stream) {
|
||||
match SslStream::connect(&ctx, stream) {
|
||||
Ok(_) => (),
|
||||
Err(err) => panic!("Expected success, got {:?}", err),
|
||||
}
|
||||
});
|
||||
|
||||
run_test!(verify_trusted_callback_override_bad, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, _x509_ctx: &X509StoreContext) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback));
|
||||
ctx.set_verify_callback(SSL_VERIFY_PEER, |_, _| false);
|
||||
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
Ok(_) => {}
|
||||
Err(err) => panic!("Unexpected error {:?}", err),
|
||||
}
|
||||
assert!(SslStream::connect_generic(&ctx, stream).is_err());
|
||||
assert!(SslStream::connect(&ctx, stream).is_err());
|
||||
});
|
||||
|
||||
run_test!(verify_callback_load_certs, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, x509_ctx: &X509StoreContext) -> bool {
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify_callback(SSL_VERIFY_PEER, |_, x509_ctx| {
|
||||
assert!(x509_ctx.get_current_cert().is_some());
|
||||
true
|
||||
}
|
||||
});
|
||||
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback));
|
||||
|
||||
assert!(SslStream::connect_generic(&ctx, stream).is_ok());
|
||||
assert!(SslStream::connect(&ctx, stream).is_ok());
|
||||
});
|
||||
|
||||
run_test!(verify_trusted_get_error_ok, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, x509_ctx: &X509StoreContext) -> bool {
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify_callback(SSL_VERIFY_PEER, |_, x509_ctx| {
|
||||
assert!(x509_ctx.get_error().is_none());
|
||||
true
|
||||
}
|
||||
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback));
|
||||
});
|
||||
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
Ok(_) => {}
|
||||
Err(err) => panic!("Unexpected error {:?}", err),
|
||||
}
|
||||
assert!(SslStream::connect_generic(&ctx, stream).is_ok());
|
||||
assert!(SslStream::connect(&ctx, stream).is_ok());
|
||||
});
|
||||
|
||||
run_test!(verify_trusted_get_error_err, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, x509_ctx: &X509StoreContext) -> bool {
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify_callback(SSL_VERIFY_PEER, |_, x509_ctx| {
|
||||
assert!(x509_ctx.get_error().is_some());
|
||||
false
|
||||
}
|
||||
});
|
||||
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, Some(callback as VerifyCallback));
|
||||
|
||||
assert!(SslStream::connect_generic(&ctx, stream).is_err());
|
||||
assert!(SslStream::connect(&ctx, stream).is_err());
|
||||
});
|
||||
|
||||
run_test!(verify_callback_data, |method, stream| {
|
||||
fn callback(_preverify_ok: bool, x509_ctx: &X509StoreContext, node_id: &Vec<u8>) -> bool {
|
||||
let cert = x509_ctx.get_current_cert();
|
||||
match cert {
|
||||
None => false,
|
||||
Some(cert) => {
|
||||
let fingerprint = cert.fingerprint(SHA1).unwrap();
|
||||
&fingerprint == node_id
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
|
||||
// Node id was generated as SHA256 hash of certificate "test/cert.pem"
|
||||
|
|
@ -371,10 +340,19 @@ run_test!(verify_callback_data, |method, stream| {
|
|||
// Please update if "test/cert.pem" will ever change
|
||||
let node_hash_str = "E19427DAC79FBE758394945276A6E4F15F0BEBE6";
|
||||
let node_id = node_hash_str.from_hex().unwrap();
|
||||
ctx.set_verify_with_data(SSL_VERIFY_PEER, callback, node_id);
|
||||
ctx.set_verify_callback(SSL_VERIFY_PEER, move |_preverify_ok, x509_ctx| {
|
||||
let cert = x509_ctx.get_current_cert();
|
||||
match cert {
|
||||
None => false,
|
||||
Some(cert) => {
|
||||
let fingerprint = cert.fingerprint(SHA1).unwrap();
|
||||
fingerprint == node_id
|
||||
}
|
||||
}
|
||||
});
|
||||
ctx.set_verify_depth(1);
|
||||
|
||||
match SslStream::connect_generic(&ctx, stream) {
|
||||
match SslStream::connect(&ctx, stream) {
|
||||
Ok(_) => (),
|
||||
Err(err) => panic!("Expected success, got {:?}", err),
|
||||
}
|
||||
|
|
@ -402,7 +380,7 @@ run_test!(ssl_verify_callback, |method, stream| {
|
|||
}
|
||||
});
|
||||
|
||||
match SslStream::connect_generic(ssl, stream) {
|
||||
match SslStream::connect(ssl, stream) {
|
||||
Ok(_) => (),
|
||||
Err(err) => panic!("Expected success, got {:?}", err),
|
||||
}
|
||||
|
|
@ -419,14 +397,14 @@ fn test_write_hits_stream() {
|
|||
let guard = thread::spawn(move || {
|
||||
let ctx = SslContext::new(Sslv23).unwrap();
|
||||
let stream = TcpStream::connect(addr).unwrap();
|
||||
let mut stream = SslStream::connect_generic(&ctx, stream).unwrap();
|
||||
let mut stream = SslStream::connect(&ctx, stream).unwrap();
|
||||
|
||||
stream.write_all(b"hello").unwrap();
|
||||
stream
|
||||
});
|
||||
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM).unwrap();
|
||||
ctx.set_private_key_file(&Path::new("test/key.pem"), X509FileType::PEM).unwrap();
|
||||
let stream = listener.accept().unwrap().0;
|
||||
|
|
@ -440,17 +418,10 @@ fn test_write_hits_stream() {
|
|||
|
||||
#[test]
|
||||
fn test_set_certificate_and_private_key() {
|
||||
let key_path = Path::new("test/key.pem");
|
||||
let cert_path = Path::new("test/cert.pem");
|
||||
let mut key_file = File::open(&key_path)
|
||||
.ok()
|
||||
.expect("Failed to open `test/key.pem`");
|
||||
let mut cert_file = File::open(&cert_path)
|
||||
.ok()
|
||||
.expect("Failed to open `test/cert.pem`");
|
||||
|
||||
let key = PKey::private_key_from_pem(&mut key_file).unwrap();
|
||||
let cert = X509::from_pem(&mut cert_file).unwrap();
|
||||
let key = include_bytes!("../../../test/key.pem");
|
||||
let key = PKey::private_key_from_pem(key).unwrap();
|
||||
let cert = include_bytes!("../../../test/cert.pem");
|
||||
let cert = X509::from_pem(cert).unwrap();
|
||||
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
ctx.set_private_key(&key).unwrap();
|
||||
|
|
@ -460,8 +431,8 @@ fn test_set_certificate_and_private_key() {
|
|||
}
|
||||
|
||||
run_test!(get_ctx_options, |method, _| {
|
||||
let mut ctx = SslContext::new(method).unwrap();
|
||||
ctx.get_options();
|
||||
let ctx = SslContext::new(method).unwrap();
|
||||
ctx.options();
|
||||
});
|
||||
|
||||
run_test!(set_ctx_options, |method, _| {
|
||||
|
|
@ -480,7 +451,7 @@ run_test!(clear_ctx_options, |method, _| {
|
|||
#[test]
|
||||
fn test_write() {
|
||||
let (_s, stream) = Server::new();
|
||||
let mut stream = SslStream::connect_generic(&SslContext::new(Sslv23).unwrap(), stream).unwrap();
|
||||
let mut stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), stream).unwrap();
|
||||
stream.write_all("hello".as_bytes()).unwrap();
|
||||
stream.flush().unwrap();
|
||||
stream.write_all(" there".as_bytes()).unwrap();
|
||||
|
|
@ -498,7 +469,7 @@ fn test_write_direct() {
|
|||
}
|
||||
|
||||
run_test!(get_peer_certificate, |method, stream| {
|
||||
let stream = SslStream::connect_generic(&SslContext::new(method).unwrap(), stream).unwrap();
|
||||
let stream = SslStream::connect(&SslContext::new(method).unwrap(), stream).unwrap();
|
||||
let cert = stream.ssl().peer_certificate().unwrap();
|
||||
let fingerprint = cert.fingerprint(SHA1).unwrap();
|
||||
let node_hash_str = "E19427DAC79FBE758394945276A6E4F15F0BEBE6";
|
||||
|
|
@ -511,7 +482,7 @@ run_test!(get_peer_certificate, |method, stream| {
|
|||
fn test_write_dtlsv1() {
|
||||
let (_s, stream) = Server::new_dtlsv1(iter::repeat("y\n"));
|
||||
|
||||
let mut stream = SslStream::connect_generic(&SslContext::new(Dtlsv1).unwrap(), stream).unwrap();
|
||||
let mut stream = SslStream::connect(&SslContext::new(Dtlsv1).unwrap(), stream).unwrap();
|
||||
stream.write_all(b"hello").unwrap();
|
||||
stream.flush().unwrap();
|
||||
stream.write_all(b" there").unwrap();
|
||||
|
|
@ -521,7 +492,7 @@ fn test_write_dtlsv1() {
|
|||
#[test]
|
||||
fn test_read() {
|
||||
let (_s, tcp) = Server::new();
|
||||
let mut stream = SslStream::connect_generic(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
|
||||
let mut stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
|
||||
stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap();
|
||||
stream.flush().unwrap();
|
||||
io::copy(&mut stream, &mut io::sink()).ok().expect("read error");
|
||||
|
|
@ -539,7 +510,7 @@ fn test_read_direct() {
|
|||
#[test]
|
||||
fn test_pending() {
|
||||
let (_s, tcp) = Server::new();
|
||||
let mut stream = SslStream::connect_generic(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
|
||||
let mut stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
|
||||
stream.write_all("GET /\r\n\r\n".as_bytes()).unwrap();
|
||||
stream.flush().unwrap();
|
||||
|
||||
|
|
@ -562,7 +533,7 @@ fn test_pending() {
|
|||
#[test]
|
||||
fn test_state() {
|
||||
let (_s, tcp) = Server::new();
|
||||
let stream = SslStream::connect_generic(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
|
||||
let stream = SslStream::connect(&SslContext::new(Sslv23).unwrap(), tcp).unwrap();
|
||||
assert_eq!(stream.ssl().state_string(), "SSLOK ");
|
||||
assert_eq!(stream.ssl().state_string_long(),
|
||||
"SSL negotiation finished successfully");
|
||||
|
|
@ -575,7 +546,7 @@ fn test_state() {
|
|||
fn test_connect_with_unilateral_alpn() {
|
||||
let (_s, stream) = Server::new();
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]);
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
Ok(_) => {}
|
||||
|
|
@ -597,13 +568,13 @@ fn test_connect_with_unilateral_alpn() {
|
|||
fn test_connect_with_unilateral_npn() {
|
||||
let (_s, stream) = Server::new();
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]);
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
Ok(_) => {}
|
||||
Err(err) => panic!("Unexpected error {:?}", err),
|
||||
}
|
||||
let stream = match SslStream::connect_generic(&ctx, stream) {
|
||||
let stream = match SslStream::connect(&ctx, stream) {
|
||||
Ok(stream) => stream,
|
||||
Err(err) => panic!("Expected success, got {:?}", err),
|
||||
};
|
||||
|
|
@ -619,7 +590,7 @@ fn test_connect_with_unilateral_npn() {
|
|||
fn test_connect_with_alpn_successful_multiple_matching() {
|
||||
let (_s, stream) = Server::new_alpn();
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
ctx.set_alpn_protocols(&[b"spdy/3.1", b"http/1.1"]);
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
Ok(_) => {}
|
||||
|
|
@ -641,13 +612,13 @@ fn test_connect_with_alpn_successful_multiple_matching() {
|
|||
fn test_connect_with_npn_successful_multiple_matching() {
|
||||
let (_s, stream) = Server::new_alpn();
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
ctx.set_npn_protocols(&[b"spdy/3.1", b"http/1.1"]);
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
Ok(_) => {}
|
||||
Err(err) => panic!("Unexpected error {:?}", err),
|
||||
}
|
||||
let stream = match SslStream::connect_generic(&ctx, stream) {
|
||||
let stream = match SslStream::connect(&ctx, stream) {
|
||||
Ok(stream) => stream,
|
||||
Err(err) => panic!("Expected success, got {:?}", err),
|
||||
};
|
||||
|
|
@ -664,7 +635,7 @@ fn test_connect_with_npn_successful_multiple_matching() {
|
|||
fn test_connect_with_alpn_successful_single_match() {
|
||||
let (_s, stream) = Server::new_alpn();
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
ctx.set_alpn_protocols(&[b"spdy/3.1"]);
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
Ok(_) => {}
|
||||
|
|
@ -688,13 +659,13 @@ fn test_connect_with_alpn_successful_single_match() {
|
|||
fn test_connect_with_npn_successful_single_match() {
|
||||
let (_s, stream) = Server::new_alpn();
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
ctx.set_npn_protocols(&[b"spdy/3.1"]);
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
Ok(_) => {}
|
||||
Err(err) => panic!("Unexpected error {:?}", err),
|
||||
}
|
||||
let stream = match SslStream::connect_generic(&ctx, stream) {
|
||||
let stream = match SslStream::connect(&ctx, stream) {
|
||||
Ok(stream) => stream,
|
||||
Err(err) => panic!("Expected success, got {:?}", err),
|
||||
};
|
||||
|
|
@ -713,7 +684,7 @@ fn test_npn_server_advertise_multiple() {
|
|||
// We create a different context instance for the server...
|
||||
let listener_ctx = {
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]);
|
||||
assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM)
|
||||
.is_ok());
|
||||
|
|
@ -728,7 +699,7 @@ fn test_npn_server_advertise_multiple() {
|
|||
});
|
||||
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
ctx.set_npn_protocols(&[b"spdy/3.1"]);
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
Ok(_) => {}
|
||||
|
|
@ -736,7 +707,7 @@ fn test_npn_server_advertise_multiple() {
|
|||
}
|
||||
// Now connect to the socket and make sure the protocol negotiation works...
|
||||
let stream = TcpStream::connect(localhost).unwrap();
|
||||
let stream = match SslStream::connect_generic(&ctx, stream) {
|
||||
let stream = match SslStream::connect(&ctx, stream) {
|
||||
Ok(stream) => stream,
|
||||
Err(err) => panic!("Expected success, got {:?}", err),
|
||||
};
|
||||
|
|
@ -754,7 +725,7 @@ fn test_alpn_server_advertise_multiple() {
|
|||
// We create a different context instance for the server...
|
||||
let listener_ctx = {
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]);
|
||||
assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM)
|
||||
.is_ok());
|
||||
|
|
@ -769,7 +740,7 @@ fn test_alpn_server_advertise_multiple() {
|
|||
});
|
||||
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
ctx.set_alpn_protocols(&[b"spdy/3.1"]);
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
Ok(_) => {}
|
||||
|
|
@ -795,7 +766,7 @@ fn test_alpn_server_select_none() {
|
|||
// We create a different context instance for the server...
|
||||
let listener_ctx = {
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]);
|
||||
assert!(ctx.set_certificate_file(&Path::new("test/cert.pem"), X509FileType::PEM)
|
||||
.is_ok());
|
||||
|
|
@ -810,7 +781,7 @@ fn test_alpn_server_select_none() {
|
|||
});
|
||||
|
||||
let mut ctx = SslContext::new(Sslv23).unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
ctx.set_alpn_protocols(&[b"http/2"]);
|
||||
match ctx.set_CA_file(&Path::new("test/cert.pem")) {
|
||||
Ok(_) => {}
|
||||
|
|
@ -838,7 +809,7 @@ mod dtlsv1 {
|
|||
use crypto::hash::Type::SHA256;
|
||||
use ssl::SslMethod;
|
||||
use ssl::SslMethod::Dtlsv1;
|
||||
use ssl::{SslContext, SslStream, VerifyCallback};
|
||||
use ssl::{SslContext, SslStream};
|
||||
use ssl::SSL_VERIFY_PEER;
|
||||
use x509::X509StoreContext;
|
||||
|
||||
|
|
@ -855,7 +826,7 @@ mod dtlsv1 {
|
|||
fn test_read_dtlsv1() {
|
||||
let (_s, stream) = Server::new_dtlsv1(Some("hello"));
|
||||
|
||||
let mut stream = SslStream::connect_generic(&SslContext::new(Dtlsv1).unwrap(), stream).unwrap();
|
||||
let mut stream = SslStream::connect(&SslContext::new(Dtlsv1).unwrap(), stream).unwrap();
|
||||
let mut buf = [0u8; 100];
|
||||
assert!(stream.read(&mut buf).is_ok());
|
||||
}
|
||||
|
|
@ -864,15 +835,15 @@ fn test_read_dtlsv1() {
|
|||
#[cfg(feature = "sslv2")]
|
||||
fn test_sslv2_connect_failure() {
|
||||
let (_s, tcp) = Server::new_tcp(&["-no_ssl2", "-www"]);
|
||||
SslStream::connect_generic(&SslContext::new(Sslv2).unwrap(), tcp)
|
||||
SslStream::connect(&SslContext::new(Sslv2).unwrap(), tcp)
|
||||
.err()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn wait_io(stream: &NonblockingSslStream<TcpStream>, read: bool, timeout_ms: u32) -> bool {
|
||||
fn wait_io(stream: &TcpStream, read: bool, timeout_ms: u32) -> bool {
|
||||
unsafe {
|
||||
let mut set: select::fd_set = mem::zeroed();
|
||||
select::fd_set(&mut set, stream.get_ref());
|
||||
select::fd_set(&mut set, stream);
|
||||
|
||||
let write = if read {
|
||||
0 as *mut _
|
||||
|
|
@ -884,7 +855,19 @@ fn wait_io(stream: &NonblockingSslStream<TcpStream>, read: bool, timeout_ms: u32
|
|||
} else {
|
||||
&mut set as *mut _
|
||||
};
|
||||
select::select(stream.get_ref(), read, write, 0 as *mut _, timeout_ms).unwrap()
|
||||
select::select(stream, read, write, 0 as *mut _, timeout_ms).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn handshake(res: Result<SslStream<TcpStream>, HandshakeError<TcpStream>>)
|
||||
-> SslStream<TcpStream> {
|
||||
match res {
|
||||
Ok(s) => s,
|
||||
Err(HandshakeError::Interrupted(s)) => {
|
||||
wait_io(s.get_ref(), true, 1_000);
|
||||
handshake(s.handshake())
|
||||
}
|
||||
Err(err) => panic!("error on handshake {:?}", err),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -893,7 +876,7 @@ fn test_write_nonblocking() {
|
|||
let (_s, stream) = Server::new();
|
||||
stream.set_nonblocking(true).unwrap();
|
||||
let cx = SslContext::new(Sslv23).unwrap();
|
||||
let mut stream = NonblockingSslStream::connect(&cx, stream).unwrap();
|
||||
let mut stream = handshake(SslStream::connect(&cx, stream));
|
||||
|
||||
let mut iterations = 0;
|
||||
loop {
|
||||
|
|
@ -903,16 +886,16 @@ fn test_write_nonblocking() {
|
|||
// openssl.
|
||||
panic!("Too many read/write round trips in handshake!!");
|
||||
}
|
||||
let result = stream.write(b"hello");
|
||||
let result = stream.ssl_write(b"hello");
|
||||
match result {
|
||||
Ok(_) => {
|
||||
break;
|
||||
}
|
||||
Err(NonblockingSslError::WantRead) => {
|
||||
assert!(wait_io(&stream, true, 1000));
|
||||
Err(Error::WantRead(_)) => {
|
||||
assert!(wait_io(stream.get_ref(), true, 1000));
|
||||
}
|
||||
Err(NonblockingSslError::WantWrite) => {
|
||||
assert!(wait_io(&stream, false, 1000));
|
||||
Err(Error::WantWrite(_)) => {
|
||||
assert!(wait_io(stream.get_ref(), false, 1000));
|
||||
}
|
||||
Err(other) => {
|
||||
panic!("Unexpected SSL Error: {:?}", other);
|
||||
|
|
@ -930,7 +913,7 @@ fn test_read_nonblocking() {
|
|||
let (_s, stream) = Server::new();
|
||||
stream.set_nonblocking(true).unwrap();
|
||||
let cx = SslContext::new(Sslv23).unwrap();
|
||||
let mut stream = NonblockingSslStream::connect(&cx, stream).unwrap();
|
||||
let mut stream = handshake(SslStream::connect(&cx, stream));
|
||||
|
||||
let mut iterations = 0;
|
||||
loop {
|
||||
|
|
@ -940,17 +923,17 @@ fn test_read_nonblocking() {
|
|||
// openssl.
|
||||
panic!("Too many read/write round trips in handshake!!");
|
||||
}
|
||||
let result = stream.write(b"GET /\r\n\r\n");
|
||||
let result = stream.ssl_write(b"GET /\r\n\r\n");
|
||||
match result {
|
||||
Ok(n) => {
|
||||
assert_eq!(n, 9);
|
||||
break;
|
||||
}
|
||||
Err(NonblockingSslError::WantRead) => {
|
||||
assert!(wait_io(&stream, true, 1000));
|
||||
Err(Error::WantRead(..)) => {
|
||||
assert!(wait_io(stream.get_ref(), true, 1000));
|
||||
}
|
||||
Err(NonblockingSslError::WantWrite) => {
|
||||
assert!(wait_io(&stream, false, 1000));
|
||||
Err(Error::WantWrite(..)) => {
|
||||
assert!(wait_io(stream.get_ref(), false, 1000));
|
||||
}
|
||||
Err(other) => {
|
||||
panic!("Unexpected SSL Error: {:?}", other);
|
||||
|
|
@ -958,7 +941,7 @@ fn test_read_nonblocking() {
|
|||
}
|
||||
}
|
||||
let mut input_buffer = [0u8; 1500];
|
||||
let result = stream.read(&mut input_buffer);
|
||||
let result = stream.ssl_read(&mut input_buffer);
|
||||
let bytes_read = match result {
|
||||
Ok(n) => {
|
||||
// This branch is unlikely, but on an overloaded VM with
|
||||
|
|
@ -966,8 +949,8 @@ fn test_read_nonblocking() {
|
|||
// be in the receive buffer before we issue the read() syscall...
|
||||
n
|
||||
}
|
||||
Err(NonblockingSslError::WantRead) => {
|
||||
assert!(wait_io(&stream, true, 3000));
|
||||
Err(Error::WantRead(..)) => {
|
||||
assert!(wait_io(stream.get_ref(), true, 3000));
|
||||
// Second read should return application data.
|
||||
stream.read(&mut input_buffer).unwrap()
|
||||
}
|
||||
|
|
@ -979,14 +962,6 @@ fn test_read_nonblocking() {
|
|||
assert_eq!(&input_buffer[..5], b"HTTP/");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn broken_try_clone_doesnt_crash() {
|
||||
let context = SslContext::new(SslMethod::Sslv23).unwrap();
|
||||
let inner = TcpStream::connect("example.com:443").unwrap();
|
||||
let stream1 = SslStream::connect(&context, inner).unwrap();
|
||||
let _stream2 = stream1.try_clone().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "blammo")]
|
||||
#[cfg(feature = "nightly")]
|
||||
|
|
@ -1093,7 +1068,7 @@ fn refcount_ssl_context() {
|
|||
fn default_verify_paths() {
|
||||
let mut ctx = SslContext::new(SslMethod::Sslv23).unwrap();
|
||||
ctx.set_default_verify_paths().unwrap();
|
||||
ctx.set_verify(SSL_VERIFY_PEER, None);
|
||||
ctx.set_verify(SSL_VERIFY_PEER);
|
||||
let s = TcpStream::connect("google.com:443").unwrap();
|
||||
let mut socket = SslStream::connect(&ctx, s).unwrap();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
use libc::{c_char, c_int, c_long, c_ulong, c_uint, c_void};
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::cmp::Ordering;
|
||||
use std::ffi::CString;
|
||||
use std::iter::repeat;
|
||||
|
|
@ -14,15 +12,15 @@ use std::collections::HashMap;
|
|||
use std::marker::PhantomData;
|
||||
|
||||
use asn1::Asn1Time;
|
||||
use bio::MemBio;
|
||||
use bio::{MemBio, MemBioSlice};
|
||||
use crypto::hash;
|
||||
use crypto::hash::Type as HashType;
|
||||
use crypto::pkey::{PKey, Parts};
|
||||
use crypto::rand::rand_bytes;
|
||||
use ffi;
|
||||
use ffi_extras;
|
||||
use ssl::error::{SslError, StreamError};
|
||||
use nid::Nid;
|
||||
use error::ErrorStack;
|
||||
|
||||
pub mod extension;
|
||||
|
||||
|
|
@ -116,13 +114,6 @@ impl X509StoreContext {
|
|||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # #[allow(unstable)]
|
||||
/// # fn main() {
|
||||
/// use std::fs;
|
||||
/// use std::fs::File;
|
||||
/// use std::io::prelude::*;
|
||||
/// use std::path::Path;
|
||||
///
|
||||
/// use openssl::crypto::hash::Type;
|
||||
/// use openssl::x509::X509Generator;
|
||||
/// use openssl::x509::extension::{Extension, KeyUsageOption};
|
||||
|
|
@ -135,17 +126,8 @@ impl X509StoreContext {
|
|||
/// .add_extension(Extension::KeyUsage(vec![KeyUsageOption::DigitalSignature]));
|
||||
///
|
||||
/// let (cert, pkey) = gen.generate().unwrap();
|
||||
///
|
||||
/// let cert_path = "doc_cert.pem";
|
||||
/// let mut file = File::create(cert_path).unwrap();
|
||||
/// assert!(cert.write_pem(&mut file).is_ok());
|
||||
/// # let _ = fs::remove_file(cert_path);
|
||||
///
|
||||
/// let pkey_path = "doc_key.pem";
|
||||
/// let mut file = File::create(pkey_path).unwrap();
|
||||
/// assert!(pkey.write_pem(&mut file).is_ok());
|
||||
/// # let _ = fs::remove_file(pkey_path);
|
||||
/// # }
|
||||
/// let cert_pem = cert.write_pem().unwrap();
|
||||
/// let pkey_pem = pkey.write_pem().unwrap();
|
||||
/// ```
|
||||
pub struct X509Generator {
|
||||
bits: u32,
|
||||
|
|
@ -256,7 +238,7 @@ impl X509Generator {
|
|||
fn add_extension_internal(x509: *mut ffi::X509,
|
||||
exttype: &extension::ExtensionType,
|
||||
value: &str)
|
||||
-> Result<(), SslError> {
|
||||
-> Result<(), ErrorStack> {
|
||||
unsafe {
|
||||
let mut ctx: ffi::X509V3_CTX = mem::zeroed();
|
||||
ffi::X509V3_set_ctx(&mut ctx, x509, x509, ptr::null_mut(), ptr::null_mut(), 0);
|
||||
|
|
@ -288,7 +270,7 @@ impl X509Generator {
|
|||
fn add_name_internal(name: *mut ffi::X509_NAME,
|
||||
key: &str,
|
||||
value: &str)
|
||||
-> Result<(), SslError> {
|
||||
-> Result<(), ErrorStack> {
|
||||
let value_len = value.len() as c_int;
|
||||
lift_ssl!(unsafe {
|
||||
let key = CString::new(key.as_bytes()).unwrap();
|
||||
|
|
@ -319,7 +301,7 @@ impl X509Generator {
|
|||
}
|
||||
|
||||
/// Generates a private key and a self-signed certificate and returns them
|
||||
pub fn generate<'a>(&self) -> Result<(X509<'a>, PKey), SslError> {
|
||||
pub fn generate<'a>(&self) -> Result<(X509<'a>, PKey), ErrorStack> {
|
||||
ffi::init();
|
||||
|
||||
let mut p_key = PKey::new();
|
||||
|
|
@ -331,7 +313,7 @@ impl X509Generator {
|
|||
|
||||
/// Sets the certificate public-key, then self-sign and return it
|
||||
/// Note: That the bit-length of the private key is used (set_bitlength is ignored)
|
||||
pub fn sign<'a>(&self, p_key: &PKey) -> Result<X509<'a>, SslError> {
|
||||
pub fn sign<'a>(&self, p_key: &PKey) -> Result<X509<'a>, ErrorStack> {
|
||||
ffi::init();
|
||||
|
||||
unsafe {
|
||||
|
|
@ -391,7 +373,7 @@ impl X509Generator {
|
|||
}
|
||||
|
||||
/// Obtain a certificate signing request (CSR)
|
||||
pub fn request(&self, p_key: &PKey) -> Result<X509Req, SslError> {
|
||||
pub fn request(&self, p_key: &PKey) -> Result<X509Req, ErrorStack> {
|
||||
let cert = match self.sign(p_key) {
|
||||
Ok(c) => c,
|
||||
Err(x) => return Err(x),
|
||||
|
|
@ -444,12 +426,8 @@ impl<'ctx> X509<'ctx> {
|
|||
}
|
||||
|
||||
/// Reads certificate from PEM, takes ownership of handle
|
||||
pub fn from_pem<R>(reader: &mut R) -> Result<X509<'ctx>, SslError>
|
||||
where R: Read
|
||||
{
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
|
||||
|
||||
pub fn from_pem(buf: &[u8]) -> Result<X509<'ctx>, ErrorStack> {
|
||||
let mem_bio = try!(MemBioSlice::new(buf));
|
||||
unsafe {
|
||||
let handle = try_ssl_null!(ffi::PEM_read_bio_X509(mem_bio.get_handle(),
|
||||
ptr::null_mut(),
|
||||
|
|
@ -523,25 +501,21 @@ impl<'ctx> X509<'ctx> {
|
|||
}
|
||||
|
||||
/// Writes certificate as PEM
|
||||
pub fn write_pem<W>(&self, writer: &mut W) -> Result<(), SslError>
|
||||
where W: Write
|
||||
{
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
pub fn write_pem(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mem_bio = try!(MemBio::new());
|
||||
unsafe {
|
||||
try_ssl!(ffi::PEM_write_bio_X509(mem_bio.get_handle(), self.handle));
|
||||
}
|
||||
io::copy(&mut mem_bio, writer).map_err(StreamError).map(|_| ())
|
||||
Ok(mem_bio.get_buf().to_owned())
|
||||
}
|
||||
|
||||
/// Returns a DER serialized form of the certificate
|
||||
pub fn save_der(&self) -> Result<Vec<u8>, SslError> {
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
pub fn save_der(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mem_bio = try!(MemBio::new());
|
||||
unsafe {
|
||||
ffi::i2d_X509_bio(mem_bio.get_handle(), self.handle);
|
||||
}
|
||||
let mut v = Vec::new();
|
||||
try!(io::copy(&mut mem_bio, &mut v).map_err(StreamError));
|
||||
Ok(v)
|
||||
Ok(mem_bio.get_buf().to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -627,12 +601,8 @@ impl X509Req {
|
|||
}
|
||||
|
||||
/// Reads CSR from PEM
|
||||
pub fn from_pem<R>(reader: &mut R) -> Result<X509Req, SslError>
|
||||
where R: Read
|
||||
{
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
|
||||
|
||||
pub fn from_pem(buf: &[u8]) -> Result<X509Req, ErrorStack> {
|
||||
let mem_bio = try!(MemBioSlice::new(buf));
|
||||
unsafe {
|
||||
let handle = try_ssl_null!(ffi::PEM_read_bio_X509_REQ(mem_bio.get_handle(),
|
||||
ptr::null_mut(),
|
||||
|
|
@ -643,25 +613,21 @@ impl X509Req {
|
|||
}
|
||||
|
||||
/// Writes CSR as PEM
|
||||
pub fn write_pem<W>(&self, writer: &mut W) -> Result<(), SslError>
|
||||
where W: Write
|
||||
{
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
unsafe {
|
||||
try_ssl!(ffi::PEM_write_bio_X509_REQ(mem_bio.get_handle(), self.handle));
|
||||
pub fn write_pem(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mem_bio = try!(MemBio::new());
|
||||
if unsafe { ffi::PEM_write_bio_X509_REQ(mem_bio.get_handle(), self.handle) } != 1 {
|
||||
return Err(ErrorStack::get());
|
||||
}
|
||||
io::copy(&mut mem_bio, writer).map_err(StreamError).map(|_| ())
|
||||
Ok(mem_bio.get_buf().to_owned())
|
||||
}
|
||||
|
||||
/// Returns a DER serialized form of the CSR
|
||||
pub fn save_der(&self) -> Result<Vec<u8>, SslError> {
|
||||
let mut mem_bio = try!(MemBio::new());
|
||||
pub fn save_der(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
let mem_bio = try!(MemBio::new());
|
||||
unsafe {
|
||||
ffi::i2d_X509_REQ_bio(mem_bio.get_handle(), self.handle);
|
||||
}
|
||||
let mut v = Vec::new();
|
||||
try!(io::copy(&mut mem_bio, &mut v).map_err(StreamError));
|
||||
Ok(v)
|
||||
Ok(mem_bio.get_buf().to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
use serialize::hex::FromHex;
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
use std::fs::File;
|
||||
|
||||
use crypto::hash::Type::SHA1;
|
||||
use crypto::pkey::PKey;
|
||||
|
|
@ -30,8 +27,8 @@ fn get_generator() -> X509Generator {
|
|||
#[test]
|
||||
fn test_cert_gen() {
|
||||
let (cert, pkey) = get_generator().generate().unwrap();
|
||||
cert.write_pem(&mut io::sink()).unwrap();
|
||||
pkey.write_pem(&mut io::sink()).unwrap();
|
||||
cert.write_pem().unwrap();
|
||||
pkey.write_pem().unwrap();
|
||||
|
||||
// FIXME: check data in result to be correct, needs implementation
|
||||
// of X509 getters
|
||||
|
|
@ -70,7 +67,7 @@ fn test_req_gen() {
|
|||
pkey.gen(512);
|
||||
|
||||
let req = get_generator().request(&pkey).unwrap();
|
||||
req.write_pem(&mut io::sink()).unwrap();
|
||||
req.write_pem().unwrap();
|
||||
|
||||
// FIXME: check data in result to be correct, needs implementation
|
||||
// of X509_REQ getters
|
||||
|
|
@ -78,12 +75,8 @@ fn test_req_gen() {
|
|||
|
||||
#[test]
|
||||
fn test_cert_loading() {
|
||||
let cert_path = Path::new("test/cert.pem");
|
||||
let mut file = File::open(&cert_path)
|
||||
.ok()
|
||||
.expect("Failed to open `test/cert.pem`");
|
||||
|
||||
let cert = X509::from_pem(&mut file).ok().expect("Failed to load PEM");
|
||||
let cert = include_bytes!("../../test/cert.pem");
|
||||
let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
|
||||
let fingerprint = cert.fingerprint(SHA1).unwrap();
|
||||
|
||||
let hash_str = "E19427DAC79FBE758394945276A6E4F15F0BEBE6";
|
||||
|
|
@ -94,12 +87,8 @@ fn test_cert_loading() {
|
|||
|
||||
#[test]
|
||||
fn test_save_der() {
|
||||
let cert_path = Path::new("test/cert.pem");
|
||||
let mut file = File::open(&cert_path)
|
||||
.ok()
|
||||
.expect("Failed to open `test/cert.pem`");
|
||||
|
||||
let cert = X509::from_pem(&mut file).ok().expect("Failed to load PEM");
|
||||
let cert = include_bytes!("../../test/cert.pem");
|
||||
let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
|
||||
|
||||
let der = cert.save_der().unwrap();
|
||||
assert!(!der.is_empty());
|
||||
|
|
@ -107,12 +96,8 @@ fn test_save_der() {
|
|||
|
||||
#[test]
|
||||
fn test_subject_read_cn() {
|
||||
let cert_path = Path::new("test/cert.pem");
|
||||
let mut file = File::open(&cert_path)
|
||||
.ok()
|
||||
.expect("Failed to open `test/cert.pem`");
|
||||
|
||||
let cert = X509::from_pem(&mut file).ok().expect("Failed to load PEM");
|
||||
let cert = include_bytes!("../../test/cert.pem");
|
||||
let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
|
||||
let subject = cert.subject_name();
|
||||
let cn = match subject.text_by_nid(Nid::CN) {
|
||||
Some(x) => x,
|
||||
|
|
@ -124,12 +109,8 @@ fn test_subject_read_cn() {
|
|||
|
||||
#[test]
|
||||
fn test_nid_values() {
|
||||
let cert_path = Path::new("test/nid_test_cert.pem");
|
||||
let mut file = File::open(&cert_path)
|
||||
.ok()
|
||||
.expect("Failed to open `test/nid_test_cert.pem`");
|
||||
|
||||
let cert = X509::from_pem(&mut file).ok().expect("Failed to load PEM");
|
||||
let cert = include_bytes!("../../test/nid_test_cert.pem");
|
||||
let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
|
||||
let subject = cert.subject_name();
|
||||
|
||||
let cn = match subject.text_by_nid(Nid::CN) {
|
||||
|
|
@ -153,12 +134,8 @@ fn test_nid_values() {
|
|||
|
||||
#[test]
|
||||
fn test_nid_uid_value() {
|
||||
let cert_path = Path::new("test/nid_uid_test_cert.pem");
|
||||
let mut file = File::open(&cert_path)
|
||||
.ok()
|
||||
.expect("Failed to open `test/nid_uid_test_cert.pem`");
|
||||
|
||||
let cert = X509::from_pem(&mut file).ok().expect("Failed to load PEM");
|
||||
let cert = include_bytes!("../../test/nid_uid_test_cert.pem");
|
||||
let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
|
||||
let subject = cert.subject_name();
|
||||
|
||||
let cn = match subject.text_by_nid(Nid::UserId) {
|
||||
|
|
@ -170,8 +147,8 @@ fn test_nid_uid_value() {
|
|||
|
||||
#[test]
|
||||
fn test_subject_alt_name() {
|
||||
let mut file = File::open("test/alt_name_cert.pem").unwrap();
|
||||
let cert = X509::from_pem(&mut file).unwrap();
|
||||
let cert = include_bytes!("../../test/alt_name_cert.pem");
|
||||
let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
|
||||
|
||||
let subject_alt_names = cert.subject_alt_names().unwrap();
|
||||
assert_eq!(3, subject_alt_names.len());
|
||||
|
|
@ -184,8 +161,8 @@ fn test_subject_alt_name() {
|
|||
|
||||
#[test]
|
||||
fn test_subject_alt_name_iter() {
|
||||
let mut file = File::open("test/alt_name_cert.pem").unwrap();
|
||||
let cert = X509::from_pem(&mut file).unwrap();
|
||||
let cert = include_bytes!("../../test/alt_name_cert.pem");
|
||||
let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
|
||||
|
||||
let subject_alt_names = cert.subject_alt_names().unwrap();
|
||||
let mut subject_alt_names_iter = subject_alt_names.iter();
|
||||
|
|
|
|||
|
|
@ -7,10 +7,6 @@ if [ "$TEST_FEATURES" == "true" ]; then
|
|||
FEATURES="tlsv1_2 tlsv1_1 dtlsv1 dtlsv1_2 sslv3 aes_xts aes_ctr npn alpn rfc5114 ecdh_auto pkcs5_pbkdf2_hmac"
|
||||
fi
|
||||
|
||||
if [ "$TRAVIS_RUST_VERSION" == "nightly" ]; then
|
||||
FEATURES="$FEATURES nightly catch_unwind"
|
||||
fi
|
||||
|
||||
if [ "$TRAVIS_OS_NAME" != "osx" ]; then
|
||||
export OPENSSL_LIB_DIR=$HOME/openssl/lib
|
||||
export OPENSSL_INCLUDE_DIR=$HOME/openssl/include
|
||||
|
|
|
|||
Loading…
Reference in New Issue