diff options
Diffstat (limited to 'openssl/src/crypto')
| -rw-r--r-- | openssl/src/crypto/dsa.rs | 128 | ||||
| -rw-r--r-- | openssl/src/crypto/mod.rs | 1 | ||||
| -rw-r--r-- | openssl/src/crypto/pkey.rs | 132 | ||||
| -rw-r--r-- | openssl/src/crypto/rsa.rs | 132 |
4 files changed, 153 insertions, 240 deletions
diff --git a/openssl/src/crypto/dsa.rs b/openssl/src/crypto/dsa.rs index 7e384ae3..de35893b 100644 --- a/openssl/src/crypto/dsa.rs +++ b/openssl/src/crypto/dsa.rs @@ -1,25 +1,21 @@ use ffi; use std::fmt; -use ssl::error::{SslError, StreamError}; +use error::ErrorStack; use std::ptr; -use std::io::{self, Read, Write}; -use libc::{c_uint, c_int}; +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; - -#[cfg(feature = "catch_unwind")] -use libc::{c_char, c_void}; -#[cfg(feature = "catch_unwind")] use crypto::util::{CallbackState, invoke_passwd_cb}; + /// Builder for upfront DSA parameter generateration pub struct DSAParams(*mut ffi::DSA); impl DSAParams { - pub fn with_size(size: usize) -> Result<DSAParams, SslError> { + pub fn with_size(size: usize) -> Result<DSAParams, ErrorStack> { unsafe { // Wrap it so that if we panic we'll call the dtor let dsa = DSAParams(try_ssl_null!(ffi::DSA_new())); @@ -30,7 +26,7 @@ impl DSAParams { } /// Generate a key pair from the initialized parameters - pub fn generate(self) -> Result<DSA, SslError> { + pub fn generate(self) -> Result<DSA, ErrorStack> { unsafe { try_ssl!(ffi::DSA_generate_key(self.0)); let dsa = DSA(self.0); @@ -66,17 +62,15 @@ impl DSA { /// Generate a DSA key pair /// For more complicated key generation scenarios see the `DSAParams` type - pub fn generate(size: usize) -> Result<DSA, SslError> { + pub fn generate(size: usize) -> Result<DSA, ErrorStack> { let params = try!(DSAParams::with_size(size)); params.generate() } /// Reads a DSA private key from PEM formatted data. - pub fn private_key_from_pem<R>(reader: &mut R) -> Result<DSA, SslError> - where R: Read - { - let mut mem_bio = try!(MemBio::new()); - try!(io::copy(reader, &mut mem_bio).map_err(StreamError)); + 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(), @@ -94,15 +88,12 @@ impl DSA { /// /// The callback will be passed the password buffer and should return the number of characters /// placed into the buffer. - /// - /// Requires the `catch_unwind` feature. - #[cfg(feature = "catch_unwind")] - pub fn private_key_from_pem_cb<R, F>(reader: &mut R, pass_cb: F) -> Result<DSA, SslError> - 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).map_err(StreamError)); + let mem_bio = try!(MemBioSlice::new(buf)); unsafe { let cb_ptr = &mut cb as *mut _ as *mut c_void; @@ -117,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) -> Result<(), SslError> - 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, @@ -129,18 +119,15 @@ impl DSA { None, ptr::null_mut())) }; - - try!(io::copy(&mut mem_bio, writer).map_err(StreamError)); - 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) -> Result<DSA, SslError> - 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).map_err(StreamError)); + 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(), @@ -151,28 +138,23 @@ impl DSA { } /// Writes an DSA public key as PEM formatted data - pub fn public_key_to_pem<W>(&self, writer: &mut W) -> Result<(), SslError> - 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).map_err(StreamError)); - Ok(()) + Ok(mem_bio.get_buf().to_owned()) } - pub fn size(&self) -> Result<isize, SslError> { + pub fn size(&self) -> Option<u32> { if self.has_q() { - unsafe { Ok(ffi::DSA_size(self.0) as isize) } + unsafe { Some(ffi::DSA_size(self.0) as u32) } } else { - Err(SslError::OpenSslErrors(vec![])) + None } } - pub fn sign(&self, hash: hash::Type, message: &[u8]) -> Result<Vec<u8>, SslError> { - let k_len = try!(self.size()) as c_uint; - let mut sig = vec![0;k_len as usize]; + pub fn sign(&self, hash: hash::Type, message: &[u8]) -> Result<Vec<u8>, ErrorStack> { + let k_len = self.size().expect("DSA missing a q") as c_uint; + let mut sig = vec![0; k_len as usize]; let mut sig_len = k_len; assert!(self.has_private_key()); @@ -189,7 +171,7 @@ impl DSA { } } - pub fn verify(&self, hash: hash::Type, message: &[u8], sig: &[u8]) -> Result<bool, SslError> { + pub fn verify(&self, hash: hash::Type, message: &[u8], sig: &[u8]) -> Result<bool, ErrorStack> { unsafe { let result = ffi::DSA_verify(hash.as_nid() as c_int, message.as_ptr(), @@ -208,7 +190,7 @@ impl DSA { } // The following getters are unsafe, since BigNum::new_from_ffi fails upon null pointers - pub fn p(&self) -> Result<BigNum, SslError> { + pub fn p(&self) -> Result<BigNum, ErrorStack> { unsafe { BigNum::new_from_ffi((*self.0).p) } } @@ -216,7 +198,7 @@ impl DSA { unsafe { !(*self.0).p.is_null() } } - pub fn q(&self) -> Result<BigNum, SslError> { + pub fn q(&self) -> Result<BigNum, ErrorStack> { unsafe { BigNum::new_from_ffi((*self.0).q) } } @@ -224,7 +206,7 @@ impl DSA { unsafe { !(*self.0).q.is_null() } } - pub fn g(&self) -> Result<BigNum, SslError> { + pub fn g(&self) -> Result<BigNum, ErrorStack> { unsafe { BigNum::new_from_ffi((*self.0).g) } } @@ -249,19 +231,18 @@ 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::*; use crypto::hash::*; #[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(); @@ -281,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 = { @@ -305,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 = { @@ -331,18 +312,17 @@ mod test { } #[test] - #[cfg(feature = "catch_unwind")] 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 _; - password[1] = b'y' as _; - password[2] = b'p' as _; - password[3] = b'a' as _; - password[4] = b's' as _; - password[5] = b's' as _; + password[0] = b'm' as c_char; + password[1] = b'y' as c_char; + password[2] = b'p' as c_char; + password[3] = b'a' as c_char; + password[4] = b's' as c_char; + password[5] = b's' as c_char; 6 }).unwrap(); diff --git a/openssl/src/crypto/mod.rs b/openssl/src/crypto/mod.rs index 6a34bd59..5b891ce7 100644 --- a/openssl/src/crypto/mod.rs +++ b/openssl/src/crypto/mod.rs @@ -25,7 +25,6 @@ pub mod symm; pub mod memcmp; pub mod rsa; pub mod dsa; -#[cfg(feature = "catch_unwind")] mod util; mod symm_internal; diff --git a/openssl/src/crypto/pkey.rs b/openssl/src/crypto/pkey.rs index 15744047..ab9a4a95 100644 --- a/openssl/src/crypto/pkey.rs +++ b/openssl/src/crypto/pkey.rs @@ -1,21 +1,15 @@ -use libc::{c_int, c_uint, c_ulong}; -use std::io; -use std::io::prelude::*; +use libc::{c_int, c_uint, c_ulong, c_void, c_char}; use std::iter::repeat; use std::mem; use std::ptr; -use bio::MemBio; +use bio::{MemBio, MemBioSlice}; use crypto::HashTypeInternals; use crypto::hash; use crypto::hash::Type as HashType; use ffi; -use ssl::error::{SslError, StreamError}; use crypto::rsa::RSA; - -#[cfg(feature = "catch_unwind")] -use libc::{c_void, c_char}; -#[cfg(feature = "catch_unwind")] +use error::ErrorStack; use crypto::util::{CallbackState, invoke_passwd_cb}; #[derive(Copy, Clone)] @@ -80,17 +74,14 @@ impl PKey { } /// Reads private key from PEM, takes ownership of handle - pub fn private_key_from_pem<R>(reader: &mut R) -> Result<PKey, SslError> - where R: Read - { - let mut mem_bio = try!(MemBio::new()); - try!(io::copy(reader, &mut mem_bio).map_err(StreamError)); - + 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(), None, ptr::null_mut())); + Ok(PKey { evp: evp as *mut ffi::EVP_PKEY, parts: Parts::Both, @@ -103,17 +94,11 @@ impl PKey { /// /// The callback will be passed the password buffer and should return the number of characters /// placed into the buffer. - /// - /// Requires the `catch_unwind` feature. - #[cfg(feature = "catch_unwind")] - pub fn private_key_from_pem_cb<R, F>(reader: &mut R, pass_cb: F) -> Result<PKey, SslError> - 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).map_err(StreamError)); - + 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(), @@ -128,12 +113,8 @@ impl PKey { } /// Reads public key from PEM, takes ownership of handle - pub fn public_key_from_pem<R>(reader: &mut R) -> Result<PKey, SslError> - where R: Read - { - let mut mem_bio = try!(MemBio::new()); - try!(io::copy(reader, &mut mem_bio).map_err(StreamError)); - + 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(), @@ -147,13 +128,13 @@ impl PKey { } /// Reads an RSA private key from PEM, takes ownership of handle - pub fn private_rsa_key_from_pem<R>(reader: &mut R) -> Result<PKey, SslError> - 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()); - try_ssl!(ffi::EVP_PKEY_set1_RSA(evp, rsa.as_ptr())); + if ffi::EVP_PKEY_set1_RSA(evp, rsa.as_ptr()) == 0 { + return Err(ErrorStack::get()); + } Ok(PKey { evp: evp, @@ -163,13 +144,13 @@ impl PKey { } /// Reads an RSA public key from PEM, takes ownership of handle - pub fn public_rsa_key_from_pem<R>(reader: &mut R) -> Result<PKey, SslError> - 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()); - try_ssl!(ffi::EVP_PKEY_set1_RSA(evp, rsa.as_ptr())); + if ffi::EVP_PKEY_set1_RSA(evp, rsa.as_ptr()) == 0 { + return Err(ErrorStack::get()); + } Ok(PKey { evp: evp, @@ -282,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> */) - -> Result<(), SslError> { - 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, @@ -296,20 +275,14 @@ impl PKey { ptr::null_mut())); } - let mut buf = vec![]; - try!(mem_bio.read_to_end(&mut buf).map_err(StreamError)); - writer.write_all(&buf).map_err(StreamError) + 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> */) - -> Result<(), SslError> { - 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).map_err(StreamError)); - writer.write_all(&buf).map_err(StreamError) + Ok(mem_bio.get_buf().to_owned()) } /** @@ -394,7 +367,7 @@ impl PKey { openssl_padding_code(padding)); if rv < 0 as c_int { - // println!("{:?}", SslError::get()); + // println!("{:?}", ErrorStack::get()); vec![] } else { r.truncate(rv as usize); @@ -650,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; @@ -695,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] @@ -821,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 2b563a7a..226b2aab 100644 --- a/openssl/src/crypto/rsa.rs +++ b/openssl/src/crypto/rsa.rs @@ -1,18 +1,13 @@ use ffi; use std::fmt; -use ssl::error::{SslError, StreamError}; use std::ptr; -use std::io::{self, Read, Write}; -use libc::c_int; +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; - -#[cfg(feature = "catch_unwind")] -use libc::{c_void, c_char}; -#[cfg(feature = "catch_unwind")] use crypto::util::{CallbackState, invoke_passwd_cb}; pub struct RSA(*mut ffi::RSA); @@ -28,7 +23,7 @@ impl Drop for RSA { impl RSA { /// only useful for associating the key material directly with the key, it's safer to use /// the supplied load and save methods for DER formatted keys. - pub fn from_public_components(n: BigNum, e: BigNum) -> Result<RSA, SslError> { + pub fn from_public_components(n: BigNum, e: BigNum) -> Result<RSA, ErrorStack> { unsafe { let rsa = try_ssl_null!(ffi::RSA_new()); (*rsa).n = n.into_raw(); @@ -45,7 +40,7 @@ impl RSA { dp: BigNum, dq: BigNum, qi: BigNum) - -> Result<RSA, SslError> { + -> Result<RSA, ErrorStack> { unsafe { let rsa = try_ssl_null!(ffi::RSA_new()); (*rsa).n = n.into_raw(); @@ -66,12 +61,8 @@ impl RSA { } /// Reads an RSA private key from PEM formatted data. - pub fn private_key_from_pem<R>(reader: &mut R) -> Result<RSA, SslError> - where R: Read - { - let mut mem_bio = try!(MemBio::new()); - try!(io::copy(reader, &mut mem_bio).map_err(StreamError)); - + 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(), @@ -82,16 +73,11 @@ impl RSA { } /// Reads an RSA private key from PEM formatted data and supplies a password callback. - /// - /// Requires the `catch_unwind` feature. - #[cfg(feature = "catch_unwind")] - pub fn private_key_from_pem_cb<R, F>(reader: &mut R, pass_cb: F) -> Result<RSA, SslError> - 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).map_err(StreamError)); + let mem_bio = try!(MemBioSlice::new(buf)); unsafe { let cb_ptr = &mut cb as *mut _ as *mut c_void; @@ -105,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) -> Result<(), SslError> - 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(), @@ -119,17 +103,12 @@ impl RSA { None, ptr::null_mut())); } - try!(io::copy(&mut mem_bio, writer).map_err(StreamError)); - 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) -> Result<RSA, SslError> - where R: Read - { - let mut mem_bio = try!(MemBio::new()); - try!(io::copy(reader, &mut mem_bio).map_err(StreamError)); - + 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(), @@ -140,30 +119,27 @@ impl RSA { } /// Writes an RSA public key as PEM formatted data - pub fn public_key_to_pem<W>(&self, writer: &mut W) -> Result<(), SslError> - 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).map_err(StreamError)); - Ok(()) + Ok(mem_bio.get_buf().to_owned()) } - pub fn size(&self) -> Result<u32, SslError> { + pub fn size(&self) -> Option<u32> { if self.has_n() { - unsafe { Ok(ffi::RSA_size(self.0) as u32) } + unsafe { Some(ffi::RSA_size(self.0) as u32) } } else { - Err(SslError::OpenSslErrors(vec![])) + None } } - pub fn sign(&self, hash: hash::Type, message: &[u8]) -> Result<Vec<u8>, SslError> { - let k_len = try!(self.size()); - let mut sig = vec![0;k_len as usize]; + pub fn sign(&self, hash: hash::Type, message: &[u8]) -> Result<Vec<u8>, ErrorStack> { + let k_len = self.size().expect("RSA missing an n"); + let mut sig = vec![0; k_len as usize]; let mut sig_len = k_len; unsafe { @@ -178,7 +154,7 @@ impl RSA { } } - pub fn verify(&self, hash: hash::Type, message: &[u8], sig: &[u8]) -> Result<bool, SslError> { + pub fn verify(&self, hash: hash::Type, message: &[u8], sig: &[u8]) -> Result<bool, ErrorStack> { unsafe { let result = ffi::RSA_verify(hash.as_nid() as c_int, message.as_ptr(), @@ -196,32 +172,42 @@ impl RSA { } // The following getters are unsafe, since BigNum::new_from_ffi fails upon null pointers - pub fn n(&self) -> Result<BigNum, SslError> { - unsafe { BigNum::new_from_ffi((*self.0).n) } + pub fn n(&self) -> Result<BigNum, ErrorStack> { + unsafe { + BigNum::new_from_ffi((*self.0).n) + } } pub fn has_n(&self) -> bool { unsafe { !(*self.0).n.is_null() } } - pub fn d(&self) -> Result<BigNum, SslError> { - unsafe { BigNum::new_from_ffi((*self.0).d) } + pub fn d(&self) -> Result<BigNum, ErrorStack> { + unsafe { + BigNum::new_from_ffi((*self.0).d) + } } - pub fn e(&self) -> Result<BigNum, SslError> { - unsafe { BigNum::new_from_ffi((*self.0).e) } + pub fn e(&self) -> Result<BigNum, ErrorStack> { + unsafe { + BigNum::new_from_ffi((*self.0).e) + } } pub fn has_e(&self) -> bool { unsafe { !(*self.0).e.is_null() } } - pub fn p(&self) -> Result<BigNum, SslError> { - unsafe { BigNum::new_from_ffi((*self.0).p) } + pub fn p(&self) -> Result<BigNum, ErrorStack> { + unsafe { + BigNum::new_from_ffi((*self.0).p) + } } - pub fn q(&self) -> Result<BigNum, SslError> { - unsafe { BigNum::new_from_ffi((*self.0).q) } + pub fn q(&self) -> Result<BigNum, ErrorStack> { + unsafe { + BigNum::new_from_ffi((*self.0).q) + } } } @@ -233,8 +219,9 @@ impl fmt::Debug for RSA { #[cfg(test)] mod test { - use std::fs::File; use std::io::Write; + use libc::c_char; + use super::*; use crypto::hash::*; @@ -266,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(); @@ -280,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(); @@ -293,18 +280,17 @@ mod test { } #[test] - #[cfg(feature = "catch_unwind")] 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 _; - password[1] = b'y' as _; - password[2] = b'p' as _; - password[3] = b'a' as _; - password[4] = b's' as _; - password[5] = b's' as _; + password[0] = b'm' as c_char; + password[1] = b'y' as c_char; + password[2] = b'p' as c_char; + password[3] = b'a' as c_char; + password[4] = b's' as c_char; + password[5] = b's' as c_char; 6 }).unwrap(); |