diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/bio/mod.rs | 28 | ||||
| -rwxr-xr-x[-rw-r--r--] | src/ffi.rs | 21 | ||||
| -rw-r--r-- | src/ssl/mod.rs | 6 | ||||
| -rw-r--r-- | src/ssl/tests.rs | 39 |
4 files changed, 76 insertions, 18 deletions
diff --git a/src/bio/mod.rs b/src/bio/mod.rs index 5c5e8df0..a6dc9dc2 100644 --- a/src/bio/mod.rs +++ b/src/bio/mod.rs @@ -1,5 +1,5 @@ use libc::{c_void, c_int}; -use std::io::{IoResult, IoError, OtherIoError}; +use std::io::{EndOfFile, IoResult, IoError, OtherIoError}; use std::io::{Reader, Writer}; use std::ptr; @@ -62,9 +62,22 @@ impl Reader for MemBio { buf.len() as c_int) }; - if ret < 0 { - // FIXME: provide details from OpenSSL - Err(IoError{kind: OtherIoError, desc: "mem bio read error", detail: None}) + if ret <= 0 { + let is_eof = unsafe { ffi::BIO_eof(self.bio) }; + let err = if is_eof { + IoError { + kind: EndOfFile, + desc: "MemBio EOF", + detail: None + } + } else { + IoError { + kind: OtherIoError, + desc: "MemBio read error", + detail: Some(format!("{}", SslError::get())) + } + }; + Err(err) } else { Ok(ret as uint) } @@ -78,8 +91,11 @@ impl Writer for MemBio { buf.len() as c_int) }; if buf.len() != ret as uint { - // FIXME: provide details from OpenSSL - Err(IoError{kind: OtherIoError, desc: "mem bio write error", detail: None}) + Err(IoError { + kind: OtherIoError, + desc: "MemBio write error", + detail: Some(format!("{}", SslError::get())) + }) } else { Ok(()) } diff --git a/src/ffi.rs b/src/ffi.rs index ec53df4b..40291869 100644..100755 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -1,6 +1,7 @@ #![allow(non_camel_case_types, non_uppercase_statics, non_snake_case)] #![allow(dead_code)] use libc::{c_void, c_int, c_char, c_ulong, c_long, c_uint, c_uchar, size_t}; +use std::ptr; pub type ASN1_INTEGER = c_void; pub type ASN1_STRING = c_void; @@ -84,6 +85,8 @@ pub type PrivateKeyWriteCallback = extern "C" fn(buf: *mut c_char, size: c_int, rwflag: c_int, user_data: *mut c_void) -> c_int; +pub static BIO_CTRL_EOF: c_int = 2; + pub static CRYPTO_LOCK: c_int = 1; pub static MBSTRING_ASC: c_int = MBSTRING_FLAG | 1; @@ -189,12 +192,25 @@ extern { } /* Since the openssl BN_is_zero is sometimes a macro, this wrapper is necessary. */ pub unsafe fn BN_is_zero(a: *mut BIGNUM) -> c_int { bn_is_zero(a) } +/* Special import from native/bn_is_zero.c */ +#[link(name="wrapped")] +extern "C" { + pub fn bn_is_zero(a: *mut BIGNUM) -> c_int; +} + +// Functions converted from macros +pub unsafe fn BIO_eof(b: *mut BIO) -> bool { + BIO_ctrl(b, BIO_CTRL_EOF, 0, ptr::null_mut()) == 1 +} + +// True functions extern "C" { pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int; pub fn ASN1_STRING_type_new(ty: c_int) -> *mut ASN1_STRING; pub fn ASN1_TIME_free(tm: *mut ASN1_TIME); - pub fn BIO_free_all(a: *mut BIO); + pub fn BIO_ctrl(b: *mut BIO, cmd: c_int, larg: c_long, parg: *mut c_void) -> c_long; + pub fn BIO_free_all(b: *mut BIO); pub fn BIO_new(type_: *const BIO_METHOD) -> *mut BIO; pub fn BIO_read(b: *mut BIO, buf: *mut c_void, len: c_int) -> c_int; pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int; @@ -241,9 +257,6 @@ extern "C" { pub fn BN_cmp(a: *mut BIGNUM, b: *mut BIGNUM) -> c_int; pub fn BN_ucmp(a: *mut BIGNUM, b: *mut BIGNUM) -> c_int; - /* Special import from native/bn_is_zero.c */ - pub fn bn_is_zero(a: *mut BIGNUM) -> c_int; - /* Prime handling */ pub fn BN_generate_prime_ex(r: *mut BIGNUM, bits: c_int, safe: c_int, add: *mut BIGNUM, rem: *mut BIGNUM, cb: *const c_void) -> c_int; pub fn BN_is_prime_ex(p: *mut BIGNUM, checks: c_int, ctx: *mut BN_CTX, cb: *const c_void) -> c_int; diff --git a/src/ssl/mod.rs b/src/ssl/mod.rs index 9dd22766..67437b52 100644 --- a/src/ssl/mod.rs +++ b/src/ssl/mod.rs @@ -248,7 +248,7 @@ impl SslContext { #[allow(non_snake_case)] /// Specifies the file that contains trusted CA certificates. - pub fn set_CA_file(&mut self, file: &str) -> Option<SslError> { + pub fn set_CA_file(&mut self, file: &Path) -> Option<SslError> { wrap_ssl_result(file.with_c_str(|file| { unsafe { ffi::SSL_CTX_load_verify_locations(self.ctx, file, ptr::null()) @@ -257,7 +257,7 @@ impl SslContext { } /// Specifies the file that is client certificate - pub fn set_certificate_file(&mut self, file: &str, + pub fn set_certificate_file(&mut self, file: &Path, file_type: X509FileType) -> Option<SslError> { wrap_ssl_result(file.with_c_str(|file| { unsafe { @@ -267,7 +267,7 @@ impl SslContext { } /// Specifies the file that is client private key - pub fn set_private_key_file(&mut self, file: &str, + pub fn set_private_key_file(&mut self, file: &Path, file_type: X509FileType) -> Option<SslError> { wrap_ssl_result(file.with_c_str(|file| { unsafe { diff --git a/src/ssl/tests.rs b/src/ssl/tests.rs index 0e6edbf7..f98352be 100644 --- a/src/ssl/tests.rs +++ b/src/ssl/tests.rs @@ -1,4 +1,4 @@ -use std::io::Writer; +use std::io::{File, Open, Write, Writer}; use std::io::net::tcp::TcpStream; use std::num::FromStrRadix; use std::str; @@ -34,7 +34,7 @@ fn test_verify_trusted() { let stream = TcpStream::connect("127.0.0.1", 15418).unwrap(); let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SslVerifyPeer, None); - match ctx.set_CA_file("test/cert.pem") { + match ctx.set_CA_file(&Path::new("test/cert.pem")) { None => {} Some(err) => fail!("Unexpected error {}", err) } @@ -77,7 +77,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)); - match ctx.set_CA_file("test/cert.pem") { + match ctx.set_CA_file(&Path::new("test/cert.pem")) { None => {} Some(err) => fail!("Unexpected error {}", err) } @@ -95,7 +95,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)); - match ctx.set_CA_file("test/cert.pem") { + match ctx.set_CA_file(&Path::new("test/cert.pem")) { None => {} Some(err) => fail!("Unexpected error {}", err) } @@ -123,7 +123,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)); - match ctx.set_CA_file("test/cert.pem") { + match ctx.set_CA_file(&Path::new("test/cert.pem")) { None => {} Some(err) => fail!("Unexpected error {}", err) } @@ -218,6 +218,35 @@ fn test_cert_gen() { let res = gen.generate(); assert!(res.is_ok()); + + let (cert, pkey) = res.unwrap(); + + #[cfg(unix)] + static NULL_PATH: &'static str = "/dev/null"; + #[cfg(windows)] + static NULL_PATH: &'static str = "nul"; + + let cert_path = Path::new(NULL_PATH); + let mut file = File::open_mode(&cert_path, Open, Write).unwrap(); + assert!(cert.write_pem(&mut file).is_ok()); + + let key_path = Path::new(NULL_PATH); + let mut file = File::open_mode(&key_path, Open, Write).unwrap(); + assert!(pkey.write_pem(&mut file).is_ok()); + // FIXME: check data in result to be correct, needs implementation // of X509 getters } + +#[test] +fn test_bn_is_zero() { + use ffi; + use std::ptr; + + unsafe { + let bn = ffi::BN_new(); + assert!(bn != ptr::null_mut()); + // Just make sure it is linked and resolved correctly + ffi::BN_is_zero(bn); + } +} |