Add arbitrary X509 extensions by OID string
This commit is contained in:
parent
e367567d00
commit
b46574b635
|
|
@ -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 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_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 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;
|
pub fn i2d_RSA_PUBKEY(k: *mut RSA, buf: *const *mut u8) -> c_int;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use nid::Nid;
|
use nid::Nid;
|
||||||
|
|
||||||
#[derive(Clone,Copy,Hash,PartialEq,Eq)]
|
#[derive(Clone,Hash,PartialEq,Eq)]
|
||||||
pub enum ExtensionType {
|
pub enum ExtensionType {
|
||||||
KeyUsage,
|
KeyUsage,
|
||||||
ExtKeyUsage,
|
ExtKeyUsage,
|
||||||
OtherNid(Nid),
|
OtherNid(Nid),
|
||||||
|
OtherStr(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
@ -13,6 +14,7 @@ pub enum Extension {
|
||||||
KeyUsage(Vec<KeyUsageOption>),
|
KeyUsage(Vec<KeyUsageOption>),
|
||||||
ExtKeyUsage(Vec<ExtKeyUsageOption>),
|
ExtKeyUsage(Vec<ExtKeyUsageOption>),
|
||||||
OtherNid(Nid,String),
|
OtherNid(Nid,String),
|
||||||
|
OtherStr(String,String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Extension {
|
impl Extension {
|
||||||
|
|
@ -21,14 +23,25 @@ impl Extension {
|
||||||
&Extension::KeyUsage(_) => ExtensionType::KeyUsage,
|
&Extension::KeyUsage(_) => ExtensionType::KeyUsage,
|
||||||
&Extension::ExtKeyUsage(_) => ExtensionType::ExtKeyUsage,
|
&Extension::ExtKeyUsage(_) => ExtensionType::ExtKeyUsage,
|
||||||
&Extension::OtherNid(nid,_) => ExtensionType::OtherNid(nid),
|
&Extension::OtherNid(nid,_) => ExtensionType::OtherNid(nid),
|
||||||
|
&Extension::OtherStr(ref s,_) => ExtensionType::OtherStr(s.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtensionType {
|
||||||
|
pub fn get_nid(&self) -> Option<Nid> {
|
||||||
|
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 {
|
match self {
|
||||||
&Extension::KeyUsage(_) => Nid::KeyUsage,
|
&ExtensionType::OtherStr(ref s) => Some(s),
|
||||||
&Extension::ExtKeyUsage(_) => Nid::ExtendedKeyUsage,
|
_ => None,
|
||||||
&Extension::OtherNid(nid,_) => nid,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -49,6 +62,7 @@ impl ToString for Extension {
|
||||||
&Extension::KeyUsage(ref purposes) => join(purposes.iter(),","),
|
&Extension::KeyUsage(ref purposes) => join(purposes.iter(),","),
|
||||||
&Extension::ExtKeyUsage(ref purposes) => join(purposes.iter(),","),
|
&Extension::ExtKeyUsage(ref purposes) => join(purposes.iter(),","),
|
||||||
&Extension::OtherNid(_,ref value) => value.clone(),
|
&Extension::OtherNid(_,ref value) => value.clone(),
|
||||||
|
&Extension::OtherStr(_,ref value) => value.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -242,17 +242,22 @@ impl X509Generator {
|
||||||
self
|
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 {
|
unsafe {
|
||||||
let mut ctx: ffi::X509V3_CTX = mem::zeroed();
|
let mut ctx: ffi::X509V3_CTX = mem::zeroed();
|
||||||
ffi::X509V3_set_ctx(&mut ctx, x509, x509,
|
ffi::X509V3_set_ctx(&mut ctx, x509, x509,
|
||||||
ptr::null_mut(), ptr::null_mut(), 0);
|
ptr::null_mut(), ptr::null_mut(), 0);
|
||||||
let value = CString::new(value.as_bytes()).unwrap();
|
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),
|
mem::transmute(&ctx),
|
||||||
extension,
|
nid as c_int,
|
||||||
value.as_ptr() as *mut c_char);
|
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;
|
let mut success = false;
|
||||||
if ext != ptr::null_mut() {
|
if ext != ptr::null_mut() {
|
||||||
success = ffi::X509_add_ext(x509, ext, -1) != 0;
|
success = ffi::X509_add_ext(x509, ext, -1) != 0;
|
||||||
|
|
@ -331,8 +336,8 @@ impl X509Generator {
|
||||||
try!(X509Generator::add_name(name, "CN", &self.CN));
|
try!(X509Generator::add_name(name, "CN", &self.CN));
|
||||||
ffi::X509_set_issuer_name(x509.handle, name);
|
ffi::X509_set_issuer_name(x509.handle, name);
|
||||||
|
|
||||||
for ext in self.extensions.values() {
|
for (exttype,ext) in self.extensions.iter() {
|
||||||
try!(X509Generator::add_extension_internal(x509.handle, ext.get_nid() as c_int, &ext.to_string()));
|
try!(X509Generator::add_extension_internal(x509.handle, exttype, &ext.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let hash_fn = self.hash_type.evp_md();
|
let hash_fn = self.hash_type.evp_md();
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use std::fs::File;
|
||||||
|
|
||||||
use crypto::hash::Type::{SHA256};
|
use crypto::hash::Type::{SHA256};
|
||||||
use x509::{X509, X509Generator};
|
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::KeyUsageOption::{DigitalSignature, KeyEncipherment};
|
||||||
use x509::extension::ExtKeyUsageOption::{self, ClientAuth, ServerAuth};
|
use x509::extension::ExtKeyUsageOption::{self, ClientAuth, ServerAuth};
|
||||||
use nid::Nid;
|
use nid::Nid;
|
||||||
|
|
@ -18,8 +18,9 @@ fn test_cert_gen() {
|
||||||
.set_CN("test_me")
|
.set_CN("test_me")
|
||||||
.set_sign_hash(SHA256)
|
.set_sign_hash(SHA256)
|
||||||
.add_extension(KeyUsage(vec![DigitalSignature, KeyEncipherment]))
|
.add_extension(KeyUsage(vec![DigitalSignature, KeyEncipherment]))
|
||||||
.add_extension(ExtKeyUsage(vec![ClientAuth, ServerAuth, ExtKeyUsageOption::Other("2.999".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(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();
|
let (cert, pkey) = gen.generate().unwrap();
|
||||||
cert.write_pem(&mut io::sink()).unwrap();
|
cert.write_pem(&mut io::sink()).unwrap();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue