Unverified Commit a99fb686 authored by Steven Fackler's avatar Steven Fackler Committed by GitHub
Browse files

Merge pull request #1494 from sven-hm/add_private_key_to_pkcs8_passphrase

Add private key to pkcs8 passphrase
parents 10894d31 7a7fb8f5
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -66,6 +66,15 @@ const_ptr_api! {
        ) -> c_int;
        pub fn PEM_write_bio_PKCS7(bp: *mut BIO, x: #[const_ptr_if(ossl300)] PKCS7) -> c_int;
        pub fn PEM_write_bio_EC_PUBKEY(bp: *mut BIO, ec: #[const_ptr_if(ossl300)] EC_KEY) -> c_int;
        pub fn i2d_PKCS8PrivateKey_bio(
            bp: *mut BIO,
            x: #[const_ptr_if(ossl300)] EVP_PKEY,
            enc: *const EVP_CIPHER,
            kstr: #[const_ptr_if(ossl300)] c_char,
            klen: c_int,
            cb: pem_password_cb,
            u: *mut c_void,
        ) -> c_int;
    }
}

+41 −2
Original line number Diff line number Diff line
@@ -49,13 +49,12 @@ use std::fmt;
use std::mem;
use std::ptr;

use crate::bio::MemBioSlice;
use crate::bio::{MemBio, MemBioSlice};
use crate::dh::Dh;
use crate::dsa::Dsa;
use crate::ec::EcKey;
use crate::error::ErrorStack;
use crate::rsa::Rsa;
#[cfg(ossl110)]
use crate::symm::Cipher;
use crate::util::{invoke_passwd_cb, CallbackState};
use crate::{cvt, cvt_p};
@@ -684,6 +683,35 @@ impl PKey<Private> {
        }
    }

    /// Serializes a private key into a DER-formatted PKCS#8, using the supplied password to
    /// encrypt the key.
    ///
    /// # Panics
    ///
    /// Panics if `passphrase` contains an embedded null.
    pub fn private_key_to_pkcs8_passphrase(
        &self,
        cipher: Cipher,
        passphrase: &[u8],
    ) -> Result<Vec<u8>, ErrorStack> {
        unsafe {
            let bio = MemBio::new()?;
            let len = passphrase.len();
            let passphrase = CString::new(passphrase).unwrap();
            cvt(ffi::i2d_PKCS8PrivateKey_bio(
                bio.as_ptr(),
                self.as_ptr(),
                cipher.as_ptr(),
                passphrase.as_ptr() as *const _ as *mut _,
                len as ::libc::c_int,
                None,
                ptr::null_mut(),
            ))?;

            Ok(bio.get_buf().to_owned())
        }
    }

    /// Creates a private key from its raw byte representation
    ///
    /// Algorithm types that support raw private keys are HMAC, X25519, ED25519, X448 or ED448
@@ -877,6 +905,17 @@ mod tests {
    fn test_encrypted_pkcs8_passphrase() {
        let key = include_bytes!("../test/pkcs8.der");
        PKey::private_key_from_pkcs8_passphrase(key, b"mypass").unwrap();

        let rsa = Rsa::generate(2048).unwrap();
        let pkey = PKey::from_rsa(rsa).unwrap();
        let der = pkey
            .private_key_to_pkcs8_passphrase(Cipher::aes_128_cbc(), b"mypass")
            .unwrap();
        let pkey2 = PKey::private_key_from_pkcs8_passphrase(&der, b"mypass").unwrap();
        assert_eq!(
            pkey.private_key_to_der().unwrap(),
            pkey2.private_key_to_der().unwrap()
        );
    }

    #[test]
+1 −0
Original line number Diff line number Diff line
@@ -109,6 +109,7 @@ fn main() {
            s.starts_with("PEM_read_bio_") ||
            (s.starts_with("PEM_write_bio_") && s.ends_with("PrivateKey")) ||
            s == "d2i_PKCS8PrivateKey_bio" ||
            s == "i2d_PKCS8PrivateKey_bio" ||
            s == "SSL_get_ex_new_index" ||
            s == "SSL_CTX_get_ex_new_index" ||
            s == "CRYPTO_get_ex_new_index"