aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bio/mod.rs28
-rwxr-xr-x[-rw-r--r--]src/ffi.rs21
-rw-r--r--src/ssl/mod.rs6
-rw-r--r--src/ssl/tests.rs39
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);
+ }
+}