From 4f5f0d4eab259654c5e26077560c773cd8c6ce57 Mon Sep 17 00:00:00 2001 From: Anatoly Ikorsky Date: Thu, 9 May 2024 11:15:02 +0300 Subject: [PATCH] rustls: add pkcs8 and sec1 keys support --- src/conn/opts/rustls_opts.rs | 81 ++++++++++++++++++++++++++++++++--- tests/client-key.der | Bin 0 -> 1190 bytes tests/client-key.pkcs8.der | Bin 0 -> 1216 bytes tests/client-key.pkcs8.pem | 28 ++++++++++++ 4 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 tests/client-key.der create mode 100644 tests/client-key.pkcs8.der create mode 100644 tests/client-key.pkcs8.pem diff --git a/src/conn/opts/rustls_opts.rs b/src/conn/opts/rustls_opts.rs index f741230..95f2fc4 100644 --- a/src/conn/opts/rustls_opts.rs +++ b/src/conn/opts/rustls_opts.rs @@ -1,7 +1,7 @@ #![cfg(feature = "rustls-tls")] use rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs1KeyDer}; -use rustls_pemfile::{certs, rsa_private_keys}; +use rustls_pemfile::{certs, ec_private_keys, pkcs8_private_keys, rsa_private_keys}; use std::{borrow::Cow, path::Path}; @@ -70,13 +70,84 @@ impl ClientIdentity { } let mut priv_key = None; - for key in rsa_private_keys(&mut &*key_data).into_iter().take(1) { + + for key in rsa_private_keys(&mut &*key_data).take(1) { priv_key = Some(PrivateKeyDer::Pkcs1(key?.clone_key())); } - let priv_key = - priv_key.unwrap_or_else(|| PrivateKeyDer::Pkcs1(PrivatePkcs1KeyDer::from(key_data))); + if priv_key.is_none() { + for key in pkcs8_private_keys(&mut &*key_data).take(1) { + priv_key = Some(PrivateKeyDer::Pkcs8(key?.clone_key())) + } + } + + if priv_key.is_none() { + for key in ec_private_keys(&mut &*key_data).take(1) { + priv_key = Some(PrivateKeyDer::Sec1(key?.clone_key())) + } + } + + if let Some(priv_key) = priv_key { + return Ok((cert_chain, dbg!(priv_key))); + } + + match PrivateKeyDer::try_from(key_data.as_slice()) { + Ok(key) => Ok((cert_chain, key.clone_key())), + Err(_) => Ok(( + cert_chain, + PrivateKeyDer::Pkcs1(PrivatePkcs1KeyDer::from(key_data)), + )), + } + } +} + +#[cfg(test)] +mod tests { + use std::path::Path; + + use rustls::pki_types::PrivateKeyDer; + + use crate::ClientIdentity; + + #[test] + fn load_pkcs1() { + let (_certs, key_pem) = ClientIdentity::new( + Path::new("tests/client.crt"), + Path::new("tests/client-key.pem"), + ) + .load() + .unwrap(); + assert!(matches!(key_pem, PrivateKeyDer::Pkcs1(_))); + + let (_certs, key_der) = ClientIdentity::new( + Path::new("tests/client.crt"), + Path::new("tests/client-key.pem"), + ) + .load() + .unwrap(); + assert!(matches!(key_der, PrivateKeyDer::Pkcs1(_))); + + assert_eq!(key_der, key_pem); + } + + #[test] + fn load_pkcs8() { + let (_certs, key_der) = ClientIdentity::new( + Path::new("tests/client.crt"), + Path::new("tests/client-key.pkcs8.der"), + ) + .load() + .unwrap(); + assert!(matches!(key_der, PrivateKeyDer::Pkcs8(_))); + + let (_certs, key_pem) = ClientIdentity::new( + Path::new("tests/client.crt"), + Path::new("tests/client-key.pkcs8.pem"), + ) + .load() + .unwrap(); + assert!(matches!(key_pem, PrivateKeyDer::Pkcs8(_))); - Ok((cert_chain, priv_key)) + assert_eq!(key_der, key_pem); } } diff --git a/tests/client-key.der b/tests/client-key.der new file mode 100644 index 0000000000000000000000000000000000000000..c9c1be64ea8f0c84a3074b0f90e4087ef732c1f4 GIT binary patch literal 1190 zcmV;X1X=qqf&`)h0RRGm0RaG@aD?)lAO`!L3ytLubN)fPr5~<~t~T{BpDU3sxFms6 zXreDyeTO0C#)eJkX%2!KkA(7cqE3VO?$1WN**xe0g)W=SZ3R-6Bk`0$tC}TTKP;@6 zFGZMkgj=r{K%|Vu+#lofLkn0eBMH;uH|ES=6)mLD2(bMq`u?N*8b)2*9KFxhqbGvv zSg>iVmXH@0K!B6`P7%1=LK7^TDY&D^yybPsc2-ZHQW|7YBcw+K7%LX%KoMR zyaO~AIeEf2)kJEjIWu$4EM{z?>U0Nf^8DADpb(hMzJsN>3ubHj3J~V5W>@3`=?O}YfvrOywSLiBDdF zw<=f$Jc|ar@iaC~gAntP2R+{-PI+|{3WGGfJw1+h4|o}JsKgsqDe$j)^UYiXsEDYI zI5DEHOvxRZ{j!jgFL-SW+|r||27j|g)i1eitl^P{e?V3sWtvGkDbj~E>giGoD0|gq z6jXxg*p?sza$xbk7Kb0FAsw5JhZDYPCb&4W;fc9e#tAVPUqs{-B7KPn@Yh^l#3 zHyMbK(M7q1vO`oJ>R*3pIB#BqA&{hs;xuwQh^ZT$g}m1XLjZq4*l1V8(g1RKlzAX~TrHRBH&YmY{;D()oJ= zfq)<{1y9k1{W#g>)n#*N3-@LS%x+rjILQ!s${v2o{L6!kKFF_fETwne*8sqDB?!y| z(u*GA;!4tt66#*PUVotiP8*caC(2nzjwGY`rwP?_666u}`~?A*nd+RDTv&LNQUrrZ9p8q5=T`0)hbn0HAP$@|++B z`<)Aox zM!eZP=mCW;o6KzmQkEm}ltHVSC0su&te7uFn0AC)uNOe1jK31UECbK&(@=*qZmXXI3_Ile zxa~R#mh?nLUkuV2$GB#_6a7r(9&d?HUV^tOSOz?c2E6e!Hcf*N^N|NV-y=?WbrcGN zG`u}Mj&~1u8FHw^8&)asuX^*%Tmz_xsEs%=qOVNJ9h&{JkdrTXZ42Deqp1devqse~ zxoxcBk%oUjRv=}XNjfRghc)WyQVS@1)nyb^g6Y_nAOmt>@xJ4c*%_NEUeu~cecalg z))cjQBx|&|kb1N>^BBclpr3KT_evQIV4U*Q~%UOVj1PcPO@xTsv*qT+KP*mSg~5nw5_ z9x2U(P=|JuhNU1vd049g-OxWOBbA7%c~&+1mxrMSrR37SIe`z>xUV|Z!q>AD+ zayy8r8=Zx`*DrT6=2bgHIO>fj2 zD2}xMQ@8+-5i7dqcATIG?vAW17i^j;2v7f#;n5!q(>`I8uLM}S4!Y;nc~u)EUPg*Z zXIieJ$Ab+}8!GiSImVI!DQJka8RChc|EbH_kIj^DN`j;aTl!I@pW{B~tWvk83r<@)T{~vy%*dso60+)&d?}&$ z8lhmud9_r+tMO^WgtSy^2(Ol)f~eB@djf%gATI?^(S`ju+2z$`b7%|qW(dq~TI@K< z5P8ZTe#-pIgN#1NuW~Gf{2g-Fjq-C2&XL!nw;0%eQyM9XmdY@LYT{Xii5_=nnJNH))(RKtcAs?sZK^N` z)NPdkjT90~W@@iVyS1+4_DgLUePC6ab%hYrse_0d!9SSN(0pEh0hl(1q5apMa1y-!R_rc&KD_?*)asg?|h|HA40P literal 0 HcmV?d00001 diff --git a/tests/client-key.pkcs8.pem b/tests/client-key.pkcs8.pem new file mode 100644 index 0000000..ae6ec02 --- /dev/null +++ b/tests/client-key.pkcs8.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCgcITynCAG+50L +jeUPc/5BuqUfrouuNvUwnyuRL7gkgVJooi9XfYch5caGTehpDoIaj4TydKJOg/ju +z0a82TzoAYUum8xtBVKWI/GUQauaJVw/LKyYL0WYdoRbrxdApIzG3B/j80MLWCwj +CdPiN+bMXxUtpNAIsP0o+v6j/BpGXdwcvc/WoyeC61iwaayWljlf1Fb0LQDCQ//5 +1Jea5wVbsFq4r5/06Vc4qWhkrDXcFjRqNPevPoMn4sr+pgC8AzQWOXnCN9VEaqg5 +M3POLGZsoup0B23y/NeaoBCYzL6DpbgLZmv6ChDmrmY+u89JxLi67CItvukJSo+B +r32vKJCLAgMBAAECggEAYlx5dY/4Jq/N2U6V90JiyANYxrKpGhbBfZyoBiveVise +zd1Y7uebmFGZw68x5G6rnwMMO+T7uO06CZb0REVfDNIZx7hmvRP9TOUeb4lPXoK3 +KlgGPIsGvPE0Nk2DEPORBz3fI055dRQKgzS8PT2Odw94GXKoxBtWKfCvevPNXAOo +iKiNODGir0zJHZr9spCTL3htC9zSo6kGf7NG1S+5bazhkYZ/QFYgZZpJOinShzXq +6VILKHvVZRRUgunYliADcmDxvuOR2RmbKl7Uqkh93Nqf1hS1eSRrtLiQesSztbwr +7IdGQMJ46SxC7HuVuQfVu2/GK4SJHQJSKDRvryIGeQKBgQDSdl7wj1byAD9G6jrF +yiOjCmQKFEVvsk81zF/hHI5eO+zPTy/WTbioXNyi4nMg2HS0pxFgKbQeKc2DUId2 +lIalIEJ5WKsC3dA/KiOViKp5VjcZiJDRRbmFskNUHupff2k4b16DIZCkiuI0cjuI +qRudhbzXL3cy5lU7RDqwhkWKxwKBgQDDJ1q85KlfqiP4yF4x90TFfsXim+8yTW/U +GyiOtP9TuACQESu653acoAfujqwsF2yaKghP/5Lh0R8M0z5hlK8EWLoOuufVeVUb +JF5GiklnWq6ix4MNUBsq9TY5xpIBKWiItBniiaD/qcvZj82UcEqCpAhb+lGln+M+ +56xSwOFoHQKBgE5nuMDHta1cODaUBicvQg14ToKOwLt24xl4tPNpLwSeMH+e0YR1 +2egnCC9KS3eeDARNBSUdBDQEgMJ92qlrdanIldsdFEByICWX7j/D9TZUzxwdC05b +Ol07ZufMyKWhErLqknwpofgaoWDGebVUwqvxacOEtFRrCK+WoIKo0vl7AoGAIC8F +T9GF/TjZ5dVlc2gL92YIzG5a7DjJEHnKHn7K/MuDjD7Ir3IspXfe1wDAdCUIzAPS +ix7i4krSjBLqXr1ef6ECThuU0CfKWUeOJKP5pwnVcxLkEfX8BQGbh7uvqHFjw+ev +vSRlYMRn0eFdTfWW1CSpHEIT5PSRTXZ3fM5CXiECgYB6/B1y143ycw7OkdejtxjY +f1MaKYqWyjCDauJZhYked2eZKgCA1goX6XafdQBtqjAI1G2VAY0UEktmaq9Ju7Wu +4/ZLbRl9YFWbdYUQ1KmDiBzBP5jS0HxenauNB/EXMhjkYvOEg+rt4CDQhdahn4CQ +Nt8w3vB4qGR07wWFu4V/DA== +-----END PRIVATE KEY-----