Loading openssl/src/pkcs12.rs +3 −33 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ use pkey::PKey; use error::ErrorStack; use x509::X509; use types::OpenSslType; use stack::Stack; /// A PKCS #12 archive. pub struct Pkcs12(*mut ffi::PKCS12); Loading Loading @@ -48,19 +49,12 @@ impl Pkcs12 { let pkey = PKey::from_ptr(pkey); let cert = X509::from_ptr(cert); let chain = chain as *mut _; let mut chain_out = vec![]; for i in 0..compat::OPENSSL_sk_num(chain) { let x509 = compat::OPENSSL_sk_value(chain, i); chain_out.push(X509::from_ptr(x509 as *mut _)); } compat::OPENSSL_sk_free(chain as *mut _); let chain = Stack::from_ptr(chain).into_iter().collect(); Ok(ParsedPkcs12 { pkey: pkey, cert: cert, chain: chain_out, chain: chain, }) } } Loading @@ -72,30 +66,6 @@ pub struct ParsedPkcs12 { pub chain: Vec<X509>, } #[cfg(ossl110)] mod compat { pub use ffi::OPENSSL_sk_free; pub use ffi::OPENSSL_sk_num; pub use ffi::OPENSSL_sk_value; } #[cfg(ossl10x)] #[allow(bad_style)] mod compat { use libc::{c_int, c_void}; use ffi; pub use ffi::sk_free as OPENSSL_sk_free; pub unsafe fn OPENSSL_sk_num(stack: *mut ffi::_STACK) -> c_int { (*stack).num } pub unsafe fn OPENSSL_sk_value(stack: *const ffi::_STACK, idx: c_int) -> *mut c_void { *(*stack).data.offset(idx as isize) as *mut c_void } } #[cfg(test)] mod test { use hash::MessageDigest; Loading openssl/src/stack.rs +70 −21 Original line number Diff line number Diff line Loading @@ -4,16 +4,16 @@ use std::borrow::Borrow; use std::convert::AsRef; use std::marker::PhantomData; use libc::c_int; use std::mem; use ffi; use types::{OpenSslType, OpenSslTypeRef}; use util::Opaque; #[cfg(ossl10x)] use ffi::{sk_pop as OPENSSL_sk_pop, sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num, sk_value as OPENSSL_sk_value}; sk_value as OPENSSL_sk_value, _STACK as OPENSSL_STACK}; #[cfg(ossl110)] use ffi::{OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value}; use ffi::{OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK}; /// Trait implemented by types which can be placed in a stack. /// Loading Loading @@ -57,6 +57,20 @@ impl<T: Stackable> Drop for Stack<T> { } } impl<T: Stackable> iter::IntoIterator for Stack<T> { type IntoIter = IntoIter<T>; type Item = T; fn into_iter(self) -> IntoIter<T> { let it = IntoIter { stack: self.0, idx: 0, }; mem::forget(self); it } } impl<T: Stackable> AsRef<StackRef<T>> for Stack<T> { fn as_ref(&self) -> &StackRef<T> { &*self Loading Loading @@ -92,31 +106,66 @@ impl<T: Stackable> DerefMut for Stack<T> { } } pub struct IntoIter<T: Stackable> { stack: *mut T::StackType, idx: c_int, } impl<T: Stackable> IntoIter<T> { fn stack_len(&self) -> c_int { unsafe { OPENSSL_sk_num(self.stack as *mut _) } } unsafe fn get(&mut self, i: c_int) -> T { let ptr = OPENSSL_sk_value(self.stack as *mut _, i); T::from_ptr(ptr as *mut _) } } impl<T: Stackable> Drop for IntoIter<T> { fn drop(&mut self) { unsafe { for i in self.idx..self.stack_len() { self.get(i); } OPENSSL_sk_free(self.stack as *mut _); } } } impl<T: Stackable> Iterator for IntoIter<T> { type Item = T; fn next(&mut self) -> Option<T> { unsafe { if self.idx == self.stack_len() { None } else { let idx = self.idx; self.idx += 1; let v = self.get(idx); Some(v) } } } fn size_hint(&self) -> (usize, Option<usize>) { let size = (self.stack_len() - self.idx) as usize; (size, Some(size)) } } impl<T: Stackable> ExactSizeIterator for IntoIter<T> {} pub struct StackRef<T: Stackable>(Opaque, PhantomData<T>); impl<T: Stackable> OpenSslTypeRef for StackRef<T> { type CType = T::StackType; } impl<T: Stackable> StackRef<T> { /// OpenSSL stack types are just a (kinda) typesafe wrapper around /// a `_STACK` object. We can therefore safely cast it and access /// the `_STACK` members without having to worry about the real /// layout of `T::StackType`. /// /// If that sounds unsafe then keep in mind that's exactly how the /// OpenSSL 1.1.0 new C stack code works. #[cfg(ossl10x)] fn as_stack(&self) -> *mut ffi::_STACK { self.as_ptr() as *mut _ } /// OpenSSL 1.1.0 replaced the stack macros with a functions and /// only exposes an opaque OPENSSL_STACK struct /// publicly. #[cfg(ossl110)] fn as_stack(&self) -> *mut ffi::OPENSSL_STACK { fn as_stack(&self) -> *mut OPENSSL_STACK { self.as_ptr() as *mut _ } Loading Loading
openssl/src/pkcs12.rs +3 −33 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ use pkey::PKey; use error::ErrorStack; use x509::X509; use types::OpenSslType; use stack::Stack; /// A PKCS #12 archive. pub struct Pkcs12(*mut ffi::PKCS12); Loading Loading @@ -48,19 +49,12 @@ impl Pkcs12 { let pkey = PKey::from_ptr(pkey); let cert = X509::from_ptr(cert); let chain = chain as *mut _; let mut chain_out = vec![]; for i in 0..compat::OPENSSL_sk_num(chain) { let x509 = compat::OPENSSL_sk_value(chain, i); chain_out.push(X509::from_ptr(x509 as *mut _)); } compat::OPENSSL_sk_free(chain as *mut _); let chain = Stack::from_ptr(chain).into_iter().collect(); Ok(ParsedPkcs12 { pkey: pkey, cert: cert, chain: chain_out, chain: chain, }) } } Loading @@ -72,30 +66,6 @@ pub struct ParsedPkcs12 { pub chain: Vec<X509>, } #[cfg(ossl110)] mod compat { pub use ffi::OPENSSL_sk_free; pub use ffi::OPENSSL_sk_num; pub use ffi::OPENSSL_sk_value; } #[cfg(ossl10x)] #[allow(bad_style)] mod compat { use libc::{c_int, c_void}; use ffi; pub use ffi::sk_free as OPENSSL_sk_free; pub unsafe fn OPENSSL_sk_num(stack: *mut ffi::_STACK) -> c_int { (*stack).num } pub unsafe fn OPENSSL_sk_value(stack: *const ffi::_STACK, idx: c_int) -> *mut c_void { *(*stack).data.offset(idx as isize) as *mut c_void } } #[cfg(test)] mod test { use hash::MessageDigest; Loading
openssl/src/stack.rs +70 −21 Original line number Diff line number Diff line Loading @@ -4,16 +4,16 @@ use std::borrow::Borrow; use std::convert::AsRef; use std::marker::PhantomData; use libc::c_int; use std::mem; use ffi; use types::{OpenSslType, OpenSslTypeRef}; use util::Opaque; #[cfg(ossl10x)] use ffi::{sk_pop as OPENSSL_sk_pop, sk_free as OPENSSL_sk_free, sk_num as OPENSSL_sk_num, sk_value as OPENSSL_sk_value}; sk_value as OPENSSL_sk_value, _STACK as OPENSSL_STACK}; #[cfg(ossl110)] use ffi::{OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value}; use ffi::{OPENSSL_sk_pop, OPENSSL_sk_free, OPENSSL_sk_num, OPENSSL_sk_value, OPENSSL_STACK}; /// Trait implemented by types which can be placed in a stack. /// Loading Loading @@ -57,6 +57,20 @@ impl<T: Stackable> Drop for Stack<T> { } } impl<T: Stackable> iter::IntoIterator for Stack<T> { type IntoIter = IntoIter<T>; type Item = T; fn into_iter(self) -> IntoIter<T> { let it = IntoIter { stack: self.0, idx: 0, }; mem::forget(self); it } } impl<T: Stackable> AsRef<StackRef<T>> for Stack<T> { fn as_ref(&self) -> &StackRef<T> { &*self Loading Loading @@ -92,31 +106,66 @@ impl<T: Stackable> DerefMut for Stack<T> { } } pub struct IntoIter<T: Stackable> { stack: *mut T::StackType, idx: c_int, } impl<T: Stackable> IntoIter<T> { fn stack_len(&self) -> c_int { unsafe { OPENSSL_sk_num(self.stack as *mut _) } } unsafe fn get(&mut self, i: c_int) -> T { let ptr = OPENSSL_sk_value(self.stack as *mut _, i); T::from_ptr(ptr as *mut _) } } impl<T: Stackable> Drop for IntoIter<T> { fn drop(&mut self) { unsafe { for i in self.idx..self.stack_len() { self.get(i); } OPENSSL_sk_free(self.stack as *mut _); } } } impl<T: Stackable> Iterator for IntoIter<T> { type Item = T; fn next(&mut self) -> Option<T> { unsafe { if self.idx == self.stack_len() { None } else { let idx = self.idx; self.idx += 1; let v = self.get(idx); Some(v) } } } fn size_hint(&self) -> (usize, Option<usize>) { let size = (self.stack_len() - self.idx) as usize; (size, Some(size)) } } impl<T: Stackable> ExactSizeIterator for IntoIter<T> {} pub struct StackRef<T: Stackable>(Opaque, PhantomData<T>); impl<T: Stackable> OpenSslTypeRef for StackRef<T> { type CType = T::StackType; } impl<T: Stackable> StackRef<T> { /// OpenSSL stack types are just a (kinda) typesafe wrapper around /// a `_STACK` object. We can therefore safely cast it and access /// the `_STACK` members without having to worry about the real /// layout of `T::StackType`. /// /// If that sounds unsafe then keep in mind that's exactly how the /// OpenSSL 1.1.0 new C stack code works. #[cfg(ossl10x)] fn as_stack(&self) -> *mut ffi::_STACK { self.as_ptr() as *mut _ } /// OpenSSL 1.1.0 replaced the stack macros with a functions and /// only exposes an opaque OPENSSL_STACK struct /// publicly. #[cfg(ossl110)] fn as_stack(&self) -> *mut ffi::OPENSSL_STACK { fn as_stack(&self) -> *mut OPENSSL_STACK { self.as_ptr() as *mut _ } Loading