diff --git a/openssl/src/dsa.rs b/openssl/src/dsa.rs index 53d7babf..86476aac 100644 --- a/openssl/src/dsa.rs +++ b/openssl/src/dsa.rs @@ -216,6 +216,12 @@ mod test { #[test] pub fn test_password() { + let key = include_bytes!("../test/dsa-encrypted.pem"); + Dsa::private_key_from_pem_passphrase(key, b"mypass").unwrap(); + } + + #[test] + pub fn test_password_callback() { let mut password_queried = false; let key = include_bytes!("../test/dsa-encrypted.pem"); Dsa::private_key_from_pem_callback(key, |password| { diff --git a/openssl/src/ec_key.rs b/openssl/src/ec_key.rs index 99d62ad3..7406572a 100644 --- a/openssl/src/ec_key.rs +++ b/openssl/src/ec_key.rs @@ -11,6 +11,8 @@ use types::OpenSslTypeRef; type_!(EcKey, EcKeyRef, ffi::EC_KEY, ffi::EC_KEY_free); impl EcKeyRef { + private_key_to_pem!(ffi::PEM_write_bio_ECPrivateKey); + /// Serializes the private key components to DER. pub fn private_key_to_der(&self) -> Result, ErrorStack> { unsafe { diff --git a/openssl/src/macros.rs b/openssl/src/macros.rs index b225f322..9f1d7746 100644 --- a/openssl/src/macros.rs +++ b/openssl/src/macros.rs @@ -52,6 +52,27 @@ macro_rules! private_key_from_pem { } } + /// Deserializes a PEM-formatted private key, using the supplied password if the key is + /// encrypted. + /// + /// # Panics + /// + /// Panics if `passphrase` contains an embedded null. + pub fn private_key_from_pem_passphrase(pem: &[u8], + passphrase: &[u8]) + -> Result<$t, ::error::ErrorStack> { + unsafe { + ffi::init(); + let bio = try!(::bio::MemBioSlice::new(pem)); + let passphrase = ::std::ffi::CString::new(passphrase).unwrap(); + cvt_p($f(bio.as_ptr(), + ptr::null_mut(), + None, + passphrase.as_ptr() as *const _ as *mut _)) + .map($t) + } + } + /// Deserializes a PEM-formatted private key, using a callback to retrieve a password if the /// key is encrypted. /// @@ -69,7 +90,7 @@ macro_rules! private_key_from_pem { cvt_p($f(bio.as_ptr(), ptr::null_mut(), Some(::util::invoke_passwd_cb::), - &mut cb as *mut _ as *mut ::libc::c_void)) + &mut cb as *mut _ as *mut _)) .map($t) } } @@ -81,7 +102,7 @@ macro_rules! private_key_to_pem { /// Serializes the private key to PEM. pub fn private_key_to_pem(&self) -> Result, ::error::ErrorStack> { unsafe { - let bio = try!(MemBio::new()); + let bio = try!(::bio::MemBio::new()); try!(cvt($f(bio.as_ptr(), self.as_ptr(), ptr::null(), diff --git a/openssl/src/rsa.rs b/openssl/src/rsa.rs index 3ebbe542..bf127abe 100644 --- a/openssl/src/rsa.rs +++ b/openssl/src/rsa.rs @@ -408,6 +408,12 @@ mod test { #[test] pub fn test_password() { + let key = include_bytes!("../test/rsa-encrypted.pem"); + Rsa::private_key_from_pem_passphrase(key, b"mypass").unwrap(); + } + + #[test] + pub fn test_password_callback() { let mut password_queried = false; let key = include_bytes!("../test/rsa-encrypted.pem"); Rsa::private_key_from_pem_callback(key, |password| {