From f2775898530bbe7545fcc8dc9ca4e34ea6c49303 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Tue, 12 May 2020 14:34:01 +0200 Subject: [PATCH] allow parsing several certificates from a single pem Signed-off-by: Marc-Antoine Perennou --- src/imp/openssl.rs | 5 +++++ src/imp/security_framework.rs | 16 ++++++++++++++++ src/lib.rs | 6 ++++++ 3 files changed, 27 insertions(+) diff --git a/src/imp/openssl.rs b/src/imp/openssl.rs index 6dfbd6e5..44b87b1e 100644 --- a/src/imp/openssl.rs +++ b/src/imp/openssl.rs @@ -177,6 +177,11 @@ impl Certificate { Ok(Certificate(cert)) } + pub fn stack_from_pem(buf: &[u8]) -> Result, Error> { + let mut certs = X509::stack_from_pem(buf)?; + Ok(certs.drain(..).map(Certificate).collect()) + } + pub fn to_der(&self) -> Result, Error> { let der = self.0.to_der()?; Ok(der) diff --git a/src/imp/security_framework.rs b/src/imp/security_framework.rs index a3510352..3fc2059d 100644 --- a/src/imp/security_framework.rs +++ b/src/imp/security_framework.rs @@ -167,6 +167,22 @@ impl Certificate { panic!("Not implemented on iOS"); } + #[cfg(not(target_os = "ios"))] + pub fn stack_from_pem(buf: &[u8]) -> Result, Error> { + let mut items = SecItems::default(); + ImportOptions::new().items(&mut items).import(buf)?; + if items.identities.is_empty() && items.keys.is_empty() { + Ok(items.certificates.drain(..).map(Certificate)) + } else { + Err(Error(base::Error::from(errSecParam))) + } + } + + #[cfg(target_os = "ios")] + pub fn stack_from_pem(buf: &[u8]) -> Result, Error> { + panic!("Not implemented on iOS"); + } + pub fn to_der(&self) -> Result, Error> { Ok(self.0.to_der()) } diff --git a/src/lib.rs b/src/lib.rs index c91a2756..c44c8f43 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -198,6 +198,12 @@ impl Certificate { Ok(Certificate(cert)) } + /// Parses some PEM-formatted X509 certificates. + pub fn stack_from_pem(buf: &[u8]) -> Result> { + let mut certs = imp::Certificate::stack_from_pem(buf)?; + Ok(certs.drain(..).map(Certificate).collect()) + } + /// Returns the DER-encoded representation of this certificate. pub fn to_der(&self) -> Result> { let der = self.0.to_der()?;