Merge pull request #1196 from oberien/private-key-from-pkcs8
Support for PKCS#8 unencrypted private key deserialization
This commit is contained in:
commit
9ccddf7abc
|
|
@ -405,6 +405,18 @@ extern "C" {
|
|||
pub fn EVP_PKEY_keygen(ctx: *mut EVP_PKEY_CTX, key: *mut *mut EVP_PKEY) -> c_int;
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(any(ossl110, libressl280))] {
|
||||
extern "C" {
|
||||
pub fn EVP_PKCS82PKEY(p8: *const PKCS8_PRIV_KEY_INFO) -> *mut EVP_PKEY;
|
||||
}
|
||||
} else {
|
||||
extern "C" {
|
||||
pub fn EVP_PKCS82PKEY(p8: *mut PKCS8_PRIV_KEY_INFO) -> *mut EVP_PKEY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn EVP_EncodeBlock(dst: *mut c_uchar, src: *const c_uchar, src_len: c_int) -> c_int;
|
||||
pub fn EVP_DecodeBlock(dst: *mut c_uchar, src: *const c_uchar, src_len: c_int) -> c_int;
|
||||
|
|
|
|||
|
|
@ -123,6 +123,8 @@ cfg_if! {
|
|||
}
|
||||
}
|
||||
|
||||
pub enum PKCS8_PRIV_KEY_INFO {}
|
||||
|
||||
pub enum EVP_PKEY_ASN1_METHOD {}
|
||||
|
||||
pub enum EVP_PKEY_CTX {}
|
||||
|
|
|
|||
|
|
@ -137,6 +137,14 @@ extern "C" {
|
|||
cb: pem_password_cb,
|
||||
u: *mut c_void,
|
||||
) -> *mut EVP_PKEY;
|
||||
pub fn d2i_PKCS8_PRIV_KEY_INFO(
|
||||
k: *mut *mut PKCS8_PRIV_KEY_INFO,
|
||||
buf: *mut *const u8,
|
||||
length: c_long,
|
||||
) -> *mut PKCS8_PRIV_KEY_INFO;
|
||||
pub fn PKCS8_PRIV_KEY_INFO_free(
|
||||
p8inf: *mut PKCS8_PRIV_KEY_INFO,
|
||||
);
|
||||
|
||||
pub fn PEM_read_bio_PKCS7(
|
||||
bio: *mut BIO,
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
use ffi;
|
||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||
use libc::c_int;
|
||||
use libc::{c_int, c_long};
|
||||
use std::ffi::CString;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
|
@ -524,6 +524,28 @@ impl PKey<Private> {
|
|||
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<PKey<Private>, ErrorStack>
|
||||
{
|
||||
unsafe {
|
||||
ffi::init();
|
||||
let len = der.len().min(c_long::max_value() as usize) as c_long;
|
||||
let p8inf = cvt_p(ffi::d2i_PKCS8_PRIV_KEY_INFO(
|
||||
ptr::null_mut(),
|
||||
&mut der.as_ptr(),
|
||||
len,
|
||||
))?;
|
||||
let res = cvt_p(ffi::EVP_PKCS82PKEY(p8inf))
|
||||
.map(|p| PKey::from_ptr(p));
|
||||
ffi::PKCS8_PRIV_KEY_INFO_free(p8inf);
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserializes a DER-formatted PKCS#8 private key, using a callback to retrieve the password
|
||||
/// if the key is encrpyted.
|
||||
///
|
||||
|
|
@ -639,6 +661,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");
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue