diff --git a/openssl-sys/src/ossl_typ.rs b/openssl-sys/src/ossl_typ.rs index adf72684..fa6eb1ba 100644 --- a/openssl-sys/src/ossl_typ.rs +++ b/openssl-sys/src/ossl_typ.rs @@ -123,6 +123,8 @@ cfg_if! { } } +pub enum PKCS8_PRIV_KEY_INFO {} + pub enum EVP_PKEY_ASN1_METHOD {} pub enum EVP_PKEY_CTX {} diff --git a/openssl-sys/src/pem.rs b/openssl-sys/src/pem.rs index 64703377..d6a76f05 100644 --- a/openssl-sys/src/pem.rs +++ b/openssl-sys/src/pem.rs @@ -137,6 +137,13 @@ extern "C" { cb: pem_password_cb, u: *mut c_void, ) -> *mut EVP_PKEY; + pub fn d2i_PKCS8_PRIV_KEY_INFO_bio( + bp: *mut BIO, + x: *mut *mut PKCS8_PRIV_KEY_INFO, + ) -> *mut PKCS8_PRIV_KEY_INFO; + pub fn EVP_PKCS82PKEY( + p8: *const PKCS8_PRIV_KEY_INFO, + ) -> *mut EVP_PKEY; pub fn PEM_read_bio_PKCS7( bio: *mut BIO, diff --git a/openssl/src/pkey.rs b/openssl/src/pkey.rs index f1ab1e2e..bcbfc385 100644 --- a/openssl/src/pkey.rs +++ b/openssl/src/pkey.rs @@ -524,6 +524,25 @@ impl PKey { ffi::d2i_AutoPrivateKey } + /// Deserializes a DER-formatted PKCS#8 unencrypted private key. + /// + /// This method is mainly for interoperability reasons. Encrypted keyfiles should be preferred. + pub fn private_key_from_pkcs8( + der: &[u8], + ) -> Result, ErrorStack> + { + unsafe { + ffi::init(); + let bio = MemBioSlice::new(der)?; + let p8inf = cvt_p(ffi::d2i_PKCS8_PRIV_KEY_INFO_bio( + bio.as_ptr(), + ptr::null_mut(), + ))?; + cvt_p(ffi::EVP_PKCS82PKEY(p8inf)) + .map(|p| PKey::from_ptr(p)) + } + } + /// Deserializes a DER-formatted PKCS#8 private key, using a callback to retrieve the password /// if the key is encrpyted. /// @@ -639,6 +658,12 @@ mod tests { assert!(PKey::private_key_from_pem_passphrase(&pem, b"fizzbuzz").is_err()); } + #[test] + fn test_unencrypted_pkcs8() { + let key = include_bytes!("../test/pkcs8-nocrypt.der"); + PKey::private_key_from_pkcs8(key).unwrap(); + } + #[test] fn test_encrypted_pkcs8_passphrase() { let key = include_bytes!("../test/pkcs8.der"); diff --git a/openssl/test/pkcs8-nocrypt.der b/openssl/test/pkcs8-nocrypt.der new file mode 100644 index 00000000..04fbdc20 Binary files /dev/null and b/openssl/test/pkcs8-nocrypt.der differ