192f3ab15Sopenharmony_ci//! PKCS #12 archives. 292f3ab15Sopenharmony_ci 392f3ab15Sopenharmony_ciuse foreign_types::{ForeignType, ForeignTypeRef}; 492f3ab15Sopenharmony_ciuse libc::c_int; 592f3ab15Sopenharmony_ciuse std::ffi::CString; 692f3ab15Sopenharmony_ciuse std::ptr; 792f3ab15Sopenharmony_ci 892f3ab15Sopenharmony_ciuse crate::error::ErrorStack; 992f3ab15Sopenharmony_ci#[cfg(not(boringssl))] 1092f3ab15Sopenharmony_ciuse crate::hash::MessageDigest; 1192f3ab15Sopenharmony_ciuse crate::nid::Nid; 1292f3ab15Sopenharmony_ciuse crate::pkey::{HasPrivate, PKey, PKeyRef, Private}; 1392f3ab15Sopenharmony_ciuse crate::stack::Stack; 1492f3ab15Sopenharmony_ciuse crate::util::ForeignTypeExt; 1592f3ab15Sopenharmony_ciuse crate::x509::{X509Ref, X509}; 1692f3ab15Sopenharmony_ciuse crate::{cvt, cvt_p}; 1792f3ab15Sopenharmony_ciuse openssl_macros::corresponds; 1892f3ab15Sopenharmony_ci 1992f3ab15Sopenharmony_ciforeign_type_and_impl_send_sync! { 2092f3ab15Sopenharmony_ci type CType = ffi::PKCS12; 2192f3ab15Sopenharmony_ci fn drop = ffi::PKCS12_free; 2292f3ab15Sopenharmony_ci 2392f3ab15Sopenharmony_ci pub struct Pkcs12; 2492f3ab15Sopenharmony_ci pub struct Pkcs12Ref; 2592f3ab15Sopenharmony_ci} 2692f3ab15Sopenharmony_ci 2792f3ab15Sopenharmony_ciimpl Pkcs12Ref { 2892f3ab15Sopenharmony_ci to_der! { 2992f3ab15Sopenharmony_ci /// Serializes the `Pkcs12` to its standard DER encoding. 3092f3ab15Sopenharmony_ci #[corresponds(i2d_PKCS12)] 3192f3ab15Sopenharmony_ci to_der, 3292f3ab15Sopenharmony_ci ffi::i2d_PKCS12 3392f3ab15Sopenharmony_ci } 3492f3ab15Sopenharmony_ci 3592f3ab15Sopenharmony_ci /// Deprecated. 3692f3ab15Sopenharmony_ci #[deprecated(note = "Use parse2 instead", since = "0.10.46")] 3792f3ab15Sopenharmony_ci #[allow(deprecated)] 3892f3ab15Sopenharmony_ci pub fn parse(&self, pass: &str) -> Result<ParsedPkcs12, ErrorStack> { 3992f3ab15Sopenharmony_ci let parsed = self.parse2(pass)?; 4092f3ab15Sopenharmony_ci 4192f3ab15Sopenharmony_ci Ok(ParsedPkcs12 { 4292f3ab15Sopenharmony_ci pkey: parsed.pkey.unwrap(), 4392f3ab15Sopenharmony_ci cert: parsed.cert.unwrap(), 4492f3ab15Sopenharmony_ci chain: parsed.ca, 4592f3ab15Sopenharmony_ci }) 4692f3ab15Sopenharmony_ci } 4792f3ab15Sopenharmony_ci 4892f3ab15Sopenharmony_ci /// Extracts the contents of the `Pkcs12`. 4992f3ab15Sopenharmony_ci #[corresponds(PKCS12_parse)] 5092f3ab15Sopenharmony_ci pub fn parse2(&self, pass: &str) -> Result<ParsedPkcs12_2, ErrorStack> { 5192f3ab15Sopenharmony_ci unsafe { 5292f3ab15Sopenharmony_ci let pass = CString::new(pass.as_bytes()).unwrap(); 5392f3ab15Sopenharmony_ci 5492f3ab15Sopenharmony_ci let mut pkey = ptr::null_mut(); 5592f3ab15Sopenharmony_ci let mut cert = ptr::null_mut(); 5692f3ab15Sopenharmony_ci let mut ca = ptr::null_mut(); 5792f3ab15Sopenharmony_ci 5892f3ab15Sopenharmony_ci cvt(ffi::PKCS12_parse( 5992f3ab15Sopenharmony_ci self.as_ptr(), 6092f3ab15Sopenharmony_ci pass.as_ptr(), 6192f3ab15Sopenharmony_ci &mut pkey, 6292f3ab15Sopenharmony_ci &mut cert, 6392f3ab15Sopenharmony_ci &mut ca, 6492f3ab15Sopenharmony_ci ))?; 6592f3ab15Sopenharmony_ci 6692f3ab15Sopenharmony_ci let pkey = PKey::from_ptr_opt(pkey); 6792f3ab15Sopenharmony_ci let cert = X509::from_ptr_opt(cert); 6892f3ab15Sopenharmony_ci let ca = Stack::from_ptr_opt(ca); 6992f3ab15Sopenharmony_ci 7092f3ab15Sopenharmony_ci Ok(ParsedPkcs12_2 { pkey, cert, ca }) 7192f3ab15Sopenharmony_ci } 7292f3ab15Sopenharmony_ci } 7392f3ab15Sopenharmony_ci} 7492f3ab15Sopenharmony_ci 7592f3ab15Sopenharmony_ciimpl Pkcs12 { 7692f3ab15Sopenharmony_ci from_der! { 7792f3ab15Sopenharmony_ci /// Deserializes a DER-encoded PKCS#12 archive. 7892f3ab15Sopenharmony_ci #[corresponds(d2i_PKCS12)] 7992f3ab15Sopenharmony_ci from_der, 8092f3ab15Sopenharmony_ci Pkcs12, 8192f3ab15Sopenharmony_ci ffi::d2i_PKCS12 8292f3ab15Sopenharmony_ci } 8392f3ab15Sopenharmony_ci 8492f3ab15Sopenharmony_ci /// Creates a new builder for a protected pkcs12 certificate. 8592f3ab15Sopenharmony_ci /// 8692f3ab15Sopenharmony_ci /// This uses the defaults from the OpenSSL library: 8792f3ab15Sopenharmony_ci /// 8892f3ab15Sopenharmony_ci /// * `nid_key` - `AES_256_CBC` (3.0.0+) or `PBE_WITHSHA1AND3_KEY_TRIPLEDES_CBC` 8992f3ab15Sopenharmony_ci /// * `nid_cert` - `AES_256_CBC` (3.0.0+) or `PBE_WITHSHA1AND40BITRC2_CBC` 9092f3ab15Sopenharmony_ci /// * `iter` - `2048` 9192f3ab15Sopenharmony_ci /// * `mac_iter` - `2048` 9292f3ab15Sopenharmony_ci /// * `mac_md` - `SHA-256` (3.0.0+) or `SHA-1` (`SHA-1` only for BoringSSL) 9392f3ab15Sopenharmony_ci pub fn builder() -> Pkcs12Builder { 9492f3ab15Sopenharmony_ci ffi::init(); 9592f3ab15Sopenharmony_ci 9692f3ab15Sopenharmony_ci Pkcs12Builder { 9792f3ab15Sopenharmony_ci name: None, 9892f3ab15Sopenharmony_ci pkey: None, 9992f3ab15Sopenharmony_ci cert: None, 10092f3ab15Sopenharmony_ci ca: None, 10192f3ab15Sopenharmony_ci nid_key: Nid::UNDEF, 10292f3ab15Sopenharmony_ci nid_cert: Nid::UNDEF, 10392f3ab15Sopenharmony_ci iter: ffi::PKCS12_DEFAULT_ITER, 10492f3ab15Sopenharmony_ci mac_iter: ffi::PKCS12_DEFAULT_ITER, 10592f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 10692f3ab15Sopenharmony_ci mac_md: None, 10792f3ab15Sopenharmony_ci } 10892f3ab15Sopenharmony_ci } 10992f3ab15Sopenharmony_ci} 11092f3ab15Sopenharmony_ci 11192f3ab15Sopenharmony_ci#[deprecated(note = "Use ParsedPkcs12_2 instead", since = "0.10.46")] 11292f3ab15Sopenharmony_cipub struct ParsedPkcs12 { 11392f3ab15Sopenharmony_ci pub pkey: PKey<Private>, 11492f3ab15Sopenharmony_ci pub cert: X509, 11592f3ab15Sopenharmony_ci pub chain: Option<Stack<X509>>, 11692f3ab15Sopenharmony_ci} 11792f3ab15Sopenharmony_ci 11892f3ab15Sopenharmony_cipub struct ParsedPkcs12_2 { 11992f3ab15Sopenharmony_ci pub pkey: Option<PKey<Private>>, 12092f3ab15Sopenharmony_ci pub cert: Option<X509>, 12192f3ab15Sopenharmony_ci pub ca: Option<Stack<X509>>, 12292f3ab15Sopenharmony_ci} 12392f3ab15Sopenharmony_ci 12492f3ab15Sopenharmony_cipub struct Pkcs12Builder { 12592f3ab15Sopenharmony_ci // FIXME borrow 12692f3ab15Sopenharmony_ci name: Option<CString>, 12792f3ab15Sopenharmony_ci pkey: Option<PKey<Private>>, 12892f3ab15Sopenharmony_ci cert: Option<X509>, 12992f3ab15Sopenharmony_ci ca: Option<Stack<X509>>, 13092f3ab15Sopenharmony_ci nid_key: Nid, 13192f3ab15Sopenharmony_ci nid_cert: Nid, 13292f3ab15Sopenharmony_ci iter: c_int, 13392f3ab15Sopenharmony_ci mac_iter: c_int, 13492f3ab15Sopenharmony_ci // FIXME remove 13592f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 13692f3ab15Sopenharmony_ci mac_md: Option<MessageDigest>, 13792f3ab15Sopenharmony_ci} 13892f3ab15Sopenharmony_ci 13992f3ab15Sopenharmony_ciimpl Pkcs12Builder { 14092f3ab15Sopenharmony_ci /// The `friendlyName` used for the certificate and private key. 14192f3ab15Sopenharmony_ci pub fn name(&mut self, name: &str) -> &mut Self { 14292f3ab15Sopenharmony_ci self.name = Some(CString::new(name).unwrap()); 14392f3ab15Sopenharmony_ci self 14492f3ab15Sopenharmony_ci } 14592f3ab15Sopenharmony_ci 14692f3ab15Sopenharmony_ci /// The private key. 14792f3ab15Sopenharmony_ci pub fn pkey<T>(&mut self, pkey: &PKeyRef<T>) -> &mut Self 14892f3ab15Sopenharmony_ci where 14992f3ab15Sopenharmony_ci T: HasPrivate, 15092f3ab15Sopenharmony_ci { 15192f3ab15Sopenharmony_ci let new_pkey = unsafe { PKeyRef::from_ptr(pkey.as_ptr()) }; 15292f3ab15Sopenharmony_ci self.pkey = Some(new_pkey.to_owned()); 15392f3ab15Sopenharmony_ci self 15492f3ab15Sopenharmony_ci } 15592f3ab15Sopenharmony_ci 15692f3ab15Sopenharmony_ci /// The certificate. 15792f3ab15Sopenharmony_ci pub fn cert(&mut self, cert: &X509Ref) -> &mut Self { 15892f3ab15Sopenharmony_ci self.cert = Some(cert.to_owned()); 15992f3ab15Sopenharmony_ci self 16092f3ab15Sopenharmony_ci } 16192f3ab15Sopenharmony_ci 16292f3ab15Sopenharmony_ci /// An additional set of certificates to include in the archive beyond the one provided to 16392f3ab15Sopenharmony_ci /// `build`. 16492f3ab15Sopenharmony_ci pub fn ca(&mut self, ca: Stack<X509>) -> &mut Self { 16592f3ab15Sopenharmony_ci self.ca = Some(ca); 16692f3ab15Sopenharmony_ci self 16792f3ab15Sopenharmony_ci } 16892f3ab15Sopenharmony_ci 16992f3ab15Sopenharmony_ci /// The encryption algorithm that should be used for the key 17092f3ab15Sopenharmony_ci pub fn key_algorithm(&mut self, nid: Nid) -> &mut Self { 17192f3ab15Sopenharmony_ci self.nid_key = nid; 17292f3ab15Sopenharmony_ci self 17392f3ab15Sopenharmony_ci } 17492f3ab15Sopenharmony_ci 17592f3ab15Sopenharmony_ci /// The encryption algorithm that should be used for the cert 17692f3ab15Sopenharmony_ci pub fn cert_algorithm(&mut self, nid: Nid) -> &mut Self { 17792f3ab15Sopenharmony_ci self.nid_cert = nid; 17892f3ab15Sopenharmony_ci self 17992f3ab15Sopenharmony_ci } 18092f3ab15Sopenharmony_ci 18192f3ab15Sopenharmony_ci /// Key iteration count, default is 2048 as of this writing 18292f3ab15Sopenharmony_ci pub fn key_iter(&mut self, iter: u32) -> &mut Self { 18392f3ab15Sopenharmony_ci self.iter = iter as c_int; 18492f3ab15Sopenharmony_ci self 18592f3ab15Sopenharmony_ci } 18692f3ab15Sopenharmony_ci 18792f3ab15Sopenharmony_ci /// MAC iteration count, default is the same as key_iter. 18892f3ab15Sopenharmony_ci /// 18992f3ab15Sopenharmony_ci /// Old implementations don't understand MAC iterations greater than 1, (pre 1.0.1?), if such 19092f3ab15Sopenharmony_ci /// compatibility is required this should be set to 1. 19192f3ab15Sopenharmony_ci pub fn mac_iter(&mut self, mac_iter: u32) -> &mut Self { 19292f3ab15Sopenharmony_ci self.mac_iter = mac_iter as c_int; 19392f3ab15Sopenharmony_ci self 19492f3ab15Sopenharmony_ci } 19592f3ab15Sopenharmony_ci 19692f3ab15Sopenharmony_ci /// MAC message digest type 19792f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 19892f3ab15Sopenharmony_ci pub fn mac_md(&mut self, md: MessageDigest) -> &mut Self { 19992f3ab15Sopenharmony_ci self.mac_md = Some(md); 20092f3ab15Sopenharmony_ci self 20192f3ab15Sopenharmony_ci } 20292f3ab15Sopenharmony_ci 20392f3ab15Sopenharmony_ci /// Deprecated. 20492f3ab15Sopenharmony_ci #[deprecated( 20592f3ab15Sopenharmony_ci note = "Use Self::{name, pkey, cert, build2} instead.", 20692f3ab15Sopenharmony_ci since = "0.10.46" 20792f3ab15Sopenharmony_ci )] 20892f3ab15Sopenharmony_ci pub fn build<T>( 20992f3ab15Sopenharmony_ci mut self, 21092f3ab15Sopenharmony_ci password: &str, 21192f3ab15Sopenharmony_ci friendly_name: &str, 21292f3ab15Sopenharmony_ci pkey: &PKeyRef<T>, 21392f3ab15Sopenharmony_ci cert: &X509Ref, 21492f3ab15Sopenharmony_ci ) -> Result<Pkcs12, ErrorStack> 21592f3ab15Sopenharmony_ci where 21692f3ab15Sopenharmony_ci T: HasPrivate, 21792f3ab15Sopenharmony_ci { 21892f3ab15Sopenharmony_ci self.name(friendly_name) 21992f3ab15Sopenharmony_ci .pkey(pkey) 22092f3ab15Sopenharmony_ci .cert(cert) 22192f3ab15Sopenharmony_ci .build2(password) 22292f3ab15Sopenharmony_ci } 22392f3ab15Sopenharmony_ci 22492f3ab15Sopenharmony_ci /// Builds the PKCS#12 object. 22592f3ab15Sopenharmony_ci #[corresponds(PKCS12_create)] 22692f3ab15Sopenharmony_ci pub fn build2(&self, password: &str) -> Result<Pkcs12, ErrorStack> { 22792f3ab15Sopenharmony_ci unsafe { 22892f3ab15Sopenharmony_ci let pass = CString::new(password).unwrap(); 22992f3ab15Sopenharmony_ci let pass = pass.as_ptr(); 23092f3ab15Sopenharmony_ci let friendly_name = self.name.as_ref().map_or(ptr::null(), |p| p.as_ptr()); 23192f3ab15Sopenharmony_ci let pkey = self.pkey.as_ref().map_or(ptr::null(), |p| p.as_ptr()); 23292f3ab15Sopenharmony_ci let cert = self.cert.as_ref().map_or(ptr::null(), |p| p.as_ptr()); 23392f3ab15Sopenharmony_ci let ca = self 23492f3ab15Sopenharmony_ci .ca 23592f3ab15Sopenharmony_ci .as_ref() 23692f3ab15Sopenharmony_ci .map(|ca| ca.as_ptr()) 23792f3ab15Sopenharmony_ci .unwrap_or(ptr::null_mut()); 23892f3ab15Sopenharmony_ci let nid_key = self.nid_key.as_raw(); 23992f3ab15Sopenharmony_ci let nid_cert = self.nid_cert.as_raw(); 24092f3ab15Sopenharmony_ci 24192f3ab15Sopenharmony_ci // According to the OpenSSL docs, keytype is a non-standard extension for MSIE, 24292f3ab15Sopenharmony_ci // It's values are KEY_SIG or KEY_EX, see the OpenSSL docs for more information: 24392f3ab15Sopenharmony_ci // https://www.openssl.org/docs/manmaster/crypto/PKCS12_create.html 24492f3ab15Sopenharmony_ci let keytype = 0; 24592f3ab15Sopenharmony_ci 24692f3ab15Sopenharmony_ci let pkcs12 = cvt_p(ffi::PKCS12_create( 24792f3ab15Sopenharmony_ci pass as *mut _, 24892f3ab15Sopenharmony_ci friendly_name as *mut _, 24992f3ab15Sopenharmony_ci pkey as *mut _, 25092f3ab15Sopenharmony_ci cert as *mut _, 25192f3ab15Sopenharmony_ci ca, 25292f3ab15Sopenharmony_ci nid_key, 25392f3ab15Sopenharmony_ci nid_cert, 25492f3ab15Sopenharmony_ci self.iter, 25592f3ab15Sopenharmony_ci self.mac_iter, 25692f3ab15Sopenharmony_ci keytype, 25792f3ab15Sopenharmony_ci )) 25892f3ab15Sopenharmony_ci .map(Pkcs12)?; 25992f3ab15Sopenharmony_ci 26092f3ab15Sopenharmony_ci #[cfg(not(boringssl))] 26192f3ab15Sopenharmony_ci // BoringSSL does not support overriding the MAC and will always 26292f3ab15Sopenharmony_ci // use SHA-1 26392f3ab15Sopenharmony_ci { 26492f3ab15Sopenharmony_ci let md_type = self 26592f3ab15Sopenharmony_ci .mac_md 26692f3ab15Sopenharmony_ci .map(|md_type| md_type.as_ptr()) 26792f3ab15Sopenharmony_ci .unwrap_or(ptr::null()); 26892f3ab15Sopenharmony_ci 26992f3ab15Sopenharmony_ci cvt(ffi::PKCS12_set_mac( 27092f3ab15Sopenharmony_ci pkcs12.as_ptr(), 27192f3ab15Sopenharmony_ci pass, 27292f3ab15Sopenharmony_ci -1, 27392f3ab15Sopenharmony_ci ptr::null_mut(), 27492f3ab15Sopenharmony_ci 0, 27592f3ab15Sopenharmony_ci self.mac_iter, 27692f3ab15Sopenharmony_ci md_type, 27792f3ab15Sopenharmony_ci ))?; 27892f3ab15Sopenharmony_ci } 27992f3ab15Sopenharmony_ci 28092f3ab15Sopenharmony_ci Ok(pkcs12) 28192f3ab15Sopenharmony_ci } 28292f3ab15Sopenharmony_ci } 28392f3ab15Sopenharmony_ci} 28492f3ab15Sopenharmony_ci 28592f3ab15Sopenharmony_ci#[cfg(test)] 28692f3ab15Sopenharmony_cimod test { 28792f3ab15Sopenharmony_ci use crate::asn1::Asn1Time; 28892f3ab15Sopenharmony_ci use crate::hash::MessageDigest; 28992f3ab15Sopenharmony_ci use crate::nid::Nid; 29092f3ab15Sopenharmony_ci use crate::pkey::PKey; 29192f3ab15Sopenharmony_ci use crate::rsa::Rsa; 29292f3ab15Sopenharmony_ci use crate::x509::extension::KeyUsage; 29392f3ab15Sopenharmony_ci use crate::x509::{X509Name, X509}; 29492f3ab15Sopenharmony_ci 29592f3ab15Sopenharmony_ci use super::*; 29692f3ab15Sopenharmony_ci 29792f3ab15Sopenharmony_ci #[test] 29892f3ab15Sopenharmony_ci fn parse() { 29992f3ab15Sopenharmony_ci #[cfg(ossl300)] 30092f3ab15Sopenharmony_ci let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); 30192f3ab15Sopenharmony_ci 30292f3ab15Sopenharmony_ci let der = include_bytes!("../test/identity.p12"); 30392f3ab15Sopenharmony_ci let pkcs12 = Pkcs12::from_der(der).unwrap(); 30492f3ab15Sopenharmony_ci let parsed = pkcs12.parse2("mypass").unwrap(); 30592f3ab15Sopenharmony_ci 30692f3ab15Sopenharmony_ci assert_eq!( 30792f3ab15Sopenharmony_ci hex::encode(parsed.cert.unwrap().digest(MessageDigest::sha1()).unwrap()), 30892f3ab15Sopenharmony_ci "59172d9313e84459bcff27f967e79e6e9217e584" 30992f3ab15Sopenharmony_ci ); 31092f3ab15Sopenharmony_ci 31192f3ab15Sopenharmony_ci let chain = parsed.ca.unwrap(); 31292f3ab15Sopenharmony_ci assert_eq!(chain.len(), 1); 31392f3ab15Sopenharmony_ci assert_eq!( 31492f3ab15Sopenharmony_ci hex::encode(chain[0].digest(MessageDigest::sha1()).unwrap()), 31592f3ab15Sopenharmony_ci "c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875" 31692f3ab15Sopenharmony_ci ); 31792f3ab15Sopenharmony_ci } 31892f3ab15Sopenharmony_ci 31992f3ab15Sopenharmony_ci #[test] 32092f3ab15Sopenharmony_ci fn parse_empty_chain() { 32192f3ab15Sopenharmony_ci #[cfg(ossl300)] 32292f3ab15Sopenharmony_ci let _provider = crate::provider::Provider::try_load(None, "legacy", true).unwrap(); 32392f3ab15Sopenharmony_ci 32492f3ab15Sopenharmony_ci let der = include_bytes!("../test/keystore-empty-chain.p12"); 32592f3ab15Sopenharmony_ci let pkcs12 = Pkcs12::from_der(der).unwrap(); 32692f3ab15Sopenharmony_ci let parsed = pkcs12.parse2("cassandra").unwrap(); 32792f3ab15Sopenharmony_ci if let Some(stack) = parsed.ca { 32892f3ab15Sopenharmony_ci assert_eq!(stack.len(), 0); 32992f3ab15Sopenharmony_ci } 33092f3ab15Sopenharmony_ci } 33192f3ab15Sopenharmony_ci 33292f3ab15Sopenharmony_ci #[test] 33392f3ab15Sopenharmony_ci fn create() { 33492f3ab15Sopenharmony_ci let subject_name = "ns.example.com"; 33592f3ab15Sopenharmony_ci let rsa = Rsa::generate(2048).unwrap(); 33692f3ab15Sopenharmony_ci let pkey = PKey::from_rsa(rsa).unwrap(); 33792f3ab15Sopenharmony_ci 33892f3ab15Sopenharmony_ci let mut name = X509Name::builder().unwrap(); 33992f3ab15Sopenharmony_ci name.append_entry_by_nid(Nid::COMMONNAME, subject_name) 34092f3ab15Sopenharmony_ci .unwrap(); 34192f3ab15Sopenharmony_ci let name = name.build(); 34292f3ab15Sopenharmony_ci 34392f3ab15Sopenharmony_ci let key_usage = KeyUsage::new().digital_signature().build().unwrap(); 34492f3ab15Sopenharmony_ci 34592f3ab15Sopenharmony_ci let mut builder = X509::builder().unwrap(); 34692f3ab15Sopenharmony_ci builder.set_version(2).unwrap(); 34792f3ab15Sopenharmony_ci builder 34892f3ab15Sopenharmony_ci .set_not_before(&Asn1Time::days_from_now(0).unwrap()) 34992f3ab15Sopenharmony_ci .unwrap(); 35092f3ab15Sopenharmony_ci builder 35192f3ab15Sopenharmony_ci .set_not_after(&Asn1Time::days_from_now(365).unwrap()) 35292f3ab15Sopenharmony_ci .unwrap(); 35392f3ab15Sopenharmony_ci builder.set_subject_name(&name).unwrap(); 35492f3ab15Sopenharmony_ci builder.set_issuer_name(&name).unwrap(); 35592f3ab15Sopenharmony_ci builder.append_extension(key_usage).unwrap(); 35692f3ab15Sopenharmony_ci builder.set_pubkey(&pkey).unwrap(); 35792f3ab15Sopenharmony_ci builder.sign(&pkey, MessageDigest::sha256()).unwrap(); 35892f3ab15Sopenharmony_ci let cert = builder.build(); 35992f3ab15Sopenharmony_ci 36092f3ab15Sopenharmony_ci let pkcs12 = Pkcs12::builder() 36192f3ab15Sopenharmony_ci .name(subject_name) 36292f3ab15Sopenharmony_ci .pkey(&pkey) 36392f3ab15Sopenharmony_ci .cert(&cert) 36492f3ab15Sopenharmony_ci .build2("mypass") 36592f3ab15Sopenharmony_ci .unwrap(); 36692f3ab15Sopenharmony_ci let der = pkcs12.to_der().unwrap(); 36792f3ab15Sopenharmony_ci 36892f3ab15Sopenharmony_ci let pkcs12 = Pkcs12::from_der(&der).unwrap(); 36992f3ab15Sopenharmony_ci let parsed = pkcs12.parse2("mypass").unwrap(); 37092f3ab15Sopenharmony_ci 37192f3ab15Sopenharmony_ci assert_eq!( 37292f3ab15Sopenharmony_ci &*parsed.cert.unwrap().digest(MessageDigest::sha1()).unwrap(), 37392f3ab15Sopenharmony_ci &*cert.digest(MessageDigest::sha1()).unwrap() 37492f3ab15Sopenharmony_ci ); 37592f3ab15Sopenharmony_ci assert!(parsed.pkey.unwrap().public_eq(&pkey)); 37692f3ab15Sopenharmony_ci } 37792f3ab15Sopenharmony_ci 37892f3ab15Sopenharmony_ci #[test] 37992f3ab15Sopenharmony_ci fn create_only_ca() { 38092f3ab15Sopenharmony_ci let ca = include_bytes!("../test/root-ca.pem"); 38192f3ab15Sopenharmony_ci let ca = X509::from_pem(ca).unwrap(); 38292f3ab15Sopenharmony_ci let mut chain = Stack::new().unwrap(); 38392f3ab15Sopenharmony_ci chain.push(ca).unwrap(); 38492f3ab15Sopenharmony_ci 38592f3ab15Sopenharmony_ci let pkcs12 = Pkcs12::builder().ca(chain).build2("hunter2").unwrap(); 38692f3ab15Sopenharmony_ci let parsed = pkcs12.parse2("hunter2").unwrap(); 38792f3ab15Sopenharmony_ci 38892f3ab15Sopenharmony_ci assert!(parsed.cert.is_none()); 38992f3ab15Sopenharmony_ci assert!(parsed.pkey.is_none()); 39092f3ab15Sopenharmony_ci assert_eq!(parsed.ca.unwrap().len(), 1); 39192f3ab15Sopenharmony_ci } 39292f3ab15Sopenharmony_ci} 393