Start on GeneralName

This commit is contained in:
Steven Fackler 2016-04-28 22:16:29 -07:00
parent d6bc3bb16f
commit caf9272c85
3 changed files with 97 additions and 13 deletions

View File

@ -34,10 +34,23 @@ pub type X509_NAME = c_void;
pub type X509_NAME_ENTRY = c_void; pub type X509_NAME_ENTRY = c_void;
pub type X509_REQ = c_void; pub type X509_REQ = c_void;
pub type X509_STORE_CTX = c_void; pub type X509_STORE_CTX = c_void;
pub type stack_st_X509_EXTENSION = c_void;
pub type stack_st_void = c_void;
pub type bio_st = c_void; pub type bio_st = c_void;
#[repr(C)]
pub struct stack_st_X509_EXTENSION {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_GENERAL_NAME {
pub stack: _STACK,
}
#[repr(C)]
pub struct stack_st_void {
pub stack: _STACK,
}
pub type bio_info_cb = Option<unsafe extern "C" fn(*mut BIO, pub type bio_info_cb = Option<unsafe extern "C" fn(*mut BIO,
c_int, c_int,
*const c_char, *const c_char,
@ -63,6 +76,15 @@ pub struct BIO_METHOD {
// so we can create static BIO_METHODs // so we can create static BIO_METHODs
unsafe impl Sync for BIO_METHOD {} unsafe impl Sync for BIO_METHOD {}
#[repr(C)]
pub struct _STACK {
pub num: c_int,
pub data: *mut *mut c_char,
pub sorted: c_int,
pub num_alloc: c_int,
pub comp: Option<unsafe extern "C" fn(*const c_void, *const c_void)>,
}
#[repr(C)] #[repr(C)]
pub struct RSA { pub struct RSA {
pub pad: c_int, pub pad: c_int,
@ -178,6 +200,17 @@ pub struct X509V3_CTX {
// Maybe more here // Maybe more here
} }
#[repr(C)]
pub struct GENERAL_NAME {
pub type_: c_int,
pub d: *mut c_void,
}
impl Copy for GENERAL_NAME {}
impl Clone for GENERAL_NAME {
fn clone(&self) -> GENERAL_NAME { *self }
}
impl Copy for X509V3_CTX {} impl Copy for X509V3_CTX {}
impl Clone for X509V3_CTX { impl Clone for X509V3_CTX {
fn clone(&self) -> X509V3_CTX { *self } fn clone(&self) -> X509V3_CTX { *self }
@ -333,6 +366,16 @@ pub const X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: c_int = 45;
pub const X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: c_int = 53; pub const X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: c_int = 53;
pub const X509_V_OK: c_int = 0; pub const X509_V_OK: c_int = 0;
pub const GEN_OTHERNAME: c_int = 0;
pub const GEN_EMAIL: c_int = 1;
pub const GEN_DNS: c_int = 2;
pub const GEN_X400: c_int = 3;
pub const GEN_DIRNAME: c_int = 4;
pub const GEN_EDIPARTY: c_int = 5;
pub const GEN_URI: c_int = 6;
pub const GEN_IPADD: c_int = 7;
pub const GEN_RID: c_int = 8;
static mut MUTEXES: *mut Vec<Mutex<()>> = 0 as *mut Vec<Mutex<()>>; static mut MUTEXES: *mut Vec<Mutex<()>> = 0 as *mut Vec<Mutex<()>>;
static mut GUARDS: *mut Vec<Option<MutexGuard<'static, ()>>> = 0 as *mut Vec<Option<MutexGuard<'static, ()>>>; static mut GUARDS: *mut Vec<Option<MutexGuard<'static, ()>>> = 0 as *mut Vec<Option<MutexGuard<'static, ()>>>;
@ -760,6 +803,8 @@ extern "C" {
pub fn X509_NAME_ENTRY_get_data(ne: *mut X509_NAME_ENTRY) -> *mut ASN1_STRING; pub fn X509_NAME_ENTRY_get_data(ne: *mut X509_NAME_ENTRY) -> *mut ASN1_STRING;
pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_char, s: *mut ASN1_STRING) -> c_int; pub fn ASN1_STRING_to_UTF8(out: *mut *mut c_char, s: *mut ASN1_STRING) -> c_int;
pub fn ASN1_STRING_length(x: *mut ASN1_STRING) -> c_int;
pub fn ASN1_STRING_data(x: *mut ASN1_STRING) -> *mut c_uchar;
pub fn X509_STORE_CTX_get_current_cert(ct: *mut X509_STORE_CTX) -> *mut X509; pub fn X509_STORE_CTX_get_current_cert(ct: *mut X509_STORE_CTX) -> *mut X509;
pub fn X509_STORE_CTX_get_error(ctx: *mut X509_STORE_CTX) -> c_int; pub fn X509_STORE_CTX_get_error(ctx: *mut X509_STORE_CTX) -> c_int;

View File

@ -1,4 +1,9 @@
use std::fmt; use std::fmt;
use std::marker::PhantomData;
use std::slice;
use std::str;
use ffi;
use nid::Nid; use nid::Nid;
/// Type-only version of the `Extension` enum. /// Type-only version of the `Extension` enum.
@ -218,3 +223,37 @@ 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))
}
}
}

View File

@ -2,13 +2,14 @@ use libc::{c_char, c_int, c_long, c_ulong, c_uint, c_void};
use std::io; use std::io;
use std::io::prelude::*; use std::io::prelude::*;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::ffi::{CString, CStr}; use std::ffi::CString;
use std::iter::repeat; use std::iter::repeat;
use std::mem; use std::mem;
use std::ptr; use std::ptr;
use std::ops::Deref; use std::ops::Deref;
use std::fmt; use std::fmt;
use std::str; use std::str;
use std::slice;
use std::collections::HashMap; use std::collections::HashMap;
use asn1::Asn1Time; use asn1::Asn1Time;
@ -29,14 +30,12 @@ use self::extension::{ExtensionType, Extension};
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
pub struct SslString { pub struct SslString(&'static str);
s: &'static str,
}
impl<'s> Drop for SslString { impl<'s> Drop for SslString {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
ffi::CRYPTO_free(self.s.as_ptr() as *mut c_void); ffi::CRYPTO_free(self.0.as_ptr() as *mut c_void);
} }
} }
} }
@ -45,25 +44,26 @@ impl Deref for SslString {
type Target = str; type Target = str;
fn deref(&self) -> &str { fn deref(&self) -> &str {
self.s self.0
} }
} }
impl SslString { impl SslString {
unsafe fn new(buf: *const c_char) -> SslString { unsafe fn new(buf: *const c_char, len: c_int) -> SslString {
SslString { s: str::from_utf8(CStr::from_ptr(buf as *const _).to_bytes()).unwrap() } let slice = slice::from_raw_parts(buf as *const _, len as usize);
SslString(str::from_utf8_unchecked(slice))
} }
} }
impl fmt::Display for SslString { impl fmt::Display for SslString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self.s, f) fmt::Display::fmt(self.0, f)
} }
} }
impl fmt::Debug for SslString { impl fmt::Debug for SslString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(self.s, f) fmt::Debug::fmt(self.0, f)
} }
} }
@ -570,7 +570,7 @@ impl<'x> X509Name<'x> {
assert!(!str_from_asn1.is_null()); assert!(!str_from_asn1.is_null());
Some(SslString::new(str_from_asn1)) Some(SslString::new(str_from_asn1, len))
} }
} }
} }