Document SAN APIs and tweak accessor names
This commit is contained in:
parent
87782b22cf
commit
2cfb25136f
|
|
@ -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<GeneralNames<'a>> {
|
pub fn subject_alt_names<'a>(&'a self) -> Option<GeneralNames<'a>> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let stack = ffi::X509_get_ext_d2i(self.handle,
|
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,
|
X509ApplicationVerification = X509_V_ERR_APPLICATION_VERIFICATION,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// A collection of OpenSSL `GENERAL_NAME`s.
|
||||||
pub struct GeneralNames<'a> {
|
pub struct GeneralNames<'a> {
|
||||||
stack: *const ffi::stack_st_GENERAL_NAME,
|
stack: *const ffi::stack_st_GENERAL_NAME,
|
||||||
m: PhantomData<&'a ()>,
|
m: PhantomData<&'a ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GeneralNames<'a> {
|
impl<'a> GeneralNames<'a> {
|
||||||
|
/// Returns the number of `GeneralName`s in this structure.
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
unsafe {
|
unsafe {
|
||||||
(*self.stack).stack.num as usize
|
(*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> {
|
pub fn get(&self, idx: usize) -> GeneralName<'a> {
|
||||||
unsafe {
|
unsafe {
|
||||||
assert!(idx < self.len());
|
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 {
|
pub fn iter(&self) -> GeneralNamesIter {
|
||||||
GeneralNamesIter {
|
GeneralNamesIter {
|
||||||
names: self,
|
names: self,
|
||||||
|
|
@ -828,6 +837,7 @@ impl<'a> IntoIterator for &'a GeneralNames<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An iterator over OpenSSL `GENERAL_NAME`s.
|
||||||
pub struct GeneralNamesIter<'a> {
|
pub struct GeneralNamesIter<'a> {
|
||||||
names: &'a GeneralNames<'a>,
|
names: &'a GeneralNames<'a>,
|
||||||
idx: usize,
|
idx: usize,
|
||||||
|
|
@ -845,15 +855,24 @@ impl<'a> Iterator for GeneralNamesIter<'a> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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> {
|
pub struct GeneralName<'a> {
|
||||||
name: *const ffi::GENERAL_NAME,
|
name: *const ffi::GENERAL_NAME,
|
||||||
m: PhantomData<&'a ()>,
|
m: PhantomData<&'a ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GeneralName<'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 {
|
unsafe {
|
||||||
if (*self.name).type_ != ffi::GEN_DNS {
|
if (*self.name).type_ != ffi::GEN_DNS {
|
||||||
return None;
|
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 {
|
unsafe {
|
||||||
if (*self.name).type_ != ffi::GEN_IPADD {
|
if (*self.name).type_ != ffi::GEN_IPADD {
|
||||||
return None;
|
return None;
|
||||||
|
|
|
||||||
|
|
@ -165,9 +165,10 @@ fn test_subject_alt_name() {
|
||||||
|
|
||||||
let subject_alt_names = cert.subject_alt_names().unwrap();
|
let subject_alt_names = cert.subject_alt_names().unwrap();
|
||||||
assert_eq!(3, subject_alt_names.len());
|
assert_eq!(3, subject_alt_names.len());
|
||||||
assert_eq!(Some("foobar.com"), subject_alt_names.get(0).dns());
|
assert_eq!(Some("foobar.com"), subject_alt_names.get(0).dnsname());
|
||||||
assert_eq!(subject_alt_names.get(1).ipadd(), Some(&[127, 0, 0, 1][..]));
|
assert_eq!(subject_alt_names.get(1).ipaddress(), 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!(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]
|
#[test]
|
||||||
|
|
@ -177,8 +178,9 @@ fn test_subject_alt_name_iter() {
|
||||||
|
|
||||||
let subject_alt_names = cert.subject_alt_names().unwrap();
|
let subject_alt_names = cert.subject_alt_names().unwrap();
|
||||||
let mut subject_alt_names_iter = subject_alt_names.iter();
|
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().dnsname(), 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().ipaddress(), 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().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());
|
assert!(subject_alt_names_iter.next().is_none());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue