aboutsummaryrefslogtreecommitdiff
path: root/openssl/src
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2016-04-29 21:15:32 -0700
committerSteven Fackler <[email protected]>2016-04-29 21:15:32 -0700
commit32722e18501b06fbd51a8871f8bea0cddb4b132c (patch)
treea80964967a6aa180eabb05fc7ac8058476592fe9 /openssl/src
parentStart on GeneralName (diff)
downloadrust-openssl-32722e18501b06fbd51a8871f8bea0cddb4b132c.tar.xz
rust-openssl-32722e18501b06fbd51a8871f8bea0cddb4b132c.zip
Add accessors for x509 subject alt names
Diffstat (limited to 'openssl/src')
-rw-r--r--openssl/src/x509/extension.rs38
-rw-r--r--openssl/src/x509/mod.rs79
-rw-r--r--openssl/src/x509/tests.rs12
3 files changed, 89 insertions, 40 deletions
diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs
index c0b3bad4..7ff0c1ca 100644
--- a/openssl/src/x509/extension.rs
+++ b/openssl/src/x509/extension.rs
@@ -1,8 +1,4 @@
use std::fmt;
-use std::marker::PhantomData;
-use std::slice;
-use std::str;
-use ffi;
use nid::Nid;
@@ -223,37 +219,3 @@ impl fmt::Display for AltNameOption {
})
}
}
-
-pub struct GeneralName<'a> {
- name: *const ffi::GENERAL_NAME,
- m: PhantomData<&'a ()>,
-}
-
-impl<'a> GeneralName<'a> {
- pub fn dns(&self) -> Option<&str> {
- unsafe {
- if (*self.name).type_ != ffi::GEN_DNS {
- return None;
- }
-
- let ptr = ffi::ASN1_STRING_data((*self.name).d as *mut _);
- let len = ffi::ASN1_STRING_length((*self.name).d as *mut _);
-
- let slice = slice::from_raw_parts(ptr as *const u8, len as usize);
- Some(str::from_utf8_unchecked(slice))
- }
- }
-
- pub fn ipadd(&self) -> Option<&[u8]> {
- unsafe {
- if (*self.name).type_ != ffi::GEN_IPADD {
- return None;
- }
-
- let ptr = ffi::ASN1_STRING_data((*self.name).d as *mut _);
- let len = ffi::ASN1_STRING_length((*self.name).d as *mut _);
-
- Some(slice::from_raw_parts(ptr as *const u8, len as usize))
- }
- }
-}
diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs
index cb2c7494..cdd729aa 100644
--- a/openssl/src/x509/mod.rs
+++ b/openssl/src/x509/mod.rs
@@ -11,6 +11,7 @@ use std::fmt;
use std::str;
use std::slice;
use std::collections::HashMap;
+use std::marker::PhantomData;
use asn1::Asn1Time;
use bio::MemBio;
@@ -21,7 +22,7 @@ use crypto::rand::rand_bytes;
use ffi;
use ffi_extras;
use ssl::error::{SslError, StreamError};
-use nid;
+use nid::Nid;
pub mod extension;
@@ -464,6 +465,23 @@ impl<'ctx> X509<'ctx> {
}
}
+ pub fn subject_alt_names<'a>(&'a self) -> Option<GeneralNames<'a>> {
+ unsafe {
+ let stack = ffi::X509_get_ext_d2i(self.handle,
+ Nid::SubjectAltName as c_int,
+ ptr::null_mut(),
+ ptr::null_mut());
+ if stack.is_null() {
+ return None;
+ }
+
+ Some(GeneralNames {
+ stack: stack as *const _,
+ m: PhantomData,
+ })
+ }
+ }
+
pub fn public_key(&self) -> PKey {
let pkey = unsafe { ffi::X509_get_pubkey(self.handle) };
assert!(!pkey.is_null());
@@ -544,7 +562,7 @@ pub struct X509NameEntry<'x> {
}
impl<'x> X509Name<'x> {
- pub fn text_by_nid(&self, nid: nid::Nid) -> Option<SslString> {
+ pub fn text_by_nid(&self, nid: Nid) -> Option<SslString> {
unsafe {
let loc = ffi::X509_NAME_get_index_by_NID(self.name, nid as c_int, -1);
if loc == -1 {
@@ -766,6 +784,63 @@ make_validation_error!(X509_V_OK,
X509ApplicationVerification = X509_V_ERR_APPLICATION_VERIFICATION,
);
+pub struct GeneralNames<'a> {
+ stack: *const ffi::stack_st_GENERAL_NAME,
+ m: PhantomData<&'a ()>,
+}
+
+impl<'a> GeneralNames<'a> {
+ pub fn len(&self) -> usize {
+ unsafe {
+ (*self.stack).stack.num as usize
+ }
+ }
+
+ pub fn get(&self, idx: usize) -> GeneralName<'a> {
+ unsafe {
+ assert!(idx < self.len());
+
+ GeneralName {
+ name: *(*self.stack).stack.data.offset(idx as isize) as *const ffi::GENERAL_NAME,
+ m: PhantomData,
+ }
+ }
+ }
+}
+
+pub struct GeneralName<'a> {
+ name: *const ffi::GENERAL_NAME,
+ m: PhantomData<&'a ()>,
+}
+
+impl<'a> GeneralName<'a> {
+ pub fn dns(&self) -> Option<&str> {
+ unsafe {
+ if (*self.name).type_ != ffi::GEN_DNS {
+ return None;
+ }
+
+ let ptr = ffi::ASN1_STRING_data((*self.name).d as *mut _);
+ let len = ffi::ASN1_STRING_length((*self.name).d as *mut _);
+
+ let slice = slice::from_raw_parts(ptr as *const u8, len as usize);
+ Some(str::from_utf8_unchecked(slice))
+ }
+ }
+
+ pub fn ipadd(&self) -> Option<&[u8]> {
+ unsafe {
+ if (*self.name).type_ != ffi::GEN_IPADD {
+ return None;
+ }
+
+ let ptr = ffi::ASN1_STRING_data((*self.name).d as *mut _);
+ let len = ffi::ASN1_STRING_length((*self.name).d as *mut _);
+
+ Some(slice::from_raw_parts(ptr as *const u8, len as usize))
+ }
+ }
+}
#[test]
fn test_negative_serial() {
diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs
index 69ad37f8..5f4d432e 100644
--- a/openssl/src/x509/tests.rs
+++ b/openssl/src/x509/tests.rs
@@ -157,3 +157,15 @@ fn test_nid_uid_value() {
};
assert_eq!(&cn as &str, "this is the userId");
}
+
+#[test]
+fn test_subject_alt_name() {
+ let mut file = File::open("test/alt_name_cert.pem").unwrap();
+ let cert = X509::from_pem(&mut file).unwrap();
+
+ 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"[..]));
+}