diff options
Diffstat (limited to 'openssl/src')
| -rw-r--r-- | openssl/src/c_helpers.c | 20 | ||||
| -rw-r--r-- | openssl/src/c_helpers.rs | 14 | ||||
| -rw-r--r-- | openssl/src/crypto/hmac.rs | 24 | ||||
| -rw-r--r-- | openssl/src/crypto/mod.rs | 1 | ||||
| -rw-r--r-- | openssl/src/crypto/pkcs12.rs | 92 | ||||
| -rw-r--r-- | openssl/src/dh/mod.rs | 2 | ||||
| -rw-r--r-- | openssl/src/lib.rs | 2 | ||||
| -rw-r--r-- | openssl/src/ssl/mod.rs | 4 | ||||
| -rw-r--r-- | openssl/src/ssl/tests/mod.rs | 28 | ||||
| -rw-r--r-- | openssl/src/x509/mod.rs | 44 | ||||
| -rw-r--r-- | openssl/src/x509/tests.rs | 2 |
11 files changed, 175 insertions, 58 deletions
diff --git a/openssl/src/c_helpers.c b/openssl/src/c_helpers.c index 13041956..5d149553 100644 --- a/openssl/src/c_helpers.c +++ b/openssl/src/c_helpers.c @@ -3,19 +3,19 @@ #include <openssl/dh.h> #include <openssl/bn.h> -void rust_SSL_CTX_clone(SSL_CTX *ctx) { +void rust_0_8_SSL_CTX_clone(SSL_CTX *ctx) { CRYPTO_add(&ctx->references,1,CRYPTO_LOCK_SSL_CTX); } -void rust_X509_clone(X509 *x509) { +void rust_0_8_X509_clone(X509 *x509) { CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); } -STACK_OF(X509_EXTENSION) *rust_X509_get_extensions(X509 *x) { +STACK_OF(X509_EXTENSION) *rust_0_8_X509_get_extensions(X509 *x) { return x->cert_info ? x->cert_info->extensions : NULL; } -DH *rust_DH_new_from_params(BIGNUM *p, BIGNUM *g, BIGNUM *q) { +DH *rust_0_8_DH_new_from_params(BIGNUM *p, BIGNUM *g, BIGNUM *q) { DH *dh; if ((dh = DH_new()) == NULL) { @@ -28,32 +28,32 @@ DH *rust_DH_new_from_params(BIGNUM *p, BIGNUM *g, BIGNUM *q) { } #if OPENSSL_VERSION_NUMBER < 0x10000000L -int rust_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl) { +int rust_0_8_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl) { HMAC_Init_ex(ctx, key, key_len, md, impl); return 1; } -int rust_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len) { +int rust_0_8_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len) { HMAC_Update(ctx, data, len); return 1; } -int rust_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) { +int rust_0_8_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) { HMAC_Final(ctx, md, len); return 1; } #else -int rust_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl) { +int rust_0_8_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, ENGINE *impl) { return HMAC_Init_ex(ctx, key, key_len, md, impl); } -int rust_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len) { +int rust_0_8_HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, int len) { return HMAC_Update(ctx, data, len); } -int rust_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) { +int rust_0_8_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) { return HMAC_Final(ctx, md, len); } #endif diff --git a/openssl/src/c_helpers.rs b/openssl/src/c_helpers.rs index 90fcf877..74ddb9ac 100644 --- a/openssl/src/c_helpers.rs +++ b/openssl/src/c_helpers.rs @@ -3,12 +3,12 @@ use libc::{c_int, c_void, c_uint, c_uchar}; #[allow(dead_code)] extern "C" { - pub fn rust_SSL_CTX_clone(cxt: *mut ffi::SSL_CTX); - pub fn rust_X509_clone(x509: *mut ffi::X509); - pub fn rust_X509_get_extensions(x: *mut ffi::X509) -> *mut ffi::stack_st_X509_EXTENSION; + pub fn rust_0_8_SSL_CTX_clone(cxt: *mut ffi::SSL_CTX); + pub fn rust_0_8_X509_clone(x509: *mut ffi::X509); + pub fn rust_0_8_X509_get_extensions(x: *mut ffi::X509) -> *mut ffi::stack_st_X509_EXTENSION; - pub fn rust_HMAC_Init_ex(ctx: *mut ffi::HMAC_CTX, key: *const c_void, keylen: c_int, md: *const ffi::EVP_MD, impl_: *mut ffi::ENGINE) -> c_int; - pub fn rust_HMAC_Final(ctx: *mut ffi::HMAC_CTX, output: *mut c_uchar, len: *mut c_uint) -> c_int; - pub fn rust_HMAC_Update(ctx: *mut ffi::HMAC_CTX, input: *const c_uchar, len: c_uint) -> c_int; - pub fn rust_DH_new_from_params(p: *mut ffi::BIGNUM, g: *mut ffi::BIGNUM, q: *mut ffi::BIGNUM) -> *mut ffi::DH; + pub fn rust_0_8_HMAC_Init_ex(ctx: *mut ffi::HMAC_CTX, key: *const c_void, keylen: c_int, md: *const ffi::EVP_MD, impl_: *mut ffi::ENGINE) -> c_int; + pub fn rust_0_8_HMAC_Final(ctx: *mut ffi::HMAC_CTX, output: *mut c_uchar, len: *mut c_uint) -> c_int; + pub fn rust_0_8_HMAC_Update(ctx: *mut ffi::HMAC_CTX, input: *const c_uchar, len: c_uint) -> c_int; + pub fn rust_0_8_DH_new_from_params(p: *mut ffi::BIGNUM, g: *mut ffi::BIGNUM, q: *mut ffi::BIGNUM) -> *mut ffi::DH; } diff --git a/openssl/src/crypto/hmac.rs b/openssl/src/crypto/hmac.rs index 857be339..1847d6b1 100644 --- a/openssl/src/crypto/hmac.rs +++ b/openssl/src/crypto/hmac.rs @@ -92,11 +92,11 @@ impl HMAC { fn init_once(&mut self, md: *const ffi::EVP_MD, key: &[u8]) -> Result<(), ErrorStack> { unsafe { - try_ssl!(c_helpers::rust_HMAC_Init_ex(&mut self.ctx, - key.as_ptr() as *const _, - key.len() as c_int, - md, - 0 as *mut _)); + try_ssl!(c_helpers::rust_0_8_HMAC_Init_ex(&mut self.ctx, + key.as_ptr() as *const _, + key.len() as c_int, + md, + 0 as *mut _)); } self.state = Reset; Ok(()) @@ -113,11 +113,11 @@ impl HMAC { // If the key and/or md is not supplied it's reused from the last time // avoiding redundant initializations unsafe { - try_ssl!(c_helpers::rust_HMAC_Init_ex(&mut self.ctx, - 0 as *const _, - 0, - 0 as *const _, - 0 as *mut _)); + try_ssl!(c_helpers::rust_0_8_HMAC_Init_ex(&mut self.ctx, + 0 as *const _, + 0, + 0 as *const _, + 0 as *mut _)); } self.state = Reset; Ok(()) @@ -130,7 +130,7 @@ impl HMAC { while !data.is_empty() { let len = cmp::min(data.len(), c_uint::max_value() as usize); unsafe { - try_ssl!(c_helpers::rust_HMAC_Update(&mut self.ctx, data.as_ptr(), len as c_uint)); + try_ssl!(c_helpers::rust_0_8_HMAC_Update(&mut self.ctx, data.as_ptr(), len as c_uint)); } data = &data[len..]; } @@ -147,7 +147,7 @@ impl HMAC { unsafe { let mut len = ffi::EVP_MAX_MD_SIZE; let mut res = vec![0; len as usize]; - try_ssl!(c_helpers::rust_HMAC_Final(&mut self.ctx, res.as_mut_ptr(), &mut len)); + try_ssl!(c_helpers::rust_0_8_HMAC_Final(&mut self.ctx, res.as_mut_ptr(), &mut len)); res.truncate(len as usize); self.state = Finalized; Ok(res) diff --git a/openssl/src/crypto/mod.rs b/openssl/src/crypto/mod.rs index 93aba9eb..b8b109a2 100644 --- a/openssl/src/crypto/mod.rs +++ b/openssl/src/crypto/mod.rs @@ -18,6 +18,7 @@ pub mod hash; #[cfg(feature = "hmac")] pub mod hmac; pub mod pkcs5; +pub mod pkcs12; pub mod pkey; pub mod rand; pub mod symm; diff --git a/openssl/src/crypto/pkcs12.rs b/openssl/src/crypto/pkcs12.rs new file mode 100644 index 00000000..89bcbd5c --- /dev/null +++ b/openssl/src/crypto/pkcs12.rs @@ -0,0 +1,92 @@ +//! PKCS #12 archives. + +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); + +impl Drop for Pkcs12 { + fn drop(&mut self) { + unsafe { ffi::PKCS12_free(self.0); } + } +} + +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_ssl_null!(ffi::d2i_PKCS12(ptr::null_mut(), &mut ptr, length)); + Ok(Pkcs12(p12)) + } + } + + /// 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_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 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(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/dh/mod.rs b/openssl/src/dh/mod.rs index 78dcb778..e0cf885a 100644 --- a/openssl/src/dh/mod.rs +++ b/openssl/src/dh/mod.rs @@ -15,7 +15,7 @@ impl DH { #[cfg(feature = "dh_from_params")] pub fn from_params(p: BigNum, g: BigNum, q: BigNum) -> Result<DH, ErrorStack> { let dh = unsafe { - try_ssl_null!(::c_helpers::rust_DH_new_from_params(p.as_ptr(), g.as_ptr(), q.as_ptr())) + try_ssl_null!(::c_helpers::rust_0_8_DH_new_from_params(p.as_ptr(), g.as_ptr(), q.as_ptr())) }; mem::forget(p); mem::forget(g); diff --git a/openssl/src/lib.rs b/openssl/src/lib.rs index d7e69b0c..f20401f6 100644 --- a/openssl/src/lib.rs +++ b/openssl/src/lib.rs @@ -1,4 +1,4 @@ -#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.8.0")] +#![doc(html_root_url="https://sfackler.github.io/rust-openssl/doc/v0.8.1")] #[macro_use] extern crate bitflags; diff --git a/openssl/src/ssl/mod.rs b/openssl/src/ssl/mod.rs index 82ee3127..64a2ccaf 100644 --- a/openssl/src/ssl/mod.rs +++ b/openssl/src/ssl/mod.rs @@ -662,7 +662,7 @@ impl Clone for SslContext { /// Requires the `ssl_context_clone` feature. fn clone(&self) -> Self { unsafe { - ::c_helpers::rust_SSL_CTX_clone(self.as_ptr()); + ::c_helpers::rust_0_8_SSL_CTX_clone(self.as_ptr()); SslContext::from_ptr(self.as_ptr()) } } @@ -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/ssl/tests/mod.rs b/openssl/src/ssl/tests/mod.rs index bfcaa5e4..4e4985e1 100644 --- a/openssl/src/ssl/tests/mod.rs +++ b/openssl/src/ssl/tests/mod.rs @@ -245,7 +245,7 @@ run_test!(verify_trusted, |method, stream| { let mut ctx = SslContext::new(method).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -314,7 +314,7 @@ run_test!(verify_trusted_get_error_ok, |method, stream| { true }); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -338,7 +338,7 @@ run_test!(verify_callback_data, |method, stream| { // in DER format. // Command: openssl x509 -in test/cert.pem -outform DER | openssl dgst -sha256 // Please update if "test/cert.pem" will ever change - let node_hash_str = "E19427DAC79FBE758394945276A6E4F15F0BEBE6"; + let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; let node_id = node_hash_str.from_hex().unwrap(); ctx.set_verify_callback(SSL_VERIFY_PEER, move |_preverify_ok, x509_ctx| { let cert = x509_ctx.current_cert(); @@ -367,7 +367,7 @@ run_test!(ssl_verify_callback, |method, stream| { let ctx = SslContext::new(method).unwrap(); let mut ssl = ctx.into_ssl().unwrap(); - let node_hash_str = "E19427DAC79FBE758394945276A6E4F15F0BEBE6"; + let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; let node_id = node_hash_str.from_hex().unwrap(); ssl.set_verify_callback(SSL_VERIFY_PEER, move |_, x509| { CHECKED.store(1, Ordering::SeqCst); @@ -472,7 +472,7 @@ run_test!(get_peer_certificate, |method, stream| { let stream = SslStream::connect(&SslContext::new(method).unwrap(), stream).unwrap(); let cert = stream.ssl().peer_certificate().unwrap(); let fingerprint = cert.fingerprint(SHA1).unwrap(); - let node_hash_str = "E19427DAC79FBE758394945276A6E4F15F0BEBE6"; + let node_hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; let node_id = node_hash_str.from_hex().unwrap(); assert_eq!(node_id, fingerprint) }); @@ -548,7 +548,7 @@ fn test_connect_with_unilateral_alpn() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/1.1", b"spdy/3.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -570,7 +570,7 @@ fn test_connect_with_unilateral_npn() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"http/1.1", b"spdy/3.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -592,7 +592,7 @@ fn test_connect_with_alpn_successful_multiple_matching() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"spdy/3.1", b"http/1.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -614,7 +614,7 @@ fn test_connect_with_npn_successful_multiple_matching() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"spdy/3.1", b"http/1.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -637,7 +637,7 @@ fn test_connect_with_alpn_successful_single_match() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"spdy/3.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -661,7 +661,7 @@ fn test_connect_with_npn_successful_single_match() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"spdy/3.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -701,7 +701,7 @@ fn test_npn_server_advertise_multiple() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_npn_protocols(&[b"spdy/3.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -742,7 +742,7 @@ fn test_alpn_server_advertise_multiple() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"spdy/3.1"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } @@ -783,7 +783,7 @@ fn test_alpn_server_select_none() { let mut ctx = SslContext::new(Sslv23).unwrap(); ctx.set_verify(SSL_VERIFY_PEER); ctx.set_alpn_protocols(&[b"http/2"]); - match ctx.set_CA_file(&Path::new("test/cert.pem")) { + match ctx.set_CA_file(&Path::new("test/root-ca.pem")) { Ok(_) => {} Err(err) => panic!("Unexpected error {:?}", err), } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 4cb4458a..0cc0eca7 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()), @@ -359,7 +359,7 @@ impl X509Generator { let req = ffi::X509_to_X509_REQ(cert.as_ptr(), ptr::null_mut(), ptr::null()); try_ssl_null!(req); - let exts = ::c_helpers::rust_X509_get_extensions(cert.as_ptr()); + let exts = ::c_helpers::rust_0_8_X509_get_extensions(cert.as_ptr()); if exts != ptr::null_mut() { try_ssl!(ffi::X509_REQ_add_extensions(req, exts)); } @@ -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 { @@ -402,7 +408,7 @@ impl<'a> X509Ref<'a> { } Some(GeneralNames { - stack: stack as *const _, + stack: stack as *mut _, m: PhantomData, }) } @@ -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)) } } } @@ -481,7 +493,7 @@ impl Clone for X509 { /// Requires the `x509_clone` feature. fn clone(&self) -> X509 { unsafe { - ::c_helpers::rust_X509_clone(self.as_ptr()); + ::c_helpers::rust_0_8_X509_clone(self.as_ptr()); X509::new(self.as_ptr()) } } @@ -723,12 +735,24 @@ make_validation_error!(X509_V_OK, X509ApplicationVerification = X509_V_ERR_APPLICATION_VERIFICATION, ); +// FIXME remove lifetime param for 0.9 /// A collection of OpenSSL `GENERAL_NAME`s. pub struct GeneralNames<'a> { - stack: *const ffi::stack_st_GENERAL_NAME, + stack: *mut ffi::stack_st_GENERAL_NAME, m: PhantomData<&'a ()>, } +impl<'a> Drop for GeneralNames<'a> { + fn drop(&mut self) { + unsafe { + // This transmute is dubious but it's what openssl itself does... + let free: unsafe extern "C" fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free; + let free: unsafe extern "C" fn(*mut c_void) = mem::transmute(free); + ffi::sk_pop_free(&mut (*self.stack).stack, Some(free)); + } + } +} + impl<'a> GeneralNames<'a> { /// Returns the number of `GeneralName`s in this structure. pub fn len(&self) -> usize { diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index c09b31cd..43add896 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -86,7 +86,7 @@ fn test_cert_loading() { let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); let fingerprint = cert.fingerprint(SHA1).unwrap(); - let hash_str = "E19427DAC79FBE758394945276A6E4F15F0BEBE6"; + let hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; let hash_vec = hash_str.from_hex().unwrap(); assert_eq!(fingerprint, hash_vec); |