Merge remote-tracking branch 'upstream/master'

Conflicts:
	openssl-sys/src/lib.rs
This commit is contained in:
Chris Cole 2014-12-23 15:14:27 -05:00
commit 156fc65eb0
13 changed files with 90 additions and 58 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "openssl" name = "openssl"
version = "0.2.3" version = "0.2.8"
authors = ["Steven Fackler <sfackler@gmail.com>"] authors = ["Steven Fackler <sfackler@gmail.com>"]
license = "Apache-2.0" license = "Apache-2.0"
description = "OpenSSL bindings" description = "OpenSSL bindings"
@ -17,4 +17,4 @@ aes_xts = ["openssl-sys/aes_xts"]
[dependencies.openssl-sys] [dependencies.openssl-sys]
path = "openssl-sys" path = "openssl-sys"
version = "0.2.3" version = "0.2.8"

View File

@ -25,7 +25,7 @@ For some reason, the OpenSSL distribution for Windows is structured differently,
2. Run the installer, making note of where it's installing OpenSSL. The option to copy the libraries to the Windows system directory or `[OpenSSL folder]/bin` is your choice. The latter is probably preferable, and the default. 2. Run the installer, making note of where it's installing OpenSSL. The option to copy the libraries to the Windows system directory or `[OpenSSL folder]/bin` is your choice. The latter is probably preferable, and the default.
3. Navigate to `[OpenSSL folder]/lib/MinGW/`, and copy `libeay32.a` and `ssleay32.a` (If 64-bit, then they will have `64` instead of `32`.) to your Rust install's libs folder. The default should be: 3. Navigate to `[OpenSSL folder]/lib/MinGW/`, and copy `libeay32.a` and `ssleay32.a` (If 64-bit, then they will have `64` instead of `32`.) to your Rust install's libs folder. The default should be:
* 32-bit: `C:\Program Files (x86)\Rust\bin\rustlib\i686-pc-mingw32\lib` * 32-bit: `C:\Program Files (x86)\Rust\bin\rustlib\i686-pc-mingw32\lib`
* 64-bit: TODO * 64-bit: `C:\Program Files (x86)\Rust\bin\rustlib\x86_64-pc-windows-gnu\lib`
4. Rename `libeay32.a` and `ssleay32.a` to `libcrypto.a` and `libssl.a`, respectively. 4. Rename `libeay32.a` and `ssleay32.a` to `libcrypto.a` and `libssl.a`, respectively.
5. Run `cargo build`. 5. Run `cargo build`.

View File

@ -1,6 +1,6 @@
[package] [package]
name = "openssl-sys" name = "openssl-sys"
version = "0.2.3" version = "0.2.8"
authors = ["Alex Crichton <alex@alexcrichton.com>", authors = ["Alex Crichton <alex@alexcrichton.com>",
"Steven Fackler <sfackler@gmail.com>"] "Steven Fackler <sfackler@gmail.com>"]
license = "MIT" license = "MIT"

View File

@ -9,9 +9,14 @@ fn main() {
if pkg_config::find_library("openssl").is_err() { if pkg_config::find_library("openssl").is_err() {
let mut flags = " -l crypto -l ssl".to_string();
let target = os::getenv("TARGET").unwrap(); let target = os::getenv("TARGET").unwrap();
let is_android = target.find_str("android").is_some();
let mut flags = if is_android {
" -l crypto:static -l ssl:static"
} else {
" -l crypto -l ssl"
}.to_string();
let win_pos = target.find_str("windows") let win_pos = target.find_str("windows")
.or(target.find_str("win32")) .or(target.find_str("win32"))
@ -23,7 +28,7 @@ fn main() {
flags.push_str(" -l gdi32 -l wsock32"); flags.push_str(" -l gdi32 -l wsock32");
} }
if target.find_str("android").is_some() { if is_android {
let path = os::getenv("OPENSSL_PATH").expect("Android does not provide openssl libraries, please \ let path = os::getenv("OPENSSL_PATH").expect("Android does not provide openssl libraries, please \
build them yourselves (instructions in the README) \ build them yourselves (instructions in the README) \
and provide their location through $OPENSSL_PATH."); and provide their location through $OPENSSL_PATH.");

View File

@ -2,7 +2,6 @@
#![allow(dead_code)] #![allow(dead_code)]
extern crate libc; extern crate libc;
extern crate rustrt;
#[cfg(feature = "libressl-pnacl-sys")] #[cfg(feature = "libressl-pnacl-sys")]
extern crate "libressl-pnacl-sys" as _for_linkage; extern crate "libressl-pnacl-sys" as _for_linkage;
@ -10,7 +9,7 @@ extern crate "libressl-pnacl-sys" as _for_linkage;
use libc::{c_void, c_int, c_char, c_ulong, c_long, c_uint, c_uchar, size_t}; use libc::{c_void, c_int, c_char, c_ulong, c_long, c_uint, c_uchar, size_t};
use std::mem; use std::mem;
use std::ptr; use std::ptr;
use rustrt::mutex::NativeMutex; use std::sync::{StaticMutex, StaticMutexGuard, MUTEX_INIT};
use std::sync::{Once, ONCE_INIT}; use std::sync::{Once, ONCE_INIT};
pub type ASN1_INTEGER = c_void; pub type ASN1_INTEGER = c_void;
@ -49,6 +48,8 @@ pub struct EVP_MD_CTX {
update: *mut c_void update: *mut c_void
} }
impl Copy for EVP_MD_CTX {}
#[repr(C)] #[repr(C)]
pub struct HMAC_CTX { pub struct HMAC_CTX {
md: *mut EVP_MD, md: *mut EVP_MD,
@ -59,6 +60,8 @@ pub struct HMAC_CTX {
key: [c_uchar, ..128] key: [c_uchar, ..128]
} }
impl Copy for HMAC_CTX {}
#[repr(C)] #[repr(C)]
pub struct X509V3_CTX { pub struct X509V3_CTX {
flags: c_int, flags: c_int,
@ -72,6 +75,8 @@ pub struct X509V3_CTX {
// Maybe more here // Maybe more here
} }
impl Copy for X509V3_CTX {}
#[repr(C)] #[repr(C)]
pub struct BIGNUM { pub struct BIGNUM {
pub d: *mut c_void, pub d: *mut c_void,
@ -81,6 +86,8 @@ pub struct BIGNUM {
pub flags: c_int, pub flags: c_int,
} }
impl Copy for BIGNUM {}
#[repr(C)] #[repr(C)]
pub struct BIGNUM_PTR { pub struct BIGNUM_PTR {
pub ptr: *mut BIGNUM, pub ptr: *mut BIGNUM,
@ -189,7 +196,8 @@ pub const X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: c_int = 45;
pub const X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: c_int = 53; pub const X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: c_int = 53;
pub const X509_V_OK: c_int = 0; pub const X509_V_OK: c_int = 0;
static mut MUTEXES: *mut Vec<NativeMutex> = 0 as *mut Vec<NativeMutex>; static mut MUTEXES: *mut Vec<StaticMutex> = 0 as *mut Vec<StaticMutex>;
static mut GUARDS: *mut Vec<Option<StaticMutexGuard>> = 0 as *mut Vec<Option<StaticMutexGuard>>;
extern fn locking_function(mode: c_int, n: c_int, _file: *const c_char, extern fn locking_function(mode: c_int, n: c_int, _file: *const c_char,
_line: c_int) { _line: c_int) {
@ -197,9 +205,9 @@ extern fn locking_function(mode: c_int, n: c_int, _file: *const c_char,
let mutex = &(*MUTEXES)[n as uint]; let mutex = &(*MUTEXES)[n as uint];
if mode & CRYPTO_LOCK != 0 { if mode & CRYPTO_LOCK != 0 {
mutex.lock_noguard(); (*GUARDS)[n as uint] = Some(mutex.lock());
} else { } else {
mutex.unlock_noguard(); &(*GUARDS)[n as uint].take();
} }
} }
} }
@ -213,8 +221,10 @@ pub fn init() {
SSL_load_error_strings(); SSL_load_error_strings();
let num_locks = CRYPTO_num_locks(); let num_locks = CRYPTO_num_locks();
let mutexes = box Vec::from_fn(num_locks as uint, |_| NativeMutex::new()); let mutexes = box Vec::from_fn(num_locks as uint, |_| MUTEX_INIT);
MUTEXES = mem::transmute(mutexes); MUTEXES = mem::transmute(mutexes);
let guards: Box<Vec<Option<StaticMutexGuard>>> = box Vec::from_fn(num_locks as uint, |_| None);
GUARDS = mem::transmute(guards);
CRYPTO_set_locking_callback(locking_function); CRYPTO_set_locking_callback(locking_function);
}) })

View File

@ -7,6 +7,7 @@ use ssl::error::SslError;
pub struct BigNum(*mut ffi::BIGNUM); pub struct BigNum(*mut ffi::BIGNUM);
#[deriving(Copy)]
#[repr(C)] #[repr(C)]
pub enum RNGProperty { pub enum RNGProperty {
MsbMaybeZero = -1, MsbMaybeZero = -1,
@ -25,7 +26,7 @@ macro_rules! with_ctx(
r r
} }
}); });
) );
macro_rules! with_bn( macro_rules! with_bn(
($name:ident, $action:block) => ({ ($name:ident, $action:block) => ({
@ -41,7 +42,7 @@ macro_rules! with_bn(
Err(err) => Err(err), Err(err) => Err(err),
} }
}); });
) );
macro_rules! with_bn_in_ctx( macro_rules! with_bn_in_ctx(
($name:ident, $ctx_name:ident, $action:block) => ({ ($name:ident, $ctx_name:ident, $action:block) => ({
@ -65,7 +66,7 @@ macro_rules! with_bn_in_ctx(
Err(err) => Err(err), Err(err) => Err(err),
} }
}); });
) );
impl BigNum { impl BigNum {
pub fn new() -> Result<BigNum, SslError> { pub fn new() -> Result<BigNum, SslError> {
@ -441,45 +442,45 @@ pub mod unchecked {
use ffi; use ffi;
use super::{BigNum}; use super::{BigNum};
impl Add<BigNum, BigNum> for BigNum { impl<'a> Add<&'a BigNum, BigNum> for &'a BigNum {
fn add(&self, oth: &BigNum) -> BigNum { fn add(self, oth: &'a BigNum) -> BigNum {
self.checked_add(oth).unwrap() self.checked_add(oth).unwrap()
} }
} }
impl Sub<BigNum, BigNum> for BigNum { impl<'a> Sub<&'a BigNum, BigNum> for &'a BigNum {
fn sub(&self, oth: &BigNum) -> BigNum { fn sub(self, oth: &'a BigNum) -> BigNum {
self.checked_sub(oth).unwrap() self.checked_sub(oth).unwrap()
} }
} }
impl Mul<BigNum, BigNum> for BigNum { impl<'a> Mul<&'a BigNum, BigNum> for &'a BigNum {
fn mul(&self, oth: &BigNum) -> BigNum { fn mul(self, oth: &'a BigNum) -> BigNum {
self.checked_mul(oth).unwrap() self.checked_mul(oth).unwrap()
} }
} }
impl Div<BigNum, BigNum> for BigNum { impl<'a> Div<&'a BigNum, BigNum> for &'a BigNum {
fn div(&self, oth: &BigNum) -> BigNum { fn div(self, oth: &'a BigNum) -> BigNum {
self.checked_div(oth).unwrap() self.checked_div(oth).unwrap()
} }
} }
impl Rem<BigNum, BigNum> for BigNum { impl<'a> Rem<&'a BigNum, BigNum> for &'a BigNum {
fn rem(&self, oth: &BigNum) -> BigNum { fn rem(self, oth: &'a BigNum) -> BigNum {
self.checked_mod(oth).unwrap() self.checked_mod(oth).unwrap()
} }
} }
impl Shl<i32, BigNum> for BigNum { impl<'a> Shl<i32, BigNum> for &'a BigNum {
fn shl(&self, n: &i32) -> BigNum { fn shl(self, n: i32) -> BigNum {
self.checked_shl(n).unwrap() self.checked_shl(&n).unwrap()
} }
} }
impl Shr<i32, BigNum> for BigNum { impl<'a> Shr<i32, BigNum> for &'a BigNum {
fn shr(&self, n: &i32) -> BigNum { fn shr(self, n: i32) -> BigNum {
self.checked_shr(n).unwrap() self.checked_shr(&n).unwrap()
} }
} }
@ -497,7 +498,7 @@ pub mod unchecked {
} }
impl Neg<BigNum> for BigNum { impl Neg<BigNum> for BigNum {
fn neg(&self) -> BigNum { fn neg(self) -> BigNum {
let mut n = self.clone(); let mut n = self.clone();
n.negate(); n.negate();
n n

View File

@ -4,6 +4,7 @@ use std::io;
use ffi; use ffi;
#[deriving(Copy)]
pub enum HashType { pub enum HashType {
MD5, MD5,
SHA1, SHA1,
@ -134,7 +135,7 @@ mod tests {
} }
fn compare(calced_raw: Vec<u8>, hashtest: &HashTest) { fn compare(calced_raw: Vec<u8>, hashtest: &HashTest) {
let calced = calced_raw.as_slice().to_hex().into_string(); let calced = calced_raw.as_slice().to_hex().to_string();
if calced != hashtest.expected_output { if calced != hashtest.expected_output {
println!("Test failed - {} != {}", calced, hashtest.expected_output); println!("Test failed - {} != {}", calced, hashtest.expected_output);

View File

@ -55,7 +55,7 @@ impl HMAC {
let mut res = Vec::from_elem(self.len, 0u8); let mut res = Vec::from_elem(self.len, 0u8);
let mut outlen = 0; let mut outlen = 0;
ffi::HMAC_Final(&mut self.ctx, res.as_mut_ptr(), &mut outlen); ffi::HMAC_Final(&mut self.ctx, res.as_mut_ptr(), &mut outlen);
assert!(self.len == outlen as uint) assert!(self.len == outlen as uint);
res res
} }
} }

View File

@ -6,7 +6,7 @@ use crypto::hash::HashType;
use ffi; use ffi;
use ssl::error::{SslError, StreamError}; use ssl::error::{SslError, StreamError};
#[deriving(Copy)]
enum Parts { enum Parts {
Neither, Neither,
Public, Public,
@ -14,6 +14,7 @@ enum Parts {
} }
/// Represents a role an asymmetric key might be appropriate for. /// Represents a role an asymmetric key might be appropriate for.
#[deriving(Copy)]
pub enum Role { pub enum Role {
Encrypt, Encrypt,
Decrypt, Decrypt,
@ -22,6 +23,7 @@ pub enum Role {
} }
/// Type of encryption padding to use. /// Type of encryption padding to use.
#[deriving(Copy)]
pub enum EncryptionPadding { pub enum EncryptionPadding {
OAEP, OAEP,
PKCS1v15 PKCS1v15

View File

@ -2,12 +2,14 @@ use libc::{c_int};
use ffi; use ffi;
#[deriving(Copy)]
pub enum Mode { pub enum Mode {
Encrypt, Encrypt,
Decrypt, Decrypt,
} }
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[deriving(Copy)]
pub enum Type { pub enum Type {
AES_128_ECB, AES_128_ECB,
AES_128_CBC, AES_128_CBC,

View File

@ -33,6 +33,7 @@ fn init() {
/// Determines the SSL method supported /// Determines the SSL method supported
#[deriving(Show, Hash, PartialEq, Eq)] #[deriving(Show, Hash, PartialEq, Eq)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[deriving(Copy)]
pub enum SslMethod { pub enum SslMethod {
#[cfg(feature = "sslv2")] #[cfg(feature = "sslv2")]
/// Only support the SSLv2 protocol, requires `feature="sslv2"` /// Only support the SSLv2 protocol, requires `feature="sslv2"`
@ -68,6 +69,7 @@ impl SslMethod {
} }
/// Determines the type of certificate verification used /// Determines the type of certificate verification used
#[deriving(Copy)]
#[repr(i32)] #[repr(i32)]
pub enum SslVerifyMode { pub enum SslVerifyMode {
/// Verify that the server's certificate is trusted /// Verify that the server's certificate is trusted
@ -91,8 +93,9 @@ fn get_verify_data_idx<T>() -> c_int {
unsafe { unsafe {
INIT.doit(|| { INIT.doit(|| {
let f: ffi::CRYPTO_EX_free = free_data_box::<T>;
let idx = ffi::SSL_CTX_get_ex_new_index(0, ptr::null(), None, let idx = ffi::SSL_CTX_get_ex_new_index(0, ptr::null(), None,
None, Some(free_data_box::<T>)); None, Some(f));
assert!(idx >= 0); assert!(idx >= 0);
VERIFY_DATA_IDX = idx; VERIFY_DATA_IDX = idx;
}); });
@ -197,7 +200,9 @@ impl SslContext {
unsafe { unsafe {
ffi::SSL_CTX_set_ex_data(self.ctx, VERIFY_IDX, ffi::SSL_CTX_set_ex_data(self.ctx, VERIFY_IDX,
mem::transmute(verify)); mem::transmute(verify));
ffi::SSL_CTX_set_verify(self.ctx, mode as c_int, Some(raw_verify)); let f: extern fn(c_int, *mut ffi::X509_STORE_CTX) -> c_int =
raw_verify;
ffi::SSL_CTX_set_verify(self.ctx, mode as c_int, Some(f));
} }
} }
@ -214,7 +219,9 @@ impl SslContext {
mem::transmute(Some(verify))); mem::transmute(Some(verify)));
ffi::SSL_CTX_set_ex_data(self.ctx, get_verify_data_idx::<T>(), ffi::SSL_CTX_set_ex_data(self.ctx, get_verify_data_idx::<T>(),
mem::transmute(data)); mem::transmute(data));
ffi::SSL_CTX_set_verify(self.ctx, mode as c_int, Some(raw_verify_with_data::<T>)); let f: extern fn(c_int, *mut ffi::X509_STORE_CTX) -> c_int =
raw_verify_with_data::<T>;
ffi::SSL_CTX_set_verify(self.ctx, mode as c_int, Some(f));
} }
} }
@ -382,7 +389,7 @@ impl Ssl {
} }
#[deriving(FromPrimitive)] #[deriving(FromPrimitive, Show)]
#[repr(i32)] #[repr(i32)]
enum LibSslError { enum LibSslError {
ErrorNone = ffi::SSL_ERROR_NONE, ErrorNone = ffi::SSL_ERROR_NONE,
@ -487,7 +494,7 @@ impl<S: Stream> SslStream<S> {
LibSslError::ErrorWantWrite => { try_ssl_stream!(self.flush()) } LibSslError::ErrorWantWrite => { try_ssl_stream!(self.flush()) }
LibSslError::ErrorZeroReturn => return Err(SslSessionClosed), LibSslError::ErrorZeroReturn => return Err(SslSessionClosed),
LibSslError::ErrorSsl => return Err(SslError::get()), LibSslError::ErrorSsl => return Err(SslError::get()),
_ => unreachable!() err => panic!("unexpected error {}", err),
} }
} }
} }
@ -539,7 +546,7 @@ impl<S: Stream> Writer for SslStream<S> {
let mut start = 0; let mut start = 0;
while start < buf.len() { while start < buf.len() {
let ret = self.in_retry_wrapper(|ssl| { let ret = self.in_retry_wrapper(|ssl| {
ssl.write(buf.split_at(start).val1()) ssl.write(buf.split_at(start).1)
}); });
match ret { match ret {
Ok(len) => start += len as uint, Ok(len) => start += len as uint,

View File

@ -1,10 +1,11 @@
use serialize::hex::FromHex; use serialize::hex::FromHex;
use std::io::{Writer};
use std::io::net::tcp::TcpStream; use std::io::net::tcp::TcpStream;
use std::io::{Writer};
use std::thread::Thread;
use crypto::hash::HashType::{SHA256}; use crypto::hash::HashType::{SHA256};
use ssl::SslMethod::Sslv23; use ssl::SslMethod::Sslv23;
use ssl::{SslContext, SslStream}; use ssl::{SslContext, SslStream, VerifyCallback};
use ssl::SslVerifyMode::SslVerifyPeer; use ssl::SslVerifyMode::SslVerifyPeer;
use x509::{X509StoreContext}; use x509::{X509StoreContext};
@ -52,7 +53,7 @@ fn test_verify_untrusted_callback_override_ok() {
} }
let stream = TcpStream::connect("127.0.0.1:15418").unwrap(); let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
let mut ctx = SslContext::new(Sslv23).unwrap(); let mut ctx = SslContext::new(Sslv23).unwrap();
ctx.set_verify(SslVerifyPeer, Some(callback)); ctx.set_verify(SslVerifyPeer, Some(callback as VerifyCallback));
match SslStream::new(&ctx, stream) { match SslStream::new(&ctx, stream) {
Ok(_) => (), Ok(_) => (),
Err(err) => panic!("Expected success, got {}", err) Err(err) => panic!("Expected success, got {}", err)
@ -66,7 +67,7 @@ fn test_verify_untrusted_callback_override_bad() {
} }
let stream = TcpStream::connect("127.0.0.1:15418").unwrap(); let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
let mut ctx = SslContext::new(Sslv23).unwrap(); let mut ctx = SslContext::new(Sslv23).unwrap();
ctx.set_verify(SslVerifyPeer, Some(callback)); ctx.set_verify(SslVerifyPeer, Some(callback as VerifyCallback));
assert!(SslStream::new(&ctx, stream).is_err()); assert!(SslStream::new(&ctx, stream).is_err());
} }
@ -77,7 +78,7 @@ fn test_verify_trusted_callback_override_ok() {
} }
let stream = TcpStream::connect("127.0.0.1:15418").unwrap(); let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
let mut ctx = SslContext::new(Sslv23).unwrap(); let mut ctx = SslContext::new(Sslv23).unwrap();
ctx.set_verify(SslVerifyPeer, Some(callback)); ctx.set_verify(SslVerifyPeer, Some(callback as VerifyCallback));
match ctx.set_CA_file(&Path::new("test/cert.pem")) { match ctx.set_CA_file(&Path::new("test/cert.pem")) {
None => {} None => {}
Some(err) => panic!("Unexpected error {}", err) Some(err) => panic!("Unexpected error {}", err)
@ -95,7 +96,7 @@ fn test_verify_trusted_callback_override_bad() {
} }
let stream = TcpStream::connect("127.0.0.1:15418").unwrap(); let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
let mut ctx = SslContext::new(Sslv23).unwrap(); let mut ctx = SslContext::new(Sslv23).unwrap();
ctx.set_verify(SslVerifyPeer, Some(callback)); ctx.set_verify(SslVerifyPeer, Some(callback as VerifyCallback));
match ctx.set_CA_file(&Path::new("test/cert.pem")) { match ctx.set_CA_file(&Path::new("test/cert.pem")) {
None => {} None => {}
Some(err) => panic!("Unexpected error {}", err) Some(err) => panic!("Unexpected error {}", err)
@ -111,7 +112,7 @@ fn test_verify_callback_load_certs() {
} }
let stream = TcpStream::connect("127.0.0.1:15418").unwrap(); let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
let mut ctx = SslContext::new(Sslv23).unwrap(); let mut ctx = SslContext::new(Sslv23).unwrap();
ctx.set_verify(SslVerifyPeer, Some(callback)); ctx.set_verify(SslVerifyPeer, Some(callback as VerifyCallback));
assert!(SslStream::new(&ctx, stream).is_ok()); assert!(SslStream::new(&ctx, stream).is_ok());
} }
@ -123,7 +124,7 @@ fn test_verify_trusted_get_error_ok() {
} }
let stream = TcpStream::connect("127.0.0.1:15418").unwrap(); let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
let mut ctx = SslContext::new(Sslv23).unwrap(); let mut ctx = SslContext::new(Sslv23).unwrap();
ctx.set_verify(SslVerifyPeer, Some(callback)); ctx.set_verify(SslVerifyPeer, Some(callback as VerifyCallback));
match ctx.set_CA_file(&Path::new("test/cert.pem")) { match ctx.set_CA_file(&Path::new("test/cert.pem")) {
None => {} None => {}
Some(err) => panic!("Unexpected error {}", err) Some(err) => panic!("Unexpected error {}", err)
@ -139,7 +140,7 @@ fn test_verify_trusted_get_error_err() {
} }
let stream = TcpStream::connect("127.0.0.1:15418").unwrap(); let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
let mut ctx = SslContext::new(Sslv23).unwrap(); let mut ctx = SslContext::new(Sslv23).unwrap();
ctx.set_verify(SslVerifyPeer, Some(callback)); ctx.set_verify(SslVerifyPeer, Some(callback as VerifyCallback));
assert!(SslStream::new(&ctx, stream).is_err()); assert!(SslStream::new(&ctx, stream).is_err());
} }
@ -198,7 +199,7 @@ fn test_clone() {
let stream = TcpStream::connect("127.0.0.1:15418").unwrap(); let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
let mut stream = SslStream::new(&SslContext::new(Sslv23).unwrap(), stream).unwrap(); let mut stream = SslStream::new(&SslContext::new(Sslv23).unwrap(), stream).unwrap();
let mut stream2 = stream.clone(); let mut stream2 = stream.clone();
spawn(proc() { let _t = Thread::spawn(move || {
stream2.write("GET /\r\n\r\n".as_bytes()).unwrap(); stream2.write("GET /\r\n\r\n".as_bytes()).unwrap();
stream2.flush().unwrap(); stream2.flush().unwrap();
}); });

View File

@ -15,6 +15,7 @@ use ssl::error::{SslError, StreamError};
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
#[deriving(Copy)]
#[repr(i32)] #[repr(i32)]
pub enum X509FileType { pub enum X509FileType {
PEM = ffi::X509_FILETYPE_PEM, PEM = ffi::X509_FILETYPE_PEM,
@ -22,6 +23,7 @@ pub enum X509FileType {
Default = ffi::X509_FILETYPE_DEFAULT Default = ffi::X509_FILETYPE_DEFAULT
} }
#[allow(missing_copy_implementations)]
pub struct X509StoreContext { pub struct X509StoreContext {
ctx: *mut ffi::X509_STORE_CTX ctx: *mut ffi::X509_STORE_CTX
} }
@ -54,7 +56,7 @@ trait AsStr<'a> {
fn as_str(&self) -> &'a str; fn as_str(&self) -> &'a str;
} }
#[deriving(Clone)] #[deriving(Clone, Copy)]
pub enum KeyUsage { pub enum KeyUsage {
DigitalSignature, DigitalSignature,
NonRepudiation, NonRepudiation,
@ -84,7 +86,7 @@ impl AsStr<'static> for KeyUsage {
} }
#[deriving(Clone)] #[deriving(Clone, Copy)]
pub enum ExtKeyUsage { pub enum ExtKeyUsage {
ServerAuth, ServerAuth,
ClientAuth, ClientAuth,
@ -360,7 +362,7 @@ impl<'ctx> X509<'ctx> {
} }
/// Reads certificate from PEM, takes ownership of handle /// Reads certificate from PEM, takes ownership of handle
pub fn from_pem(reader: &mut Reader) -> Result<X509<'ctx>, SslError> { pub fn from_pem<R>(reader: &mut R) -> Result<X509<'ctx>, SslError> where R: Reader {
let mut mem_bio = try!(MemBio::new()); let mut mem_bio = try!(MemBio::new());
let buf = try!(reader.read_to_end().map_err(StreamError)); let buf = try!(reader.read_to_end().map_err(StreamError));
try!(mem_bio.write(buf.as_slice()).map_err(StreamError)); try!(mem_bio.write(buf.as_slice()).map_err(StreamError));
@ -402,7 +404,7 @@ impl<'ctx> X509<'ctx> {
} }
/// Writes certificate as PEM /// Writes certificate as PEM
pub fn write_pem(&self, writer: &mut Writer) -> Result<(), SslError> { pub fn write_pem<W>(&self, writer: &mut W) -> Result<(), SslError> where W: Writer{
let mut mem_bio = try!(MemBio::new()); let mut mem_bio = try!(MemBio::new());
unsafe { unsafe {
try_ssl!(ffi::PEM_write_bio_X509(mem_bio.get_handle(), try_ssl!(ffi::PEM_write_bio_X509(mem_bio.get_handle(),
@ -430,6 +432,7 @@ pub struct X509Name<'x> {
macro_rules! make_validation_error( macro_rules! make_validation_error(
($ok_val:ident, $($name:ident = $val:ident,)+) => ( ($ok_val:ident, $($name:ident = $val:ident,)+) => (
#[deriving(Copy)]
pub enum X509ValidationError { pub enum X509ValidationError {
$($name,)+ $($name,)+
X509UnknownError(c_int) X509UnknownError(c_int)
@ -446,7 +449,7 @@ macro_rules! make_validation_error(
} }
} }
) )
) );
make_validation_error!(X509_V_OK, make_validation_error!(X509_V_OK,
X509UnableToGetIssuerCert = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT, X509UnableToGetIssuerCert = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT,
@ -502,7 +505,7 @@ make_validation_error!(X509_V_OK,
X509UnsupportedNameSyntax = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX, X509UnsupportedNameSyntax = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX,
X509CrlPathValidationError= X509_V_ERR_CRL_PATH_VALIDATION_ERROR, X509CrlPathValidationError= X509_V_ERR_CRL_PATH_VALIDATION_ERROR,
X509ApplicationVerification = X509_V_ERR_APPLICATION_VERIFICATION, X509ApplicationVerification = X509_V_ERR_APPLICATION_VERIFICATION,
) );
#[test] #[test]