aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLionel Flandrin <[email protected]>2016-10-31 23:53:28 +0100
committerLionel Flandrin <[email protected]>2016-11-01 21:23:18 +0100
commit36bf0bb38750412e5c2700273a850f16398cc427 (patch)
tree547b6ce043a53f6b0ae09ac7d8cbc57edbdebcd0
parentImplement a generic Stack API to deal with OpenSSL stacks (diff)
downloadrust-openssl-36bf0bb38750412e5c2700273a850f16398cc427.tar.xz
rust-openssl-36bf0bb38750412e5c2700273a850f16398cc427.zip
Replace GeneralNames by the new Stack API
-rw-r--r--openssl/src/ssl/connector.rs10
-rw-r--r--openssl/src/x509/mod.rs145
-rw-r--r--openssl/src/x509/tests.rs6
3 files changed, 25 insertions, 136 deletions
diff --git a/openssl/src/ssl/connector.rs b/openssl/src/ssl/connector.rs
index b2e00a81..c95b0fa1 100644
--- a/openssl/src/ssl/connector.rs
+++ b/openssl/src/ssl/connector.rs
@@ -256,7 +256,8 @@ mod verify {
use std::str;
use nid;
- use x509::{X509StoreContext, X509, GeneralNames, X509Name};
+ use x509::{X509StoreContext, X509, X509Name, GeneralName};
+ use stack::Stack;
use types::Ref;
pub fn verify_callback(domain: &str,
@@ -275,15 +276,16 @@ mod verify {
fn verify_hostname(domain: &str, cert: &Ref<X509>) -> bool {
match cert.subject_alt_names() {
- Some(names) => verify_subject_alt_names(domain, &names),
+ Some(names) => verify_subject_alt_names(domain, names),
None => verify_subject_name(domain, &cert.subject_name()),
}
}
- fn verify_subject_alt_names(domain: &str, names: &GeneralNames) -> bool {
+ fn verify_subject_alt_names(domain: &str,
+ names: Stack<GeneralName>) -> bool {
let ip = domain.parse();
- for name in names {
+ for name in &names {
match ip {
Ok(ip) => {
if let Some(actual) = name.ipaddress() {
diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs
index 28f2542f..dcda5913 100644
--- a/openssl/src/x509/mod.rs
+++ b/openssl/src/x509/mod.rs
@@ -1,11 +1,10 @@
-use libc::{c_char, c_int, c_long, c_ulong, c_void};
+use libc::{c_char, c_int, c_long, c_ulong};
use std::borrow::Borrow;
use std::cmp;
use std::collections::HashMap;
use std::error::Error;
use std::ffi::{CStr, CString};
use std::fmt;
-use std::marker::PhantomData;
use std::mem;
use std::ptr;
use std::slice;
@@ -21,6 +20,7 @@ use error::ErrorStack;
use ffi;
use nid::Nid;
use types::{OpenSslType, Ref};
+use stack::{Stack, Stackable};
#[cfg(ossl10x)]
use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data};
@@ -346,7 +346,7 @@ impl Ref<X509> {
}
/// Returns this certificate's SAN entries, if they exist.
- pub fn subject_alt_names(&self) -> Option<GeneralNames> {
+ pub fn subject_alt_names(&self) -> Option<Stack<GeneralName>> {
unsafe {
let stack = ffi::X509_get_ext_d2i(self.as_ptr(),
ffi::NID_subject_alt_name,
@@ -356,7 +356,7 @@ impl Ref<X509> {
return None;
}
- Some(GeneralNames { stack: stack as *mut _ })
+ Some(Stack::from_ptr(stack as *mut _))
}
}
@@ -678,135 +678,18 @@ impl X509VerifyError {
}
}
-/// A collection of OpenSSL `GENERAL_NAME`s.
-pub struct GeneralNames {
- stack: *mut ffi::stack_st_GENERAL_NAME,
-}
-
-impl Drop for GeneralNames {
- #[cfg(ossl10x)]
- 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));
- }
- }
-
- #[cfg(ossl110)]
- 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::OPENSSL_sk_pop_free(self.stack as *mut _, Some(free));
- }
- }
-}
-
-impl GeneralNames {
- /// Returns the number of `GeneralName`s in this structure.
- pub fn len(&self) -> usize {
- self._len()
- }
-
- #[cfg(ossl10x)]
- fn _len(&self) -> usize {
- unsafe { (*self.stack).stack.num as usize }
- }
-
- #[cfg(ossl110)]
- fn _len(&self) -> usize {
- unsafe { ffi::OPENSSL_sk_num(self.stack as *const _) as usize }
- }
-
- /// Returns the specified `GeneralName`.
- ///
- /// # Panics
- ///
- /// Panics if `idx` is not less than `len()`.
- pub fn get<'a>(&'a self, idx: usize) -> GeneralName<'a> {
- unsafe {
- assert!(idx < self.len());
- GeneralName {
- name: self._get(idx),
- m: PhantomData,
- }
- }
- }
-
- #[cfg(ossl10x)]
- unsafe fn _get(&self, idx: usize) -> *const ffi::GENERAL_NAME {
- *(*self.stack).stack.data.offset(idx as isize) as *const ffi::GENERAL_NAME
- }
-
- #[cfg(ossl110)]
- unsafe fn _get(&self, idx: usize) -> *const ffi::GENERAL_NAME {
- ffi::OPENSSL_sk_value(self.stack as *const _, idx as c_int) as *mut _
- }
-
- /// Returns an iterator over the `GeneralName`s in this structure.
- pub fn iter(&self) -> GeneralNamesIter {
- GeneralNamesIter {
- names: self,
- idx: 0,
- }
- }
-}
-
-impl<'a> IntoIterator for &'a GeneralNames {
- type Item = GeneralName<'a>;
- type IntoIter = GeneralNamesIter<'a>;
-
- fn into_iter(self) -> GeneralNamesIter<'a> {
- self.iter()
- }
-}
-
-/// An iterator over OpenSSL `GENERAL_NAME`s.
-pub struct GeneralNamesIter<'a> {
- names: &'a GeneralNames,
- idx: usize,
-}
-
-impl<'a> Iterator for GeneralNamesIter<'a> {
- type Item = GeneralName<'a>;
-
- fn next(&mut self) -> Option<Self::Item> {
- if self.idx < self.names.len() {
- let name = self.names.get(self.idx);
- self.idx += 1;
- Some(name)
- } else {
- None
- }
- }
+type_!(GeneralName, ffi::GENERAL_NAME, ffi::GENERAL_NAME_free);
- fn size_hint(&self) -> (usize, Option<usize>) {
- let size = self.names.len() - self.idx;
- (size, Some(size))
- }
-}
-
-impl<'a> ExactSizeIterator for GeneralNamesIter<'a> {}
-
-/// An OpenSSL `GENERAL_NAME`.
-pub struct GeneralName<'a> {
- name: *const ffi::GENERAL_NAME,
- m: PhantomData<&'a ()>,
-}
-
-impl<'a> GeneralName<'a> {
+impl Ref<GeneralName> {
/// Returns the contents of this `GeneralName` if it is a `dNSName`.
pub fn dnsname(&self) -> Option<&str> {
unsafe {
- if (*self.name).type_ != ffi::GEN_DNS {
+ if (*self.as_ptr()).type_ != ffi::GEN_DNS {
return None;
}
- let ptr = ASN1_STRING_data((*self.name).d as *mut _);
- let len = ffi::ASN1_STRING_length((*self.name).d as *mut _);
+ let ptr = ASN1_STRING_data((*self.as_ptr()).d as *mut _);
+ let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _);
let slice = slice::from_raw_parts(ptr as *const u8, len as usize);
// dNSNames are stated to be ASCII (specifically IA5). Hopefully
@@ -819,18 +702,22 @@ impl<'a> GeneralName<'a> {
/// Returns the contents of this `GeneralName` if it is an `iPAddress`.
pub fn ipaddress(&self) -> Option<&[u8]> {
unsafe {
- if (*self.name).type_ != ffi::GEN_IPADD {
+ if (*self.as_ptr()).type_ != ffi::GEN_IPADD {
return None;
}
- let ptr = ASN1_STRING_data((*self.name).d as *mut _);
- let len = ffi::ASN1_STRING_length((*self.name).d as *mut _);
+ let ptr = ASN1_STRING_data((*self.as_ptr()).d as *mut _);
+ let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _);
Some(slice::from_raw_parts(ptr as *const u8, len as usize))
}
}
}
+impl Stackable for GeneralName {
+ type StackType = ffi::stack_st_GENERAL_NAME;
+}
+
#[test]
fn test_negative_serial() {
// I guess that's enough to get a random negative number
diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs
index db93c3a8..2527d538 100644
--- a/openssl/src/x509/tests.rs
+++ b/openssl/src/x509/tests.rs
@@ -152,10 +152,10 @@ fn test_subject_alt_name() {
let subject_alt_names = cert.subject_alt_names().unwrap();
assert_eq!(3, subject_alt_names.len());
- assert_eq!(Some("foobar.com"), subject_alt_names.get(0).dnsname());
- assert_eq!(subject_alt_names.get(1).ipaddress(),
+ assert_eq!(Some("foobar.com"), subject_alt_names[0].dnsname());
+ assert_eq!(subject_alt_names[1].ipaddress(),
Some(&[127, 0, 0, 1][..]));
- assert_eq!(subject_alt_names.get(2).ipaddress(),
+ assert_eq!(subject_alt_names[2].ipaddress(),
Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..]));
}