Loading openssl-sys/src/lib.rs +1 −1 Original line number Diff line number Diff line Loading @@ -1639,7 +1639,7 @@ extern { e: *mut ENGINE, key: *const c_uchar, keylen: c_int) -> *mut EVP_PKEY; pub fn d2i_PKCS8PrivateKey_bio(bp: *mut BIO, x: *mut *mut EVP_PKEY, cb: Option<PasswordCallback>, u: *mut c_void) -> *mut EVP_PKEY; pub fn EVP_PKEY_CTX_ctrl(ctx: *mut EVP_PKEY_CTX, keytype: c_int, optype: c_int, cmd: c_int, p1: c_int, p2: *mut c_void) -> c_int; Loading openssl/src/pkey.rs +62 −1 Original line number Diff line number Diff line use libc::{c_void, c_char, c_int}; use std::ptr; use std::mem; use std::ffi::CString; use ffi; use foreign_types::{Opaque, ForeignType, ForeignTypeRef}; Loading @@ -11,7 +12,7 @@ use dsa::Dsa; use ec::EcKey; use rsa::{Rsa, Padding}; use error::ErrorStack; use util::{CallbackState, invoke_passwd_cb_old}; use util::{CallbackState, invoke_passwd_cb, invoke_passwd_cb_old}; foreign_type! { type CType = ffi::EVP_PKEY; Loading Loading @@ -140,6 +141,47 @@ impl PKey { private_key_from_pem!(PKey, ffi::PEM_read_bio_PrivateKey); public_key_from_pem!(PKey, ffi::PEM_read_bio_PUBKEY); /// Deserializes a DER-formatted PKCS#8 private key, using a callback to retrieve the password /// if the key is encrpyted. /// /// The callback should copy the password into the provided buffer and return the number of /// bytes written. pub fn private_key_from_pkcs8_callback<F>(der: &[u8], callback: F) -> Result<PKey, ErrorStack> where F: FnOnce(&mut [u8]) -> Result<usize, ErrorStack> { unsafe { ffi::init(); let mut cb = CallbackState::new(callback); let bio = try!(MemBioSlice::new(der)); cvt_p(ffi::d2i_PKCS8PrivateKey_bio(bio.as_ptr(), ptr::null_mut(), Some(invoke_passwd_cb::<F>), &mut cb as *mut _ as *mut _)) .map(PKey) } } /// Deserializes a DER-formatted PKCS#8 private key, using the supplied password if the key is /// encrypted. /// /// # Panics /// /// Panics if `passphrase` contains an embedded null. pub fn private_key_from_pkcs8_passphrase(der: &[u8], passphrase: &[u8]) -> Result<PKey, ErrorStack> { unsafe { ffi::init(); let bio = try!(MemBioSlice::new(der)); let passphrase = CString::new(passphrase).unwrap(); cvt_p(ffi::d2i_PKCS8PrivateKey_bio(bio.as_ptr(), ptr::null_mut(), None, passphrase.as_ptr() as *const _ as *mut _)) .map(PKey) } } #[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")] pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<PKey, ErrorStack> where F: FnOnce(&mut [c_char]) -> usize Loading Loading @@ -200,6 +242,25 @@ mod tests { assert!(PKey::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err()); } #[test] fn test_encrypted_pkcs8_passphrase() { let key = include_bytes!("../test/pkcs8.der"); PKey::private_key_from_pkcs8_passphrase(key, b"mypass").unwrap(); } #[test] fn test_encrypted_pkcs8_callback() { let mut password_queried = false; let key = include_bytes!("../test/pkcs8.der"); PKey::private_key_from_pkcs8_callback(key, |password| { password_queried = true; password[..6].copy_from_slice(b"mypass"); Ok(6) }) .unwrap(); assert!(password_queried); } #[test] fn test_private_key_from_pem() { let key = include_bytes!("../test/key.pem"); Loading openssl/test/pkcs8.der 0 → 100644 +1.27 KiB File added.No diff preview for this file type. View file Loading
openssl-sys/src/lib.rs +1 −1 Original line number Diff line number Diff line Loading @@ -1639,7 +1639,7 @@ extern { e: *mut ENGINE, key: *const c_uchar, keylen: c_int) -> *mut EVP_PKEY; pub fn d2i_PKCS8PrivateKey_bio(bp: *mut BIO, x: *mut *mut EVP_PKEY, cb: Option<PasswordCallback>, u: *mut c_void) -> *mut EVP_PKEY; pub fn EVP_PKEY_CTX_ctrl(ctx: *mut EVP_PKEY_CTX, keytype: c_int, optype: c_int, cmd: c_int, p1: c_int, p2: *mut c_void) -> c_int; Loading
openssl/src/pkey.rs +62 −1 Original line number Diff line number Diff line use libc::{c_void, c_char, c_int}; use std::ptr; use std::mem; use std::ffi::CString; use ffi; use foreign_types::{Opaque, ForeignType, ForeignTypeRef}; Loading @@ -11,7 +12,7 @@ use dsa::Dsa; use ec::EcKey; use rsa::{Rsa, Padding}; use error::ErrorStack; use util::{CallbackState, invoke_passwd_cb_old}; use util::{CallbackState, invoke_passwd_cb, invoke_passwd_cb_old}; foreign_type! { type CType = ffi::EVP_PKEY; Loading Loading @@ -140,6 +141,47 @@ impl PKey { private_key_from_pem!(PKey, ffi::PEM_read_bio_PrivateKey); public_key_from_pem!(PKey, ffi::PEM_read_bio_PUBKEY); /// Deserializes a DER-formatted PKCS#8 private key, using a callback to retrieve the password /// if the key is encrpyted. /// /// The callback should copy the password into the provided buffer and return the number of /// bytes written. pub fn private_key_from_pkcs8_callback<F>(der: &[u8], callback: F) -> Result<PKey, ErrorStack> where F: FnOnce(&mut [u8]) -> Result<usize, ErrorStack> { unsafe { ffi::init(); let mut cb = CallbackState::new(callback); let bio = try!(MemBioSlice::new(der)); cvt_p(ffi::d2i_PKCS8PrivateKey_bio(bio.as_ptr(), ptr::null_mut(), Some(invoke_passwd_cb::<F>), &mut cb as *mut _ as *mut _)) .map(PKey) } } /// Deserializes a DER-formatted PKCS#8 private key, using the supplied password if the key is /// encrypted. /// /// # Panics /// /// Panics if `passphrase` contains an embedded null. pub fn private_key_from_pkcs8_passphrase(der: &[u8], passphrase: &[u8]) -> Result<PKey, ErrorStack> { unsafe { ffi::init(); let bio = try!(MemBioSlice::new(der)); let passphrase = CString::new(passphrase).unwrap(); cvt_p(ffi::d2i_PKCS8PrivateKey_bio(bio.as_ptr(), ptr::null_mut(), None, passphrase.as_ptr() as *const _ as *mut _)) .map(PKey) } } #[deprecated(since = "0.9.2", note = "use private_key_from_pem_callback")] pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<PKey, ErrorStack> where F: FnOnce(&mut [c_char]) -> usize Loading Loading @@ -200,6 +242,25 @@ mod tests { assert!(PKey::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err()); } #[test] fn test_encrypted_pkcs8_passphrase() { let key = include_bytes!("../test/pkcs8.der"); PKey::private_key_from_pkcs8_passphrase(key, b"mypass").unwrap(); } #[test] fn test_encrypted_pkcs8_callback() { let mut password_queried = false; let key = include_bytes!("../test/pkcs8.der"); PKey::private_key_from_pkcs8_callback(key, |password| { password_queried = true; password[..6].copy_from_slice(b"mypass"); Ok(6) }) .unwrap(); assert!(password_queried); } #[test] fn test_private_key_from_pem() { let key = include_bytes!("../test/key.pem"); Loading