Loading openssl/src/lib.rs +1 −0 Original line number Diff line number Diff line Loading @@ -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 } openssl/src/ssl/tests.rs +2 −2 Original line number Diff line number Diff line Loading @@ -223,7 +223,7 @@ run_test!(verify_callback_data, |method, stream| { // in DER format. // Command: openssl x509 -in test/cert.pem -outform DER | openssl dgst -sha256 // Please update if "test/cert.pem" will ever change let node_hash_str = "46e3f1a6d17a41ce70d0c66ef51cee2ab4ba67cac8940e23f10c1f944b49fb5c"; let node_hash_str = "db400bb62f1b1f29c3b8f323b8f7d9dea724fdcd67104ef549c772ae3749655b"; let node_id = node_hash_str.from_hex().unwrap(); ctx.set_verify_with_data(SSL_VERIFY_PEER, callback, node_id); ctx.set_verify_depth(1); Loading Loading @@ -320,7 +320,7 @@ run_test!(get_peer_certificate, |method, stream| { let stream = SslStream::new(&SslContext::new(method).unwrap(), stream).unwrap(); let cert = stream.get_peer_certificate().unwrap(); let fingerprint = cert.fingerprint(SHA256).unwrap(); let node_hash_str = "46e3f1a6d17a41ce70d0c66ef51cee2ab4ba67cac8940e23f10c1f944b49 fb5c"; let node_hash_str = "db400bb62f1b1f29c3b8f323b8f7d9dea724fdcd67104ef549c772ae3749655b"; let node_id = node_hash_str.from_hex().unwrap(); assert_eq!(node_id, fingerprint) }); Loading openssl/src/x509/mod.rs +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}; Loading @@ -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 { Loading Loading @@ -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)] Loading openssl/src/x509/tests.rs +19 −1 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ use crypto::hash::Type::{SHA256}; use x509::{X509, X509Generator}; use x509::KeyUsage::{DigitalSignature, KeyEncipherment}; use x509::ExtKeyUsage::{ClientAuth, ServerAuth}; use nid::Nid; #[test] fn test_cert_gen() { Loading Loading @@ -46,8 +47,25 @@ fn test_cert_loading() { // in DER format. // Command: openssl x509 -in test/cert.pem -outform DER | openssl dgst -sha256 // Please update if "test/cert.pem" will ever change let hash_str = "46e3f1a6d17a41ce70d0c66ef51cee2ab4ba67cac8940e23f10c1f944b49fb5c"; let hash_str = "db400bb62f1b1f29c3b8f323b8f7d9dea724fdcd67104ef549c772ae3749655b"; let hash_vec = hash_str.from_hex().unwrap(); assert_eq!(fingerprint, hash_vec); } #[test] fn test_subject_read_cn() { let cert_path = Path::new("test/cert.pem"); let mut file = File::open(&cert_path) .ok() .expect("Failed to open `test/cert.pem`"); let cert = X509::from_pem(&mut file).ok().expect("Failed to load PEM"); let subject = cert.subject_name(); let cn = match subject.text_by_nid(Nid::CN) { Some(x) => x, None => panic!("Failed to read CN from cert") }; assert_eq!(&cn as &str, "test_cert") } Loading
openssl/src/lib.rs +1 −0 Original line number Diff line number Diff line Loading @@ -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 }
openssl/src/ssl/tests.rs +2 −2 Original line number Diff line number Diff line Loading @@ -223,7 +223,7 @@ run_test!(verify_callback_data, |method, stream| { // in DER format. // Command: openssl x509 -in test/cert.pem -outform DER | openssl dgst -sha256 // Please update if "test/cert.pem" will ever change let node_hash_str = "46e3f1a6d17a41ce70d0c66ef51cee2ab4ba67cac8940e23f10c1f944b49fb5c"; let node_hash_str = "db400bb62f1b1f29c3b8f323b8f7d9dea724fdcd67104ef549c772ae3749655b"; let node_id = node_hash_str.from_hex().unwrap(); ctx.set_verify_with_data(SSL_VERIFY_PEER, callback, node_id); ctx.set_verify_depth(1); Loading Loading @@ -320,7 +320,7 @@ run_test!(get_peer_certificate, |method, stream| { let stream = SslStream::new(&SslContext::new(method).unwrap(), stream).unwrap(); let cert = stream.get_peer_certificate().unwrap(); let fingerprint = cert.fingerprint(SHA256).unwrap(); let node_hash_str = "46e3f1a6d17a41ce70d0c66ef51cee2ab4ba67cac8940e23f10c1f944b49 fb5c"; let node_hash_str = "db400bb62f1b1f29c3b8f323b8f7d9dea724fdcd67104ef549c772ae3749655b"; let node_id = node_hash_str.from_hex().unwrap(); assert_eq!(node_id, fingerprint) }); Loading
openssl/src/x509/mod.rs +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}; Loading @@ -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 { Loading Loading @@ -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)] Loading
openssl/src/x509/tests.rs +19 −1 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ use crypto::hash::Type::{SHA256}; use x509::{X509, X509Generator}; use x509::KeyUsage::{DigitalSignature, KeyEncipherment}; use x509::ExtKeyUsage::{ClientAuth, ServerAuth}; use nid::Nid; #[test] fn test_cert_gen() { Loading Loading @@ -46,8 +47,25 @@ fn test_cert_loading() { // in DER format. // Command: openssl x509 -in test/cert.pem -outform DER | openssl dgst -sha256 // Please update if "test/cert.pem" will ever change let hash_str = "46e3f1a6d17a41ce70d0c66ef51cee2ab4ba67cac8940e23f10c1f944b49fb5c"; let hash_str = "db400bb62f1b1f29c3b8f323b8f7d9dea724fdcd67104ef549c772ae3749655b"; let hash_vec = hash_str.from_hex().unwrap(); assert_eq!(fingerprint, hash_vec); } #[test] fn test_subject_read_cn() { let cert_path = Path::new("test/cert.pem"); let mut file = File::open(&cert_path) .ok() .expect("Failed to open `test/cert.pem`"); let cert = X509::from_pem(&mut file).ok().expect("Failed to load PEM"); let subject = cert.subject_name(); let cn = match subject.text_by_nid(Nid::CN) { Some(x) => x, None => panic!("Failed to read CN from cert") }; assert_eq!(&cn as &str, "test_cert") }