aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/pkcs12.rs
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2016-11-05 20:06:50 -0700
committerSteven Fackler <[email protected]>2016-11-05 20:06:50 -0700
commita0b56c437803a08413755928040a0970a93a7b83 (patch)
tree0f21848301b62d6078eafaee10e513df4163087b /openssl/src/pkcs12.rs
parentMerge branch 'release-v0.8.3' into release (diff)
parentRelease v0.9.0 (diff)
downloadrust-openssl-0.9.0.tar.xz
rust-openssl-0.9.0.zip
Merge branch 'release-v0.9.0' into releasev0.9.0
Diffstat (limited to 'openssl/src/pkcs12.rs')
-rw-r--r--openssl/src/pkcs12.rs86
1 files changed, 86 insertions, 0 deletions
diff --git a/openssl/src/pkcs12.rs b/openssl/src/pkcs12.rs
new file mode 100644
index 00000000..1ef0bf3f
--- /dev/null
+++ b/openssl/src/pkcs12.rs
@@ -0,0 +1,86 @@
+//! PKCS #12 archives.
+
+use ffi;
+use libc::{c_long, c_uchar};
+use std::cmp;
+use std::ptr;
+use std::ffi::CString;
+
+use {cvt, cvt_p};
+use pkey::PKey;
+use error::ErrorStack;
+use x509::X509;
+use types::{OpenSslType, OpenSslTypeRef};
+use stack::Stack;
+
+type_!(Pkcs12, Pkcs12Ref, ffi::PKCS12, ffi::PKCS12_free);
+
+impl Pkcs12 {
+ /// Deserializes a `Pkcs12` structure from DER-encoded data.
+ pub fn from_der(der: &[u8]) -> Result<Pkcs12, ErrorStack> {
+ unsafe {
+ ffi::init();
+ let mut ptr = der.as_ptr() as *const c_uchar;
+ let length = cmp::min(der.len(), c_long::max_value() as usize) as c_long;
+ let p12 = try!(cvt_p(ffi::d2i_PKCS12(ptr::null_mut(), &mut ptr, length)));
+ Ok(Pkcs12(p12))
+ }
+ }
+}
+
+impl Pkcs12Ref {
+ /// Extracts the contents of the `Pkcs12`.
+ pub fn parse(&self, pass: &str) -> Result<ParsedPkcs12, ErrorStack> {
+ unsafe {
+ let pass = CString::new(pass).unwrap();
+
+ let mut pkey = ptr::null_mut();
+ let mut cert = ptr::null_mut();
+ let mut chain = ptr::null_mut();
+
+ try!(cvt(ffi::PKCS12_parse(self.as_ptr(),
+ pass.as_ptr(),
+ &mut pkey,
+ &mut cert,
+ &mut chain)));
+
+ let pkey = PKey::from_ptr(pkey);
+ let cert = X509::from_ptr(cert);
+ let chain = Stack::from_ptr(chain);
+
+ Ok(ParsedPkcs12 {
+ pkey: pkey,
+ cert: cert,
+ chain: chain,
+ })
+ }
+ }
+}
+
+pub struct ParsedPkcs12 {
+ pub pkey: PKey,
+ pub cert: X509,
+ pub chain: Stack<X509>,
+}
+
+#[cfg(test)]
+mod test {
+ use hash::MessageDigest;
+ use serialize::hex::ToHex;
+
+ use super::*;
+
+ #[test]
+ fn parse() {
+ let der = include_bytes!("../test/identity.p12");
+ let pkcs12 = Pkcs12::from_der(der).unwrap();
+ let parsed = pkcs12.parse("mypass").unwrap();
+
+ assert_eq!(parsed.cert.fingerprint(MessageDigest::sha1()).unwrap().to_hex(),
+ "59172d9313e84459bcff27f967e79e6e9217e584");
+
+ assert_eq!(parsed.chain.len(), 1);
+ assert_eq!(parsed.chain[0].fingerprint(MessageDigest::sha1()).unwrap().to_hex(),
+ "c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875");
+ }
+}