diff --git a/openssl-sys/src/lib.rs b/openssl-sys/src/lib.rs index 9f2041a4..950ca42f 100644 --- a/openssl-sys/src/lib.rs +++ b/openssl-sys/src/lib.rs @@ -603,6 +603,7 @@ extern "C" { pub fn X509_STORE_CTX_get_ex_data(ctx: *mut X509_STORE_CTX, idx: c_int) -> *mut c_void; pub fn X509V3_EXT_conf_nid(conf: *mut c_void, ctx: *mut X509V3_CTX, ext_nid: c_int, value: *mut c_char) -> *mut X509_EXTENSION; + pub fn X509V3_EXT_conf(conf: *mut c_void, ctx: *mut X509V3_CTX, name: *mut c_char, value: *mut c_char) -> *mut X509_EXTENSION; pub fn X509V3_set_ctx(ctx: *mut X509V3_CTX, issuer: *mut X509, subject: *mut X509, req: *mut X509_REQ, crl: *mut X509_CRL, flags: c_int); pub fn i2d_RSA_PUBKEY(k: *mut RSA, buf: *const *mut u8) -> c_int; diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index 4576ad1a..78058b72 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -1,11 +1,12 @@ use std::fmt; use nid::Nid; -#[derive(Clone,Copy,Hash,PartialEq,Eq)] +#[derive(Clone,Hash,PartialEq,Eq)] pub enum ExtensionType { KeyUsage, ExtKeyUsage, OtherNid(Nid), + OtherStr(String), } #[derive(Clone)] @@ -13,6 +14,7 @@ pub enum Extension { KeyUsage(Vec), ExtKeyUsage(Vec), OtherNid(Nid,String), + OtherStr(String,String), } impl Extension { @@ -21,14 +23,25 @@ impl Extension { &Extension::KeyUsage(_) => ExtensionType::KeyUsage, &Extension::ExtKeyUsage(_) => ExtensionType::ExtKeyUsage, &Extension::OtherNid(nid,_) => ExtensionType::OtherNid(nid), + &Extension::OtherStr(ref s,_) => ExtensionType::OtherStr(s.clone()), + } + } +} + +impl ExtensionType { + pub fn get_nid(&self) -> Option { + match self { + &ExtensionType::KeyUsage => Some(Nid::KeyUsage), + &ExtensionType::ExtKeyUsage => Some(Nid::ExtendedKeyUsage), + &ExtensionType::OtherNid(nid) => Some(nid), + &ExtensionType::OtherStr(_) => None, } } - pub fn get_nid(&self) -> Nid { + pub fn get_name<'a>(&'a self) -> Option<&'a str> { match self { - &Extension::KeyUsage(_) => Nid::KeyUsage, - &Extension::ExtKeyUsage(_) => Nid::ExtendedKeyUsage, - &Extension::OtherNid(nid,_) => nid, + &ExtensionType::OtherStr(ref s) => Some(s), + _ => None, } } } @@ -49,6 +62,7 @@ impl ToString for Extension { &Extension::KeyUsage(ref purposes) => join(purposes.iter(),","), &Extension::ExtKeyUsage(ref purposes) => join(purposes.iter(),","), &Extension::OtherNid(_,ref value) => value.clone(), + &Extension::OtherStr(_,ref value) => value.clone(), } } } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 42bb7a08..423a258f 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -242,17 +242,22 @@ impl X509Generator { self } - fn add_extension_internal(x509: *mut ffi::X509, extension: c_int, 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); let value = CString::new(value.as_bytes()).unwrap(); - let ext = ffi::X509V3_EXT_conf_nid(ptr::null_mut(), + let ext=match exttype.get_nid() { + Some(nid) => ffi::X509V3_EXT_conf_nid(ptr::null_mut(), mem::transmute(&ctx), - extension, - value.as_ptr() as *mut c_char); - + nid as c_int, + value.as_ptr() as *mut c_char), + None => ffi::X509V3_EXT_conf(ptr::null_mut(), + mem::transmute(&ctx), + exttype.get_name().unwrap().as_ptr() as *mut c_char, + value.as_ptr() as *mut c_char), + }; let mut success = false; if ext != ptr::null_mut() { success = ffi::X509_add_ext(x509, ext, -1) != 0; @@ -331,8 +336,8 @@ impl X509Generator { try!(X509Generator::add_name(name, "CN", &self.CN)); ffi::X509_set_issuer_name(x509.handle, name); - for ext in self.extensions.values() { - try!(X509Generator::add_extension_internal(x509.handle, ext.get_nid() as c_int, &ext.to_string())); + for (exttype,ext) in self.extensions.iter() { + try!(X509Generator::add_extension_internal(x509.handle, exttype, &ext.to_string())); } let hash_fn = self.hash_type.evp_md(); diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 0061453c..ff7d1173 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -5,7 +5,7 @@ use std::fs::File; use crypto::hash::Type::{SHA256}; use x509::{X509, X509Generator}; -use x509::extension::Extension::{KeyUsage,ExtKeyUsage,OtherNid}; +use x509::extension::Extension::{KeyUsage,ExtKeyUsage,OtherNid,OtherStr}; use x509::extension::KeyUsageOption::{DigitalSignature, KeyEncipherment}; use x509::extension::ExtKeyUsageOption::{self, ClientAuth, ServerAuth}; use nid::Nid; @@ -18,8 +18,9 @@ fn test_cert_gen() { .set_CN("test_me") .set_sign_hash(SHA256) .add_extension(KeyUsage(vec![DigitalSignature, KeyEncipherment])) - .add_extension(ExtKeyUsage(vec![ClientAuth, ServerAuth, ExtKeyUsageOption::Other("2.999".to_owned())])) - .add_extension(OtherNid(Nid::BasicConstraints,"critical,CA:TRUE".to_owned())); + .add_extension(ExtKeyUsage(vec![ClientAuth, ServerAuth, ExtKeyUsageOption::Other("2.999.1".to_owned())])) + .add_extension(OtherNid(Nid::BasicConstraints,"critical,CA:TRUE".to_owned())) + .add_extension(OtherStr("2.999.2".to_owned(),"ASN1:UTF8:example value".to_owned())); let (cert, pkey) = gen.generate().unwrap(); cert.write_pem(&mut io::sink()).unwrap();