From 2cfb25136f6c09c76c3ff173edf3a22e64ba72ca Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 1 May 2016 09:09:51 -0700 Subject: [PATCH] Document SAN APIs and tweak accessor names --- openssl/src/x509/mod.rs | 24 ++++++++++++++++++++++-- openssl/src/x509/tests.rs | 14 ++++++++------ 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index da45a930..6d38047a 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -469,6 +469,7 @@ impl<'ctx> X509<'ctx> { } } + /// Returns this certificate's SAN entries, if they exist. pub fn subject_alt_names<'a>(&'a self) -> Option> { unsafe { let stack = ffi::X509_get_ext_d2i(self.handle, @@ -788,18 +789,25 @@ make_validation_error!(X509_V_OK, X509ApplicationVerification = X509_V_ERR_APPLICATION_VERIFICATION, ); +/// A collection of OpenSSL `GENERAL_NAME`s. pub struct GeneralNames<'a> { stack: *const ffi::stack_st_GENERAL_NAME, m: PhantomData<&'a ()>, } impl<'a> GeneralNames<'a> { + /// Returns the number of `GeneralName`s in this structure. pub fn len(&self) -> usize { unsafe { (*self.stack).stack.num as usize } } + /// Returns the specified `GeneralName`. + /// + /// # Panics + /// + /// Panics if `idx` is not less than `len()`. pub fn get(&self, idx: usize) -> GeneralName<'a> { unsafe { assert!(idx < self.len()); @@ -811,6 +819,7 @@ impl<'a> GeneralNames<'a> { } } + /// Returns an iterator over the `GeneralName`s in this structure. pub fn iter(&self) -> GeneralNamesIter { GeneralNamesIter { names: self, @@ -828,6 +837,7 @@ impl<'a> IntoIterator for &'a GeneralNames<'a> { } } +/// An iterator over OpenSSL `GENERAL_NAME`s. pub struct GeneralNamesIter<'a> { names: &'a GeneralNames<'a>, idx: usize, @@ -845,15 +855,24 @@ impl<'a> Iterator for GeneralNamesIter<'a> { None } } + + fn size_hint(&self) -> (usize, Option) { + 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> { - pub fn dns(&self) -> Option<&str> { + /// 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 { return None; @@ -867,7 +886,8 @@ impl<'a> GeneralName<'a> { } } - pub fn ipadd(&self) -> Option<&[u8]> { + /// 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 { return None; diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index aa41bfc6..0032d108 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -165,9 +165,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).dns()); - assert_eq!(subject_alt_names.get(1).ipadd(), Some(&[127, 0, 0, 1][..])); - assert_eq!(subject_alt_names.get(2).ipadd(), Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])); + assert_eq!(Some("foobar.com"), subject_alt_names.get(0).dnsname()); + assert_eq!(subject_alt_names.get(1).ipaddress(), Some(&[127, 0, 0, 1][..])); + assert_eq!(subject_alt_names.get(2).ipaddress(), + Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])); } #[test] @@ -177,8 +178,9 @@ fn test_subject_alt_name_iter() { let subject_alt_names = cert.subject_alt_names().unwrap(); let mut subject_alt_names_iter = subject_alt_names.iter(); - assert_eq!(subject_alt_names_iter.next().unwrap().dns(), Some("foobar.com")); - assert_eq!(subject_alt_names_iter.next().unwrap().ipadd(), Some(&[127, 0, 0, 1][..])); - assert_eq!(subject_alt_names_iter.next().unwrap().ipadd(), Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])); + assert_eq!(subject_alt_names_iter.next().unwrap().dnsname(), Some("foobar.com")); + assert_eq!(subject_alt_names_iter.next().unwrap().ipaddress(), Some(&[127, 0, 0, 1][..])); + assert_eq!(subject_alt_names_iter.next().unwrap().ipaddress(), + Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])); assert!(subject_alt_names_iter.next().is_none()); }