Commit e88f1567 authored by Joseph Glanville's avatar Joseph Glanville Committed by Joseph Glanville
Browse files

Add support for reading X509 subject information

parent e7a5ecc8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -22,3 +22,4 @@ pub mod bio;
pub mod crypto;
pub mod ssl;
pub mod x509;
pub mod nid;

openssl/src/nid.rs

0 → 100644
+170 −0
Original line number Diff line number Diff line
#[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
}
+82 −2
Original line number Diff line number Diff line
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)]