Fixed incorrect EOF handling in MemBio, added error description
Actually, EOF wasn't handled at all and it caused `mem_bio.read_to_end()` to fail. Which in turn failed all `write_pem` implementations.
This commit is contained in:
parent
e4b8b5e697
commit
3ba768bc28
|
|
@ -1,5 +1,5 @@
|
||||||
use libc::{c_void, c_int};
|
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::io::{Reader, Writer};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
|
|
@ -62,9 +62,22 @@ impl Reader for MemBio {
|
||||||
buf.len() as c_int)
|
buf.len() as c_int)
|
||||||
};
|
};
|
||||||
|
|
||||||
if ret < 0 {
|
if ret <= 0 {
|
||||||
// FIXME: provide details from OpenSSL
|
let is_eof = unsafe { ffi::BIO_eof(self.bio) };
|
||||||
Err(IoError{kind: OtherIoError, desc: "mem bio read error", detail: None})
|
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 {
|
} else {
|
||||||
Ok(ret as uint)
|
Ok(ret as uint)
|
||||||
}
|
}
|
||||||
|
|
@ -78,8 +91,11 @@ impl Writer for MemBio {
|
||||||
buf.len() as c_int)
|
buf.len() as c_int)
|
||||||
};
|
};
|
||||||
if buf.len() != ret as uint {
|
if buf.len() != ret as uint {
|
||||||
// FIXME: provide details from OpenSSL
|
Err(IoError {
|
||||||
Err(IoError{kind: OtherIoError, desc: "mem bio write error", detail: None})
|
kind: OtherIoError,
|
||||||
|
desc: "MemBio write error",
|
||||||
|
detail: Some(format!("{}", SslError::get()))
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#![allow(non_camel_case_types, non_uppercase_statics, non_snake_case)]
|
#![allow(non_camel_case_types, non_uppercase_statics, non_snake_case)]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
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::ptr;
|
||||||
|
|
||||||
pub type ASN1_INTEGER = c_void;
|
pub type ASN1_INTEGER = c_void;
|
||||||
pub type ASN1_STRING = 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)
|
rwflag: c_int, user_data: *mut c_void)
|
||||||
-> c_int;
|
-> c_int;
|
||||||
|
|
||||||
|
pub static BIO_CTRL_EOF: c_int = 2;
|
||||||
|
|
||||||
pub static CRYPTO_LOCK: c_int = 1;
|
pub static CRYPTO_LOCK: c_int = 1;
|
||||||
|
|
||||||
pub static MBSTRING_ASC: c_int = MBSTRING_FLAG | 1;
|
pub static MBSTRING_ASC: c_int = MBSTRING_FLAG | 1;
|
||||||
|
|
@ -195,12 +198,19 @@ extern "C" {
|
||||||
pub fn bn_is_zero(a: *mut BIGNUM) -> c_int;
|
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" {
|
extern "C" {
|
||||||
pub fn ASN1_INTEGER_set(dest: *mut ASN1_INTEGER, value: c_long) -> c_int;
|
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_STRING_type_new(ty: c_int) -> *mut ASN1_STRING;
|
||||||
pub fn ASN1_TIME_free(tm: *mut ASN1_TIME);
|
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_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_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;
|
pub fn BIO_write(b: *mut BIO, buf: *const c_void, len: c_int) -> c_int;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::io::Writer;
|
use std::io::{File, Open, Write, Writer};
|
||||||
use std::io::net::tcp::TcpStream;
|
use std::io::net::tcp::TcpStream;
|
||||||
use std::num::FromStrRadix;
|
use std::num::FromStrRadix;
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
@ -218,6 +218,22 @@ fn test_cert_gen() {
|
||||||
|
|
||||||
let res = gen.generate();
|
let res = gen.generate();
|
||||||
assert!(res.is_ok());
|
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
|
// FIXME: check data in result to be correct, needs implementation
|
||||||
// of X509 getters
|
// of X509 getters
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue