From a7fa260331f856e45a4bb9c4eff78ed17a1cb595 Mon Sep 17 00:00:00 2001 From: oberien Date: Sun, 1 Dec 2019 03:02:01 +0100 Subject: [PATCH] Support for PKCS#8 unencrypted private key deserialization --- openssl-sys/src/ossl_typ.rs | 2 ++ openssl-sys/src/pem.rs | 7 +++++++ openssl/src/pkey.rs | 25 +++++++++++++++++++++++++ openssl/test/pkcs8-nocrypt.der | Bin 0 -> 1216 bytes 4 files changed, 34 insertions(+) create mode 100644 openssl/test/pkcs8-nocrypt.der 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 0000000000000000000000000000000000000000..04fbdc208af21bef611cba201f4352939e934d5f GIT binary patch literal 1216 zcmV;x1V8&Qf&{z*0RS)!1_>&LNQUrrZ9p8q5=T`0)hbn0JtfNIjnox z>EEI=Ze~SK13M49-d&$kBOt<3&9k9a0P|d7N?y+QwntJ~9B&0j9K}X56I#~`3NM1` zijm?B8cr@(UH_HUVDw8UKFe%}zZ`8voa9cbWO`B4X0zc;_5jB5^nlh$(JX$y;o2(q z%r;kpWn6ZxR=C43P$<%a6aTylIIYlH zhcB!{Yo7-WBc(6KT}xXyvxYeb6r3uxVF*<}4-Z5N*0e}X8f+$AR)gdZ?W4zYuw9lm zSh=iB-Z)+y6lK>35p3;F8hN;}epWBQA~<#Eeo1Cgwf}=orERjV>$m_Hn4n!7Ga^oHlPN2+)Wr>;42PUb?>=NZxT zjeQ+;^D^lSC6so=(5n9(`d+IpogQhjuA#=TKg4%ZDJKsLa?P%7#3uv|XGf%28;4EG zp;}ZrpH;4Krr$*(Y9$!2dkRNnV5OqRE#Z?q3Yt@UyvBy52{NbFmJ?|eJ73|F>V;%b zWxsBqMJ3XcJ3wO2l@A$id$Lr0*qOrPDs9Xgs;(eHR?(_TGi**ozq0w%v3UZ4fdKFE zveNS_lp3vd%z!GG%VE%FAzev9(3r;{A5xXenPm5xG2r@HAl{;ySHN%BD<%DI@()eL z^tlPheDzjClo_OydkeitoRkL);!+EoaPZ zJ+@;XDQT4sA^nFGyponqwQrPEs?P#}fdIsONX~`2n}Z|Z(C&M?C3rht`CT{`s8~O> zuUoHbN)KdM4}5MGc9E!iC~D|pf#OXB5sJo(N(ze>e}LryvX~}JjUD*-}fV3oPy_GH~yRDej;@2z*qw38D?fIoHY5+%*D$ zfNQ)6VDnN_(~hFw$%IzQs|J~L&7c798cF^@QX+IBQPpDPmT{5iQcsK_ZiGpBMmv7L zEaU9RF7+3Z6V5@^lbty!j0B{>y!09tj(I{jI3{SVt5);2^^l3EH(Azz%O^ix9`{ z0)c=KT!UxWihsu=KAC|eAa=48mnzoE1hwL6PR+@+7KI_sl8v6FPRO{OT18S!El|Q8 zC5FznQMucjl~-%Zev#MtzV7D{ycin(H79?PT%WmuOozLSGRkfm5L<2yT;?3~(q^k< e{i>d=u^m@tp6-Ai2kOFUIU(JPR;qtZnHmW{L`6ve literal 0 HcmV?d00001