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]
name = "openssl"
version = "0.2.3"
version = "0.2.8"
authors = ["Steven Fackler <sfackler@gmail.com>"]
license = "Apache-2.0"
description = "OpenSSL bindings"
@ -17,4 +17,4 @@ aes_xts = ["openssl-sys/aes_xts"]
[dependencies.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.
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`
* 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.
5. Run `cargo build`.

View File

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

View File

@ -9,9 +9,14 @@ fn main() {
if pkg_config::find_library("openssl").is_err() {
let mut flags = " -l crypto -l ssl".to_string();
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")
.or(target.find_str("win32"))
@ -23,7 +28,7 @@ fn main() {
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 \
build them yourselves (instructions in the README) \
and provide their location through $OPENSSL_PATH.");

View File

@ -2,7 +2,6 @@
#![allow(dead_code)]
extern crate libc;
extern crate rustrt;
#[cfg(feature = "libressl-pnacl-sys")]
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 std::mem;
use std::ptr;
use rustrt::mutex::NativeMutex;
use std::sync::{StaticMutex, StaticMutexGuard, MUTEX_INIT};
use std::sync::{Once, ONCE_INIT};
pub type ASN1_INTEGER = c_void;
@ -49,6 +48,8 @@ pub struct EVP_MD_CTX {
update: *mut c_void
}
impl Copy for EVP_MD_CTX {}
#[repr(C)]
pub struct HMAC_CTX {
md: *mut EVP_MD,
@ -59,6 +60,8 @@ pub struct HMAC_CTX {
key: [c_uchar, ..128]
}
impl Copy for HMAC_CTX {}
#[repr(C)]
pub struct X509V3_CTX {
flags: c_int,
@ -72,6 +75,8 @@ pub struct X509V3_CTX {
// Maybe more here
}
impl Copy for X509V3_CTX {}
#[repr(C)]
pub struct BIGNUM {
pub d: *mut c_void,
@ -81,6 +86,8 @@ pub struct BIGNUM {
pub flags: c_int,
}
impl Copy for BIGNUM {}
#[repr(C)]
pub struct BIGNUM_PTR {
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_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,
_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];
if mode & CRYPTO_LOCK != 0 {
mutex.lock_noguard();
(*GUARDS)[n as uint] = Some(mutex.lock());
} else {
mutex.unlock_noguard();
&(*GUARDS)[n as uint].take();
}
}
}
@ -213,8 +221,10 @@ pub fn init() {
SSL_load_error_strings();
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);
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);
})

View File

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

View File

@ -4,6 +4,7 @@ use std::io;
use ffi;
#[deriving(Copy)]
pub enum HashType {
MD5,
SHA1,
@ -134,7 +135,7 @@ mod tests {
}
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 {
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 outlen = 0;
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
}
}

View File

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

View File

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

View File

@ -33,6 +33,7 @@ fn init() {
/// Determines the SSL method supported
#[deriving(Show, Hash, PartialEq, Eq)]
#[allow(non_camel_case_types)]
#[deriving(Copy)]
pub enum SslMethod {
#[cfg(feature = "sslv2")]
/// Only support the SSLv2 protocol, requires `feature="sslv2"`
@ -68,6 +69,7 @@ impl SslMethod {
}
/// Determines the type of certificate verification used
#[deriving(Copy)]
#[repr(i32)]
pub enum SslVerifyMode {
/// Verify that the server's certificate is trusted
@ -91,8 +93,9 @@ fn get_verify_data_idx<T>() -> c_int {
unsafe {
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,
None, Some(free_data_box::<T>));
None, Some(f));
assert!(idx >= 0);
VERIFY_DATA_IDX = idx;
});
@ -197,7 +200,9 @@ impl SslContext {
unsafe {
ffi::SSL_CTX_set_ex_data(self.ctx, VERIFY_IDX,
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)));
ffi::SSL_CTX_set_ex_data(self.ctx, get_verify_data_idx::<T>(),
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)]
enum LibSslError {
ErrorNone = ffi::SSL_ERROR_NONE,
@ -487,7 +494,7 @@ impl<S: Stream> SslStream<S> {
LibSslError::ErrorWantWrite => { try_ssl_stream!(self.flush()) }
LibSslError::ErrorZeroReturn => return Err(SslSessionClosed),
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;
while start < buf.len() {
let ret = self.in_retry_wrapper(|ssl| {
ssl.write(buf.split_at(start).val1())
ssl.write(buf.split_at(start).1)
});
match ret {
Ok(len) => start += len as uint,

View File

@ -1,10 +1,11 @@
use serialize::hex::FromHex;
use std::io::{Writer};
use std::io::net::tcp::TcpStream;
use std::io::{Writer};
use std::thread::Thread;
use crypto::hash::HashType::{SHA256};
use ssl::SslMethod::Sslv23;
use ssl::{SslContext, SslStream};
use ssl::{SslContext, SslStream, VerifyCallback};
use ssl::SslVerifyMode::SslVerifyPeer;
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 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) {
Ok(_) => (),
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 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());
}
@ -77,7 +78,7 @@ fn test_verify_trusted_callback_override_ok() {
}
let stream = TcpStream::connect("127.0.0.1:15418").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")) {
None => {}
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 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")) {
None => {}
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 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());
}
@ -123,7 +124,7 @@ fn test_verify_trusted_get_error_ok() {
}
let stream = TcpStream::connect("127.0.0.1:15418").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")) {
None => {}
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 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());
}
@ -198,7 +199,7 @@ fn test_clone() {
let stream = TcpStream::connect("127.0.0.1:15418").unwrap();
let mut stream = SslStream::new(&SslContext::new(Sslv23).unwrap(), stream).unwrap();
let mut stream2 = stream.clone();
spawn(proc() {
let _t = Thread::spawn(move || {
stream2.write("GET /\r\n\r\n".as_bytes()).unwrap();
stream2.flush().unwrap();
});

View File

@ -15,6 +15,7 @@ use ssl::error::{SslError, StreamError};
#[cfg(test)]
mod tests;
#[deriving(Copy)]
#[repr(i32)]
pub enum X509FileType {
PEM = ffi::X509_FILETYPE_PEM,
@ -22,6 +23,7 @@ pub enum X509FileType {
Default = ffi::X509_FILETYPE_DEFAULT
}
#[allow(missing_copy_implementations)]
pub struct X509StoreContext {
ctx: *mut ffi::X509_STORE_CTX
}
@ -54,7 +56,7 @@ trait AsStr<'a> {
fn as_str(&self) -> &'a str;
}
#[deriving(Clone)]
#[deriving(Clone, Copy)]
pub enum KeyUsage {
DigitalSignature,
NonRepudiation,
@ -84,7 +86,7 @@ impl AsStr<'static> for KeyUsage {
}
#[deriving(Clone)]
#[deriving(Clone, Copy)]
pub enum ExtKeyUsage {
ServerAuth,
ClientAuth,
@ -360,7 +362,7 @@ impl<'ctx> X509<'ctx> {
}
/// 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 buf = try!(reader.read_to_end().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
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());
unsafe {
try_ssl!(ffi::PEM_write_bio_X509(mem_bio.get_handle(),
@ -430,6 +432,7 @@ pub struct X509Name<'x> {
macro_rules! make_validation_error(
($ok_val:ident, $($name:ident = $val:ident,)+) => (
#[deriving(Copy)]
pub enum X509ValidationError {
$($name,)+
X509UnknownError(c_int)
@ -446,7 +449,7 @@ macro_rules! make_validation_error(
}
}
)
)
);
make_validation_error!(X509_V_OK,
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,
X509CrlPathValidationError= X509_V_ERR_CRL_PATH_VALIDATION_ERROR,
X509ApplicationVerification = X509_V_ERR_APPLICATION_VERIFICATION,
)
);
#[test]