Add support for reading X509 subject information
This commit is contained in:
parent
e7a5ecc8dd
commit
e88f1567b4
|
|
@ -22,3 +22,4 @@ pub mod bio;
|
||||||
pub mod crypto;
|
pub mod crypto;
|
||||||
pub mod ssl;
|
pub mod ssl;
|
||||||
pub mod x509;
|
pub mod x509;
|
||||||
|
pub mod nid;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::ffi::CString;
|
use std::ffi::{CString, CStr};
|
||||||
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::fmt;
|
||||||
|
use std::str;
|
||||||
|
|
||||||
use asn1::{Asn1Time};
|
use asn1::{Asn1Time};
|
||||||
use bio::{MemBio};
|
use bio::{MemBio};
|
||||||
|
|
@ -15,11 +18,50 @@ use crypto::pkey::{PKey,Parts};
|
||||||
use crypto::rand::rand_bytes;
|
use crypto::rand::rand_bytes;
|
||||||
use ffi;
|
use ffi;
|
||||||
use ssl::error::{SslError, StreamError};
|
use ssl::error::{SslError, StreamError};
|
||||||
|
use nid;
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
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)]
|
#[derive(Copy, Clone)]
|
||||||
#[repr(i32)]
|
#[repr(i32)]
|
||||||
pub enum X509FileType {
|
pub enum X509FileType {
|
||||||
|
|
@ -458,6 +500,44 @@ pub struct X509Name<'x> {
|
||||||
name: *mut ffi::X509_NAME
|
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(
|
macro_rules! make_validation_error(
|
||||||
($ok_val:ident, $($name:ident = $val:ident,)+) => (
|
($ok_val:ident, $($name:ident = $val:ident,)+) => (
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue