parent
06065ddcee
commit
19f3b8a11a
|
|
@ -1639,7 +1639,7 @@ extern {
|
||||||
e: *mut ENGINE,
|
e: *mut ENGINE,
|
||||||
key: *const c_uchar,
|
key: *const c_uchar,
|
||||||
keylen: c_int) -> *mut EVP_PKEY;
|
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;
|
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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use libc::{c_void, c_char, c_int};
|
use libc::{c_void, c_char, c_int};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::ffi::CString;
|
||||||
use ffi;
|
use ffi;
|
||||||
use foreign_types::{Opaque, ForeignType, ForeignTypeRef};
|
use foreign_types::{Opaque, ForeignType, ForeignTypeRef};
|
||||||
|
|
||||||
|
|
@ -11,7 +12,7 @@ use dsa::Dsa;
|
||||||
use ec::EcKey;
|
use ec::EcKey;
|
||||||
use rsa::{Rsa, Padding};
|
use rsa::{Rsa, Padding};
|
||||||
use error::ErrorStack;
|
use error::ErrorStack;
|
||||||
use util::{CallbackState, invoke_passwd_cb_old};
|
use util::{CallbackState, invoke_passwd_cb, invoke_passwd_cb_old};
|
||||||
|
|
||||||
foreign_type! {
|
foreign_type! {
|
||||||
type CType = ffi::EVP_PKEY;
|
type CType = ffi::EVP_PKEY;
|
||||||
|
|
@ -140,6 +141,47 @@ impl PKey {
|
||||||
private_key_from_pem!(PKey, ffi::PEM_read_bio_PrivateKey);
|
private_key_from_pem!(PKey, ffi::PEM_read_bio_PrivateKey);
|
||||||
public_key_from_pem!(PKey, ffi::PEM_read_bio_PUBKEY);
|
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")]
|
#[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>
|
pub fn private_key_from_pem_cb<F>(buf: &[u8], pass_cb: F) -> Result<PKey, ErrorStack>
|
||||||
where F: FnOnce(&mut [c_char]) -> usize
|
where F: FnOnce(&mut [c_char]) -> usize
|
||||||
|
|
@ -200,6 +242,25 @@ mod tests {
|
||||||
assert!(PKey::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
|
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]
|
#[test]
|
||||||
fn test_private_key_from_pem() {
|
fn test_private_key_from_pem() {
|
||||||
let key = include_bytes!("../test/key.pem");
|
let key = include_bytes!("../test/key.pem");
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in New Issue