Loading openssl-sys/src/lib.rs +1 −0 Original line number Diff line number Diff line Loading @@ -1683,6 +1683,7 @@ extern { pub fn X509_STORE_CTX_get_error_depth(ctx: *mut X509_STORE_CTX) -> 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 X509V3_set_nconf(ctx: *mut X509V3_CTX, conf: *mut CONF); pub fn X509_REQ_add_extensions(req: *mut X509_REQ, exts: *mut stack_st_X509_EXTENSION) -> c_int; pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int; Loading openssl/src/x509/extension.rs +159 −1 Original line number Diff line number Diff line use std::fmt; use std::fmt::{self, Write}; use error::ErrorStack; use nid::{self, Nid}; use x509::X509Extension; /// Type-only version of the `Extension` enum. /// Loading Loading @@ -219,3 +221,159 @@ impl fmt::Display for AltNameOption { }) } } pub struct BasicConstraints { critical: bool, ca: bool, pathlen: Option<u32>, } impl BasicConstraints { pub fn new() -> BasicConstraints { BasicConstraints { critical: false, ca: false, pathlen: None, } } pub fn critical(&mut self, critical: bool) -> &mut BasicConstraints { self.critical = critical; self } pub fn ca(&mut self, ca: bool) -> &mut BasicConstraints { self.ca = ca; self } pub fn pathlen(&mut self, pathlen: u32) -> &mut BasicConstraints { self.pathlen = Some(pathlen); self } pub fn build(&self) -> Result<X509Extension, ErrorStack> { let mut value = String::new(); if self.critical { value.push_str("critical,"); } value.push_str("CA:"); if self.ca { value.push_str("TRUE"); } else { value.push_str("FALSE"); } if let Some(pathlen) = self.pathlen { write!(value, ",pathlen:{}", pathlen).unwrap(); } X509Extension::new_nid(None, None, nid::BASIC_CONSTRAINTS, &value) } } pub struct KeyUsage { critical: bool, digital_signature: bool, non_repudiation: bool, key_encipherment: bool, data_encipherment: bool, key_agreement: bool, key_cert_sign: bool, crl_sign: bool, encipher_only: bool, decipher_only: bool, } impl KeyUsage { pub fn new() -> KeyUsage { KeyUsage { critical: false, digital_signature: false, non_repudiation: false, key_encipherment: false, data_encipherment: false, key_agreement: false, key_cert_sign: false, crl_sign: false, encipher_only: false, decipher_only: false, } } pub fn critical(&mut self, critical: bool) -> &mut KeyUsage { self.critical = critical; self } pub fn digital_signature(&mut self, digital_signature: bool) -> &mut KeyUsage { self.digital_signature = digital_signature; self } pub fn non_repudiation(&mut self, non_repudiation: bool) -> &mut KeyUsage { self.non_repudiation = non_repudiation; self } pub fn key_encipherment(&mut self, key_encipherment: bool) -> &mut KeyUsage { self.key_encipherment = key_encipherment; self } pub fn data_encipherment(&mut self, data_encipherment: bool) -> &mut KeyUsage { self.data_encipherment = data_encipherment; self } pub fn key_agreement(&mut self, key_agreement: bool) -> &mut KeyUsage { self.key_agreement = key_agreement; self } pub fn key_cert_sign(&mut self, key_cert_sign: bool) -> &mut KeyUsage { self.key_cert_sign = key_cert_sign; self } pub fn crl_sign(&mut self, crl_sign: bool) -> &mut KeyUsage { self.crl_sign = crl_sign; self } pub fn encipher_only(&mut self, encipher_only: bool) -> &mut KeyUsage { self.encipher_only = encipher_only; self } pub fn decipher_only(&mut self, decipher_only: bool) -> &mut KeyUsage { self.decipher_only = decipher_only; self } pub fn build(&self) -> Result<X509Extension, ErrorStack> { let mut value = String::new(); let mut first = true; append(&mut value, &mut first, self.critical, "critical"); append(&mut value, &mut first, self.digital_signature, "digitalSignature"); append(&mut value, &mut first, self.non_repudiation, "nonRepudiation"); append(&mut value, &mut first, self.key_encipherment, "keyEncipherment"); append(&mut value, &mut first, self.data_encipherment, "dataEncipherment"); append(&mut value, &mut first, self.key_agreement, "keyAgreement"); append(&mut value, &mut first, self.key_cert_sign, "keyCertSign"); append(&mut value, &mut first, self.crl_sign, "cRLSign"); append(&mut value, &mut first, self.encipher_only, "encipherOnly"); append(&mut value, &mut first, self.decipher_only, "decipherOnly"); X509Extension::new_nid(None, None, nid::KEY_USAGE, &value) } } fn append(value: &mut String, first: &mut bool, should: bool, element: &str) { if !should { return; } if !*first { value.push(','); } *first = false; value.push_str(element); } openssl/src/x509/mod.rs +78 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ use std::collections::HashMap; use std::error::Error; use std::ffi::{CStr, CString}; use std::fmt; use std::marker::PhantomData; use std::mem; use std::path::Path; use std::ptr; Loading @@ -14,6 +15,7 @@ use std::str; use {cvt, cvt_p}; use asn1::{Asn1StringRef, Asn1Time, Asn1TimeRef, Asn1IntegerRef}; use bio::{MemBio, MemBioSlice}; use conf::ConfRef; use hash::MessageDigest; use pkey::{PKey, PKeyRef}; use rand::rand_bytes; Loading Loading @@ -396,6 +398,37 @@ impl X509Builder { unsafe { cvt(ffi::X509_set_pubkey(self.0.as_ptr(), key.as_ptr())).map(|_| ()) } } pub fn x509v3_context<'a>(&'a self, issuer: Option<&'a X509Ref>, conf: Option<&'a ConfRef>) -> X509v3Context<'a> { unsafe { let mut ctx = mem::zeroed(); let issuer = match issuer { Some(issuer) => issuer.as_ptr(), None => self.0.as_ptr(), }; let subject = self.0.as_ptr(); ffi::X509V3_set_ctx(&mut ctx, issuer, subject, ptr::null_mut(), ptr::null_mut(), 0); // nodb case taken care of since we zeroed ctx above if let Some(conf) = conf { ffi::X509V3_set_nconf(&mut ctx, conf.as_ptr()); } X509v3Context(ctx, PhantomData) } } pub fn append_extension(&mut self, extension: X509Extension) -> Result<(), ErrorStack> { unsafe { try!(cvt(ffi::X509_add_ext(self.0.as_ptr(), extension.as_ptr(), -1))); mem::forget(extension); Ok(()) } } pub fn sign(&mut self, key: &PKeyRef, hash: MessageDigest) -> Result<(), ErrorStack> { unsafe { cvt(ffi::X509_sign(self.0.as_ptr(), key.as_ptr(), hash.as_ptr())).map(|_| ()) } } Loading Loading @@ -554,6 +587,51 @@ impl Stackable for X509 { type StackType = ffi::stack_st_X509; } pub struct X509v3Context<'a>(ffi::X509V3_CTX, PhantomData<(&'a X509Ref, &'a ConfRef)>); impl<'a> X509v3Context<'a> { pub fn as_ptr(&self) -> *mut ffi::X509V3_CTX { &self.0 as *const _ as *mut _ } } type_!(X509Extension, X509ExtensionRef, ffi::X509_EXTENSION, ffi::X509_EXTENSION_free); impl X509Extension { pub fn new(conf: Option<&ConfRef>, context: Option<&X509v3Context>, name: &str, value: &str) -> Result<X509Extension, ErrorStack> { let name = CString::new(name).unwrap(); let value = CString::new(value).unwrap(); unsafe { let conf = conf.map_or(ptr::null_mut(), ConfRef::as_ptr); let context = context.map_or(ptr::null_mut(), X509v3Context::as_ptr); let name = name.as_ptr() as *mut _; let value = value.as_ptr() as *mut _; cvt_p(ffi::X509V3_EXT_nconf(conf, context, name, value)).map(X509Extension) } } pub fn new_nid(conf: Option<&ConfRef>, context: Option<&X509v3Context>, name: Nid, value: &str) -> Result<X509Extension, ErrorStack> { let value = CString::new(value).unwrap(); unsafe { let conf = conf.map_or(ptr::null_mut(), ConfRef::as_ptr); let context = context.map_or(ptr::null_mut(), X509v3Context::as_ptr); let name = name.as_raw(); let value = value.as_ptr() as *mut _; cvt_p(ffi::X509V3_EXT_nconf_nid(conf, context, name, value)).map(X509Extension) } } } pub struct X509NameBuilder(X509Name); impl X509NameBuilder { Loading openssl/src/x509/tests.rs +16 −11 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ use hash::MessageDigest; use pkey::PKey; use rsa::Rsa; use x509::{X509, X509Generator, X509Name}; use x509::extension::Extension::{KeyUsage, ExtKeyUsage, SubjectAltName, OtherNid, OtherStr}; use x509::extension::{Extension, BasicConstraints, KeyUsage}; use x509::extension::AltNameOption as SAN; use x509::extension::KeyUsageOption::{DigitalSignature, KeyEncipherment}; use x509::extension::ExtKeyUsageOption::{self, ClientAuth, ServerAuth}; Loading @@ -17,13 +17,13 @@ fn get_generator() -> X509Generator { .set_valid_period(365 * 2) .add_name("CN".to_string(), "test_me".to_string()) .set_sign_hash(MessageDigest::sha1()) .add_extension(KeyUsage(vec![DigitalSignature, KeyEncipherment])) .add_extension(ExtKeyUsage(vec![ClientAuth, .add_extension(Extension::KeyUsage(vec![DigitalSignature, KeyEncipherment])) .add_extension(Extension::ExtKeyUsage(vec![ClientAuth, ServerAuth, ExtKeyUsageOption::Other("2.999.1".to_owned())])) .add_extension(SubjectAltName(vec![(SAN::DNS, "example.com".to_owned())])) .add_extension(OtherNid(nid::BASIC_CONSTRAINTS, "critical,CA:TRUE".to_owned())) .add_extension(OtherStr("2.999.2".to_owned(), "ASN1:UTF8:example value".to_owned())) .add_extension(Extension::SubjectAltName(vec![(SAN::DNS, "example.com".to_owned())])) .add_extension(Extension::OtherNid(nid::BASIC_CONSTRAINTS, "critical,CA:TRUE".to_owned())) .add_extension(Extension::OtherStr("2.999.2".to_owned(), "ASN1:UTF8:example value".to_owned())) } fn pkey() -> PKey { Loading @@ -50,8 +50,8 @@ fn test_cert_gen() { fn test_cert_gen_extension_ordering() { let pkey = pkey(); get_generator() .add_extension(OtherNid(nid::SUBJECT_KEY_IDENTIFIER, "hash".to_owned())) .add_extension(OtherNid(nid::AUTHORITY_KEY_IDENTIFIER, "keyid:always".to_owned())) .add_extension(Extension::OtherNid(nid::SUBJECT_KEY_IDENTIFIER, "hash".to_owned())) .add_extension(Extension::OtherNid(nid::AUTHORITY_KEY_IDENTIFIER, "keyid:always".to_owned())) .sign(&pkey) .expect("Failed to generate cert with order-dependent extensions"); } Loading @@ -62,8 +62,8 @@ fn test_cert_gen_extension_ordering() { fn test_cert_gen_extension_bad_ordering() { let pkey = pkey(); let result = get_generator() .add_extension(OtherNid(nid::AUTHORITY_KEY_IDENTIFIER, "keyid:always".to_owned())) .add_extension(OtherNid(nid::SUBJECT_KEY_IDENTIFIER, "hash".to_owned())) .add_extension(Extension::OtherNid(nid::AUTHORITY_KEY_IDENTIFIER, "keyid:always".to_owned())) .add_extension(Extension::OtherNid(nid::SUBJECT_KEY_IDENTIFIER, "hash".to_owned())) .sign(&pkey); assert!(result.is_err()); Loading Loading @@ -178,7 +178,7 @@ fn test_subject_alt_name_iter() { } #[test] fn test_x509_builder() { fn x509_builder() { let pkey = pkey(); let mut name = X509Name::builder().unwrap(); Loading @@ -196,6 +196,11 @@ fn test_x509_builder() { serial.rand(128, MSB_MAYBE_ZERO, false).unwrap(); builder.set_serial_number(&serial.to_asn1_integer().unwrap()).unwrap(); let basic_constraints = BasicConstraints::new().critical(true).ca(true).build().unwrap(); builder.append_extension(basic_constraints).unwrap(); let key_usage = KeyUsage::new().digital_signature(true).key_encipherment(true).build().unwrap(); builder.append_extension(key_usage).unwrap(); builder.sign(&pkey, MessageDigest::sha256()).unwrap(); let x509 = builder.build(); Loading Loading
openssl-sys/src/lib.rs +1 −0 Original line number Diff line number Diff line Loading @@ -1683,6 +1683,7 @@ extern { pub fn X509_STORE_CTX_get_error_depth(ctx: *mut X509_STORE_CTX) -> 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 X509V3_set_nconf(ctx: *mut X509V3_CTX, conf: *mut CONF); pub fn X509_REQ_add_extensions(req: *mut X509_REQ, exts: *mut stack_st_X509_EXTENSION) -> c_int; pub fn X509_REQ_sign(x: *mut X509_REQ, pkey: *mut EVP_PKEY, md: *const EVP_MD) -> c_int; Loading
openssl/src/x509/extension.rs +159 −1 Original line number Diff line number Diff line use std::fmt; use std::fmt::{self, Write}; use error::ErrorStack; use nid::{self, Nid}; use x509::X509Extension; /// Type-only version of the `Extension` enum. /// Loading Loading @@ -219,3 +221,159 @@ impl fmt::Display for AltNameOption { }) } } pub struct BasicConstraints { critical: bool, ca: bool, pathlen: Option<u32>, } impl BasicConstraints { pub fn new() -> BasicConstraints { BasicConstraints { critical: false, ca: false, pathlen: None, } } pub fn critical(&mut self, critical: bool) -> &mut BasicConstraints { self.critical = critical; self } pub fn ca(&mut self, ca: bool) -> &mut BasicConstraints { self.ca = ca; self } pub fn pathlen(&mut self, pathlen: u32) -> &mut BasicConstraints { self.pathlen = Some(pathlen); self } pub fn build(&self) -> Result<X509Extension, ErrorStack> { let mut value = String::new(); if self.critical { value.push_str("critical,"); } value.push_str("CA:"); if self.ca { value.push_str("TRUE"); } else { value.push_str("FALSE"); } if let Some(pathlen) = self.pathlen { write!(value, ",pathlen:{}", pathlen).unwrap(); } X509Extension::new_nid(None, None, nid::BASIC_CONSTRAINTS, &value) } } pub struct KeyUsage { critical: bool, digital_signature: bool, non_repudiation: bool, key_encipherment: bool, data_encipherment: bool, key_agreement: bool, key_cert_sign: bool, crl_sign: bool, encipher_only: bool, decipher_only: bool, } impl KeyUsage { pub fn new() -> KeyUsage { KeyUsage { critical: false, digital_signature: false, non_repudiation: false, key_encipherment: false, data_encipherment: false, key_agreement: false, key_cert_sign: false, crl_sign: false, encipher_only: false, decipher_only: false, } } pub fn critical(&mut self, critical: bool) -> &mut KeyUsage { self.critical = critical; self } pub fn digital_signature(&mut self, digital_signature: bool) -> &mut KeyUsage { self.digital_signature = digital_signature; self } pub fn non_repudiation(&mut self, non_repudiation: bool) -> &mut KeyUsage { self.non_repudiation = non_repudiation; self } pub fn key_encipherment(&mut self, key_encipherment: bool) -> &mut KeyUsage { self.key_encipherment = key_encipherment; self } pub fn data_encipherment(&mut self, data_encipherment: bool) -> &mut KeyUsage { self.data_encipherment = data_encipherment; self } pub fn key_agreement(&mut self, key_agreement: bool) -> &mut KeyUsage { self.key_agreement = key_agreement; self } pub fn key_cert_sign(&mut self, key_cert_sign: bool) -> &mut KeyUsage { self.key_cert_sign = key_cert_sign; self } pub fn crl_sign(&mut self, crl_sign: bool) -> &mut KeyUsage { self.crl_sign = crl_sign; self } pub fn encipher_only(&mut self, encipher_only: bool) -> &mut KeyUsage { self.encipher_only = encipher_only; self } pub fn decipher_only(&mut self, decipher_only: bool) -> &mut KeyUsage { self.decipher_only = decipher_only; self } pub fn build(&self) -> Result<X509Extension, ErrorStack> { let mut value = String::new(); let mut first = true; append(&mut value, &mut first, self.critical, "critical"); append(&mut value, &mut first, self.digital_signature, "digitalSignature"); append(&mut value, &mut first, self.non_repudiation, "nonRepudiation"); append(&mut value, &mut first, self.key_encipherment, "keyEncipherment"); append(&mut value, &mut first, self.data_encipherment, "dataEncipherment"); append(&mut value, &mut first, self.key_agreement, "keyAgreement"); append(&mut value, &mut first, self.key_cert_sign, "keyCertSign"); append(&mut value, &mut first, self.crl_sign, "cRLSign"); append(&mut value, &mut first, self.encipher_only, "encipherOnly"); append(&mut value, &mut first, self.decipher_only, "decipherOnly"); X509Extension::new_nid(None, None, nid::KEY_USAGE, &value) } } fn append(value: &mut String, first: &mut bool, should: bool, element: &str) { if !should { return; } if !*first { value.push(','); } *first = false; value.push_str(element); }
openssl/src/x509/mod.rs +78 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ use std::collections::HashMap; use std::error::Error; use std::ffi::{CStr, CString}; use std::fmt; use std::marker::PhantomData; use std::mem; use std::path::Path; use std::ptr; Loading @@ -14,6 +15,7 @@ use std::str; use {cvt, cvt_p}; use asn1::{Asn1StringRef, Asn1Time, Asn1TimeRef, Asn1IntegerRef}; use bio::{MemBio, MemBioSlice}; use conf::ConfRef; use hash::MessageDigest; use pkey::{PKey, PKeyRef}; use rand::rand_bytes; Loading Loading @@ -396,6 +398,37 @@ impl X509Builder { unsafe { cvt(ffi::X509_set_pubkey(self.0.as_ptr(), key.as_ptr())).map(|_| ()) } } pub fn x509v3_context<'a>(&'a self, issuer: Option<&'a X509Ref>, conf: Option<&'a ConfRef>) -> X509v3Context<'a> { unsafe { let mut ctx = mem::zeroed(); let issuer = match issuer { Some(issuer) => issuer.as_ptr(), None => self.0.as_ptr(), }; let subject = self.0.as_ptr(); ffi::X509V3_set_ctx(&mut ctx, issuer, subject, ptr::null_mut(), ptr::null_mut(), 0); // nodb case taken care of since we zeroed ctx above if let Some(conf) = conf { ffi::X509V3_set_nconf(&mut ctx, conf.as_ptr()); } X509v3Context(ctx, PhantomData) } } pub fn append_extension(&mut self, extension: X509Extension) -> Result<(), ErrorStack> { unsafe { try!(cvt(ffi::X509_add_ext(self.0.as_ptr(), extension.as_ptr(), -1))); mem::forget(extension); Ok(()) } } pub fn sign(&mut self, key: &PKeyRef, hash: MessageDigest) -> Result<(), ErrorStack> { unsafe { cvt(ffi::X509_sign(self.0.as_ptr(), key.as_ptr(), hash.as_ptr())).map(|_| ()) } } Loading Loading @@ -554,6 +587,51 @@ impl Stackable for X509 { type StackType = ffi::stack_st_X509; } pub struct X509v3Context<'a>(ffi::X509V3_CTX, PhantomData<(&'a X509Ref, &'a ConfRef)>); impl<'a> X509v3Context<'a> { pub fn as_ptr(&self) -> *mut ffi::X509V3_CTX { &self.0 as *const _ as *mut _ } } type_!(X509Extension, X509ExtensionRef, ffi::X509_EXTENSION, ffi::X509_EXTENSION_free); impl X509Extension { pub fn new(conf: Option<&ConfRef>, context: Option<&X509v3Context>, name: &str, value: &str) -> Result<X509Extension, ErrorStack> { let name = CString::new(name).unwrap(); let value = CString::new(value).unwrap(); unsafe { let conf = conf.map_or(ptr::null_mut(), ConfRef::as_ptr); let context = context.map_or(ptr::null_mut(), X509v3Context::as_ptr); let name = name.as_ptr() as *mut _; let value = value.as_ptr() as *mut _; cvt_p(ffi::X509V3_EXT_nconf(conf, context, name, value)).map(X509Extension) } } pub fn new_nid(conf: Option<&ConfRef>, context: Option<&X509v3Context>, name: Nid, value: &str) -> Result<X509Extension, ErrorStack> { let value = CString::new(value).unwrap(); unsafe { let conf = conf.map_or(ptr::null_mut(), ConfRef::as_ptr); let context = context.map_or(ptr::null_mut(), X509v3Context::as_ptr); let name = name.as_raw(); let value = value.as_ptr() as *mut _; cvt_p(ffi::X509V3_EXT_nconf_nid(conf, context, name, value)).map(X509Extension) } } } pub struct X509NameBuilder(X509Name); impl X509NameBuilder { Loading
openssl/src/x509/tests.rs +16 −11 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ use hash::MessageDigest; use pkey::PKey; use rsa::Rsa; use x509::{X509, X509Generator, X509Name}; use x509::extension::Extension::{KeyUsage, ExtKeyUsage, SubjectAltName, OtherNid, OtherStr}; use x509::extension::{Extension, BasicConstraints, KeyUsage}; use x509::extension::AltNameOption as SAN; use x509::extension::KeyUsageOption::{DigitalSignature, KeyEncipherment}; use x509::extension::ExtKeyUsageOption::{self, ClientAuth, ServerAuth}; Loading @@ -17,13 +17,13 @@ fn get_generator() -> X509Generator { .set_valid_period(365 * 2) .add_name("CN".to_string(), "test_me".to_string()) .set_sign_hash(MessageDigest::sha1()) .add_extension(KeyUsage(vec![DigitalSignature, KeyEncipherment])) .add_extension(ExtKeyUsage(vec![ClientAuth, .add_extension(Extension::KeyUsage(vec![DigitalSignature, KeyEncipherment])) .add_extension(Extension::ExtKeyUsage(vec![ClientAuth, ServerAuth, ExtKeyUsageOption::Other("2.999.1".to_owned())])) .add_extension(SubjectAltName(vec![(SAN::DNS, "example.com".to_owned())])) .add_extension(OtherNid(nid::BASIC_CONSTRAINTS, "critical,CA:TRUE".to_owned())) .add_extension(OtherStr("2.999.2".to_owned(), "ASN1:UTF8:example value".to_owned())) .add_extension(Extension::SubjectAltName(vec![(SAN::DNS, "example.com".to_owned())])) .add_extension(Extension::OtherNid(nid::BASIC_CONSTRAINTS, "critical,CA:TRUE".to_owned())) .add_extension(Extension::OtherStr("2.999.2".to_owned(), "ASN1:UTF8:example value".to_owned())) } fn pkey() -> PKey { Loading @@ -50,8 +50,8 @@ fn test_cert_gen() { fn test_cert_gen_extension_ordering() { let pkey = pkey(); get_generator() .add_extension(OtherNid(nid::SUBJECT_KEY_IDENTIFIER, "hash".to_owned())) .add_extension(OtherNid(nid::AUTHORITY_KEY_IDENTIFIER, "keyid:always".to_owned())) .add_extension(Extension::OtherNid(nid::SUBJECT_KEY_IDENTIFIER, "hash".to_owned())) .add_extension(Extension::OtherNid(nid::AUTHORITY_KEY_IDENTIFIER, "keyid:always".to_owned())) .sign(&pkey) .expect("Failed to generate cert with order-dependent extensions"); } Loading @@ -62,8 +62,8 @@ fn test_cert_gen_extension_ordering() { fn test_cert_gen_extension_bad_ordering() { let pkey = pkey(); let result = get_generator() .add_extension(OtherNid(nid::AUTHORITY_KEY_IDENTIFIER, "keyid:always".to_owned())) .add_extension(OtherNid(nid::SUBJECT_KEY_IDENTIFIER, "hash".to_owned())) .add_extension(Extension::OtherNid(nid::AUTHORITY_KEY_IDENTIFIER, "keyid:always".to_owned())) .add_extension(Extension::OtherNid(nid::SUBJECT_KEY_IDENTIFIER, "hash".to_owned())) .sign(&pkey); assert!(result.is_err()); Loading Loading @@ -178,7 +178,7 @@ fn test_subject_alt_name_iter() { } #[test] fn test_x509_builder() { fn x509_builder() { let pkey = pkey(); let mut name = X509Name::builder().unwrap(); Loading @@ -196,6 +196,11 @@ fn test_x509_builder() { serial.rand(128, MSB_MAYBE_ZERO, false).unwrap(); builder.set_serial_number(&serial.to_asn1_integer().unwrap()).unwrap(); let basic_constraints = BasicConstraints::new().critical(true).ca(true).build().unwrap(); builder.append_extension(basic_constraints).unwrap(); let key_usage = KeyUsage::new().digital_signature(true).key_encipherment(true).build().unwrap(); builder.append_extension(key_usage).unwrap(); builder.sign(&pkey, MessageDigest::sha256()).unwrap(); let x509 = builder.build(); Loading