From 6291407b177dfb8bee0b50974cad57c98da110f8 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 3 Jan 2017 14:56:00 -0800 Subject: Add X509::stack_from_pem Implementation is a clone of SSL_CTX_use_certificate_chain_file --- openssl/src/x509/mod.rs | 30 ++++++++++++++++++++++++++++++ openssl/src/x509/tests.rs | 14 +++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) (limited to 'openssl/src') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 68652f8e..d90cee22 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -433,6 +433,36 @@ impl ToOwned for X509Ref { impl X509 { from_pem!(X509, ffi::PEM_read_bio_X509); from_der!(X509, ffi::d2i_X509); + + /// Deserializes a list of PEM-formatted certificates. + pub fn stack_from_pem(pem: &[u8]) -> Result, ErrorStack> { + unsafe { + ffi::init(); + let bio = try!(MemBioSlice::new(pem)); + + let mut certs = vec![]; + loop { + let r = ffi::PEM_read_bio_X509(bio.as_ptr(), + ptr::null_mut(), + None, + ptr::null_mut()); + if r.is_null() { + let err = ffi::ERR_peek_last_error(); + if ffi::ERR_GET_LIB(err) == ffi::ERR_LIB_PEM + && ffi::ERR_GET_REASON(err) == ffi::PEM_R_NO_START_LINE { + ffi::ERR_clear_error(); + break; + } + + return Err(ErrorStack::get()); + } else { + certs.push(X509(r)); + } + } + + Ok(certs) + } + } } impl Clone for X509 { diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 16ad661d..0843b19f 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1,4 +1,4 @@ -use hex::FromHex; +use hex::{FromHex, ToHex}; use hash::MessageDigest; use pkey::PKey; @@ -174,3 +174,15 @@ fn test_subject_alt_name_iter() { Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])); assert!(subject_alt_names_iter.next().is_none()); } + +#[test] +fn test_stack_from_pem() { + let certs = include_bytes!("../../test/certs.pem"); + let certs = X509::stack_from_pem(certs).unwrap(); + + assert_eq!(certs.len(), 2); + assert_eq!(certs[0].fingerprint(MessageDigest::sha1()).unwrap().to_hex(), + "59172d9313e84459bcff27f967e79e6e9217e584"); + assert_eq!(certs[1].fingerprint(MessageDigest::sha1()).unwrap().to_hex(), + "c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875"); +} -- cgit v1.2.3