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;
|
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" {
|
extern "C" {
|
||||||
pub fn EVP_EncodeBlock(dst: *mut c_uchar, src: *const c_uchar, src_len: c_int) -> c_int;
|
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;
|
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_ASN1_METHOD {}
|
||||||
|
|
||||||
pub enum EVP_PKEY_CTX {}
|
pub enum EVP_PKEY_CTX {}
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,14 @@ extern "C" {
|
||||||
cb: pem_password_cb,
|
cb: pem_password_cb,
|
||||||
u: *mut c_void,
|
u: *mut c_void,
|
||||||
) -> *mut EVP_PKEY;
|
) -> *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(
|
pub fn PEM_read_bio_PKCS7(
|
||||||
bio: *mut BIO,
|
bio: *mut BIO,
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
|
|
||||||
use ffi;
|
use ffi;
|
||||||
use foreign_types::{ForeignType, ForeignTypeRef};
|
use foreign_types::{ForeignType, ForeignTypeRef};
|
||||||
use libc::c_int;
|
use libc::{c_int, c_long};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
@ -524,6 +524,28 @@ impl PKey<Private> {
|
||||||
ffi::d2i_AutoPrivateKey
|
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
|
/// Deserializes a DER-formatted PKCS#8 private key, using a callback to retrieve the password
|
||||||
/// if the key is encrpyted.
|
/// if the key is encrpyted.
|
||||||
///
|
///
|
||||||
|
|
@ -639,6 +661,12 @@ 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_unencrypted_pkcs8() {
|
||||||
|
let key = include_bytes!("../test/pkcs8-nocrypt.der");
|
||||||
|
PKey::private_key_from_pkcs8(key).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_encrypted_pkcs8_passphrase() {
|
fn test_encrypted_pkcs8_passphrase() {
|
||||||
let key = include_bytes!("../test/pkcs8.der");
|
let key = include_bytes!("../test/pkcs8.der");
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in New Issue