aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/crypto/pkey.rs
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2016-07-31 15:15:47 -0700
committerSteven Fackler <[email protected]>2016-07-31 15:15:47 -0700
commitf0ffa246b83102d70bc59f76d136981efdafb1e7 (patch)
tree0f6036a20ba4eb7b333986206962abeb4bab6c2f /openssl/src/crypto/pkey.rs
parentRevert "Add a new trait based Nid setup" (diff)
parentMerge pull request #402 from bbatha/feat/dsa-ffi (diff)
downloadrust-openssl-f0ffa246b83102d70bc59f76d136981efdafb1e7.tar.xz
rust-openssl-f0ffa246b83102d70bc59f76d136981efdafb1e7.zip
Merge remote-tracking branch 'origin/master' into breaks
Diffstat (limited to 'openssl/src/crypto/pkey.rs')
-rw-r--r--openssl/src/crypto/pkey.rs73
1 files changed, 48 insertions, 25 deletions
diff --git a/openssl/src/crypto/pkey.rs b/openssl/src/crypto/pkey.rs
index 1020a82e..0231cc95 100644
--- a/openssl/src/crypto/pkey.rs
+++ b/openssl/src/crypto/pkey.rs
@@ -5,12 +5,19 @@ use std::iter::repeat;
use std::mem;
use std::ptr;
use bio::MemBio;
+
+use crypto::HashTypeInternals;
use crypto::hash;
use crypto::hash::Type as HashType;
use ffi;
use crypto::rsa::RSA;
use error::ErrorStack;
+#[cfg(feature = "catch_unwind")]
+use libc::{c_void, c_char};
+#[cfg(feature = "catch_unwind")]
+use crypto::util::{CallbackState, invoke_passwd_cb};
+
#[derive(Copy, Clone)]
pub enum Parts {
Neither,
@@ -41,18 +48,6 @@ fn openssl_padding_code(padding: EncryptionPadding) -> c_int {
}
}
-fn openssl_hash_nid(hash: HashType) -> c_int {
- match hash {
- HashType::MD5 => 4, // NID_md5,
- HashType::SHA1 => 64, // NID_sha1
- HashType::SHA224 => 675, // NID_sha224
- HashType::SHA256 => 672, // NID_sha256
- HashType::SHA384 => 673, // NID_sha384
- HashType::SHA512 => 674, // NID_sha512
- HashType::RIPEMD160 => 117, // NID_ripemd160
- }
-}
-
pub struct PKey {
evp: *mut ffi::EVP_PKEY,
parts: Parts,
@@ -104,6 +99,35 @@ impl PKey {
}
}
+ /// Read a private key from PEM, supplying a password callback to be invoked if the private key
+ /// is encrypted.
+ ///
+ /// 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
+ {
+ let mut cb = CallbackState::new(pass_cb);
+
+ let mut mem_bio = try!(MemBio::new());
+ try!(io::copy(reader, &mut mem_bio).map_err(StreamError));
+
+ unsafe {
+ let evp = try_ssl_null!(ffi::PEM_read_bio_PrivateKey(mem_bio.get_handle(),
+ ptr::null_mut(),
+ Some(invoke_passwd_cb::<F>),
+ &mut cb as *mut _ as *mut c_void));
+
+ Ok(PKey {
+ evp: evp as *mut ffi::EVP_PKEY,
+ parts: Parts::Both,
+ })
+ }
+ }
+
/// 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
@@ -125,7 +149,7 @@ 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
+ where R: Read
{
let rsa = try!(RSA::private_key_from_pem(reader));
unsafe {
@@ -143,7 +167,7 @@ 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
+ where R: Read
{
let rsa = try!(RSA::public_key_from_pem(reader));
unsafe {
@@ -561,7 +585,7 @@ impl PKey {
let mut r = repeat(0u8).take(len as usize + 1).collect::<Vec<_>>();
let mut len = 0;
- let rv = ffi::RSA_sign(openssl_hash_nid(hash),
+ let rv = ffi::RSA_sign(hash.as_nid() as c_int,
s.as_ptr(),
s.len() as c_uint,
r.as_mut_ptr(),
@@ -584,7 +608,7 @@ impl PKey {
panic!("Could not get RSA key for verification");
}
- let rv = ffi::RSA_verify(openssl_hash_nid(hash),
+ let rv = ffi::RSA_verify(hash.as_nid() as c_int,
h.as_ptr(),
h.len() as c_uint,
s.as_ptr(),
@@ -615,16 +639,15 @@ impl Drop for PKey {
impl Clone for PKey {
fn clone(&self) -> Self {
let mut pkey = PKey::from_handle(unsafe { ffi::EVP_PKEY_new() }, self.parts);
- // copy by encoding to DER and back
+ // copy by encoding to DER and back
match self.parts {
Parts::Public => {
pkey.load_pub(&self.save_pub()[..]);
- },
+ }
Parts::Both => {
pkey.load_priv(&self.save_priv()[..]);
- },
- Parts::Neither => {
- },
+ }
+ Parts::Neither => {}
}
pkey
}
@@ -699,8 +722,8 @@ mod tests {
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`");
+ .ok()
+ .expect("Failed to open `test/key.pem`");
super::PKey::private_rsa_key_from_pem(&mut file).unwrap();
}
@@ -709,8 +732,8 @@ mod tests {
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`");
+ .ok()
+ .expect("Failed to open `test/key.pem.pub`");
super::PKey::public_rsa_key_from_pem(&mut file).unwrap();
}