aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2016-08-14 11:11:26 -0700
committerSteven Fackler <[email protected]>2016-08-14 11:11:26 -0700
commit6b12a0cddea0d4392cf0376c68b36d87cf19b86e (patch)
tree2499194fefbe12213f2188a1c12f17212bb310a3 /openssl/src
parentMore test fixes (diff)
downloadrust-openssl-6b12a0cddea0d4392cf0376c68b36d87cf19b86e.tar.xz
rust-openssl-6b12a0cddea0d4392cf0376c68b36d87cf19b86e.zip
PKCS #12 support
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/crypto/pkcs12.rs55
-rw-r--r--openssl/src/ssl/mod.rs2
-rw-r--r--openssl/src/x509/mod.rs24
3 files changed, 72 insertions, 9 deletions
diff --git a/openssl/src/crypto/pkcs12.rs b/openssl/src/crypto/pkcs12.rs
index dfe30a6c..f35fa2c6 100644
--- a/openssl/src/crypto/pkcs12.rs
+++ b/openssl/src/crypto/pkcs12.rs
@@ -4,8 +4,11 @@ use ffi;
use libc::{c_long, c_uchar};
use std::cmp;
use std::ptr;
+use std::ffi::CString;
+use crypto::pkey::PKey;
use error::ErrorStack;
+use x509::X509;
/// A PKCS #12 archive.
pub struct Pkcs12(*mut ffi::PKCS12);
@@ -19,21 +22,69 @@ impl Drop for Pkcs12 {
impl Pkcs12 {
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_ssl_null!(ffi::d2i_PKCS12(ptr::null_mut(), &mut ptr, length));
Ok(Pkcs12(p12))
}
}
+
+ 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_ssl!(ffi::PKCS12_parse(self.0, pass.as_ptr(), &mut pkey, &mut cert, &mut chain));
+
+ let pkey = PKey::from_ptr(pkey);
+ let cert = X509::from_ptr(cert);
+
+ let mut chain_out = vec![];
+ for i in 0..(*chain).stack.num {
+ let x509 = *(*chain).stack.data.offset(i as isize) as *mut _;
+ chain_out.push(X509::from_ptr(x509));
+ }
+ ffi::sk_free(&mut (*chain).stack);
+
+ Ok(ParsedPkcs12 {
+ pkey: pkey,
+ cert: cert,
+ chain: chain_out,
+ _p: (),
+ })
+ }
+ }
+}
+
+pub struct ParsedPkcs12 {
+ pub pkey: PKey,
+ pub cert: X509,
+ pub chain: Vec<X509>,
+ _p: (),
}
#[cfg(test)]
mod test {
+ use crypto::hash::Type::SHA1;
+ use serialize::hex::ToHex;
+
use super::*;
#[test]
- fn from_der() {
+ fn parse() {
let der = include_bytes!("../../test/identity.p12");
- Pkcs12::from_der(der).unwrap();
+ let pkcs12 = Pkcs12::from_der(der).unwrap();
+ let parsed = pkcs12.parse("mypass").unwrap();
+
+ assert_eq!(parsed.cert.fingerprint(SHA1).unwrap().to_hex(),
+ "59172d9313e84459bcff27f967e79e6e9217e584");
+
+ assert_eq!(parsed.chain.len(), 1);
+ assert_eq!(parsed.chain[0].fingerprint(SHA1).unwrap().to_hex(),
+ "c0cbdf7cdd03c9773e5468e1f6d2da7d5cbb1875");
}
}
diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs
index 1ace24ed..64a2ccaf 100644
--- a/openssl/src/ssl/mod.rs
+++ b/openssl/src/ssl/mod.rs
@@ -933,7 +933,7 @@ impl<'a> SslRef<'a> {
if ptr.is_null() {
None
} else {
- Some(X509::new(ptr))
+ Some(X509::from_ptr(ptr))
}
}
}
diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs
index 9f1c1a79..4943f7a9 100644
--- a/openssl/src/x509/mod.rs
+++ b/openssl/src/x509/mod.rs
@@ -94,7 +94,7 @@ impl X509StoreContext {
if ptr.is_null() {
None
} else {
- Some(X509Ref::new(ptr))
+ Some(X509Ref::from_ptr(ptr))
}
}
}
@@ -298,7 +298,7 @@ impl X509Generator {
unsafe {
let x509 = try_ssl_null!(ffi::X509_new());
- let x509 = X509::new(x509);
+ let x509 = X509::from_ptr(x509);
try_ssl!(ffi::X509_set_version(x509.as_ptr(), 2));
try_ssl!(ffi::ASN1_INTEGER_set(ffi::X509_get_serialNumber(x509.as_ptr()),
@@ -377,8 +377,14 @@ pub struct X509Ref<'a>(*mut ffi::X509, PhantomData<&'a ()>);
impl<'a> X509Ref<'a> {
/// Creates a new `X509Ref` wrapping the provided handle.
- pub unsafe fn new(handle: *mut ffi::X509) -> X509Ref<'a> {
- X509Ref(handle, PhantomData)
+ pub unsafe fn from_ptr(x509: *mut ffi::X509) -> X509Ref<'a> {
+ X509Ref(x509, PhantomData)
+ }
+
+ ///
+ #[deprecated(note = "renamed to `X509::from_ptr`", since = "0.8.1")]
+ pub unsafe fn new(x509: *mut ffi::X509) -> X509Ref<'a> {
+ X509Ref::from_ptr(x509)
}
pub fn as_ptr(&self) -> *mut ffi::X509 {
@@ -451,8 +457,14 @@ pub struct X509(X509Ref<'static>);
impl X509 {
/// Returns a new `X509`, taking ownership of the handle.
+ pub unsafe fn from_ptr(x509: *mut ffi::X509) -> X509 {
+ X509(X509Ref::from_ptr(x509))
+ }
+
+ ///
+ #[deprecated(note = "renamed to `X509::from_ptr`", since = "0.8.1")]
pub unsafe fn new(x509: *mut ffi::X509) -> X509 {
- X509(X509Ref::new(x509))
+ X509::from_ptr(x509)
}
/// Reads a certificate from PEM.
@@ -463,7 +475,7 @@ impl X509 {
ptr::null_mut(),
None,
ptr::null_mut()));
- Ok(X509::new(handle))
+ Ok(X509::from_ptr(handle))
}
}
}