Support serialization of encrypted private keys
Switch to PEM_write_bio_PKCS8PrivateKey since the other function outputs nonstandard PEM when encrypting.
This commit is contained in:
parent
7d411c7975
commit
387e78257b
|
|
@ -1496,6 +1496,10 @@ extern {
|
|||
kstr: *mut c_uchar, klen: c_int,
|
||||
callback: Option<PasswordCallback>,
|
||||
user_data: *mut c_void) -> c_int;
|
||||
pub fn PEM_write_bio_PKCS8PrivateKey(bio: *mut BIO, pkey: *mut EVP_PKEY, cipher: *const EVP_CIPHER,
|
||||
kstr: *mut c_char, klen: c_int,
|
||||
callback: Option<PasswordCallback>,
|
||||
user_data: *mut c_void) -> c_int;
|
||||
pub fn PEM_write_bio_PUBKEY(bp: *mut BIO, x: *mut EVP_PKEY) -> c_int;
|
||||
pub fn PEM_write_bio_RSAPrivateKey(bp: *mut BIO, rsa: *mut RSA, cipher: *const EVP_CIPHER,
|
||||
kstr: *mut c_uchar, klen: c_int,
|
||||
|
|
|
|||
|
|
@ -207,6 +207,8 @@ mod compat {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use symm::Cipher;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
|
@ -220,6 +222,14 @@ mod test {
|
|||
Dsa::private_key_from_pem_passphrase(key, b"mypass").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_password() {
|
||||
let key = Dsa::generate(2048).unwrap();
|
||||
let pem = key.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar").unwrap();
|
||||
Dsa::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
|
||||
assert!(Dsa::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_password_callback() {
|
||||
let mut password_queried = false;
|
||||
|
|
|
|||
|
|
@ -113,5 +113,25 @@ macro_rules! private_key_to_pem {
|
|||
Ok(bio.get_buf().to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
/// Serializes the private key to PEM, encrypting it with the specified symmetric cipher and
|
||||
/// passphrase.
|
||||
pub fn private_key_to_pem_passphrase(&self,
|
||||
cipher: ::symm::Cipher,
|
||||
passphrase: &[u8])
|
||||
-> Result<Vec<u8>, ::error::ErrorStack> {
|
||||
unsafe {
|
||||
let bio = try!(::bio::MemBio::new());
|
||||
assert!(passphrase.len() <= ::libc::c_int::max_value() as usize);
|
||||
try!(cvt($f(bio.as_ptr(),
|
||||
self.as_ptr(),
|
||||
cipher.as_ptr(),
|
||||
passphrase.as_ptr() as *const _ as *mut _,
|
||||
passphrase.len() as ::libc::c_int,
|
||||
None,
|
||||
ptr::null_mut())));
|
||||
Ok(bio.get_buf().to_owned())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ impl PKeyRef {
|
|||
}
|
||||
}
|
||||
|
||||
private_key_to_pem!(ffi::PEM_write_bio_PrivateKey);
|
||||
private_key_to_pem!(ffi::PEM_write_bio_PKCS8PrivateKey);
|
||||
|
||||
/// Encodes the public key in the PEM format.
|
||||
pub fn public_key_to_pem(&self) -> Result<Vec<u8>, ErrorStack> {
|
||||
|
|
@ -185,6 +185,7 @@ impl PKey {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use symm::Cipher;
|
||||
use dh::Dh;
|
||||
use dsa::Dsa;
|
||||
use ec_key::EcKey;
|
||||
|
|
@ -193,6 +194,15 @@ mod tests {
|
|||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_to_password() {
|
||||
let rsa = Rsa::generate(2048).unwrap();
|
||||
let pkey = PKey::from_rsa(rsa).unwrap();
|
||||
let pem = pkey.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar").unwrap();
|
||||
PKey::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
|
||||
assert!(PKey::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_private_key_from_pem() {
|
||||
let key = include_bytes!("../test/key.pem");
|
||||
|
|
|
|||
|
|
@ -404,16 +404,18 @@ mod compat {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use symm::Cipher;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
pub fn test_password() {
|
||||
fn test_from_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() {
|
||||
fn test_from_password_callback() {
|
||||
let mut password_queried = false;
|
||||
let key = include_bytes!("../test/rsa-encrypted.pem");
|
||||
Rsa::private_key_from_pem_callback(key, |password| {
|
||||
|
|
@ -427,7 +429,15 @@ mod test {
|
|||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_public_encrypt_private_decrypt_with_padding() {
|
||||
fn test_to_password() {
|
||||
let key = Rsa::generate(2048).unwrap();
|
||||
let pem = key.private_key_to_pem_passphrase(Cipher::aes_128_cbc(), b"foobar").unwrap();
|
||||
Rsa::private_key_from_pem_passphrase(&pem, b"foobar").unwrap();
|
||||
assert!(Rsa::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_public_encrypt_private_decrypt_with_padding() {
|
||||
let key = include_bytes!("../test/rsa.pem.pub");
|
||||
let public_key = Rsa::public_key_from_pem(key).unwrap();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue