Add support for reading X509 subject information

This commit is contained in:
Joseph Glanville 2015-05-12 01:08:54 +10:00 committed by Joseph Glanville
parent e7a5ecc8dd
commit e88f1567b4
3 changed files with 253 additions and 2 deletions

View File

@ -22,3 +22,4 @@ pub mod bio;
pub mod crypto;
pub mod ssl;
pub mod x509;
pub mod nid;

170
openssl/src/nid.rs Normal file
View File

@ -0,0 +1,170 @@
#[allow(non_camel_case_types)]
#[derive(Copy, Clone)]
#[repr(usize)]
pub enum Nid {
Undefined,
Rsadsi,
Pkcs,
MD2,
MD4,
MD5,
RC4,
RsaEncryption,
RSA_MD2,
RSA_MD5,
PBE_MD2_DES,
X500,
x509,
CN,
C,
L,
ST,
O,
OU,
RSA,
Pkcs7,
Pkcs7_data,
Pkcs7_signedData,
Pkcs7_envelopedData,
Pkcs7_signedAndEnvelopedData,
Pkcs7_digestData,
Pkcs7_encryptedData,
Pkcs3,
DhKeyAgreement,
DES_ECB,
DES_CFB,
DES_CBC,
DES_EDE,
DES_EDE3,
IDEA_CBC,
IDEA_ECB,
RC2_CBC,
RC2_ECB,
RC2_CFB,
RC2_OFB,
SHA,
RSA_SHA,
DES_EDE_CBC,
DES_EDE3_CBC,
DES_OFB,
IDEA_OFB,
Pkcs9,
Email,
UnstructuredName,
ContentType,
MessageDigest,
SigningTime,
CounterSignature,
UnstructuredAddress,
ExtendedCertificateAttributes,
Netscape,
NetscapeCertExtention,
NetscapeDatatype,
DES_EDE_CFB64,
DES_EDE3_CFB64,
DES_EDE_OFB64,
DES_EDE3_OFB64,
SHA1,
RSA_SHA1,
DSA_SHA,
DSA_OLD,
PBE_SHA1_RC2_64,
PBKDF2,
DSA_SHA1_OLD,
NetscapeCertType,
NetscapeBaseUrl,
NetscapeRevocationUrl,
NetscapeCARevocationUrl,
NetscapeRenewalUrl,
NetscapeCAPolicyUrl,
NetscapeSSLServerName,
NetscapeComment,
NetscapeCertSequence,
DESX_CBC,
ID_CE,
SubjectKeyIdentifier,
KeyUsage,
PrivateKeyUsagePeriod,
SubjectAltName,
IssuerAltName,
BasicConstraints,
CrlNumber,
CertificatePolicies,
AuthorityKeyIdentifier,
BF_CBC,
BF_ECB,
BF_OFB,
MDC2,
RSA_MDC2,
RC4_40,
RC2_40_CBC,
G,
S,
I,
UID,
CrlDistributionPoints,
RSA_NP_MD5,
SN,
T,
D,
CAST5_CBC,
CAST5_ECB,
CAST5_CFB,
CAST5_OFB,
PbeWithMD5AndCast5CBC,
DSA_SHA1,
MD5_SHA1,
RSA_SHA1_2,
DSA,
RIPEMD160,
RSA_RIPEMD160,
RC5_CBC,
RC5_ECB,
RC5_CFB,
RC5_OFB,
RLE,
ZLIB,
ExtendedKeyUsage,
PKIX,
ID_KP,
ServerAuth,
ClientAuth,
CodeSigning,
EmailProtection,
TimeStamping,
MsCodeInd,
MsCodeCom,
MsCtlSigh,
MsSGC,
MsEFS,
NsSGC,
DeltaCRL,
CRLReason,
InvalidityDate,
SXNetID,
Pkcs12,
PBE_SHA1_RC4_128,
PBE_SHA1_RC4_40,
PBE_SHA1_3DES,
PBE_SHA1_2DES,
PBE_SHA1_RC2_128,
PBE_SHA1_RC2_40,
KeyBag,
Pkcs8ShroudedKeyBag,
CertBag,
CrlBag,
SecretBag,
SafeContentsBag,
FriendlyName,
LocalKeyID,
X509Certificate,
SdsiCertificate,
X509Crl,
PBES2,
PBMAC1,
HmacWithSha1,
ID_QT_CPS,
ID_QT_UNOTICE,
RC2_64_CBC,
SMIMECaps
}

View File

@ -1,11 +1,14 @@
use libc::{c_char, c_int, c_long, c_ulong, c_uint};
use libc::{c_char, c_int, c_long, c_ulong, c_uint, c_void};
use std::io;
use std::io::prelude::*;
use std::cmp::Ordering;
use std::ffi::CString;
use std::ffi::{CString, CStr};
use std::iter::repeat;
use std::mem;
use std::ptr;
use std::ops::Deref;
use std::fmt;
use std::str;
use asn1::{Asn1Time};
use bio::{MemBio};
@ -15,11 +18,50 @@ use crypto::pkey::{PKey,Parts};
use crypto::rand::rand_bytes;
use ffi;
use ssl::error::{SslError, StreamError};
use nid;
#[cfg(test)]
mod tests;
pub struct SslString<'s> {
s : &'s str
}
impl<'s> Drop for SslString<'s> {
fn drop(&mut self) {
unsafe { ffi::CRYPTO_free(self.s.as_ptr() as *mut c_void); }
}
}
impl<'s> Deref for SslString<'s> {
type Target = str;
fn deref(&self) -> &str {
self.s
}
}
impl<'s> SslString<'s> {
pub unsafe fn new(buf: *const c_char) -> SslString<'s> {
SslString {
s: str::from_utf8(CStr::from_ptr(buf).to_bytes()).unwrap()
}
}
}
impl<'s> fmt::Display for SslString<'s> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl<'s> fmt::Debug for SslString<'s> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
#[derive(Copy, Clone)]
#[repr(i32)]
pub enum X509FileType {
@ -458,6 +500,44 @@ pub struct X509Name<'x> {
name: *mut ffi::X509_NAME
}
#[allow(dead_code)]
pub struct X509NameEntry<'x> {
x509_name: &'x X509Name<'x>,
ne: *mut ffi::X509_NAME_ENTRY
}
impl <'x> X509Name<'x> {
pub fn text_by_nid(&self, nid: nid::Nid) -> Option<SslString> {
unsafe {
let loc = ffi::X509_NAME_get_index_by_NID(self.name, nid as c_int, -1);
if loc == -1 {
return None;
}
let ne = ffi::X509_NAME_get_entry(self.name, loc);
if ne.is_null() {
return None;
}
let asn1_str = ffi::X509_NAME_ENTRY_get_data(ne);
if asn1_str.is_null() {
return None;
}
let mut str_from_asn1 : *mut c_char = ptr::null_mut();
let len = ffi::ASN1_STRING_to_UTF8(&mut str_from_asn1, asn1_str);
if len < 0 {
return None
}
assert!(!str_from_asn1.is_null());
Some(SslString::new(str_from_asn1))
}
}
}
macro_rules! make_validation_error(
($ok_val:ident, $($name:ident = $val:ident,)+) => (
#[derive(Copy, Clone)]