diff options
Diffstat (limited to 'openssl/src/x509/mod.rs')
| -rw-r--r-- | openssl/src/x509/mod.rs | 186 |
1 files changed, 111 insertions, 75 deletions
diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index c7039089..ffd478ef 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -11,11 +11,11 @@ use std::fmt; use std::str; use std::collections::HashMap; -use asn1::{Asn1Time}; -use bio::{MemBio}; +use asn1::Asn1Time; +use bio::MemBio; use crypto::hash; use crypto::hash::Type as HashType; -use crypto::pkey::{PKey,Parts}; +use crypto::pkey::{PKey, Parts}; use crypto::rand::rand_bytes; use ffi; use ffi_extras; @@ -24,18 +24,20 @@ use nid; pub mod extension; -use self::extension::{ExtensionType,Extension}; +use self::extension::{ExtensionType, Extension}; #[cfg(test)] mod tests; pub struct SslString { - s : &'static str + s: &'static str, } impl<'s> Drop for SslString { fn drop(&mut self) { - unsafe { ffi::CRYPTO_free(self.s.as_ptr() as *mut c_void); } + unsafe { + ffi::CRYPTO_free(self.s.as_ptr() as *mut c_void); + } } } @@ -49,9 +51,7 @@ impl Deref for SslString { impl SslString { unsafe fn new(buf: *const c_char) -> SslString { - SslString { - s: str::from_utf8(CStr::from_ptr(buf as *const _).to_bytes()).unwrap() - } + SslString { s: str::from_utf8(CStr::from_ptr(buf as *const _).to_bytes()).unwrap() } } } @@ -72,19 +72,17 @@ impl fmt::Debug for SslString { pub enum X509FileType { PEM = ffi::X509_FILETYPE_PEM, ASN1 = ffi::X509_FILETYPE_ASN1, - Default = ffi::X509_FILETYPE_DEFAULT + Default = ffi::X509_FILETYPE_DEFAULT, } #[allow(missing_copy_implementations)] pub struct X509StoreContext { - ctx: *mut ffi::X509_STORE_CTX + ctx: *mut ffi::X509_STORE_CTX, } impl X509StoreContext { pub fn new(ctx: *mut ffi::X509_STORE_CTX) -> X509StoreContext { - X509StoreContext { - ctx: ctx - } + X509StoreContext { ctx: ctx } } pub fn get_error(&self) -> Option<X509ValidationError> { @@ -98,7 +96,11 @@ impl X509StoreContext { if ptr.is_null() { None } else { - Some(X509 { ctx: Some(self), handle: ptr, owned: false }) + Some(X509 { + ctx: Some(self), + handle: ptr, + owned: false, + }) } } } @@ -143,9 +145,9 @@ impl X509StoreContext { pub struct X509Generator { bits: u32, days: u32, - names: Vec<(String,String)>, + names: Vec<(String, String)>, // RFC 3280 ยง4.2: A certificate MUST NOT include more than one instance of a particular extension. - extensions: HashMap<ExtensionType,Extension>, + extensions: HashMap<ExtensionType, Extension>, hash_type: HashType, } @@ -165,7 +167,7 @@ impl X509Generator { days: 365, names: vec![], extensions: HashMap::new(), - hash_type: HashType::SHA1 + hash_type: HashType::SHA1, } } @@ -188,7 +190,7 @@ impl X509Generator { /// generator.add_name("CN".to_string(),"example.com".to_string()); /// ``` pub fn add_name(mut self, attr_type: String, attr_value: String) -> X509Generator { - self.names.push((attr_type,attr_value)); + self.names.push((attr_type, attr_value)); self } @@ -199,7 +201,8 @@ impl X509Generator { /// generator.add_names(vec![("CN".to_string(),"example.com".to_string())]); /// ``` pub fn add_names<I>(mut self, attrs: I) -> X509Generator - where I: IntoIterator<Item=(String,String)> { + where I: IntoIterator<Item = (String, String)> + { self.names.extend(attrs); self } @@ -216,7 +219,7 @@ impl X509Generator { /// generator.add_extension(KeyUsage(vec![DigitalSignature, KeyEncipherment])); /// ``` pub fn add_extension(mut self, ext: extension::Extension) -> X509Generator { - self.extensions.insert(ext.get_type(),ext); + self.extensions.insert(ext.get_type(), ext); self } @@ -232,8 +235,9 @@ impl X509Generator { /// generator.add_extensions(vec![KeyUsage(vec![DigitalSignature, KeyEncipherment])]); /// ``` pub fn add_extensions<I>(mut self, exts: I) -> X509Generator - where I: IntoIterator<Item=extension::Extension> { - self.extensions.extend(exts.into_iter().map(|ext|(ext.get_type(),ext))); + where I: IntoIterator<Item = extension::Extension> + { + self.extensions.extend(exts.into_iter().map(|ext| (ext.get_type(), ext))); self } @@ -242,23 +246,27 @@ impl X509Generator { self } - fn add_extension_internal(x509: *mut ffi::X509, exttype: &extension::ExtensionType, value: &str) -> Result<(), SslError> { + fn add_extension_internal(x509: *mut ffi::X509, + exttype: &extension::ExtensionType, + value: &str) + -> Result<(), SslError> { unsafe { let mut ctx: ffi::X509V3_CTX = mem::zeroed(); - ffi::X509V3_set_ctx(&mut ctx, x509, x509, - ptr::null_mut(), ptr::null_mut(), 0); + ffi::X509V3_set_ctx(&mut ctx, x509, x509, ptr::null_mut(), ptr::null_mut(), 0); let value = CString::new(value.as_bytes()).unwrap(); - let ext=match exttype.get_nid() { - Some(nid) => ffi::X509V3_EXT_conf_nid(ptr::null_mut(), - mem::transmute(&ctx), - nid as c_int, - value.as_ptr() as *mut c_char), + let ext = match exttype.get_nid() { + Some(nid) => { + ffi::X509V3_EXT_conf_nid(ptr::null_mut(), + mem::transmute(&ctx), + nid as c_int, + value.as_ptr() as *mut c_char) + } None => { - let name=CString::new(exttype.get_name().unwrap().as_bytes()).unwrap(); + let name = CString::new(exttype.get_name().unwrap().as_bytes()).unwrap(); ffi::X509V3_EXT_conf(ptr::null_mut(), - mem::transmute(&ctx), - name.as_ptr() as *mut c_char, - value.as_ptr() as *mut c_char) + mem::transmute(&ctx), + name.as_ptr() as *mut c_char, + value.as_ptr() as *mut c_char) } }; let mut success = false; @@ -270,13 +278,21 @@ impl X509Generator { } } - fn add_name_internal(name: *mut ffi::X509_NAME, key: &str, value: &str) -> Result<(), SslError> { + fn add_name_internal(name: *mut ffi::X509_NAME, + key: &str, + value: &str) + -> Result<(), SslError> { let value_len = value.len() as c_int; lift_ssl!(unsafe { let key = CString::new(key.as_bytes()).unwrap(); let value = CString::new(value.as_bytes()).unwrap(); - ffi::X509_NAME_add_entry_by_txt(name, key.as_ptr() as *const _, ffi::MBSTRING_UTF8, - value.as_ptr() as *const _, value_len, -1, 0) + ffi::X509_NAME_add_entry_by_txt(name, + key.as_ptr() as *const _, + ffi::MBSTRING_UTF8, + value.as_ptr() as *const _, + value_len, + -1, + 0) }) } @@ -315,10 +331,15 @@ impl X509Generator { let x509 = ffi::X509_new(); try_ssl_null!(x509); - let x509 = X509 { handle: x509, ctx: None, owned: true}; + let x509 = X509 { + handle: x509, + ctx: None, + owned: true, + }; try_ssl!(ffi::X509_set_version(x509.handle, 2)); - try_ssl!(ffi::ASN1_INTEGER_set(ffi::X509_get_serialNumber(x509.handle), X509Generator::random_serial())); + try_ssl!(ffi::ASN1_INTEGER_set(ffi::X509_get_serialNumber(x509.handle), + X509Generator::random_serial())); let not_before = try!(Asn1Time::days_from_now(0)); let not_after = try!(Asn1Time::days_from_now(self.days)); @@ -336,18 +357,21 @@ impl X509Generator { let name = ffi::X509_get_subject_name(x509.handle); try_ssl_null!(name); - let default=[("CN","rust-openssl")]; - let default_iter=&mut default.iter().map(|&(k,v)|(k,v)); - let arg_iter=&mut self.names.iter().map(|&(ref k,ref v)|(&k[..],&v[..])); - let iter: &mut Iterator<Item=(&str,&str)> = - if self.names.len()==0 { default_iter } else { arg_iter }; + let default = [("CN", "rust-openssl")]; + let default_iter = &mut default.iter().map(|&(k, v)| (k, v)); + let arg_iter = &mut self.names.iter().map(|&(ref k, ref v)| (&k[..], &v[..])); + let iter: &mut Iterator<Item = (&str, &str)> = if self.names.len() == 0 { + default_iter + } else { + arg_iter + }; - for (key,val) in iter { + for (key, val) in iter { try!(X509Generator::add_name_internal(name, &key, &val)); } ffi::X509_set_issuer_name(x509.handle, name); - for (exttype,ext) in self.extensions.iter() { + for (exttype, ext) in self.extensions.iter() { try!(X509Generator::add_extension_internal(x509.handle, exttype, &ext.to_string())); } @@ -359,9 +383,9 @@ impl X509Generator { /// Obtain a certificate signing request (CSR) pub fn request(&self, p_key: &PKey) -> Result<X509Req, SslError> { - let cert=match self.sign(p_key) { + let cert = match self.sign(p_key) { Ok(c) => c, - Err(x) => return Err(x) + Err(x) => return Err(x), }; unsafe { @@ -370,7 +394,7 @@ impl X509Generator { let exts = ffi_extras::X509_get_extensions(cert.handle); if exts != ptr::null_mut() { - try_ssl!(ffi::X509_REQ_add_extensions(req,exts)); + try_ssl!(ffi::X509_REQ_add_extensions(req, exts)); } let hash_fn = self.hash_type.evp_md(); @@ -387,7 +411,7 @@ impl X509Generator { pub struct X509<'ctx> { ctx: Option<&'ctx X509StoreContext>, handle: *mut ffi::X509, - owned: bool + owned: bool, } impl<'ctx> X509<'ctx> { @@ -406,19 +430,22 @@ impl<'ctx> X509<'ctx> { X509 { ctx: Some(ctx), handle: handle, - owned: false + owned: false, } } /// Reads certificate from PEM, takes ownership of handle - pub fn from_pem<R>(reader: &mut R) -> Result<X509<'ctx>, SslError> where R: Read { + pub fn from_pem<R>(reader: &mut R) -> Result<X509<'ctx>, SslError> + where R: Read + { let mut mem_bio = try!(MemBio::new()); try!(io::copy(reader, &mut mem_bio).map_err(StreamError)); unsafe { let handle = try_ssl_null!(ffi::PEM_read_bio_X509(mem_bio.get_handle(), ptr::null_mut(), - None, ptr::null_mut())); + None, + ptr::null_mut())); Ok(X509::new(handle, true)) } } @@ -429,7 +456,10 @@ impl<'ctx> X509<'ctx> { pub fn subject_name<'a>(&'a self) -> X509Name<'a> { let name = unsafe { ffi::X509_get_subject_name(self.handle) }; - X509Name { x509: self, name: name } + X509Name { + x509: self, + name: name, + } } pub fn public_key(&self) -> PKey { @@ -446,7 +476,9 @@ impl<'ctx> X509<'ctx> { let v: Vec<u8> = repeat(0).take(len as usize).collect(); let act_len: c_uint = 0; let res = unsafe { - ffi::X509_digest(self.handle, evp, mem::transmute(v.as_ptr()), + ffi::X509_digest(self.handle, + evp, + mem::transmute(v.as_ptr()), mem::transmute(&act_len)) }; @@ -457,18 +489,19 @@ impl<'ctx> X509<'ctx> { match len.cmp(&act_len) { Ordering::Greater => None, Ordering::Equal => Some(v), - Ordering::Less => panic!("Fingerprint buffer was corrupted!") + Ordering::Less => panic!("Fingerprint buffer was corrupted!"), } } } } /// Writes certificate as PEM - pub fn write_pem<W>(&self, writer: &mut W) -> Result<(), SslError> where W: Write { + pub fn write_pem<W>(&self, writer: &mut W) -> Result<(), SslError> + where W: Write + { let mut mem_bio = try!(MemBio::new()); unsafe { - try_ssl!(ffi::PEM_write_bio_X509(mem_bio.get_handle(), - self.handle)); + try_ssl!(ffi::PEM_write_bio_X509(mem_bio.get_handle(), self.handle)); } io::copy(&mut mem_bio, writer).map_err(StreamError).map(|_| ()) } @@ -485,16 +518,16 @@ impl<'ctx> Drop for X509<'ctx> { #[allow(dead_code)] pub struct X509Name<'x> { x509: &'x X509<'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 + ne: *mut ffi::X509_NAME_ENTRY, } -impl <'x> X509Name<'x> { +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); @@ -512,11 +545,11 @@ impl <'x> X509Name<'x> { return None; } - let mut str_from_asn1 : *mut c_char = ptr::null_mut(); + 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 + return None; } assert!(!str_from_asn1.is_null()); @@ -534,30 +567,32 @@ pub struct X509Req { impl X509Req { /// Creates new from handle pub fn new(handle: *mut ffi::X509_REQ) -> X509Req { - X509Req { - handle: handle, - } + X509Req { handle: handle } } /// Reads CSR from PEM - pub fn from_pem<R>(reader: &mut R) -> Result<X509Req, SslError> where R: Read { + pub fn from_pem<R>(reader: &mut R) -> Result<X509Req, SslError> + where R: Read + { let mut mem_bio = try!(MemBio::new()); try!(io::copy(reader, &mut mem_bio).map_err(StreamError)); unsafe { let handle = try_ssl_null!(ffi::PEM_read_bio_X509_REQ(mem_bio.get_handle(), - ptr::null_mut(), - None, ptr::null_mut())); + ptr::null_mut(), + None, + ptr::null_mut())); Ok(X509Req::new(handle)) } } /// Writes CSR as PEM - pub fn write_pem<W>(&self, writer: &mut W) -> Result<(), SslError> where W: Write { + pub fn write_pem<W>(&self, writer: &mut W) -> Result<(), SslError> + where W: Write + { let mut mem_bio = try!(MemBio::new()); unsafe { - try_ssl!(ffi::PEM_write_bio_X509_REQ(mem_bio.get_handle(), - self.handle)); + try_ssl!(ffi::PEM_write_bio_X509_REQ(mem_bio.get_handle(), self.handle)); } io::copy(&mut mem_bio, writer).map_err(StreamError).map(|_| ()) } @@ -651,6 +686,7 @@ make_validation_error!(X509_V_OK, fn test_negative_serial() { // I guess that's enough to get a random negative number for _ in 0..1000 { - assert!(X509Generator::random_serial() > 0, "All serials should be positive"); + assert!(X509Generator::random_serial() > 0, + "All serials should be positive"); } } |