Merge pull request #139 from vhbit/up-master

Handle recent breaking changes
This commit is contained in:
Steven Fackler 2015-01-07 08:13:19 -08:00
commit 8b67adfc90
8 changed files with 70 additions and 62 deletions

View File

@ -76,7 +76,7 @@ impl Reader for MemBio {
IoError { IoError {
kind: OtherIoError, kind: OtherIoError,
desc: "MemBio read error", desc: "MemBio read error",
detail: Some(format!("{}", SslError::get())) detail: Some(format!("{:?}", SslError::get()))
} }
}; };
Err(err) Err(err)
@ -96,7 +96,7 @@ impl Writer for MemBio {
Err(IoError { Err(IoError {
kind: OtherIoError, kind: OtherIoError,
desc: "MemBio write error", desc: "MemBio write error",
detail: Some(format!("{}", SslError::get())) detail: Some(format!("{:?}", SslError::get()))
}) })
} else { } else {
Ok(()) Ok(())

View File

@ -1,5 +1,5 @@
use libc::{c_int, c_ulong, c_void}; use libc::{c_int, c_ulong, c_void};
use std::c_str::{CString, ToCStr}; use std::ffi::{CString, c_str_to_bytes};
use std::cmp::Ordering; use std::cmp::Ordering;
use std::{fmt, ptr}; use std::{fmt, ptr};
@ -88,7 +88,7 @@ impl BigNum {
pub fn from_dec_str(s: &str) -> Result<BigNum, SslError> { pub fn from_dec_str(s: &str) -> Result<BigNum, SslError> {
BigNum::new().and_then(|v| unsafe { BigNum::new().and_then(|v| unsafe {
let c_str = s.to_c_str(); let c_str = CString::from_slice(s.as_bytes());
try_ssl!(ffi::BN_dec2bn(v.raw_ptr(), c_str.as_ptr())); try_ssl!(ffi::BN_dec2bn(v.raw_ptr(), c_str.as_ptr()));
Ok(v) Ok(v)
}) })
@ -96,7 +96,7 @@ impl BigNum {
pub fn from_hex_str(s: &str) -> Result<BigNum, SslError> { pub fn from_hex_str(s: &str) -> Result<BigNum, SslError> {
BigNum::new().and_then(|v| unsafe { BigNum::new().and_then(|v| unsafe {
let c_str = s.to_c_str(); let c_str = CString::from_slice(s.as_bytes());
try_ssl!(ffi::BN_hex2bn(v.raw_ptr(), c_str.as_ptr())); try_ssl!(ffi::BN_hex2bn(v.raw_ptr(), c_str.as_ptr()));
Ok(v) Ok(v)
}) })
@ -421,8 +421,7 @@ impl BigNum {
unsafe { unsafe {
let buf = ffi::BN_bn2dec(self.raw()); let buf = ffi::BN_bn2dec(self.raw());
assert!(!buf.is_null()); assert!(!buf.is_null());
let c_str = CString::new(buf, false); let str = String::from_utf8(c_str_to_bytes(&buf).to_vec()).unwrap();
let str = c_str.as_str().unwrap().to_string();
ffi::CRYPTO_free(buf as *mut c_void); ffi::CRYPTO_free(buf as *mut c_void);
str str
} }
@ -432,8 +431,7 @@ impl BigNum {
unsafe { unsafe {
let buf = ffi::BN_bn2hex(self.raw()); let buf = ffi::BN_bn2hex(self.raw());
assert!(!buf.is_null()); assert!(!buf.is_null());
let c_str = CString::new(buf, false); let str = String::from_utf8(c_str_to_bytes(&buf).to_vec()).unwrap();
let str = c_str.as_str().unwrap().to_string();
ffi::CRYPTO_free(buf as *mut c_void); ffi::CRYPTO_free(buf as *mut c_void);
str str
} }

2
src/lib.rs Normal file → Executable file
View File

@ -1,4 +1,4 @@
#![feature(macro_rules, unsafe_destructor, globs, associated_types, default_type_params, old_orphan_check)] #![feature(unsafe_destructor, old_orphan_check)]
#![crate_name="openssl"] #![crate_name="openssl"]
#![crate_type="rlib"] #![crate_type="rlib"]
#![crate_type="dylib"] #![crate_type="dylib"]

2
src/macros.rs Normal file → Executable file
View File

@ -1,4 +1,4 @@
#![macro_escape] #![macro_use]
macro_rules! try_ssl_stream { macro_rules! try_ssl_stream {
($e:expr) => ( ($e:expr) => (

View File

@ -3,8 +3,8 @@ pub use self::OpensslError::*;
use libc::c_ulong; use libc::c_ulong;
use std::error; use std::error;
use std::ffi::c_str_to_bytes;
use std::io::IoError; use std::io::IoError;
use std::c_str::CString;
use ffi; use ffi;
@ -51,15 +51,24 @@ pub enum OpensslError {
} }
fn get_lib(err: c_ulong) -> String { fn get_lib(err: c_ulong) -> String {
unsafe { CString::new(ffi::ERR_lib_error_string(err), false) }.to_string() unsafe {
let bytes = c_str_to_bytes(&ffi::ERR_lib_error_string(err)).to_vec();
String::from_utf8(bytes).unwrap()
}
} }
fn get_func(err: c_ulong) -> String { fn get_func(err: c_ulong) -> String {
unsafe { CString::new(ffi::ERR_func_error_string(err), false).to_string() } unsafe {
let bytes = c_str_to_bytes(&ffi::ERR_func_error_string(err)).to_vec();
String::from_utf8(bytes).unwrap()
}
} }
fn get_reason(err: c_ulong) -> String { fn get_reason(err: c_ulong) -> String {
unsafe { CString::new(ffi::ERR_reason_error_string(err), false).to_string() } unsafe {
let bytes = c_str_to_bytes(&ffi::ERR_reason_error_string(err)).to_vec();
String::from_utf8(bytes).unwrap()
}
} }
impl SslError { impl SslError {
@ -100,7 +109,7 @@ fn test_uknown_error_should_have_correct_messages() {
let UnknownError { ref library, ref function, ref reason } = errs[0]; let UnknownError { ref library, ref function, ref reason } = errs[0];
assert_eq!(library.as_slice(),"SSL routines"); assert_eq!(library.as_slice(), "SSL routines");
assert_eq!(function.as_slice(), "SSL23_GET_SERVER_HELLO"); assert_eq!(function.as_slice(), "SSL23_GET_SERVER_HELLO");
assert_eq!(reason.as_slice(), "sslv3 alert handshake failure"); assert_eq!(reason.as_slice(), "sslv3 alert handshake failure");
} }

View File

@ -1,5 +1,5 @@
use libc::{c_int, c_void, c_long}; use libc::{c_int, c_void, c_long};
use std::c_str::ToCStr; use std::ffi::{CString, c_str_to_bytes};
use std::io::{IoResult, IoError, EndOfFile, Stream, Reader, Writer}; use std::io::{IoResult, IoError, EndOfFile, Stream, Reader, Writer};
use std::mem; use std::mem;
use std::num::FromPrimitive; use std::num::FromPrimitive;
@ -237,39 +237,39 @@ impl SslContext {
#[allow(non_snake_case)] #[allow(non_snake_case)]
/// Specifies the file that contains trusted CA certificates. /// Specifies the file that contains trusted CA certificates.
pub fn set_CA_file(&mut self, file: &Path) -> Option<SslError> { pub fn set_CA_file(&mut self, file: &Path) -> Option<SslError> {
wrap_ssl_result(file.with_c_str(|file| { wrap_ssl_result(
unsafe { unsafe {
ffi::SSL_CTX_load_verify_locations(self.ctx.0, file, ptr::null()) let file = CString::from_slice(file.as_vec());
} ffi::SSL_CTX_load_verify_locations(self.ctx.0, file.as_ptr(), ptr::null())
})) })
} }
/// Specifies the file that contains certificate /// Specifies the file that contains certificate
pub fn set_certificate_file(&mut self, file: &Path, pub fn set_certificate_file(&mut self, file: &Path,
file_type: X509FileType) -> Option<SslError> { file_type: X509FileType) -> Option<SslError> {
wrap_ssl_result(file.with_c_str(|file| { wrap_ssl_result(
unsafe { unsafe {
ffi::SSL_CTX_use_certificate_file(self.ctx.0, file, file_type as c_int) let file = CString::from_slice(file.as_vec());
} ffi::SSL_CTX_use_certificate_file(self.ctx.0, file.as_ptr(), file_type as c_int)
})) })
} }
/// Specifies the file that contains private key /// Specifies the file that contains private key
pub fn set_private_key_file(&mut self, file: &Path, pub fn set_private_key_file(&mut self, file: &Path,
file_type: X509FileType) -> Option<SslError> { file_type: X509FileType) -> Option<SslError> {
wrap_ssl_result(file.with_c_str(|file| { wrap_ssl_result(
unsafe { unsafe {
ffi::SSL_CTX_use_PrivateKey_file(self.ctx.0, file, file_type as c_int) let file = CString::from_slice(file.as_vec());
} ffi::SSL_CTX_use_PrivateKey_file(self.ctx.0, file.as_ptr(), file_type as c_int)
})) })
} }
pub fn set_cipher_list(&mut self, cipher_list: &str) -> Option<SslError> { pub fn set_cipher_list(&mut self, cipher_list: &str) -> Option<SslError> {
wrap_ssl_result(cipher_list.with_c_str(|cipher_list| { wrap_ssl_result(
unsafe { unsafe {
ffi::SSL_CTX_set_cipher_list(self.ctx.0, cipher_list) let cipher_list = CString::from_slice(cipher_list.as_bytes());
} ffi::SSL_CTX_set_cipher_list(self.ctx.0, cipher_list.as_ptr())
})) })
} }
} }
@ -358,17 +358,16 @@ impl Ssl {
/// Set the host name to be used with SNI (Server Name Indication). /// Set the host name to be used with SNI (Server Name Indication).
pub fn set_hostname(&self, hostname: &str) -> Result<(), SslError> { pub fn set_hostname(&self, hostname: &str) -> Result<(), SslError> {
let ret = hostname.with_c_str(|hostname| { let ret = unsafe {
unsafe {
// This is defined as a macro: // This is defined as a macro:
// #define SSL_set_tlsext_host_name(s,name) \ // #define SSL_set_tlsext_host_name(s,name) \
// SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name) // SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name)
let hostname = CString::from_slice(hostname.as_bytes());
ffi::SSL_ctrl(self.ssl.0, ffi::SSL_CTRL_SET_TLSEXT_HOSTNAME, ffi::SSL_ctrl(self.ssl.0, ffi::SSL_CTRL_SET_TLSEXT_HOSTNAME,
ffi::TLSEXT_NAMETYPE_host_name, ffi::TLSEXT_NAMETYPE_host_name,
hostname as *const c_void as *mut c_void) hostname.as_ptr() as *mut c_void)
} };
});
// For this case, 0 indicates failure. // For this case, 0 indicates failure.
if ret == 0 { if ret == 0 {
@ -496,7 +495,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()),
err => panic!("unexpected error {}", err), err => panic!("unexpected error {:?}", err),
} }
} }
} }
@ -521,7 +520,9 @@ impl<S: Stream> SslStream<S> {
} }
let meth = unsafe { ffi::SSL_COMP_get_name(ptr) }; let meth = unsafe { ffi::SSL_COMP_get_name(ptr) };
let s = unsafe { String::from_raw_buf(meth as *const u8) }; let s = unsafe {
String::from_utf8(c_str_to_bytes(&meth).to_vec()).unwrap()
};
Some(s) Some(s)
} }

View File

@ -27,7 +27,7 @@ fn test_verify_untrusted() {
ctx.set_verify(SslVerifyPeer, None); ctx.set_verify(SslVerifyPeer, None);
match SslStream::new(&ctx, stream) { match SslStream::new(&ctx, stream) {
Ok(_) => panic!("expected failure"), Ok(_) => panic!("expected failure"),
Err(err) => println!("error {}", err) Err(err) => println!("error {:?}", err)
} }
} }
@ -38,11 +38,11 @@ fn test_verify_trusted() {
ctx.set_verify(SslVerifyPeer, None); ctx.set_verify(SslVerifyPeer, None);
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)
} }
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)
} }
} }
@ -56,7 +56,7 @@ fn test_verify_untrusted_callback_override_ok() {
ctx.set_verify(SslVerifyPeer, Some(callback as VerifyCallback)); 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)
} }
} }
@ -81,11 +81,11 @@ fn test_verify_trusted_callback_override_ok() {
ctx.set_verify(SslVerifyPeer, Some(callback as VerifyCallback)); 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)
} }
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)
} }
} }
@ -99,7 +99,7 @@ fn test_verify_trusted_callback_override_bad() {
ctx.set_verify(SslVerifyPeer, Some(callback as VerifyCallback)); 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)
} }
assert!(SslStream::new(&ctx, stream).is_err()); assert!(SslStream::new(&ctx, stream).is_err());
} }
@ -127,7 +127,7 @@ fn test_verify_trusted_get_error_ok() {
ctx.set_verify(SslVerifyPeer, Some(callback as VerifyCallback)); 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)
} }
assert!(SslStream::new(&ctx, stream).is_ok()); assert!(SslStream::new(&ctx, stream).is_ok());
} }
@ -170,7 +170,7 @@ fn test_verify_callback_data() {
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)
} }
} }

View File

@ -1,6 +1,6 @@
use libc::{c_int, c_long, c_uint}; use libc::{c_char, c_int, c_long, c_uint};
use std::c_str::ToCStr;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::ffi::CString;
use std::iter::repeat; use std::iter::repeat;
use std::mem; use std::mem;
use std::num::SignedInt; use std::num::SignedInt;
@ -243,11 +243,11 @@ impl X509Generator {
let mut ctx: ffi::X509V3_CTX = mem::zeroed(); let mut ctx: ffi::X509V3_CTX = mem::zeroed();
ffi::X509V3_set_ctx(&mut ctx, x509, x509, ffi::X509V3_set_ctx(&mut ctx, x509, x509,
ptr::null_mut(), ptr::null_mut(), 0); ptr::null_mut(), ptr::null_mut(), 0);
let ext = value.with_c_str(|value| let value = CString::from_slice(value.as_bytes());
ffi::X509V3_EXT_conf_nid(ptr::null_mut(), let ext = ffi::X509V3_EXT_conf_nid(ptr::null_mut(),
mem::transmute(&ctx), mem::transmute(&ctx),
extension, extension,
mem::transmute(value))); value.as_ptr() as *mut c_char);
let mut success = false; let mut success = false;
if ext != ptr::null_mut() { if ext != ptr::null_mut() {
@ -260,12 +260,12 @@ impl X509Generator {
fn add_name(name: *mut ffi::X509_NAME, key: &str, value: &str) -> Result<(), SslError> { fn add_name(name: *mut ffi::X509_NAME, key: &str, value: &str) -> Result<(), SslError> {
let value_len = value.len() as c_int; let value_len = value.len() as c_int;
lift_ssl!(key.with_c_str(|key| { lift_ssl!(unsafe {
value.with_c_str(|value| unsafe { let key = CString::from_slice(key.as_bytes());
ffi::X509_NAME_add_entry_by_txt(name, key, ffi::MBSTRING_UTF8, let value = CString::from_slice(value.as_bytes());
value, value_len, -1, 0) ffi::X509_NAME_add_entry_by_txt(name, key.as_ptr(), ffi::MBSTRING_UTF8,
value.as_ptr(), value_len, -1, 0)
}) })
}))
} }
fn random_serial() -> c_long { fn random_serial() -> c_long {