aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2016-08-02 20:48:42 -0700
committerSteven Fackler <[email protected]>2016-08-02 20:49:28 -0700
commit08e27f31ed851873f7684ac806b837e8cff4a28f (patch)
tree821fcef610a78e42ad116035926c64337a97807e /openssl/src
parentDrop unused feature gate (diff)
downloadrust-openssl-08e27f31ed851873f7684ac806b837e8cff4a28f.tar.xz
rust-openssl-08e27f31ed851873f7684ac806b837e8cff4a28f.zip
Restructure PEM input/output methods
Dealing with byte buffers directly avoids error handling weirdness and we were loading it all into memory before anyway.
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/bio.rs67
-rw-r--r--openssl/src/bio/mod.rs107
-rw-r--r--openssl/src/crypto/dsa.rs75
-rw-r--r--openssl/src/crypto/pkey.rs114
-rw-r--r--openssl/src/crypto/rsa.rs58
-rw-r--r--openssl/src/dh/mod.rs20
-rw-r--r--openssl/src/lib.rs2
-rw-r--r--openssl/src/ssl/tests/mod.rs15
-rw-r--r--openssl/src/x509/mod.rs70
-rw-r--r--openssl/src/x509/tests.rs57
10 files changed, 194 insertions, 391 deletions
diff --git a/openssl/src/bio.rs b/openssl/src/bio.rs
new file mode 100644
index 00000000..841aca0e
--- /dev/null
+++ b/openssl/src/bio.rs
@@ -0,0 +1,67 @@
+use std::marker::PhantomData;
+use std::ptr;
+use std::slice;
+use libc::c_int;
+use ffi;
+
+use error::ErrorStack;
+
+pub struct MemBioSlice<'a>(*mut ffi::BIO, PhantomData<&'a [u8]>);
+
+impl<'a> Drop for MemBioSlice<'a> {
+ fn drop(&mut self) {
+ unsafe {
+ ffi::BIO_free_all(self.0);
+ }
+ }
+}
+
+impl<'a> MemBioSlice<'a> {
+ pub fn new(buf: &'a [u8]) -> Result<MemBioSlice<'a>, ErrorStack> {
+ ffi::init();
+
+ assert!(buf.len() <= c_int::max_value() as usize);
+ let bio = unsafe {
+ try_ssl_null!(ffi::BIO_new_mem_buf(buf.as_ptr() as *const _, buf.len() as c_int))
+ };
+
+ Ok(MemBioSlice(bio, PhantomData))
+ }
+
+ pub fn get_handle(&self) -> *mut ffi::BIO {
+ self.0
+ }
+}
+
+pub struct MemBio(*mut ffi::BIO);
+
+impl Drop for MemBio {
+ fn drop(&mut self) {
+ unsafe {
+ ffi::BIO_free_all(self.0);
+ }
+ }
+}
+
+impl MemBio {
+ pub fn new() -> Result<MemBio, ErrorStack> {
+ ffi::init();
+
+ let bio = unsafe {
+ try_ssl_null!(ffi::BIO_new(ffi::BIO_s_mem()))
+ };
+ Ok(MemBio(bio))
+ }
+
+ pub fn get_handle(&self) -> *mut ffi::BIO {
+ self.0
+ }
+
+ pub fn get_buf(&self) -> &[u8] {
+ unsafe {
+ let mut ptr = ptr::null_mut();
+ let len = ffi::BIO_get_mem_data(self.0, &mut ptr);
+ slice::from_raw_parts(ptr as *const _ as *const _, len as usize)
+ }
+ }
+}
diff --git a/openssl/src/bio/mod.rs b/openssl/src/bio/mod.rs
deleted file mode 100644
index 2e99284f..00000000
--- a/openssl/src/bio/mod.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-use libc::{c_void, c_int};
-use std::io;
-use std::io::prelude::*;
-use std::ptr;
-use std::cmp;
-
-use ffi;
-use ffi_extras;
-use error::ErrorStack;
-
-pub struct MemBio {
- bio: *mut ffi::BIO,
- owned: bool,
-}
-
-impl Drop for MemBio {
- fn drop(&mut self) {
- if self.owned {
- unsafe {
- ffi::BIO_free_all(self.bio);
- }
- }
- }
-}
-
-impl MemBio {
- /// Creates a new owned memory based BIO
- pub fn new() -> Result<MemBio, ErrorStack> {
- ffi::init();
-
- let bio = unsafe { ffi::BIO_new(ffi::BIO_s_mem()) };
- try_ssl_null!(bio);
-
- Ok(MemBio {
- bio: bio,
- owned: true,
- })
- }
-
- /// Returns a "borrow", i.e. it has no ownership
- pub fn borrowed(bio: *mut ffi::BIO) -> MemBio {
- MemBio {
- bio: bio,
- owned: false,
- }
- }
-
- /// Consumes current bio and returns wrapped value
- /// Note that data ownership is lost and
- /// should be managed manually
- pub unsafe fn unwrap(mut self) -> *mut ffi::BIO {
- self.owned = false;
- self.bio
- }
-
- /// Temporarily gets wrapped value
- pub unsafe fn get_handle(&self) -> *mut ffi::BIO {
- self.bio
- }
-
- /// Sets the BIO's EOF state.
- pub fn set_eof(&self, eof: bool) {
- let v = if eof {
- 0
- } else {
- -1
- };
- unsafe {
- ffi_extras::BIO_set_mem_eof_return(self.bio, v);
- }
- }
-}
-
-impl Read for MemBio {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- let len = cmp::min(c_int::max_value() as usize, buf.len()) as c_int;
- let ret = unsafe { ffi::BIO_read(self.bio, buf.as_ptr() as *mut c_void, len) };
-
- if ret <= 0 {
- let is_eof = unsafe { ffi_extras::BIO_eof(self.bio) };
- if is_eof != 0 {
- Ok(0)
- } else {
- Err(io::Error::new(io::ErrorKind::Other, ErrorStack::get()))
- }
- } else {
- Ok(ret as usize)
- }
- }
-}
-
-impl Write for MemBio {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- let len = cmp::min(c_int::max_value() as usize, buf.len()) as c_int;
- let ret = unsafe { ffi::BIO_write(self.bio, buf.as_ptr() as *const c_void, len) };
-
- if ret < 0 {
- Err(io::Error::new(io::ErrorKind::Other, ErrorStack::get()))
- } else {
- Ok(ret as usize)
- }
- }
-
- fn flush(&mut self) -> io::Result<()> {
- Ok(())
- }
-}
diff --git a/openssl/src/crypto/dsa.rs b/openssl/src/crypto/dsa.rs
index a1e4572a..de35893b 100644
--- a/openssl/src/crypto/dsa.rs
+++ b/openssl/src/crypto/dsa.rs
@@ -2,11 +2,10 @@ use ffi;
use std::fmt;
use error::ErrorStack;
use std::ptr;
-use std::io::{self, Read, Write};
use libc::{c_uint, c_int, c_char, c_void};
use bn::BigNum;
-use bio::MemBio;
+use bio::{MemBio, MemBioSlice};
use crypto::hash;
use crypto::HashTypeInternals;
use crypto::util::{CallbackState, invoke_passwd_cb};
@@ -69,11 +68,9 @@ impl DSA {
}
/// Reads a DSA private key from PEM formatted data.
- pub fn private_key_from_pem<R>(reader: &mut R) -> io::Result<DSA>
- where R: Read
- {
- let mut mem_bio = try!(MemBio::new());
- try!(io::copy(reader, &mut mem_bio));
+ pub fn private_key_from_pem(buf: &[u8]) -> Result<DSA, ErrorStack> {
+ ffi::init();
+ let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let dsa = try_ssl_null!(ffi::PEM_read_bio_DSAPrivateKey(mem_bio.get_handle(),
@@ -91,12 +88,12 @@ impl DSA {
///
/// The callback will be passed the password buffer and should return the number of characters
/// placed into the buffer.
- pub fn private_key_from_pem_cb<R, F>(reader: &mut R, pass_cb: F) -> io::Result<DSA>
- where R: Read, F: FnOnce(&mut [c_char]) -> usize
+ pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<DSA, ErrorStack>
+ where F: FnOnce(&mut [c_char]) -> usize
{
+ ffi::init();
let mut cb = CallbackState::new(pass_cb);
- let mut mem_bio = try!(MemBio::new());
- try!(io::copy(reader, &mut mem_bio));
+ let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let cb_ptr = &mut cb as *mut _ as *mut c_void;
@@ -111,11 +108,10 @@ impl DSA {
}
/// Writes an DSA private key as unencrypted PEM formatted data
- pub fn private_key_to_pem<W>(&self, writer: &mut W) -> io::Result<()>
- where W: Write
+ pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack>
{
assert!(self.has_private_key());
- let mut mem_bio = try!(MemBio::new());
+ let mem_bio = try!(MemBio::new());
unsafe {
try_ssl!(ffi::PEM_write_bio_DSAPrivateKey(mem_bio.get_handle(), self.0,
@@ -123,18 +119,15 @@ impl DSA {
None, ptr::null_mut()))
};
-
- try!(io::copy(&mut mem_bio, writer));
- Ok(())
+ Ok(mem_bio.get_buf().to_owned())
}
/// Reads an DSA public key from PEM formatted data.
- pub fn public_key_from_pem<R>(reader: &mut R) -> io::Result<DSA>
- where R: Read
+ pub fn public_key_from_pem(buf: &[u8]) -> Result<DSA, ErrorStack>
{
- let mut mem_bio = try!(MemBio::new());
- try!(io::copy(reader, &mut mem_bio));
+ ffi::init();
+ let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let dsa = try_ssl_null!(ffi::PEM_read_bio_DSA_PUBKEY(mem_bio.get_handle(),
ptr::null_mut(),
@@ -145,15 +138,10 @@ impl DSA {
}
/// Writes an DSA public key as PEM formatted data
- pub fn public_key_to_pem<W>(&self, writer: &mut W) -> io::Result<()>
- where W: Write
- {
- let mut mem_bio = try!(MemBio::new());
-
+ pub fn public_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
+ let mem_bio = try!(MemBio::new());
unsafe { try_ssl!(ffi::PEM_write_bio_DSA_PUBKEY(mem_bio.get_handle(), self.0)) };
-
- try!(io::copy(&mut mem_bio, writer));
- Ok(())
+ Ok(mem_bio.get_buf().to_owned())
}
pub fn size(&self) -> Option<u32> {
@@ -243,8 +231,7 @@ impl fmt::Debug for DSA {
#[cfg(test)]
mod test {
- use std::fs::File;
- use std::io::{Write, Cursor};
+ use std::io::Write;
use libc::c_char;
use super::*;
@@ -253,11 +240,9 @@ mod test {
#[test]
pub fn test_generate() {
let key = DSA::generate(1024).unwrap();
- let mut priv_buf = Cursor::new(vec![]);
- let mut pub_buf = Cursor::new(vec![]);
- key.public_key_to_pem(&mut pub_buf).unwrap();
- key.private_key_to_pem(&mut priv_buf).unwrap();
+ key.public_key_to_pem().unwrap();
+ key.private_key_to_pem().unwrap();
let input: Vec<u8> = (0..25).cycle().take(1024).collect();
@@ -277,13 +262,13 @@ mod test {
let input: Vec<u8> = (0..25).cycle().take(1024).collect();
let private_key = {
- let mut buffer = File::open("test/dsa.pem").unwrap();
- DSA::private_key_from_pem(&mut buffer).unwrap()
+ let key = include_bytes!("../../test/dsa.pem");
+ DSA::private_key_from_pem(key).unwrap()
};
let public_key = {
- let mut buffer = File::open("test/dsa.pem.pub").unwrap();
- DSA::public_key_from_pem(&mut buffer).unwrap()
+ let key = include_bytes!("../../test/dsa.pem.pub");
+ DSA::public_key_from_pem(key).unwrap()
};
let digest = {
@@ -301,13 +286,13 @@ mod test {
pub fn test_sign_verify_fail() {
let input: Vec<u8> = (0..25).cycle().take(128).collect();
let private_key = {
- let mut buffer = File::open("test/dsa.pem").unwrap();
- DSA::private_key_from_pem(&mut buffer).unwrap()
+ let key = include_bytes!("../../test/dsa.pem");
+ DSA::private_key_from_pem(key).unwrap()
};
let public_key = {
- let mut buffer = File::open("test/dsa.pem.pub").unwrap();
- DSA::public_key_from_pem(&mut buffer).unwrap()
+ let key = include_bytes!("../../test/dsa.pem.pub");
+ DSA::public_key_from_pem(key).unwrap()
};
let digest = {
@@ -329,8 +314,8 @@ mod test {
#[test]
pub fn test_password() {
let mut password_queried = false;
- let mut buffer = File::open("test/dsa-encrypted.pem").unwrap();
- DSA::private_key_from_pem_cb(&mut buffer, |password| {
+ let key = include_bytes!("../../test/dsa-encrypted.pem");
+ DSA::private_key_from_pem_cb(key, |password| {
password_queried = true;
password[0] = b'm' as c_char;
password[1] = b'y' as c_char;
diff --git a/openssl/src/crypto/pkey.rs b/openssl/src/crypto/pkey.rs
index 29feb016..ab9a4a95 100644
--- a/openssl/src/crypto/pkey.rs
+++ b/openssl/src/crypto/pkey.rs
@@ -1,10 +1,8 @@
use libc::{c_int, c_uint, c_ulong, c_void, c_char};
-use std::io;
-use std::io::prelude::*;
use std::iter::repeat;
use std::mem;
use std::ptr;
-use bio::MemBio;
+use bio::{MemBio, MemBioSlice};
use crypto::HashTypeInternals;
use crypto::hash;
@@ -76,12 +74,8 @@ impl PKey {
}
/// Reads private key from PEM, takes ownership of handle
- pub fn private_key_from_pem<R>(reader: &mut R) -> io::Result<PKey>
- where R: Read
- {
- let mut mem_bio = try!(MemBio::new());
- try!(io::copy(reader, &mut mem_bio));
-
+ pub fn private_key_from_pem(buf: &[u8]) -> Result<PKey, ErrorStack> {
+ let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let evp = try_ssl_null!(ffi::PEM_read_bio_PrivateKey(mem_bio.get_handle(),
ptr::null_mut(),
@@ -100,14 +94,11 @@ impl PKey {
///
/// The callback will be passed the password buffer and should return the number of characters
/// placed into the buffer.
- pub fn private_key_from_pem_cb<R, F>(reader: &mut R, pass_cb: F) -> io::Result<PKey>
- where R: Read, F: FnOnce(&mut [c_char]) -> usize
+ pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<PKey, ErrorStack>
+ where F: FnOnce(&mut [c_char]) -> usize
{
let mut cb = CallbackState::new(pass_cb);
-
- let mut mem_bio = try!(MemBio::new());
- try!(io::copy(reader, &mut mem_bio));
-
+ let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let evp = try_ssl_null!(ffi::PEM_read_bio_PrivateKey(mem_bio.get_handle(),
ptr::null_mut(),
@@ -122,12 +113,8 @@ impl PKey {
}
/// Reads public key from PEM, takes ownership of handle
- pub fn public_key_from_pem<R>(reader: &mut R) -> io::Result<PKey>
- where R: Read
- {
- let mut mem_bio = try!(MemBio::new());
- try!(io::copy(reader, &mut mem_bio));
-
+ pub fn public_key_from_pem(buf: &[u8]) -> Result<PKey, ErrorStack> {
+ let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let evp = try_ssl_null!(ffi::PEM_read_bio_PUBKEY(mem_bio.get_handle(),
ptr::null_mut(),
@@ -141,14 +128,12 @@ impl PKey {
}
/// Reads an RSA private key from PEM, takes ownership of handle
- pub fn private_rsa_key_from_pem<R>(reader: &mut R) -> io::Result<PKey>
- where R: Read
- {
- let rsa = try!(RSA::private_key_from_pem(reader));
+ pub fn private_rsa_key_from_pem(buf: &[u8]) -> Result<PKey, ErrorStack> {
+ let rsa = try!(RSA::private_key_from_pem(buf));
unsafe {
let evp = try_ssl_null!(ffi::EVP_PKEY_new());
if ffi::EVP_PKEY_set1_RSA(evp, rsa.as_ptr()) == 0 {
- return Err(io::Error::new(io::ErrorKind::Other, ErrorStack::get()));
+ return Err(ErrorStack::get());
}
Ok(PKey {
@@ -159,14 +144,12 @@ impl PKey {
}
/// Reads an RSA public key from PEM, takes ownership of handle
- pub fn public_rsa_key_from_pem<R>(reader: &mut R) -> io::Result<PKey>
- where R: Read
- {
- let rsa = try!(RSA::public_key_from_pem(reader));
+ pub fn public_rsa_key_from_pem(buf: &[u8]) -> Result<PKey, ErrorStack> {
+ let rsa = try!(RSA::public_key_from_pem(buf));
unsafe {
let evp = try_ssl_null!(ffi::EVP_PKEY_new());
if ffi::EVP_PKEY_set1_RSA(evp, rsa.as_ptr()) == 0 {
- return Err(io::Error::new(io::ErrorKind::Other, ErrorStack::get()));
+ return Err(ErrorStack::get());
}
Ok(PKey {
@@ -280,10 +263,8 @@ impl PKey {
/// Stores private key as a PEM
// FIXME: also add password and encryption
- pub fn write_pem<W: Write>(&self,
- writer: &mut W /* , password: Option<String> */)
- -> io::Result<()> {
- let mut mem_bio = try!(MemBio::new());
+ pub fn write_pem(&self) -> Result<Vec<u8>, ErrorStack> {
+ let mem_bio = try!(MemBio::new());
unsafe {
try_ssl!(ffi::PEM_write_bio_PrivateKey(mem_bio.get_handle(),
self.evp,
@@ -294,20 +275,14 @@ impl PKey {
ptr::null_mut()));
}
- let mut buf = vec![];
- try!(mem_bio.read_to_end(&mut buf));
- writer.write_all(&buf)
+ Ok(mem_bio.get_buf().to_owned())
}
/// Stores public key as a PEM
- pub fn write_pub_pem<W: Write>(&self,
- writer: &mut W /* , password: Option<String> */)
- -> io::Result<()> {
- let mut mem_bio = try!(MemBio::new());
+ pub fn write_pub_pem(&self) -> Result<Vec<u8>, ErrorStack> {
+ let mem_bio = try!(MemBio::new());
unsafe { try_ssl!(ffi::PEM_write_bio_PUBKEY(mem_bio.get_handle(), self.evp)) }
- let mut buf = vec![];
- try!(mem_bio.read_to_end(&mut buf));
- writer.write_all(&buf)
+ Ok(mem_bio.get_buf().to_owned())
}
/**
@@ -648,8 +623,6 @@ impl Clone for PKey {
#[cfg(test)]
mod tests {
- use std::path::Path;
- use std::fs::File;
use crypto::hash::Type::{MD5, SHA1};
use crypto::rsa::RSA;
@@ -693,42 +666,26 @@ mod tests {
#[test]
fn test_private_key_from_pem() {
- let key_path = Path::new("test/key.pem");
- let mut file = File::open(&key_path)
- .ok()
- .expect("Failed to open `test/key.pem`");
-
- super::PKey::private_key_from_pem(&mut file).unwrap();
+ let key = include_bytes!("../../test/key.pem");
+ super::PKey::private_key_from_pem(key).unwrap();
}
#[test]
fn test_public_key_from_pem() {
- let key_path = Path::new("test/key.pem.pub");
- let mut file = File::open(&key_path)
- .ok()
- .expect("Failed to open `test/key.pem.pub`");
-
- super::PKey::public_key_from_pem(&mut file).unwrap();
+ let key = include_bytes!("../../test/key.pem.pub");
+ super::PKey::public_key_from_pem(key).unwrap();
}
#[test]
fn test_private_rsa_key_from_pem() {
- let key_path = Path::new("test/key.pem");
- let mut file = File::open(&key_path)
- .ok()
- .expect("Failed to open `test/key.pem`");
-
- super::PKey::private_rsa_key_from_pem(&mut file).unwrap();
+ let key = include_bytes!("../../test/key.pem");
+ super::PKey::private_rsa_key_from_pem(key).unwrap();
}
#[test]
fn test_public_rsa_key_from_pem() {
- let key_path = Path::new("test/key.pem.pub");
- let mut file = File::open(&key_path)
- .ok()
- .expect("Failed to open `test/key.pem.pub`");
-
- super::PKey::public_rsa_key_from_pem(&mut file).unwrap();
+ let key = include_bytes!("../../test/key.pem.pub");
+ super::PKey::public_rsa_key_from_pem(key).unwrap();
}
#[test]
@@ -819,18 +776,11 @@ mod tests {
#[test]
fn test_pem() {
- let key_path = Path::new("test/key.pem");
- let mut file = File::open(&key_path)
- .ok()
- .expect("Failed to open `test/key.pem`");
-
- let key = super::PKey::private_key_from_pem(&mut file).unwrap();
-
- let mut priv_key = Vec::new();
- let mut pub_key = Vec::new();
+ let key = include_bytes!("../../test/key.pem");
+ let key = super::PKey::private_key_from_pem(key).unwrap();
- key.write_pem(&mut priv_key).unwrap();
- key.write_pub_pem(&mut pub_key).unwrap();
+ let priv_key = key.write_pem().unwrap();
+ let pub_key = key.write_pub_pem().unwrap();
// As a super-simple verification, just check that the buffers contain
// the `PRIVATE KEY` or `PUBLIC KEY` strings.
diff --git a/openssl/src/crypto/rsa.rs b/openssl/src/crypto/rsa.rs
index 05c1c774..226b2aab 100644
--- a/openssl/src/crypto/rsa.rs
+++ b/openssl/src/crypto/rsa.rs
@@ -1,11 +1,10 @@
use ffi;
use std::fmt;
use std::ptr;
-use std::io::{self, Read, Write};
use libc::{c_int, c_void, c_char};
use bn::BigNum;
-use bio::MemBio;
+use bio::{MemBio, MemBioSlice};
use error::ErrorStack;
use crypto::HashTypeInternals;
use crypto::hash;
@@ -62,12 +61,8 @@ impl RSA {
}
/// Reads an RSA private key from PEM formatted data.
- pub fn private_key_from_pem<R>(reader: &mut R) -> io::Result<RSA>
- where R: Read
- {
- let mut mem_bio = try!(MemBio::new());
- try!(io::copy(reader, &mut mem_bio));
-
+ pub fn private_key_from_pem(buf: &[u8]) -> Result<RSA, ErrorStack> {
+ let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let rsa = try_ssl_null!(ffi::PEM_read_bio_RSAPrivateKey(mem_bio.get_handle(),
ptr::null_mut(),
@@ -78,13 +73,11 @@ impl RSA {
}
/// Reads an RSA private key from PEM formatted data and supplies a password callback.
- pub fn private_key_from_pem_cb<R, F>(reader: &mut R, pass_cb: F) -> io::Result<RSA>
- where R: Read, F: FnOnce(&mut [c_char]) -> usize
+ pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<RSA, ErrorStack>
+ where F: FnOnce(&mut [c_char]) -> usize
{
let mut cb = CallbackState::new(pass_cb);
-
- let mut mem_bio = try!(MemBio::new());
- try!(io::copy(reader, &mut mem_bio));
+ let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let cb_ptr = &mut cb as *mut _ as *mut c_void;
@@ -98,10 +91,8 @@ impl RSA {
}
/// Writes an RSA private key as unencrypted PEM formatted data
- pub fn private_key_to_pem<W>(&self, writer: &mut W) -> io::Result<()>
- where W: Write
- {
- let mut mem_bio = try!(MemBio::new());
+ pub fn private_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
+ let mem_bio = try!(MemBio::new());
unsafe {
try_ssl!(ffi::PEM_write_bio_RSAPrivateKey(mem_bio.get_handle(),
@@ -112,17 +103,12 @@ impl RSA {
None,
ptr::null_mut()));
}
- try!(io::copy(&mut mem_bio, writer));
- Ok(())
+ Ok(mem_bio.get_buf().to_owned())
}
/// Reads an RSA public key from PEM formatted data.
- pub fn public_key_from_pem<R>(reader: &mut R) -> io::Result<RSA>
- where R: Read
- {
- let mut mem_bio = try!(MemBio::new());
- try!(io::copy(reader, &mut mem_bio));
-
+ pub fn public_key_from_pem(buf: &[u8]) -> Result<RSA, ErrorStack> {
+ let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let rsa = try_ssl_null!(ffi::PEM_read_bio_RSA_PUBKEY(mem_bio.get_handle(),
ptr::null_mut(),
@@ -133,17 +119,14 @@ impl RSA {
}
/// Writes an RSA public key as PEM formatted data
- pub fn public_key_to_pem<W>(&self, writer: &mut W) -> io::Result<()>
- where W: Write
- {
- let mut mem_bio = try!(MemBio::new());
+ pub fn public_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
+ let mem_bio = try!(MemBio::new());
unsafe {
try_ssl!(ffi::PEM_write_bio_RSA_PUBKEY(mem_bio.get_handle(), self.0))
};
- try!(io::copy(&mut mem_bio, writer));
- Ok(())
+ Ok(mem_bio.get_buf().to_owned())
}
pub fn size(&self) -> Option<u32> {
@@ -236,7 +219,6 @@ impl fmt::Debug for RSA {
#[cfg(test)]
mod test {
- use std::fs::File;
use std::io::Write;
use libc::c_char;
@@ -271,8 +253,8 @@ mod test {
#[test]
pub fn test_sign() {
- let mut buffer = File::open("test/rsa.pem").unwrap();
- let private_key = RSA::private_key_from_pem(&mut buffer).unwrap();
+ let key = include_bytes!("../../test/rsa.pem");
+ let private_key = RSA::private_key_from_pem(key).unwrap();
let mut sha = Hasher::new(Type::SHA256);
sha.write_all(&signing_input_rs256()).unwrap();
@@ -285,8 +267,8 @@ mod test {
#[test]
pub fn test_verify() {
- let mut buffer = File::open("test/rsa.pem.pub").unwrap();
- let public_key = RSA::public_key_from_pem(&mut buffer).unwrap();
+ let key = include_bytes!("../../test/rsa.pem.pub");
+ let public_key = RSA::public_key_from_pem(key).unwrap();
let mut sha = Hasher::new(Type::SHA256);
sha.write_all(&signing_input_rs256()).unwrap();
@@ -300,8 +282,8 @@ mod test {
#[test]
pub fn test_password() {
let mut password_queried = false;
- let mut buffer = File::open("test/rsa-encrypted.pem").unwrap();
- RSA::private_key_from_pem_cb(&mut buffer, |password| {
+ let key = include_bytes!("../../test/rsa-encrypted.pem");
+ RSA::private_key_from_pem_cb(key, |password| {
password_queried = true;
password[0] = b'm' as c_char;
password[1] = b'y' as c_char;
diff --git a/openssl/src/dh/mod.rs b/openssl/src/dh/mod.rs
index bf1ca73e..df6f1b0a 100644
--- a/openssl/src/dh/mod.rs
+++ b/openssl/src/dh/mod.rs
@@ -1,8 +1,6 @@
use ffi;
-use std::io;
-use std::io::prelude::*;
use error::ErrorStack;
-use bio::MemBio;
+use bio::MemBioSlice;
use bn::BigNum;
use std::mem;
use std::ptr;
@@ -18,11 +16,8 @@ impl DH {
Ok(DH(dh))
}
- pub fn from_pem<R>(reader: &mut R) -> io::Result<DH>
- where R: Read
- {
- let mut mem_bio = try!(MemBio::new());
- try!(io::copy(reader, &mut mem_bio));
+ pub fn from_pem(buf: &[u8]) -> Result<DH, ErrorStack> {
+ let mem_bio = try!(MemBioSlice::new(buf));
let dh = unsafe {
ffi::PEM_read_bio_DHparams(mem_bio.get_handle(), ptr::null_mut(), None, ptr::null_mut())
};
@@ -71,8 +66,6 @@ impl Drop for DH {
#[cfg(test)]
mod tests {
- use std::fs::File;
- use std::path::Path;
use super::DH;
use bn::BigNum;
use ssl::SslContext;
@@ -123,11 +116,8 @@ mod tests {
#[test]
fn test_dh_from_pem() {
let mut ctx = SslContext::new(Sslv23).unwrap();
- let pem_path = Path::new("test/dhparams.pem");
- let mut file = File::open(&pem_path)
- .ok()
- .expect("Failed to open `test/dhparams.pem`");
- let dh = DH::from_pem(&mut file).ok().expect("Failed to load PEM");
+ let params = include_bytes!("../../test/dhparams.pem");
+ let dh = DH::from_pem(params).ok().expect("Failed to load PEM");
ctx.set_tmp_dh(dh).unwrap();
}
}
diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs
index d12af41c..4cd76613 100644
--- a/openssl/src/lib.rs
+++ b/openssl/src/lib.rs
@@ -17,7 +17,7 @@ extern crate net2;
mod macros;
pub mod asn1;
-pub mod bio;
+mod bio;
pub mod bn;
pub mod crypto;
pub mod dh;
diff --git a/openssl/src/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs
index 0b638546..b774b383 100644
--- a/openssl/src/ssl/tests/mod.rs
+++ b/openssl/src/ssl/tests/mod.rs
@@ -418,17 +418,10 @@ fn test_write_hits_stream() {
#[test]
fn test_set_certificate_and_private_key() {
- let key_path = Path::new("test/key.pem");
- let cert_path = Path::new("test/cert.pem");
- let mut key_file = File::open(&key_path)
- .ok()
- .expect("Failed to open `test/key.pem`");
- let mut cert_file = File::open(&cert_path)
- .ok()
- .expect("Failed to open `test/cert.pem`");
-
- let key = PKey::private_key_from_pem(&mut key_file).unwrap();
- let cert = X509::from_pem(&mut cert_file).unwrap();
+ let key = include_bytes!("../../../test/key.pem");
+ let key = PKey::private_key_from_pem(key).unwrap();
+ let cert = include_bytes!("../../../test/cert.pem");
+ let cert = X509::from_pem(cert).unwrap();
let mut ctx = SslContext::new(Sslv23).unwrap();
ctx.set_private_key(&key).unwrap();
diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs
index 05d8221e..64a61df0 100644
--- a/openssl/src/x509/mod.rs
+++ b/openssl/src/x509/mod.rs
@@ -1,6 +1,4 @@
use libc::{c_char, c_int, c_long, c_ulong, c_uint, c_void};
-use std::io;
-use std::io::prelude::*;
use std::cmp::Ordering;
use std::ffi::CString;
use std::iter::repeat;
@@ -14,7 +12,7 @@ use std::collections::HashMap;
use std::marker::PhantomData;
use asn1::Asn1Time;
-use bio::MemBio;
+use bio::{MemBio, MemBioSlice};
use crypto::hash;
use crypto::hash::Type as HashType;
use crypto::pkey::{PKey, Parts};
@@ -116,13 +114,6 @@ impl X509StoreContext {
/// # Example
///
/// ```
-/// # #[allow(unstable)]
-/// # fn main() {
-/// use std::fs;
-/// use std::fs::File;
-/// use std::io::prelude::*;
-/// use std::path::Path;
-///
/// use openssl::crypto::hash::Type;
/// use openssl::x509::X509Generator;
/// use openssl::x509::extension::{Extension, KeyUsageOption};
@@ -135,17 +126,8 @@ impl X509StoreContext {
/// .add_extension(Extension::KeyUsage(vec![KeyUsageOption::DigitalSignature]));
///
/// let (cert, pkey) = gen.generate().unwrap();
-///
-/// let cert_path = "doc_cert.pem";
-/// let mut file = File::create(cert_path).unwrap();
-/// assert!(cert.write_pem(&mut file).is_ok());
-/// # let _ = fs::remove_file(cert_path);
-///
-/// let pkey_path = "doc_key.pem";
-/// let mut file = File::create(pkey_path).unwrap();
-/// assert!(pkey.write_pem(&mut file).is_ok());
-/// # let _ = fs::remove_file(pkey_path);
-/// # }
+/// let cert_pem = cert.write_pem().unwrap();
+/// let pkey_pem = pkey.write_pem().unwrap();
/// ```
pub struct X509Generator {
bits: u32,
@@ -444,12 +426,8 @@ impl<'ctx> X509<'ctx> {
}
/// Reads certificate from PEM, takes ownership of handle
- pub fn from_pem<R>(reader: &mut R) -> io::Result<X509<'ctx>>
- where R: Read
- {
- let mut mem_bio = try!(MemBio::new());
- try!(io::copy(reader, &mut mem_bio));
-
+ pub fn from_pem(buf: &[u8]) -> Result<X509<'ctx>, ErrorStack> {
+ let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let handle = try_ssl_null!(ffi::PEM_read_bio_X509(mem_bio.get_handle(),
ptr::null_mut(),
@@ -523,25 +501,21 @@ impl<'ctx> X509<'ctx> {
}
/// Writes certificate as PEM
- pub fn write_pem<W>(&self, writer: &mut W) -> io::Result<()>
- where W: Write
- {
- let mut mem_bio = try!(MemBio::new());
+ pub fn write_pem(&self) -> Result<Vec<u8>, ErrorStack> {
+ let mem_bio = try!(MemBio::new());
unsafe {
try_ssl!(ffi::PEM_write_bio_X509(mem_bio.get_handle(), self.handle));
}
- io::copy(&mut mem_bio, writer).map(|_| ())
+ Ok(mem_bio.get_buf().to_owned())
}
/// Returns a DER serialized form of the certificate
pub fn save_der(&self) -> Result<Vec<u8>, ErrorStack> {
- let mut mem_bio = try!(MemBio::new());
+ let mem_bio = try!(MemBio::new());
unsafe {
ffi::i2d_X509_bio(mem_bio.get_handle(), self.handle);
}
- let mut v = Vec::new();
- drop(io::copy(&mut mem_bio, &mut v));
- Ok(v)
+ Ok(mem_bio.get_buf().to_owned())
}
}
@@ -627,12 +601,8 @@ impl X509Req {
}
/// Reads CSR from PEM
- pub fn from_pem<R>(reader: &mut R) -> io::Result<X509Req>
- where R: Read
- {
- let mut mem_bio = try!(MemBio::new());
- try!(io::copy(reader, &mut mem_bio));
-
+ pub fn from_pem(buf: &[u8]) -> Result<X509Req, ErrorStack> {
+ let mem_bio = try!(MemBioSlice::new(buf));
unsafe {
let handle = try_ssl_null!(ffi::PEM_read_bio_X509_REQ(mem_bio.get_handle(),
ptr::null_mut(),
@@ -643,25 +613,21 @@ impl X509Req {
}
/// Writes CSR as PEM
- pub fn write_pem<W>(&self, writer: &mut W) -> io::Result<()>
- where W: Write
- {
- let mut mem_bio = try!(MemBio::new());
+ pub fn write_pem(&self) -> Result<Vec<u8>, ErrorStack> {
+ let mem_bio = try!(MemBio::new());
if unsafe { ffi::PEM_write_bio_X509_REQ(mem_bio.get_handle(), self.handle) } != 1 {
- return Err(io::Error::new(io::ErrorKind::Other, ErrorStack::get()));
+ return Err(ErrorStack::get());
}
- io::copy(&mut mem_bio, writer).map(|_| ())
+ Ok(mem_bio.get_buf().to_owned())
}
/// Returns a DER serialized form of the CSR
pub fn save_der(&self) -> Result<Vec<u8>, ErrorStack> {
- let mut mem_bio = try!(MemBio::new());
+ let mem_bio = try!(MemBio::new());
unsafe {
ffi::i2d_X509_REQ_bio(mem_bio.get_handle(), self.handle);
}
- let mut v = Vec::new();
- drop(io::copy(&mut mem_bio, &mut v));
- Ok(v)
+ Ok(mem_bio.get_buf().to_owned())
}
}
diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs
index 5d9b30ab..167ca8cf 100644
--- a/openssl/src/x509/tests.rs
+++ b/openssl/src/x509/tests.rs
@@ -1,7 +1,4 @@
use serialize::hex::FromHex;
-use std::io;
-use std::path::Path;
-use std::fs::File;
use crypto::hash::Type::SHA1;
use crypto::pkey::PKey;
@@ -30,8 +27,8 @@ fn get_generator() -> X509Generator {
#[test]
fn test_cert_gen() {
let (cert, pkey) = get_generator().generate().unwrap();
- cert.write_pem(&mut io::sink()).unwrap();
- pkey.write_pem(&mut io::sink()).unwrap();
+ cert.write_pem().unwrap();
+ pkey.write_pem().unwrap();
// FIXME: check data in result to be correct, needs implementation
// of X509 getters
@@ -70,7 +67,7 @@ fn test_req_gen() {
pkey.gen(512);
let req = get_generator().request(&pkey).unwrap();
- req.write_pem(&mut io::sink()).unwrap();
+ req.write_pem().unwrap();
// FIXME: check data in result to be correct, needs implementation
// of X509_REQ getters
@@ -78,12 +75,8 @@ fn test_req_gen() {
#[test]
fn test_cert_loading() {
- let cert_path = Path::new("test/cert.pem");
- let mut file = File::open(&cert_path)
- .ok()
- .expect("Failed to open `test/cert.pem`");
-
- let cert = X509::from_pem(&mut file).ok().expect("Failed to load PEM");
+ let cert = include_bytes!("../../test/cert.pem");
+ let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
let fingerprint = cert.fingerprint(SHA1).unwrap();
let hash_str = "E19427DAC79FBE758394945276A6E4F15F0BEBE6";
@@ -94,12 +87,8 @@ fn test_cert_loading() {
#[test]
fn test_save_der() {
- let cert_path = Path::new("test/cert.pem");
- let mut file = File::open(&cert_path)
- .ok()
- .expect("Failed to open `test/cert.pem`");
-
- let cert = X509::from_pem(&mut file).ok().expect("Failed to load PEM");
+ let cert = include_bytes!("../../test/cert.pem");
+ let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
let der = cert.save_der().unwrap();
assert!(!der.is_empty());
@@ -107,12 +96,8 @@ fn test_save_der() {
#[test]
fn test_subject_read_cn() {
- let cert_path = Path::new("test/cert.pem");
- let mut file = File::open(&cert_path)
- .ok()
- .expect("Failed to open `test/cert.pem`");
-
- let cert = X509::from_pem(&mut file).ok().expect("Failed to load PEM");
+ let cert = include_bytes!("../../test/cert.pem");
+ let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
let subject = cert.subject_name();
let cn = match subject.text_by_nid(Nid::CN) {
Some(x) => x,
@@ -124,12 +109,8 @@ fn test_subject_read_cn() {
#[test]
fn test_nid_values() {
- let cert_path = Path::new("test/nid_test_cert.pem");
- let mut file = File::open(&cert_path)
- .ok()
- .expect("Failed to open `test/nid_test_cert.pem`");
-
- let cert = X509::from_pem(&mut file).ok().expect("Failed to load PEM");
+ let cert = include_bytes!("../../test/nid_test_cert.pem");
+ let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
let subject = cert.subject_name();
let cn = match subject.text_by_nid(Nid::CN) {
@@ -153,12 +134,8 @@ fn test_nid_values() {
#[test]
fn test_nid_uid_value() {
- let cert_path = Path::new("test/nid_uid_test_cert.pem");
- let mut file = File::open(&cert_path)
- .ok()
- .expect("Failed to open `test/nid_uid_test_cert.pem`");
-
- let cert = X509::from_pem(&mut file).ok().expect("Failed to load PEM");
+ let cert = include_bytes!("../../test/nid_uid_test_cert.pem");
+ let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
let subject = cert.subject_name();
let cn = match subject.text_by_nid(Nid::UserId) {
@@ -170,8 +147,8 @@ fn test_nid_uid_value() {
#[test]
fn test_subject_alt_name() {
- let mut file = File::open("test/alt_name_cert.pem").unwrap();
- let cert = X509::from_pem(&mut file).unwrap();
+ let cert = include_bytes!("../../test/alt_name_cert.pem");
+ let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
let subject_alt_names = cert.subject_alt_names().unwrap();
assert_eq!(3, subject_alt_names.len());
@@ -184,8 +161,8 @@ fn test_subject_alt_name() {
#[test]
fn test_subject_alt_name_iter() {
- let mut file = File::open("test/alt_name_cert.pem").unwrap();
- let cert = X509::from_pem(&mut file).unwrap();
+ let cert = include_bytes!("../../test/alt_name_cert.pem");
+ let cert = X509::from_pem(cert).ok().expect("Failed to load PEM");
let subject_alt_names = cert.subject_alt_names().unwrap();
let mut subject_alt_names_iter = subject_alt_names.iter();