From 43c951f743e68fac5f45119eda7c994882a1d489 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 30 Sep 2016 00:43:05 -0700 Subject: Add support for OpenSSL 1.1.0 This commit is relatively major refactoring of the `openssl-sys` crate as well as the `openssl` crate itself. The end goal here was to support OpenSSL 1.1.0, and lots of other various tweaks happened along the way. The major new features are: * OpenSSL 1.1.0 is supported * OpenSSL 0.9.8 is no longer supported (aka all OSX users by default) * All FFI bindings are verified with the `ctest` crate (same way as the `libc` crate) * CI matrixes are vastly expanded to include 32/64 of all platforms, more OpenSSL version coverage, as well as ARM coverage on Linux * The `c_helpers` module is completely removed along with the `gcc` dependency. * The `openssl-sys` build script was completely rewritten * Now uses `OPENSSL_DIR` to find the installation, not include/lib env vars. * Better error messages for mismatched versions. * Better error messages for failing to find OpenSSL on a platform (more can be done here) * Probing of OpenSSL build-time configuration to inform the API of the `*-sys` crate. * Many Cargo features have been removed as they're now enabled by default. As this is a breaking change to both the `openssl` and `openssl-sys` crates this will necessitate a major version bump of both. There's still a few more API questions remaining but let's hash that out on a PR! Closes #452 --- openssl/src/x509/mod.rs | 132 ++++++++++++++++++++++++++++++++++++---------- openssl/src/x509/tests.rs | 2 - 2 files changed, 103 insertions(+), 31 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index f5369447..086342dd 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -12,7 +12,6 @@ use std::marker::PhantomData; use HashTypeInternals; use asn1::Asn1Time; -#[cfg(feature = "x509_expiry")] use asn1::Asn1TimeRef; use bio::{MemBio, MemBioSlice}; @@ -24,6 +23,19 @@ use ffi; use nid::Nid; use error::ErrorStack; +#[cfg(ossl10x)] +use ffi::{ + X509_set_notBefore, + X509_set_notAfter, + ASN1_STRING_data, +}; +#[cfg(ossl110)] +use ffi::{ + X509_set1_notBefore as X509_set_notBefore, + X509_set1_notAfter as X509_set_notAfter, + ASN1_STRING_get0_data as ASN1_STRING_data, +}; + pub mod extension; use self::extension::{ExtensionType, Extension}; @@ -36,7 +48,7 @@ pub struct SslString(&'static str); impl<'s> Drop for SslString { fn drop(&mut self) { unsafe { - ffi::CRYPTO_free(self.0.as_ptr() as *mut c_void); + CRYPTO_free!(self.0.as_ptr() as *mut c_void); } } } @@ -50,8 +62,8 @@ impl Deref for SslString { } impl SslString { - unsafe fn new(buf: *const c_char, len: c_int) -> SslString { - let slice = slice::from_raw_parts(buf as *const _, len as usize); + unsafe fn new(buf: *const u8, len: c_int) -> SslString { + let slice = slice::from_raw_parts(buf, len as usize); SslString(str::from_utf8_unchecked(slice)) } } @@ -311,11 +323,11 @@ impl X509Generator { let not_before = try!(Asn1Time::days_from_now(0)); let not_after = try!(Asn1Time::days_from_now(self.days)); - try_ssl!(ffi::X509_set_notBefore(x509.as_ptr(), not_before.as_ptr() as *const _)); + try_ssl!(X509_set_notBefore(x509.as_ptr(), not_before.as_ptr() as *const _)); // If prev line succeded - ownership should go to cert mem::forget(not_before); - try_ssl!(ffi::X509_set_notAfter(x509.as_ptr(), not_after.as_ptr() as *const _)); + try_ssl!(X509_set_notAfter(x509.as_ptr(), not_after.as_ptr() as *const _)); // If prev line succeded - ownership should go to cert mem::forget(not_after); @@ -350,9 +362,6 @@ impl X509Generator { } /// Obtain a certificate signing request (CSR) - /// - /// Requries the `x509_generator_request` feature. - #[cfg(feature = "x509_generator_request")] pub fn request(&self, p_key: &PKey) -> Result { let cert = match self.sign(p_key) { Ok(c) => c, @@ -363,9 +372,9 @@ impl X509Generator { let req = ffi::X509_to_X509_REQ(cert.as_ptr(), ptr::null_mut(), ptr::null()); try_ssl_null!(req); - let exts = ::c_helpers::rust_0_8_X509_get_extensions(cert.as_ptr()); + let exts = compat::X509_get0_extensions(cert.as_ptr()); if exts != ptr::null_mut() { - try_ssl!(ffi::X509_REQ_add_extensions(req, exts)); + try_ssl!(ffi::X509_REQ_add_extensions(req, exts as *mut _)); } let hash_fn = self.hash_type.evp_md(); @@ -438,22 +447,18 @@ impl<'a> X509Ref<'a> { } /// Returns certificate Not After validity period. - /// Requires the `x509_expiry` feature. - #[cfg(feature = "x509_expiry")] pub fn not_after<'b>(&'b self) -> Asn1TimeRef<'b> { unsafe { - let date = ::c_helpers::rust_0_8_X509_get_notAfter(self.0); + let date = compat::X509_get_notAfter(self.0); assert!(!date.is_null()); Asn1TimeRef::from_ptr(date) } } /// Returns certificate Not Before validity period. - /// Requires the `x509_expiry` feature. - #[cfg(feature = "x509_expiry")] pub fn not_before<'b>(&'b self) -> Asn1TimeRef<'b> { unsafe { - let date = ::c_helpers::rust_0_8_X509_get_notBefore(self.0); + let date = compat::X509_get_notBefore(self.0); assert!(!date.is_null()); Asn1TimeRef::from_ptr(date) } @@ -496,7 +501,7 @@ impl X509 { /// Reads a certificate from DER. pub fn from_der(buf: &[u8]) -> Result { unsafe { - let mut ptr = buf.as_ptr() as *mut _; + let mut ptr = buf.as_ptr(); let len = cmp::min(buf.len(), c_long::max_value() as usize) as c_long; let x509 = try_ssl_null!(ffi::d2i_X509(ptr::null_mut(), &mut ptr, len)); Ok(X509::from_ptr(x509)) @@ -524,13 +529,11 @@ impl Deref for X509 { } } -#[cfg(feature = "x509_clone")] impl Clone for X509 { - /// Requires the `x509_clone` feature. fn clone(&self) -> X509 { unsafe { - ::c_helpers::rust_0_8_X509_clone(self.as_ptr()); - X509::new(self.as_ptr()) + compat::X509_up_ref(self.as_ptr()); + X509::from_ptr(self.as_ptr()) } } } @@ -561,7 +564,7 @@ impl<'x> X509Name<'x> { return None; } - let mut str_from_asn1: *mut c_char = ptr::null_mut(); + let mut str_from_asn1: *mut u8 = ptr::null_mut(); let len = ffi::ASN1_STRING_to_UTF8(&mut str_from_asn1, asn1_str); if len < 0 { @@ -779,22 +782,43 @@ pub struct GeneralNames<'a> { } impl<'a> Drop for GeneralNames<'a> { + #[cfg(ossl10x)] fn drop(&mut self) { unsafe { // This transmute is dubious but it's what openssl itself does... - let free: unsafe extern "C" fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free; - let free: unsafe extern "C" fn(*mut c_void) = mem::transmute(free); + let free: unsafe extern fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free; + let free: unsafe extern fn(*mut c_void) = mem::transmute(free); ffi::sk_pop_free(&mut (*self.stack).stack, Some(free)); } } + + #[cfg(ossl110)] + fn drop(&mut self) { + unsafe { + // This transmute is dubious but it's what openssl itself does... + let free: unsafe extern fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free; + let free: unsafe extern fn(*mut c_void) = mem::transmute(free); + ffi::OPENSSL_sk_pop_free(self.stack as *mut _, Some(free)); + } + } } impl<'a> GeneralNames<'a> { /// Returns the number of `GeneralName`s in this structure. pub fn len(&self) -> usize { + self._len() + } + + #[cfg(ossl10x)] + fn _len(&self) -> usize { unsafe { (*self.stack).stack.num as usize } } + #[cfg(ossl110)] + fn _len(&self) -> usize { + unsafe { ffi::OPENSSL_sk_num(self.stack as *const _) as usize } + } + /// Returns the specified `GeneralName`. /// /// # Panics @@ -803,14 +827,23 @@ impl<'a> GeneralNames<'a> { pub fn get(&self, idx: usize) -> GeneralName<'a> { unsafe { assert!(idx < self.len()); - GeneralName { - name: *(*self.stack).stack.data.offset(idx as isize) as *const ffi::GENERAL_NAME, + name: self._get(idx), m: PhantomData, } } } + #[cfg(ossl10x)] + unsafe fn _get(&self, idx: usize) -> *const ffi::GENERAL_NAME { + *(*self.stack).stack.data.offset(idx as isize) as *const ffi::GENERAL_NAME + } + + #[cfg(ossl110)] + unsafe fn _get(&self, idx: usize) -> *const ffi::GENERAL_NAME { + ffi::OPENSSL_sk_value(self.stack as *const _, idx as c_int) as *mut _ + } + /// Returns an iterator over the `GeneralName`s in this structure. pub fn iter(&self) -> GeneralNamesIter { GeneralNamesIter { @@ -870,7 +903,7 @@ impl<'a> GeneralName<'a> { return None; } - let ptr = ffi::ASN1_STRING_data((*self.name).d as *mut _); + let ptr = ASN1_STRING_data((*self.name).d as *mut _); let len = ffi::ASN1_STRING_length((*self.name).d as *mut _); let slice = slice::from_raw_parts(ptr as *const u8, len as usize); @@ -888,7 +921,7 @@ impl<'a> GeneralName<'a> { return None; } - let ptr = ffi::ASN1_STRING_data((*self.name).d as *mut _); + let ptr = ASN1_STRING_data((*self.name).d as *mut _); let len = ffi::ASN1_STRING_length((*self.name).d as *mut _); Some(slice::from_raw_parts(ptr as *const u8, len as usize)) @@ -904,3 +937,44 @@ fn test_negative_serial() { "All serials should be positive"); } } + +#[cfg(ossl110)] +mod compat { + pub use ffi::X509_getm_notAfter as X509_get_notAfter; + pub use ffi::X509_getm_notBefore as X509_get_notBefore; + pub use ffi::X509_up_ref; + pub use ffi::X509_get0_extensions; +} + +#[cfg(ossl10x)] +#[allow(bad_style)] +mod compat { + use libc::c_int; + use ffi; + + pub unsafe fn X509_get_notAfter(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME { + (*(*(*x).cert_info).validity).notAfter + } + + pub unsafe fn X509_get_notBefore(x: *mut ffi::X509) -> *mut ffi::ASN1_TIME { + (*(*(*x).cert_info).validity).notBefore + } + + pub unsafe fn X509_up_ref(x: *mut ffi::X509) { + ffi::CRYPTO_add_lock(&mut (*x).references, + 1, + ffi::CRYPTO_LOCK_X509, + "mod.rs\0".as_ptr() as *const _, + line!() as c_int); + } + + pub unsafe fn X509_get0_extensions(cert: *const ffi::X509) + -> *const ffi::stack_st_X509_EXTENSION { + let info = (*cert).cert_info; + if info.is_null() { + 0 as *mut _ + } else { + (*info).extensions + } + } +} diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index eac08941..07d9e1d4 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -69,7 +69,6 @@ fn test_cert_gen_extension_bad_ordering() { } #[test] -#[cfg(feature = "x509_generator_request")] fn test_req_gen() { let pkey = pkey(); @@ -93,7 +92,6 @@ fn test_cert_loading() { } #[test] -#[cfg(feature = "x509_expiry")] fn test_cert_issue_validity() { let cert = include_bytes!("../../test/cert.pem"); let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); -- cgit v1.2.3 From af51b263b17faaa3e7cb0ecc5c305b858faea64c Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 14 Oct 2016 17:39:31 -0700 Subject: Support hostname verification Closes #206 --- openssl/src/x509/mod.rs | 3 +++ openssl/src/x509/verify.rs | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 openssl/src/x509/verify.rs (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 086342dd..5b65e866 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -38,6 +38,9 @@ use ffi::{ pub mod extension; +#[cfg(feature = "openssl-110")] +pub mod verify; + use self::extension::{ExtensionType, Extension}; #[cfg(test)] diff --git a/openssl/src/x509/verify.rs b/openssl/src/x509/verify.rs new file mode 100644 index 00000000..683836e8 --- /dev/null +++ b/openssl/src/x509/verify.rs @@ -0,0 +1,41 @@ +use std::marker::PhantomData; +use libc::c_uint; +use ffi; + +use error::ErrorStack; + +bitflags! { + pub flags X509CheckFlags: c_uint { + const X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT, + const X509_CHECK_FLAG_NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS, + const X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS = ffi::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS, + const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS = ffi::X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS, + const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS + = ffi::X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS, + const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_NEVER_CHECK_SUBJECT, + } +} + +pub struct X509VerifyParamRef<'a>(*mut ffi::X509_VERIFY_PARAM, PhantomData<&'a mut ()>); + +impl<'a> X509VerifyParamRef<'a> { + pub unsafe fn from_ptr(ptr: *mut ffi::X509_VERIFY_PARAM) -> X509VerifyParamRef<'a> { + X509VerifyParamRef(ptr, PhantomData) + } + + pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) { + unsafe { + ffi::X509_VERIFY_PARAM_set_hostflags(self.0, hostflags.bits); + } + } + + pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> { + unsafe { + try_ssl!(ffi::X509_VERIFY_PARAM_set1_host(self.0, + host.as_ptr() as *const _, + host.len())) + } + + Ok(()) + } +} -- cgit v1.2.3 From d976b8f59558f57561bd37b037955b47a328902f Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 14 Oct 2016 18:04:31 -0700 Subject: Enable hostname verification on 1.0.2 --- openssl/src/x509/mod.rs | 2 +- openssl/src/x509/verify.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 5b65e866..9fed94e2 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -38,7 +38,7 @@ use ffi::{ pub mod extension; -#[cfg(feature = "openssl-110")] +#[cfg(feature = "openssl-102")] pub mod verify; use self::extension::{ExtensionType, Extension}; diff --git a/openssl/src/x509/verify.rs b/openssl/src/x509/verify.rs index 683836e8..0fc1df3a 100644 --- a/openssl/src/x509/verify.rs +++ b/openssl/src/x509/verify.rs @@ -12,6 +12,7 @@ bitflags! { const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS = ffi::X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS, const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS = ffi::X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS, + #[cfg(feature = "openssl-110")] const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_NEVER_CHECK_SUBJECT, } } -- cgit v1.2.3 From c171be551ac8d22c91cbf550e21215ae2c8b6abc Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 15 Oct 2016 15:23:29 -0700 Subject: De-enumify message digests --- openssl/src/x509/mod.rs | 23 ++++++++++------------- openssl/src/x509/tests.rs | 6 +++--- 2 files changed, 13 insertions(+), 16 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 9fed94e2..c429b486 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -10,13 +10,10 @@ use std::slice; use std::collections::HashMap; use std::marker::PhantomData; -use HashTypeInternals; use asn1::Asn1Time; use asn1::Asn1TimeRef; - use bio::{MemBio, MemBioSlice}; -use crypto::hash; -use crypto::hash::Type as HashType; +use crypto::hash::MessageDigest; use crypto::pkey::PKey; use crypto::rand::rand_bytes; use ffi; @@ -129,7 +126,7 @@ impl X509StoreContext { /// # Example /// /// ``` -/// use openssl::crypto::hash::Type; +/// use openssl::crypto::hash::MessageDigest; /// use openssl::crypto::pkey::PKey; /// use openssl::crypto::rsa::RSA; /// use openssl::x509::X509Generator; @@ -141,7 +138,7 @@ impl X509StoreContext { /// let gen = X509Generator::new() /// .set_valid_period(365*2) /// .add_name("CN".to_owned(), "SuperMegaCorp Inc.".to_owned()) -/// .set_sign_hash(Type::SHA256) +/// .set_sign_hash(MessageDigest::sha256()) /// .add_extension(Extension::KeyUsage(vec![KeyUsageOption::DigitalSignature])); /// /// let cert = gen.sign(&pkey).unwrap(); @@ -152,7 +149,7 @@ pub struct X509Generator { days: u32, names: Vec<(String, String)>, extensions: Extensions, - hash_type: HashType, + hash_type: MessageDigest, } impl X509Generator { @@ -168,7 +165,7 @@ impl X509Generator { days: 365, names: vec![], extensions: Extensions::new(), - hash_type: HashType::SHA1, + hash_type: MessageDigest::sha1(), } } @@ -239,7 +236,7 @@ impl X509Generator { self } - pub fn set_sign_hash(mut self, hash_type: hash::Type) -> X509Generator { + pub fn set_sign_hash(mut self, hash_type: MessageDigest) -> X509Generator { self.hash_type = hash_type; self } @@ -358,7 +355,7 @@ impl X509Generator { &ext.to_string())); } - let hash_fn = self.hash_type.evp_md(); + let hash_fn = self.hash_type.as_ptr(); try_ssl!(ffi::X509_sign(x509.as_ptr(), p_key.as_ptr(), hash_fn)); Ok(x509) } @@ -380,7 +377,7 @@ impl X509Generator { try_ssl!(ffi::X509_REQ_add_extensions(req, exts as *mut _)); } - let hash_fn = self.hash_type.evp_md(); + let hash_fn = self.hash_type.as_ptr(); try_ssl!(ffi::X509_REQ_sign(req, p_key.as_ptr(), hash_fn)); Ok(X509Req::new(req)) @@ -438,9 +435,9 @@ impl<'a> X509Ref<'a> { } /// Returns certificate fingerprint calculated using provided hash - pub fn fingerprint(&self, hash_type: hash::Type) -> Result, ErrorStack> { + pub fn fingerprint(&self, hash_type: MessageDigest) -> Result, ErrorStack> { unsafe { - let evp = hash_type.evp_md(); + let evp = hash_type.as_ptr(); let mut len = ffi::EVP_MAX_MD_SIZE; let mut buf = vec![0u8; len as usize]; try_ssl!(ffi::X509_digest(self.0, evp, buf.as_mut_ptr() as *mut _, &mut len)); diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 07d9e1d4..afb06408 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1,6 +1,6 @@ use serialize::hex::FromHex; -use crypto::hash::Type::SHA1; +use crypto::hash::MessageDigest; use crypto::pkey::PKey; use crypto::rsa::RSA; use x509::{X509, X509Generator}; @@ -14,7 +14,7 @@ fn get_generator() -> X509Generator { X509Generator::new() .set_valid_period(365 * 2) .add_name("CN".to_string(), "test_me".to_string()) - .set_sign_hash(SHA1) + .set_sign_hash(MessageDigest::sha1()) .add_extension(KeyUsage(vec![DigitalSignature, KeyEncipherment])) .add_extension(ExtKeyUsage(vec![ClientAuth, ServerAuth, @@ -83,7 +83,7 @@ fn test_req_gen() { fn test_cert_loading() { let cert = include_bytes!("../../test/cert.pem"); let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); - let fingerprint = cert.fingerprint(SHA1).unwrap(); + let fingerprint = cert.fingerprint(MessageDigest::sha1()).unwrap(); let hash_str = "59172d9313e84459bcff27f967e79e6e9217e584"; let hash_vec = hash_str.from_hex().unwrap(); -- cgit v1.2.3 From 7ec015325b0d900ddaf375b62f5a52d4231dc9a2 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 16 Oct 2016 21:07:17 -0700 Subject: Finish error overhaul --- openssl/src/x509/mod.rs | 119 ++++++++++++++++++++------------------------- openssl/src/x509/verify.rs | 9 ++-- 2 files changed, 58 insertions(+), 70 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index c429b486..1cd7471f 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -10,6 +10,7 @@ use std::slice; use std::collections::HashMap; use std::marker::PhantomData; +use {cvt, cvt_p}; use asn1::Asn1Time; use asn1::Asn1TimeRef; use bio::{MemBio, MemBioSlice}; @@ -251,25 +252,25 @@ impl X509Generator { 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) + try!(cvt_p(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(); - ffi::X509V3_EXT_conf(ptr::null_mut(), - mem::transmute(&ctx), - name.as_ptr() as *mut c_char, - value.as_ptr() as *mut c_char) + try!(cvt_p(ffi::X509V3_EXT_conf(ptr::null_mut(), + mem::transmute(&ctx), + name.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; + if ffi::X509_add_ext(x509, ext, -1) != 1 { ffi::X509_EXTENSION_free(ext); + Err(ErrorStack::get()) + } else { + Ok(()) } - lift_ssl_if!(!success) } } @@ -278,17 +279,18 @@ impl X509Generator { value: &str) -> Result<(), ErrorStack> { let value_len = value.len() as c_int; - lift_ssl!(unsafe { + 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) - }) + cvt(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)) + .map(|_| ()) + } } fn random_serial() -> Result { @@ -308,32 +310,30 @@ impl X509Generator { } /// Sets the certificate public-key, then self-sign and return it - /// Note: That the bit-length of the private key is used (set_bitlength is ignored) pub fn sign(&self, p_key: &PKey) -> Result { ffi::init(); unsafe { - let x509 = try_ssl_null!(ffi::X509_new()); - let x509 = X509::from_ptr(x509); + let x509 = X509::from_ptr(try!(cvt_p(ffi::X509_new()))); - try_ssl!(ffi::X509_set_version(x509.as_ptr(), 2)); - try_ssl!(ffi::ASN1_INTEGER_set(ffi::X509_get_serialNumber(x509.as_ptr()), - try!(X509Generator::random_serial()))); + try!(cvt(ffi::X509_set_version(x509.as_ptr(), 2))); + try!(cvt(ffi::ASN1_INTEGER_set(ffi::X509_get_serialNumber(x509.as_ptr()), + try!(X509Generator::random_serial())))); let not_before = try!(Asn1Time::days_from_now(0)); let not_after = try!(Asn1Time::days_from_now(self.days)); - try_ssl!(X509_set_notBefore(x509.as_ptr(), not_before.as_ptr() as *const _)); + try!(cvt(X509_set_notBefore(x509.as_ptr(), not_before.as_ptr() as *const _))); // If prev line succeded - ownership should go to cert mem::forget(not_before); - try_ssl!(X509_set_notAfter(x509.as_ptr(), not_after.as_ptr() as *const _)); + try!(cvt(X509_set_notAfter(x509.as_ptr(), not_after.as_ptr() as *const _))); // If prev line succeded - ownership should go to cert mem::forget(not_after); - try_ssl!(ffi::X509_set_pubkey(x509.as_ptr(), p_key.as_ptr())); + try!(cvt(ffi::X509_set_pubkey(x509.as_ptr(), p_key.as_ptr()))); - let name = try_ssl_null!(ffi::X509_get_subject_name(x509.as_ptr())); + let name = try!(cvt_p(ffi::X509_get_subject_name(x509.as_ptr()))); let default = [("CN", "rust-openssl")]; let default_iter = &mut default.iter().map(|&(k, v)| (k, v)); @@ -347,7 +347,7 @@ impl X509Generator { for (key, val) in iter { try!(X509Generator::add_name_internal(name, &key, &val)); } - try_ssl!(ffi::X509_set_issuer_name(x509.as_ptr(), name)); + try!(cvt(ffi::X509_set_issuer_name(x509.as_ptr(), name))); for (exttype, ext) in self.extensions.iter() { try!(X509Generator::add_extension_internal(x509.as_ptr(), @@ -356,7 +356,7 @@ impl X509Generator { } let hash_fn = self.hash_type.as_ptr(); - try_ssl!(ffi::X509_sign(x509.as_ptr(), p_key.as_ptr(), hash_fn)); + try!(cvt(ffi::X509_sign(x509.as_ptr(), p_key.as_ptr(), hash_fn))); Ok(x509) } } @@ -369,18 +369,20 @@ impl X509Generator { }; unsafe { - let req = ffi::X509_to_X509_REQ(cert.as_ptr(), ptr::null_mut(), ptr::null()); - try_ssl_null!(req); + let req = try!(cvt_p(ffi::X509_to_X509_REQ(cert.as_ptr(), + ptr::null_mut(), + ptr::null()))); + let req = X509Req::from_ptr(req); let exts = compat::X509_get0_extensions(cert.as_ptr()); if exts != ptr::null_mut() { - try_ssl!(ffi::X509_REQ_add_extensions(req, exts as *mut _)); + try!(cvt(ffi::X509_REQ_add_extensions(req.as_ptr(), exts as *mut _))); } let hash_fn = self.hash_type.as_ptr(); - try_ssl!(ffi::X509_REQ_sign(req, p_key.as_ptr(), hash_fn)); + try!(cvt(ffi::X509_REQ_sign(req.as_ptr(), p_key.as_ptr(), hash_fn))); - Ok(X509Req::new(req)) + Ok(req) } } } @@ -394,12 +396,6 @@ impl<'a> X509Ref<'a> { X509Ref(x509, PhantomData) } - /// - #[deprecated(note = "renamed to `X509::from_ptr`", since = "0.8.1")] - pub unsafe fn new(x509: *mut ffi::X509) -> X509Ref<'a> { - X509Ref::from_ptr(x509) - } - pub fn as_ptr(&self) -> *mut ffi::X509 { self.0 } @@ -429,7 +425,7 @@ impl<'a> X509Ref<'a> { pub fn public_key(&self) -> Result { unsafe { - let pkey = try_ssl_null!(ffi::X509_get_pubkey(self.0)); + let pkey = try!(cvt_p(ffi::X509_get_pubkey(self.0))); Ok(PKey::from_ptr(pkey)) } } @@ -440,7 +436,7 @@ impl<'a> X509Ref<'a> { let evp = hash_type.as_ptr(); let mut len = ffi::EVP_MAX_MD_SIZE; let mut buf = vec![0u8; len as usize]; - try_ssl!(ffi::X509_digest(self.0, evp, buf.as_mut_ptr() as *mut _, &mut len)); + try!(cvt(ffi::X509_digest(self.0, evp, buf.as_mut_ptr() as *mut _, &mut len))); buf.truncate(len as usize); Ok(buf) } @@ -468,7 +464,7 @@ impl<'a> X509Ref<'a> { pub fn to_pem(&self) -> Result, ErrorStack> { let mem_bio = try!(MemBio::new()); unsafe { - try_ssl!(ffi::PEM_write_bio_X509(mem_bio.as_ptr(), self.0)); + try!(cvt(ffi::PEM_write_bio_X509(mem_bio.as_ptr(), self.0))); } Ok(mem_bio.get_buf().to_owned()) } @@ -492,18 +488,12 @@ impl X509 { X509(X509Ref::from_ptr(x509)) } - /// - #[deprecated(note = "renamed to `X509::from_ptr`", since = "0.8.1")] - pub unsafe fn new(x509: *mut ffi::X509) -> X509 { - X509::from_ptr(x509) - } - /// Reads a certificate from DER. pub fn from_der(buf: &[u8]) -> Result { unsafe { let mut ptr = buf.as_ptr(); let len = cmp::min(buf.len(), c_long::max_value() as usize) as c_long; - let x509 = try_ssl_null!(ffi::d2i_X509(ptr::null_mut(), &mut ptr, len)); + let x509 = try!(cvt_p(ffi::d2i_X509(ptr::null_mut(), &mut ptr, len))); Ok(X509::from_ptr(x509)) } } @@ -512,10 +502,10 @@ impl X509 { pub fn from_pem(buf: &[u8]) -> Result { let mem_bio = try!(MemBioSlice::new(buf)); unsafe { - let handle = try_ssl_null!(ffi::PEM_read_bio_X509(mem_bio.as_ptr(), - ptr::null_mut(), - None, - ptr::null_mut())); + let handle = try!(cvt_p(ffi::PEM_read_bio_X509(mem_bio.as_ptr(), + ptr::null_mut(), + None, + ptr::null_mut()))); Ok(X509::from_ptr(handle)) } } @@ -582,8 +572,7 @@ impl<'x> X509Name<'x> { pub struct X509Req(*mut ffi::X509_REQ); impl X509Req { - /// Creates new from handle - pub unsafe fn new(handle: *mut ffi::X509_REQ) -> X509Req { + pub unsafe fn from_ptr(handle: *mut ffi::X509_REQ) -> X509Req { X509Req(handle) } @@ -595,11 +584,11 @@ impl X509Req { pub fn from_pem(buf: &[u8]) -> Result { let mem_bio = try!(MemBioSlice::new(buf)); unsafe { - let handle = try_ssl_null!(ffi::PEM_read_bio_X509_REQ(mem_bio.as_ptr(), - ptr::null_mut(), - None, - ptr::null_mut())); - Ok(X509Req::new(handle)) + let handle = try!(cvt_p(ffi::PEM_read_bio_X509_REQ(mem_bio.as_ptr(), + ptr::null_mut(), + None, + ptr::null_mut()))); + Ok(X509Req::from_ptr(handle)) } } diff --git a/openssl/src/x509/verify.rs b/openssl/src/x509/verify.rs index 0fc1df3a..87287875 100644 --- a/openssl/src/x509/verify.rs +++ b/openssl/src/x509/verify.rs @@ -32,11 +32,10 @@ impl<'a> X509VerifyParamRef<'a> { pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> { unsafe { - try_ssl!(ffi::X509_VERIFY_PARAM_set1_host(self.0, - host.as_ptr() as *const _, - host.len())) + cvt(ffi::X509_VERIFY_PARAM_set1_host(self.0, + host.as_ptr() as *const _, + host.len())) + .map(|_| ()) } - - Ok(()) } } -- cgit v1.2.3 From a938a001a7f64a9934b88e24f9c4115b1d0bebf6 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 16 Oct 2016 23:26:38 -0700 Subject: Fix missing import --- openssl/src/x509/verify.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/verify.rs b/openssl/src/x509/verify.rs index 87287875..5cce9bd7 100644 --- a/openssl/src/x509/verify.rs +++ b/openssl/src/x509/verify.rs @@ -2,6 +2,7 @@ use std::marker::PhantomData; use libc::c_uint; use ffi; +use cvt; use error::ErrorStack; bitflags! { -- cgit v1.2.3 From 194298a057bad2b79e45ef346a0e6f37f8bc0716 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 17 Oct 2016 21:21:09 -0700 Subject: Implement new feature setup The basic idea here is that there is a feature for each supported OpenSSL version. Enabling multiple features represents support for multiple OpenSSL versions, but it's then up to you to check which version you link against (probably by depending on openssl-sys and making a build script similar to what openssl does). --- openssl/src/x509/mod.rs | 2 +- openssl/src/x509/verify.rs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 1cd7471f..e801b1da 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -36,7 +36,7 @@ use ffi::{ pub mod extension; -#[cfg(feature = "openssl-102")] +#[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub mod verify; use self::extension::{ExtensionType, Extension}; diff --git a/openssl/src/x509/verify.rs b/openssl/src/x509/verify.rs index 5cce9bd7..be8d3d7e 100644 --- a/openssl/src/x509/verify.rs +++ b/openssl/src/x509/verify.rs @@ -1,3 +1,7 @@ +//! X509 certificate verification +//! +//! Requires the `v102` or `v110` features and OpenSSL 1.0.2 or 1.1.0. + use std::marker::PhantomData; use libc::c_uint; use ffi; @@ -13,7 +17,8 @@ bitflags! { const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS = ffi::X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS, const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS = ffi::X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS, - #[cfg(feature = "openssl-110")] + /// Requires the `v110` feature and OpenSSL 1.1.0. + #[cfg(all(feature = "v110", ossl110))] const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_NEVER_CHECK_SUBJECT, } } -- cgit v1.2.3 From 080050e10d7f1b00e164e4cb047ffc323f5d6fc9 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 18 Oct 2016 21:52:49 -0700 Subject: Drop lifetime on GeneralNames --- openssl/src/x509/mod.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index e801b1da..de74a236 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -406,7 +406,7 @@ impl<'a> X509Ref<'a> { } /// Returns this certificate's SAN entries, if they exist. - pub fn subject_alt_names<'b>(&'b self) -> Option> { + pub fn subject_alt_names(&self) -> Option { unsafe { let stack = ffi::X509_get_ext_d2i(self.0, Nid::SubjectAltName as c_int, @@ -418,7 +418,6 @@ impl<'a> X509Ref<'a> { Some(GeneralNames { stack: stack as *mut _, - m: PhantomData, }) } } @@ -763,14 +762,12 @@ make_validation_error!(X509_V_OK, X509ApplicationVerification = X509_V_ERR_APPLICATION_VERIFICATION, ); -// FIXME remove lifetime param for 0.9 /// A collection of OpenSSL `GENERAL_NAME`s. -pub struct GeneralNames<'a> { +pub struct GeneralNames { stack: *mut ffi::stack_st_GENERAL_NAME, - m: PhantomData<&'a ()>, } -impl<'a> Drop for GeneralNames<'a> { +impl Drop for GeneralNames { #[cfg(ossl10x)] fn drop(&mut self) { unsafe { @@ -792,7 +789,7 @@ impl<'a> Drop for GeneralNames<'a> { } } -impl<'a> GeneralNames<'a> { +impl GeneralNames { /// Returns the number of `GeneralName`s in this structure. pub fn len(&self) -> usize { self._len() @@ -813,7 +810,7 @@ impl<'a> GeneralNames<'a> { /// # Panics /// /// Panics if `idx` is not less than `len()`. - pub fn get(&self, idx: usize) -> GeneralName<'a> { + pub fn get<'a>(&'a self, idx: usize) -> GeneralName<'a> { unsafe { assert!(idx < self.len()); GeneralName { @@ -842,7 +839,7 @@ impl<'a> GeneralNames<'a> { } } -impl<'a> IntoIterator for &'a GeneralNames<'a> { +impl<'a> IntoIterator for &'a GeneralNames { type Item = GeneralName<'a>; type IntoIter = GeneralNamesIter<'a>; @@ -853,7 +850,7 @@ impl<'a> IntoIterator for &'a GeneralNames<'a> { /// An iterator over OpenSSL `GENERAL_NAME`s. pub struct GeneralNamesIter<'a> { - names: &'a GeneralNames<'a>, + names: &'a GeneralNames, idx: usize, } -- cgit v1.2.3 From cfd5192a7d44b8d6c77e57f091887a6a00a166db Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 18 Oct 2016 22:10:37 -0700 Subject: De-enumify X509ValidationError Also make it an Error. Closes #352. --- openssl/src/x509/mod.rs | 143 ++++++++++++++++++++---------------------------- 1 file changed, 60 insertions(+), 83 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index de74a236..50d75d63 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -1,14 +1,15 @@ use libc::{c_char, c_int, c_long, c_ulong, c_void}; use std::cmp; -use std::ffi::CString; +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::ptr; use std::ops::Deref; -use std::fmt; -use std::str; +use std::ptr; use std::slice; -use std::collections::HashMap; -use std::marker::PhantomData; +use std::str; use {cvt, cvt_p}; use asn1::Asn1Time; @@ -100,14 +101,19 @@ impl X509StoreContext { } pub fn error(&self) -> Option { - let err = unsafe { ffi::X509_STORE_CTX_get_error(self.ctx) }; - X509ValidationError::from_raw(err) + unsafe { + let err = ffi::X509_STORE_CTX_get_error(self.ctx) as c_long; + if err == ffi::X509_V_OK as c_long { + None + } else { + Some(X509ValidationError::from_raw(err)) + } + } } pub fn current_cert<'a>(&'a self) -> Option> { unsafe { let ptr = ffi::X509_STORE_CTX_get_current_cert(self.ctx); - if ptr.is_null() { None } else { @@ -685,82 +691,53 @@ impl<'a> Iterator for ExtensionsIter<'a> { } } -macro_rules! make_validation_error( - ($ok_val:ident, $($name:ident = $val:ident,)+) => ( - #[derive(Copy, Clone)] - pub enum X509ValidationError { - $($name,)+ - X509UnknownError(c_int) - } +pub struct X509ValidationError(c_long); - impl X509ValidationError { - #[doc(hidden)] - pub fn from_raw(err: c_int) -> Option { - match err { - ffi::$ok_val => None, - $(ffi::$val => Some(X509ValidationError::$name),)+ - err => Some(X509ValidationError::X509UnknownError(err)) - } - } +impl fmt::Debug for X509ValidationError { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("X509ValidationError") + .field("code", &self.0) + .field("error", &self.error_string()) + .finish() + } +} + +impl fmt::Display for X509ValidationError { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.write_str(self.error_string()) + } +} + +impl Error for X509ValidationError { + fn description(&self) -> &str { + "an X509 validation error" + } +} + +impl X509ValidationError { + /// Creates an `X509ValidationError` from a raw error number. + /// + /// # Safety + /// + /// Some methods on `X509ValidationError` are not thread safe if the error + /// number is invalid. + pub unsafe fn from_raw(err: c_long) -> X509ValidationError { + X509ValidationError(err) + } + + pub fn as_raw(&self) -> c_long { + self.0 + } + + pub fn error_string(&self) -> &'static str { + ffi::init(); + + unsafe { + let s = ffi::X509_verify_cert_error_string(self.0); + str::from_utf8(CStr::from_ptr(s).to_bytes()).unwrap() } - ) -); - -make_validation_error!(X509_V_OK, - X509UnableToGetIssuerCert = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT, - X509UnableToGetCrl = X509_V_ERR_UNABLE_TO_GET_CRL, - X509UnableToDecryptCertSignature = X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE, - X509UnableToDecryptCrlSignature = X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE, - X509UnableToDecodeIssuerPublicKey = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY, - X509CertSignatureFailure = X509_V_ERR_CERT_SIGNATURE_FAILURE, - X509CrlSignatureFailure = X509_V_ERR_CRL_SIGNATURE_FAILURE, - X509CertNotYetValid = X509_V_ERR_CERT_NOT_YET_VALID, - X509CertHasExpired = X509_V_ERR_CERT_HAS_EXPIRED, - X509CrlNotYetValid = X509_V_ERR_CRL_NOT_YET_VALID, - X509CrlHasExpired = X509_V_ERR_CRL_HAS_EXPIRED, - X509ErrorInCertNotBeforeField = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD, - X509ErrorInCertNotAfterField = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD, - X509ErrorInCrlLastUpdateField = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD, - X509ErrorInCrlNextUpdateField = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD, - X509OutOfMem = X509_V_ERR_OUT_OF_MEM, - X509DepthZeroSelfSignedCert = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT, - X509SelfSignedCertInChain = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN, - X509UnableToGetIssuerCertLocally = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, - X509UnableToVerifyLeafSignature = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE, - X509CertChainTooLong = X509_V_ERR_CERT_CHAIN_TOO_LONG, - X509CertRevoked = X509_V_ERR_CERT_REVOKED, - X509InvalidCA = X509_V_ERR_INVALID_CA, - X509PathLengthExceeded = X509_V_ERR_PATH_LENGTH_EXCEEDED, - X509InvalidPurpose = X509_V_ERR_INVALID_PURPOSE, - X509CertUntrusted = X509_V_ERR_CERT_UNTRUSTED, - X509CertRejected = X509_V_ERR_CERT_REJECTED, - X509SubjectIssuerMismatch = X509_V_ERR_SUBJECT_ISSUER_MISMATCH, - X509AkidSkidMismatch = X509_V_ERR_AKID_SKID_MISMATCH, - X509AkidIssuerSerialMismatch = X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH, - X509KeyusageNoCertsign = X509_V_ERR_KEYUSAGE_NO_CERTSIGN, - X509UnableToGetCrlIssuer = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER, - X509UnhandledCriticalExtension = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION, - X509KeyusageNoCrlSign = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN, - X509UnhandledCriticalCrlExtension = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION, - X509InvalidNonCA = X509_V_ERR_INVALID_NON_CA, - X509ProxyPathLengthExceeded = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED, - X509KeyusageNoDigitalSignature = X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE, - X509ProxyCertificatesNotAllowed = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED, - X509InvalidExtension = X509_V_ERR_INVALID_EXTENSION, - X509InavlidPolicyExtension = X509_V_ERR_INVALID_POLICY_EXTENSION, - X509NoExplicitPolicy = X509_V_ERR_NO_EXPLICIT_POLICY, - X509DifferentCrlScope = X509_V_ERR_DIFFERENT_CRL_SCOPE, - X509UnsupportedExtensionFeature = X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE, - X509UnnestedResource = X509_V_ERR_UNNESTED_RESOURCE, - X509PermittedVolation = X509_V_ERR_PERMITTED_VIOLATION, - X509ExcludedViolation = X509_V_ERR_EXCLUDED_VIOLATION, - X509SubtreeMinmax = X509_V_ERR_SUBTREE_MINMAX, - X509UnsupportedConstraintType = X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE, - X509UnsupportedConstraintSyntax = X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX, - X509UnsupportedNameSyntax = X509_V_ERR_UNSUPPORTED_NAME_SYNTAX, - X509CrlPathValidationError= X509_V_ERR_CRL_PATH_VALIDATION_ERROR, - X509ApplicationVerification = X509_V_ERR_APPLICATION_VERIFICATION, -); + } +} /// A collection of OpenSSL `GENERAL_NAME`s. pub struct GeneralNames { -- cgit v1.2.3 From 5ab037f056174b4d69024f58fe42cf0c41a34db6 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 18 Oct 2016 22:18:09 -0700 Subject: Allow the X509 verify error to be read from an SslRef --- openssl/src/x509/mod.rs | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 50d75d63..7f891231 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -100,14 +100,9 @@ impl X509StoreContext { X509StoreContext { ctx: ctx } } - pub fn error(&self) -> Option { + pub fn error(&self) -> Option { unsafe { - let err = ffi::X509_STORE_CTX_get_error(self.ctx) as c_long; - if err == ffi::X509_V_OK as c_long { - None - } else { - Some(X509ValidationError::from_raw(err)) - } + X509VerifyError::from_raw(ffi::X509_STORE_CTX_get_error(self.ctx) as c_long) } } @@ -691,38 +686,44 @@ impl<'a> Iterator for ExtensionsIter<'a> { } } -pub struct X509ValidationError(c_long); +pub struct X509VerifyError(c_long); -impl fmt::Debug for X509ValidationError { +impl fmt::Debug for X509VerifyError { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_struct("X509ValidationError") + fmt.debug_struct("X509VerifyError") .field("code", &self.0) .field("error", &self.error_string()) .finish() } } -impl fmt::Display for X509ValidationError { +impl fmt::Display for X509VerifyError { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.write_str(self.error_string()) } } -impl Error for X509ValidationError { +impl Error for X509VerifyError { fn description(&self) -> &str { "an X509 validation error" } } -impl X509ValidationError { - /// Creates an `X509ValidationError` from a raw error number. +impl X509VerifyError { + /// Creates an `X509VerifyError` from a raw error number. + /// + /// `None` will be returned if `err` is `X509_V_OK`. /// /// # Safety /// - /// Some methods on `X509ValidationError` are not thread safe if the error + /// Some methods on `X509VerifyError` are not thread safe if the error /// number is invalid. - pub unsafe fn from_raw(err: c_long) -> X509ValidationError { - X509ValidationError(err) + pub unsafe fn from_raw(err: c_long) -> Option { + if err == ffi::X509_V_OK as c_long { + None + } else { + Some(X509VerifyError(err)) + } } pub fn as_raw(&self) -> c_long { -- cgit v1.2.3 From b3eb8d516ca1f112fec37436bab56a061a934244 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 20 Oct 2016 22:41:42 -0700 Subject: Switch X509Name over to new borrow setup The use of actual references enables us to be correct with respect to mutability without needing two structs for the mutable and immutable cases and more deref impls. --- openssl/src/x509/mod.rs | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 7f891231..51c1ab29 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -18,9 +18,10 @@ use bio::{MemBio, MemBioSlice}; use crypto::hash::MessageDigest; use crypto::pkey::PKey; use crypto::rand::rand_bytes; +use error::ErrorStack; use ffi; use nid::Nid; -use error::ErrorStack; +use opaque::Opaque; #[cfg(ossl10x)] use ffi::{ @@ -401,9 +402,11 @@ impl<'a> X509Ref<'a> { self.0 } - pub fn subject_name<'b>(&'b self) -> X509Name<'b> { - let name = unsafe { ffi::X509_get_subject_name(self.0) }; - X509Name(name, PhantomData) + pub fn subject_name(&self) -> &X509NameRef { + unsafe { + let name = ffi::X509_get_subject_name(self.0); + X509NameRef::from_ptr(name) + } } /// Returns this certificate's SAN entries, if they exist. @@ -534,17 +537,25 @@ impl Drop for X509 { } } -pub struct X509Name<'x>(*mut ffi::X509_NAME, PhantomData<&'x ()>); +pub struct X509NameRef(Opaque); + +impl X509NameRef { + pub unsafe fn from_ptr<'a>(ptr: *mut ffi::X509_NAME) -> &'a X509NameRef { + &*(ptr as *mut _) + } + + pub fn as_ptr(&self) -> *mut ffi::X509_NAME { + self as *const _ as *mut _ + } -impl<'x> X509Name<'x> { pub fn text_by_nid(&self, nid: Nid) -> Option { unsafe { - let loc = ffi::X509_NAME_get_index_by_NID(self.0, nid as c_int, -1); + let loc = ffi::X509_NAME_get_index_by_NID(self.as_ptr(), nid as c_int, -1); if loc == -1 { return None; } - let ne = ffi::X509_NAME_get_entry(self.0, loc); + let ne = ffi::X509_NAME_get_entry(self.as_ptr(), loc); if ne.is_null() { return None; } -- cgit v1.2.3 From 23fc6c828bdfc7322d6e4c9a0ac8b4047f69df0f Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 21 Oct 2016 17:01:13 -0700 Subject: Convert X509Ref --- openssl/src/x509/mod.rs | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 51c1ab29..99710fc4 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -107,7 +107,7 @@ impl X509StoreContext { } } - pub fn current_cert<'a>(&'a self) -> Option> { + pub fn current_cert<'a>(&'a self) -> Option<&'a X509Ref> { unsafe { let ptr = ffi::X509_STORE_CTX_get_current_cert(self.ctx); if ptr.is_null() { @@ -390,21 +390,21 @@ impl X509Generator { } /// A borrowed public key certificate. -pub struct X509Ref<'a>(*mut ffi::X509, PhantomData<&'a ()>); +pub struct X509Ref(Opaque); -impl<'a> X509Ref<'a> { +impl X509Ref { /// Creates a new `X509Ref` wrapping the provided handle. - pub unsafe fn from_ptr(x509: *mut ffi::X509) -> X509Ref<'a> { - X509Ref(x509, PhantomData) + pub unsafe fn from_ptr<'a>(x509: *mut ffi::X509) -> &'a X509Ref { + &*(x509 as *mut _) } pub fn as_ptr(&self) -> *mut ffi::X509 { - self.0 + self as *const _ as *mut _ } pub fn subject_name(&self) -> &X509NameRef { unsafe { - let name = ffi::X509_get_subject_name(self.0); + let name = ffi::X509_get_subject_name(self.as_ptr()); X509NameRef::from_ptr(name) } } @@ -412,7 +412,7 @@ impl<'a> X509Ref<'a> { /// Returns this certificate's SAN entries, if they exist. pub fn subject_alt_names(&self) -> Option { unsafe { - let stack = ffi::X509_get_ext_d2i(self.0, + let stack = ffi::X509_get_ext_d2i(self.as_ptr(), Nid::SubjectAltName as c_int, ptr::null_mut(), ptr::null_mut()); @@ -428,7 +428,7 @@ impl<'a> X509Ref<'a> { pub fn public_key(&self) -> Result { unsafe { - let pkey = try!(cvt_p(ffi::X509_get_pubkey(self.0))); + let pkey = try!(cvt_p(ffi::X509_get_pubkey(self.as_ptr()))); Ok(PKey::from_ptr(pkey)) } } @@ -439,25 +439,25 @@ impl<'a> X509Ref<'a> { let evp = hash_type.as_ptr(); let mut len = ffi::EVP_MAX_MD_SIZE; let mut buf = vec![0u8; len as usize]; - try!(cvt(ffi::X509_digest(self.0, evp, buf.as_mut_ptr() as *mut _, &mut len))); + try!(cvt(ffi::X509_digest(self.as_ptr(), evp, buf.as_mut_ptr() as *mut _, &mut len))); buf.truncate(len as usize); Ok(buf) } } /// Returns certificate Not After validity period. - pub fn not_after<'b>(&'b self) -> Asn1TimeRef<'b> { + pub fn not_after<'a>(&'a self) -> Asn1TimeRef<'a> { unsafe { - let date = compat::X509_get_notAfter(self.0); + let date = compat::X509_get_notAfter(self.as_ptr()); assert!(!date.is_null()); Asn1TimeRef::from_ptr(date) } } /// Returns certificate Not Before validity period. - pub fn not_before<'b>(&'b self) -> Asn1TimeRef<'b> { + pub fn not_before<'a>(&'a self) -> Asn1TimeRef<'a> { unsafe { - let date = compat::X509_get_notBefore(self.0); + let date = compat::X509_get_notBefore(self.as_ptr()); assert!(!date.is_null()); Asn1TimeRef::from_ptr(date) } @@ -467,7 +467,7 @@ impl<'a> X509Ref<'a> { pub fn to_pem(&self) -> Result, ErrorStack> { let mem_bio = try!(MemBio::new()); unsafe { - try!(cvt(ffi::PEM_write_bio_X509(mem_bio.as_ptr(), self.0))); + try!(cvt(ffi::PEM_write_bio_X509(mem_bio.as_ptr(), self.as_ptr()))); } Ok(mem_bio.get_buf().to_owned()) } @@ -476,19 +476,19 @@ impl<'a> X509Ref<'a> { pub fn to_der(&self) -> Result, ErrorStack> { let mem_bio = try!(MemBio::new()); unsafe { - ffi::i2d_X509_bio(mem_bio.as_ptr(), self.0); + ffi::i2d_X509_bio(mem_bio.as_ptr(), self.as_ptr()); } Ok(mem_bio.get_buf().to_owned()) } } /// An owned public key certificate. -pub struct X509(X509Ref<'static>); +pub struct X509(*mut ffi::X509); impl X509 { /// Returns a new `X509`, taking ownership of the handle. pub unsafe fn from_ptr(x509: *mut ffi::X509) -> X509 { - X509(X509Ref::from_ptr(x509)) + X509(x509) } /// Reads a certificate from DER. @@ -515,10 +515,12 @@ impl X509 { } impl Deref for X509 { - type Target = X509Ref<'static>; + type Target = X509Ref; - fn deref(&self) -> &X509Ref<'static> { - &self.0 + fn deref(&self) -> &X509Ref { + unsafe { + X509Ref::from_ptr(self.0) + } } } -- cgit v1.2.3 From b7017a7eecf57aa6f1ab18ea1da771bafcab2ea9 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 21 Oct 2016 17:13:30 -0700 Subject: Update Asn1TimeRef --- openssl/src/x509/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 99710fc4..9c91bfc1 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -446,7 +446,7 @@ impl X509Ref { } /// Returns certificate Not After validity period. - pub fn not_after<'a>(&'a self) -> Asn1TimeRef<'a> { + pub fn not_after<'a>(&'a self) -> &'a Asn1TimeRef { unsafe { let date = compat::X509_get_notAfter(self.as_ptr()); assert!(!date.is_null()); @@ -455,7 +455,7 @@ impl X509Ref { } /// Returns certificate Not Before validity period. - pub fn not_before<'a>(&'a self) -> Asn1TimeRef<'a> { + pub fn not_before<'a>(&'a self) -> &'a Asn1TimeRef { unsafe { let date = compat::X509_get_notBefore(self.as_ptr()); assert!(!date.is_null()); -- cgit v1.2.3 From 02b4385c5d18534d7b02a3ebc3323b662251c36e Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 21 Oct 2016 19:58:06 -0700 Subject: Convert X509VerifyParamRef --- openssl/src/x509/verify.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/verify.rs b/openssl/src/x509/verify.rs index be8d3d7e..11c65dca 100644 --- a/openssl/src/x509/verify.rs +++ b/openssl/src/x509/verify.rs @@ -8,6 +8,7 @@ use ffi; use cvt; use error::ErrorStack; +use opaque::Opaque; bitflags! { pub flags X509CheckFlags: c_uint { @@ -23,22 +24,26 @@ bitflags! { } } -pub struct X509VerifyParamRef<'a>(*mut ffi::X509_VERIFY_PARAM, PhantomData<&'a mut ()>); +pub struct X509VerifyParamRef(Opaque); -impl<'a> X509VerifyParamRef<'a> { - pub unsafe fn from_ptr(ptr: *mut ffi::X509_VERIFY_PARAM) -> X509VerifyParamRef<'a> { - X509VerifyParamRef(ptr, PhantomData) +impl X509VerifyParamRef { + pub unsafe fn from_ptr_mut<'a>(ptr: *mut ffi::X509_VERIFY_PARAM) -> &'a mut X509VerifyParamRef { + &mut *(ptr as *mut _) + } + + pub fn as_ptr(&self) -> *mut ffi::X509_VERIFY_PARAM { + self as *const _ as *mut _ } pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) { unsafe { - ffi::X509_VERIFY_PARAM_set_hostflags(self.0, hostflags.bits); + ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits); } } pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> { unsafe { - cvt(ffi::X509_VERIFY_PARAM_set1_host(self.0, + cvt(ffi::X509_VERIFY_PARAM_set1_host(self.as_ptr(), host.as_ptr() as *const _, host.len())) .map(|_| ()) -- cgit v1.2.3 From 6f1a3f2834b45a546edd0a3e736b498599c996bb Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 21 Oct 2016 20:26:53 -0700 Subject: Update BigNumRef --- openssl/src/x509/verify.rs | 1 - 1 file changed, 1 deletion(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/verify.rs b/openssl/src/x509/verify.rs index 11c65dca..77095edc 100644 --- a/openssl/src/x509/verify.rs +++ b/openssl/src/x509/verify.rs @@ -2,7 +2,6 @@ //! //! Requires the `v102` or `v110` features and OpenSSL 1.0.2 or 1.1.0. -use std::marker::PhantomData; use libc::c_uint; use ffi; -- cgit v1.2.3 From 8ec53eb0e1b29d2b5c7e3afc433a26cede6dc84d Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 21 Oct 2016 20:59:07 -0700 Subject: Fix X509StoreContext --- openssl/src/x509/mod.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 9c91bfc1..db5ef1df 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -91,25 +91,26 @@ pub enum X509FileType { Default = ffi::X509_FILETYPE_DEFAULT, } -#[allow(missing_copy_implementations)] -pub struct X509StoreContext { - ctx: *mut ffi::X509_STORE_CTX, -} +pub struct X509StoreContextRef(Opaque); + +impl X509StoreContextRef { + pub unsafe fn from_ptr<'a>(ctx: *mut ffi::X509_STORE_CTX) -> &'a X509StoreContextRef { + &*(ctx as *mut _) + } -impl X509StoreContext { - pub fn new(ctx: *mut ffi::X509_STORE_CTX) -> X509StoreContext { - X509StoreContext { ctx: ctx } + pub fn as_ptr(&self) -> *mut ffi::X509_STORE_CTX { + self as *const _ as *mut _ } pub fn error(&self) -> Option { unsafe { - X509VerifyError::from_raw(ffi::X509_STORE_CTX_get_error(self.ctx) as c_long) + X509VerifyError::from_raw(ffi::X509_STORE_CTX_get_error(self.as_ptr()) as c_long) } } - pub fn current_cert<'a>(&'a self) -> Option<&'a X509Ref> { + pub fn current_cert(&self) -> Option<&X509Ref> { unsafe { - let ptr = ffi::X509_STORE_CTX_get_current_cert(self.ctx); + let ptr = ffi::X509_STORE_CTX_get_current_cert(self.as_ptr()); if ptr.is_null() { None } else { @@ -119,7 +120,7 @@ impl X509StoreContext { } pub fn error_depth(&self) -> u32 { - unsafe { ffi::X509_STORE_CTX_get_error_depth(self.ctx) as u32 } + unsafe { ffi::X509_STORE_CTX_get_error_depth(self.as_ptr()) as u32 } } } -- cgit v1.2.3 From 98b7f2f9352e4d92b44245d0737f9a45adb4ae2b Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 22 Oct 2016 09:16:38 -0700 Subject: Flatten crypto module --- openssl/src/x509/mod.rs | 6 +++--- openssl/src/x509/tests.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index db5ef1df..dfd61cac 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -15,9 +15,9 @@ use {cvt, cvt_p}; use asn1::Asn1Time; use asn1::Asn1TimeRef; use bio::{MemBio, MemBioSlice}; -use crypto::hash::MessageDigest; -use crypto::pkey::PKey; -use crypto::rand::rand_bytes; +use hash::MessageDigest; +use pkey::PKey; +use rand::rand_bytes; use error::ErrorStack; use ffi; use nid::Nid; diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index afb06408..a5eb04e7 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -1,8 +1,8 @@ use serialize::hex::FromHex; -use crypto::hash::MessageDigest; -use crypto::pkey::PKey; -use crypto::rsa::RSA; +use hash::MessageDigest; +use pkey::PKey; +use rsa::RSA; use x509::{X509, X509Generator}; use x509::extension::Extension::{KeyUsage, ExtKeyUsage, SubjectAltName, OtherNid, OtherStr}; use x509::extension::AltNameOption as SAN; -- cgit v1.2.3 From 2fd201d9c3df7fd76c0194fc10fa09cf5f0eb841 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 22 Oct 2016 10:08:21 -0700 Subject: De-enumify Nid --- openssl/src/x509/extension.rs | 8 ++++---- openssl/src/x509/mod.rs | 6 +++--- openssl/src/x509/tests.rs | 20 ++++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index 99ef62c1..fc6b3c3b 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -71,10 +71,10 @@ impl Extension { impl ExtensionType { pub fn get_nid(&self) -> Option { match self { - &ExtensionType::KeyUsage => Some(Nid::KeyUsage), - &ExtensionType::ExtKeyUsage => Some(Nid::ExtendedKeyUsage), - &ExtensionType::SubjectAltName => Some(Nid::SubjectAltName), - &ExtensionType::IssuerAltName => Some(Nid::IssuerAltName), + &ExtensionType::KeyUsage => Some(Nid::key_usage()), + &ExtensionType::ExtKeyUsage => Some(Nid::ext_key_usage()), + &ExtensionType::SubjectAltName => Some(Nid::subject_alt_name()), + &ExtensionType::IssuerAltName => Some(Nid::issuer_alt_name()), &ExtensionType::OtherNid(nid) => Some(nid), &ExtensionType::OtherStr(_) => None, } diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index dfd61cac..8653b44e 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -257,7 +257,7 @@ impl X509Generator { Some(nid) => { try!(cvt_p(ffi::X509V3_EXT_conf_nid(ptr::null_mut(), mem::transmute(&ctx), - nid as c_int, + nid.as_raw(), value.as_ptr() as *mut c_char))) } None => { @@ -414,7 +414,7 @@ impl X509Ref { pub fn subject_alt_names(&self) -> Option { unsafe { let stack = ffi::X509_get_ext_d2i(self.as_ptr(), - Nid::SubjectAltName as c_int, + ffi::NID_subject_alt_name, ptr::null_mut(), ptr::null_mut()); if stack.is_null() { @@ -553,7 +553,7 @@ impl X509NameRef { pub fn text_by_nid(&self, nid: Nid) -> Option { unsafe { - let loc = ffi::X509_NAME_get_index_by_NID(self.as_ptr(), nid as c_int, -1); + let loc = ffi::X509_NAME_get_index_by_NID(self.as_ptr(), nid.as_raw(), -1); if loc == -1 { return None; } diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index a5eb04e7..2a5d51a2 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -20,7 +20,7 @@ fn get_generator() -> X509Generator { ServerAuth, ExtKeyUsageOption::Other("2.999.1".to_owned())])) .add_extension(SubjectAltName(vec![(SAN::DNS, "example.com".to_owned())])) - .add_extension(OtherNid(Nid::BasicConstraints, "critical,CA:TRUE".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())) } @@ -48,8 +48,8 @@ fn test_cert_gen() { fn test_cert_gen_extension_ordering() { let pkey = pkey(); get_generator() - .add_extension(OtherNid(Nid::SubjectKeyIdentifier, "hash".to_owned())) - .add_extension(OtherNid(Nid::AuthorityKeyIdentifier, "keyid:always".to_owned())) + .add_extension(OtherNid(Nid::subject_key_identifier(), "hash".to_owned())) + .add_extension(OtherNid(Nid::authority_key_identifier(), "keyid:always".to_owned())) .sign(&pkey) .expect("Failed to generate cert with order-dependent extensions"); } @@ -60,9 +60,9 @@ fn test_cert_gen_extension_ordering() { fn test_cert_gen_extension_bad_ordering() { let pkey = pkey(); let result = get_generator() - .add_extension(OtherNid(Nid::AuthorityKeyIdentifier, + .add_extension(OtherNid(Nid::authority_key_identifier(), "keyid:always".to_owned())) - .add_extension(OtherNid(Nid::SubjectKeyIdentifier, "hash".to_owned())) + .add_extension(OtherNid(Nid::subject_key_identifier(), "hash".to_owned())) .sign(&pkey); assert!(result.is_err()); @@ -116,7 +116,7 @@ fn test_subject_read_cn() { let cert = include_bytes!("../../test/cert.pem"); let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); let subject = cert.subject_name(); - let cn = match subject.text_by_nid(Nid::CN) { + let cn = match subject.text_by_nid(Nid::commonName()) { Some(x) => x, None => panic!("Failed to read CN from cert"), }; @@ -130,19 +130,19 @@ fn test_nid_values() { let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); let subject = cert.subject_name(); - let cn = match subject.text_by_nid(Nid::CN) { + let cn = match subject.text_by_nid(Nid::commonName()) { Some(x) => x, None => panic!("Failed to read CN from cert"), }; assert_eq!(&cn as &str, "example.com"); - let email = match subject.text_by_nid(Nid::Email) { + let email = match subject.text_by_nid(Nid::pkcs9_emailAddress()) { Some(x) => x, None => panic!("Failed to read subject email address from cert"), }; assert_eq!(&email as &str, "test@example.com"); - let friendly = match subject.text_by_nid(Nid::FriendlyName) { + let friendly = match subject.text_by_nid(Nid::friendlyName()) { Some(x) => x, None => panic!("Failed to read subject friendly name from cert"), }; @@ -155,7 +155,7 @@ fn test_nid_uid_value() { let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); let subject = cert.subject_name(); - let cn = match subject.text_by_nid(Nid::UserId) { + let cn = match subject.text_by_nid(Nid::userId()) { Some(x) => x, None => panic!("Failed to read UID from cert"), }; -- cgit v1.2.3 From 3c50c74444e841c9178758fe18dcef38f56da243 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 22 Oct 2016 10:21:16 -0700 Subject: Camel case Rsa --- openssl/src/x509/tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 2a5d51a2..c0c7ce87 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -2,7 +2,7 @@ use serialize::hex::FromHex; use hash::MessageDigest; use pkey::PKey; -use rsa::RSA; +use rsa::Rsa; use x509::{X509, X509Generator}; use x509::extension::Extension::{KeyUsage, ExtKeyUsage, SubjectAltName, OtherNid, OtherStr}; use x509::extension::AltNameOption as SAN; @@ -25,7 +25,7 @@ fn get_generator() -> X509Generator { } fn pkey() -> PKey { - let rsa = RSA::generate(2048).unwrap(); + let rsa = Rsa::generate(2048).unwrap(); PKey::from_rsa(rsa).unwrap() } -- cgit v1.2.3 From 787cad3c8225b0c09135305477d5a962fc64d9bb Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 22 Oct 2016 15:58:06 -0700 Subject: Use constants rather than constructors for Nid --- openssl/src/x509/extension.rs | 10 +++++----- openssl/src/x509/tests.rs | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index fc6b3c3b..7ac66383 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -1,6 +1,6 @@ use std::fmt; -use nid::Nid; +use nid::{self, Nid}; /// Type-only version of the `Extension` enum. /// @@ -71,10 +71,10 @@ impl Extension { impl ExtensionType { pub fn get_nid(&self) -> Option { match self { - &ExtensionType::KeyUsage => Some(Nid::key_usage()), - &ExtensionType::ExtKeyUsage => Some(Nid::ext_key_usage()), - &ExtensionType::SubjectAltName => Some(Nid::subject_alt_name()), - &ExtensionType::IssuerAltName => Some(Nid::issuer_alt_name()), + &ExtensionType::KeyUsage => Some(nid::KEY_USAGE), + &ExtensionType::ExtKeyUsage => Some(nid::EXT_KEY_USAGE), + &ExtensionType::SubjectAltName => Some(nid::SUBJECT_ALT_NAME), + &ExtensionType::IssuerAltName => Some(nid::ISSUER_ALT_NAME), &ExtensionType::OtherNid(nid) => Some(nid), &ExtensionType::OtherStr(_) => None, } diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index c0c7ce87..185c4910 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -8,7 +8,7 @@ use x509::extension::Extension::{KeyUsage, ExtKeyUsage, SubjectAltName, OtherNid use x509::extension::AltNameOption as SAN; use x509::extension::KeyUsageOption::{DigitalSignature, KeyEncipherment}; use x509::extension::ExtKeyUsageOption::{self, ClientAuth, ServerAuth}; -use nid::Nid; +use nid; fn get_generator() -> X509Generator { X509Generator::new() @@ -20,7 +20,7 @@ fn get_generator() -> X509Generator { 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(OtherNid(nid::BASIC_CONSTRAINTS, "critical,CA:TRUE".to_owned())) .add_extension(OtherStr("2.999.2".to_owned(), "ASN1:UTF8:example value".to_owned())) } @@ -48,8 +48,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(OtherNid(nid::SUBJECT_KEY_IDENTIFIER, "hash".to_owned())) + .add_extension(OtherNid(nid::AUTHORITY_KEY_IDENTIFIER, "keyid:always".to_owned())) .sign(&pkey) .expect("Failed to generate cert with order-dependent extensions"); } @@ -60,9 +60,9 @@ 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(), + .add_extension(OtherNid(nid::AUTHORITY_KEY_IDENTIFIER, "keyid:always".to_owned())) - .add_extension(OtherNid(Nid::subject_key_identifier(), "hash".to_owned())) + .add_extension(OtherNid(nid::SUBJECT_KEY_IDENTIFIER, "hash".to_owned())) .sign(&pkey); assert!(result.is_err()); @@ -116,7 +116,7 @@ fn test_subject_read_cn() { let cert = include_bytes!("../../test/cert.pem"); let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); let subject = cert.subject_name(); - let cn = match subject.text_by_nid(Nid::commonName()) { + let cn = match subject.text_by_nid(nid::COMMONNAME) { Some(x) => x, None => panic!("Failed to read CN from cert"), }; @@ -130,19 +130,19 @@ fn test_nid_values() { let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); let subject = cert.subject_name(); - let cn = match subject.text_by_nid(Nid::commonName()) { + let cn = match subject.text_by_nid(nid::COMMONNAME) { Some(x) => x, None => panic!("Failed to read CN from cert"), }; assert_eq!(&cn as &str, "example.com"); - let email = match subject.text_by_nid(Nid::pkcs9_emailAddress()) { + let email = match subject.text_by_nid(nid::PKCS9_EMAILADDRESS) { Some(x) => x, None => panic!("Failed to read subject email address from cert"), }; assert_eq!(&email as &str, "test@example.com"); - let friendly = match subject.text_by_nid(Nid::friendlyName()) { + let friendly = match subject.text_by_nid(nid::FRIENDLYNAME) { Some(x) => x, None => panic!("Failed to read subject friendly name from cert"), }; @@ -155,7 +155,7 @@ fn test_nid_uid_value() { let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); let subject = cert.subject_name(); - let cn = match subject.text_by_nid(Nid::userId()) { + let cn = match subject.text_by_nid(nid::USERID) { Some(x) => x, None => panic!("Failed to read UID from cert"), }; -- cgit v1.2.3 From d39a2cedad749c47e3fabe7701cd1134568e5cfd Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 22 Oct 2016 16:01:26 -0700 Subject: Fix tests --- openssl/src/x509/extension.rs | 4 ++-- openssl/src/x509/mod.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/extension.rs b/openssl/src/x509/extension.rs index 7ac66383..398bbb3e 100644 --- a/openssl/src/x509/extension.rs +++ b/openssl/src/x509/extension.rs @@ -36,10 +36,10 @@ pub enum Extension { /// /// ``` /// use openssl::x509::extension::Extension::*; - /// use openssl::nid::Nid; + /// use openssl::nid; /// /// # let generator = openssl::x509::X509Generator::new(); - /// generator.add_extension(OtherNid(Nid::BasicConstraints,"critical,CA:TRUE".to_owned())); + /// generator.add_extension(OtherNid(nid::BASIC_CONSTRAINTS,"critical,CA:TRUE".to_owned())); /// ``` OtherNid(Nid, String), /// Arbitrary extensions by OID string. See `man ASN1_generate_nconf` for value syntax. diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 8653b44e..af5c722a 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -130,13 +130,13 @@ impl X509StoreContextRef { /// # Example /// /// ``` -/// use openssl::crypto::hash::MessageDigest; -/// use openssl::crypto::pkey::PKey; -/// use openssl::crypto::rsa::RSA; +/// use openssl::hash::MessageDigest; +/// use openssl::pkey::PKey; +/// use openssl::rsa::Rsa; /// use openssl::x509::X509Generator; /// use openssl::x509::extension::{Extension, KeyUsageOption}; /// -/// let rsa = RSA::generate(2048).unwrap(); +/// let rsa = Rsa::generate(2048).unwrap(); /// let pkey = PKey::from_rsa(rsa).unwrap(); /// /// let gen = X509Generator::new() -- cgit v1.2.3 From 4f59d576752aa1f44704b19befbf893dbd046465 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Wed, 26 Oct 2016 21:28:00 -0700 Subject: Move SslString to a shared location --- openssl/src/x509/mod.rs | 42 +++--------------------------------------- 1 file changed, 3 insertions(+), 39 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index af5c722a..b92462d4 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -15,6 +15,7 @@ use {cvt, cvt_p}; use asn1::Asn1Time; use asn1::Asn1TimeRef; use bio::{MemBio, MemBioSlice}; +use crypto::CryptoString; use hash::MessageDigest; use pkey::PKey; use rand::rand_bytes; @@ -46,43 +47,6 @@ use self::extension::{ExtensionType, Extension}; #[cfg(test)] mod tests; -pub struct SslString(&'static str); - -impl<'s> Drop for SslString { - fn drop(&mut self) { - unsafe { - CRYPTO_free!(self.0.as_ptr() as *mut c_void); - } - } -} - -impl Deref for SslString { - type Target = str; - - fn deref(&self) -> &str { - self.0 - } -} - -impl SslString { - unsafe fn new(buf: *const u8, len: c_int) -> SslString { - let slice = slice::from_raw_parts(buf, len as usize); - SslString(str::from_utf8_unchecked(slice)) - } -} - -impl fmt::Display for SslString { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(self.0, f) - } -} - -impl fmt::Debug for SslString { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(self.0, f) - } -} - #[derive(Copy, Clone)] #[repr(i32)] pub enum X509FileType { @@ -551,7 +515,7 @@ impl X509NameRef { self as *const _ as *mut _ } - pub fn text_by_nid(&self, nid: Nid) -> Option { + pub fn text_by_nid(&self, nid: Nid) -> Option { unsafe { let loc = ffi::X509_NAME_get_index_by_NID(self.as_ptr(), nid.as_raw(), -1); if loc == -1 { @@ -577,7 +541,7 @@ impl X509NameRef { assert!(!str_from_asn1.is_null()); - Some(SslString::new(str_from_asn1, len)) + Some(CryptoString::from_raw_parts(str_from_asn1, len as usize)) } } } -- cgit v1.2.3 From 1a288da86ce1ca94b5a0b3eac8750e5ffd03e8e7 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 28 Oct 2016 22:14:44 -0700 Subject: Make verification unconditionally exposed internally --- openssl/src/x509/mod.rs | 8 ++++---- openssl/src/x509/verify.rs | 51 ---------------------------------------------- 2 files changed, 4 insertions(+), 55 deletions(-) delete mode 100644 openssl/src/x509/verify.rs (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index b92462d4..cc6b73bb 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -37,12 +37,12 @@ use ffi::{ ASN1_STRING_get0_data as ASN1_STRING_data, }; -pub mod extension; - #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] -pub mod verify; +pub use verify; -use self::extension::{ExtensionType, Extension}; +use x509::extension::{ExtensionType, Extension}; + +pub mod extension; #[cfg(test)] mod tests; diff --git a/openssl/src/x509/verify.rs b/openssl/src/x509/verify.rs deleted file mode 100644 index 77095edc..00000000 --- a/openssl/src/x509/verify.rs +++ /dev/null @@ -1,51 +0,0 @@ -//! X509 certificate verification -//! -//! Requires the `v102` or `v110` features and OpenSSL 1.0.2 or 1.1.0. - -use libc::c_uint; -use ffi; - -use cvt; -use error::ErrorStack; -use opaque::Opaque; - -bitflags! { - pub flags X509CheckFlags: c_uint { - const X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT, - const X509_CHECK_FLAG_NO_WILDCARDS = ffi::X509_CHECK_FLAG_NO_WILDCARDS, - const X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS = ffi::X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS, - const X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS = ffi::X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS, - const X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS - = ffi::X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS, - /// Requires the `v110` feature and OpenSSL 1.1.0. - #[cfg(all(feature = "v110", ossl110))] - const X509_CHECK_FLAG_NEVER_CHECK_SUBJECT = ffi::X509_CHECK_FLAG_NEVER_CHECK_SUBJECT, - } -} - -pub struct X509VerifyParamRef(Opaque); - -impl X509VerifyParamRef { - pub unsafe fn from_ptr_mut<'a>(ptr: *mut ffi::X509_VERIFY_PARAM) -> &'a mut X509VerifyParamRef { - &mut *(ptr as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::X509_VERIFY_PARAM { - self as *const _ as *mut _ - } - - pub fn set_hostflags(&mut self, hostflags: X509CheckFlags) { - unsafe { - ffi::X509_VERIFY_PARAM_set_hostflags(self.as_ptr(), hostflags.bits); - } - } - - pub fn set_host(&mut self, host: &str) -> Result<(), ErrorStack> { - unsafe { - cvt(ffi::X509_VERIFY_PARAM_set1_host(self.as_ptr(), - host.as_ptr() as *const _, - host.len())) - .map(|_| ()) - } - } -} -- cgit v1.2.3 From 4c7a5a418ee6a71f26fb6cc720a36b5bca6f3376 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 29 Oct 2016 14:02:26 -0700 Subject: Implement client and server connectors --- openssl/src/x509/mod.rs | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index cc6b73bb..9fd6812a 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -1,4 +1,5 @@ use libc::{c_char, c_int, c_long, c_ulong, c_void}; +use std::borrow::Borrow; use std::cmp; use std::collections::HashMap; use std::error::Error; @@ -447,6 +448,17 @@ impl X509Ref { } } +impl ToOwned for X509Ref { + type Owned = X509; + + fn to_owned(&self) -> X509 { + unsafe { + compat::X509_up_ref(self.as_ptr()); + X509::from_ptr(self.as_ptr()) + } + } +} + /// An owned public key certificate. pub struct X509(*mut ffi::X509); @@ -491,10 +503,7 @@ impl Deref for X509 { impl Clone for X509 { fn clone(&self) -> X509 { - unsafe { - compat::X509_up_ref(self.as_ptr()); - X509::from_ptr(self.as_ptr()) - } + self.to_owned() } } @@ -504,6 +513,18 @@ impl Drop for X509 { } } +impl AsRef for X509 { + fn as_ref(&self) -> &X509Ref { + &*self + } +} + +impl Borrow for X509 { + fn borrow(&self) -> &X509Ref { + &*self + } +} + pub struct X509NameRef(Opaque); impl X509NameRef { -- cgit v1.2.3 From 85169e5a61645a411e67b4753b7455a0514271b2 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 29 Oct 2016 15:02:07 -0700 Subject: Fix reexport --- openssl/src/x509/mod.rs | 2 +- openssl/src/x509/verify.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 openssl/src/x509/verify.rs (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 9fd6812a..31ed11b4 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -39,7 +39,7 @@ use ffi::{ }; #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] -pub use verify; +pub mod verify; use x509::extension::{ExtensionType, Extension}; diff --git a/openssl/src/x509/verify.rs b/openssl/src/x509/verify.rs new file mode 100644 index 00000000..aa264ba9 --- /dev/null +++ b/openssl/src/x509/verify.rs @@ -0,0 +1 @@ +pub use ::verify::*; -- cgit v1.2.3 From c2b38d8bb3f141e531a3e636b8a86a073d78f316 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 29 Oct 2016 15:02:36 -0700 Subject: Move docs --- openssl/src/x509/verify.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/verify.rs b/openssl/src/x509/verify.rs index aa264ba9..8cb123e6 100644 --- a/openssl/src/x509/verify.rs +++ b/openssl/src/x509/verify.rs @@ -1 +1,5 @@ +//! X509 certificate verification +//! +//! Requires the `v102` or `v110` features and OpenSSL 1.0.2 or 1.1.0. + pub use ::verify::*; -- cgit v1.2.3 From c89f2c0be08bc77afc2f8a45e488ab8e394f0f3d Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 29 Oct 2016 16:37:26 -0700 Subject: Use PKeyRef in X509Generator --- openssl/src/x509/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 31ed11b4..b7cbe363 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -18,7 +18,7 @@ use asn1::Asn1TimeRef; use bio::{MemBio, MemBioSlice}; use crypto::CryptoString; use hash::MessageDigest; -use pkey::PKey; +use pkey::{PKey, PKeyRef}; use rand::rand_bytes; use error::ErrorStack; use ffi; @@ -278,7 +278,7 @@ impl X509Generator { } /// Sets the certificate public-key, then self-sign and return it - pub fn sign(&self, p_key: &PKey) -> Result { + pub fn sign(&self, p_key: &PKeyRef) -> Result { ffi::init(); unsafe { @@ -330,7 +330,7 @@ impl X509Generator { } /// Obtain a certificate signing request (CSR) - pub fn request(&self, p_key: &PKey) -> Result { + pub fn request(&self, p_key: &PKeyRef) -> Result { let cert = match self.sign(p_key) { Ok(c) => c, Err(x) => return Err(x), -- cgit v1.2.3 From f75f82e466993848393c7a26ccb51dc31b4547fe Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 30 Oct 2016 16:37:45 -0700 Subject: Rustfmt --- openssl/src/x509/mod.rs | 33 ++++++++++----------------------- openssl/src/x509/tests.rs | 7 +++---- 2 files changed, 13 insertions(+), 27 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index b7cbe363..b49a9848 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -26,17 +26,10 @@ use nid::Nid; use opaque::Opaque; #[cfg(ossl10x)] -use ffi::{ - X509_set_notBefore, - X509_set_notAfter, - ASN1_STRING_data, -}; +use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data}; #[cfg(ossl110)] -use ffi::{ - X509_set1_notBefore as X509_set_notBefore, - X509_set1_notAfter as X509_set_notAfter, - ASN1_STRING_get0_data as ASN1_STRING_data, -}; +use ffi::{X509_set1_notBefore as X509_set_notBefore, X509_set1_notAfter as X509_set_notAfter, + ASN1_STRING_get0_data as ASN1_STRING_data}; #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub mod verify; @@ -68,9 +61,7 @@ impl X509StoreContextRef { } pub fn error(&self) -> Option { - unsafe { - X509VerifyError::from_raw(ffi::X509_STORE_CTX_get_error(self.as_ptr()) as c_long) - } + unsafe { X509VerifyError::from_raw(ffi::X509_STORE_CTX_get_error(self.as_ptr()) as c_long) } } pub fn current_cert(&self) -> Option<&X509Ref> { @@ -386,9 +377,7 @@ impl X509Ref { return None; } - Some(GeneralNames { - stack: stack as *mut _, - }) + Some(GeneralNames { stack: stack as *mut _ }) } } @@ -495,9 +484,7 @@ impl Deref for X509 { type Target = X509Ref; fn deref(&self) -> &X509Ref { - unsafe { - X509Ref::from_ptr(self.0) - } + unsafe { X509Ref::from_ptr(self.0) } } } @@ -749,8 +736,8 @@ impl Drop for GeneralNames { fn drop(&mut self) { unsafe { // This transmute is dubious but it's what openssl itself does... - let free: unsafe extern fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free; - let free: unsafe extern fn(*mut c_void) = mem::transmute(free); + let free: unsafe extern "C" fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free; + let free: unsafe extern "C" fn(*mut c_void) = mem::transmute(free); ffi::sk_pop_free(&mut (*self.stack).stack, Some(free)); } } @@ -759,8 +746,8 @@ impl Drop for GeneralNames { fn drop(&mut self) { unsafe { // This transmute is dubious but it's what openssl itself does... - let free: unsafe extern fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free; - let free: unsafe extern fn(*mut c_void) = mem::transmute(free); + let free: unsafe extern "C" fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free; + let free: unsafe extern "C" fn(*mut c_void) = mem::transmute(free); ffi::OPENSSL_sk_pop_free(self.stack as *mut _, Some(free)); } } diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 185c4910..1c248ba2 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -60,10 +60,9 @@ 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())) - .sign(&pkey); + .add_extension(OtherNid(nid::AUTHORITY_KEY_IDENTIFIER, "keyid:always".to_owned())) + .add_extension(OtherNid(nid::SUBJECT_KEY_IDENTIFIER, "hash".to_owned())) + .sign(&pkey); assert!(result.is_err()); } -- cgit v1.2.3 From 849fca4a7b285368ea3fc6f484350d6fa59c29e8 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 19:49:37 -0700 Subject: Convert Asn1Time --- openssl/src/x509/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index b49a9848..8a4941ea 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -14,7 +14,6 @@ use std::str; use {cvt, cvt_p}; use asn1::Asn1Time; -use asn1::Asn1TimeRef; use bio::{MemBio, MemBioSlice}; use crypto::CryptoString; use hash::MessageDigest; @@ -24,6 +23,7 @@ use error::ErrorStack; use ffi; use nid::Nid; use opaque::Opaque; +use types::Ref; #[cfg(ossl10x)] use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data}; @@ -401,20 +401,20 @@ impl X509Ref { } /// Returns certificate Not After validity period. - pub fn not_after<'a>(&'a self) -> &'a Asn1TimeRef { + pub fn not_after<'a>(&'a self) -> &'a Ref { unsafe { let date = compat::X509_get_notAfter(self.as_ptr()); assert!(!date.is_null()); - Asn1TimeRef::from_ptr(date) + Ref::from_ptr(date) } } /// Returns certificate Not Before validity period. - pub fn not_before<'a>(&'a self) -> &'a Asn1TimeRef { + pub fn not_before<'a>(&'a self) -> &'a Ref { unsafe { let date = compat::X509_get_notBefore(self.as_ptr()); assert!(!date.is_null()); - Asn1TimeRef::from_ptr(date) + Ref::from_ptr(date) } } -- cgit v1.2.3 From f640613863f0b66bc004f9d9d89f73a31701d396 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 20:12:55 -0700 Subject: Update PKey --- openssl/src/x509/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 8a4941ea..d3f7fbc0 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -17,13 +17,13 @@ use asn1::Asn1Time; use bio::{MemBio, MemBioSlice}; use crypto::CryptoString; use hash::MessageDigest; -use pkey::{PKey, PKeyRef}; +use pkey::PKey; use rand::rand_bytes; use error::ErrorStack; use ffi; use nid::Nid; use opaque::Opaque; -use types::Ref; +use types::{OpenSslType, Ref}; #[cfg(ossl10x)] use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data}; @@ -269,7 +269,7 @@ impl X509Generator { } /// Sets the certificate public-key, then self-sign and return it - pub fn sign(&self, p_key: &PKeyRef) -> Result { + pub fn sign(&self, p_key: &Ref) -> Result { ffi::init(); unsafe { @@ -321,7 +321,7 @@ impl X509Generator { } /// Obtain a certificate signing request (CSR) - pub fn request(&self, p_key: &PKeyRef) -> Result { + pub fn request(&self, p_key: &Ref) -> Result { let cert = match self.sign(p_key) { Ok(c) => c, Err(x) => return Err(x), -- cgit v1.2.3 From cd7fa9fca29296adebe37dfc20d3cebc96010534 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 20:54:34 -0700 Subject: Update x509 --- openssl/src/x509/mod.rs | 123 ++++++++++++------------------------------------ 1 file changed, 30 insertions(+), 93 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index d3f7fbc0..bb2c7544 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -7,7 +7,6 @@ use std::ffi::{CStr, CString}; use std::fmt; use std::marker::PhantomData; use std::mem; -use std::ops::Deref; use std::ptr; use std::slice; use std::str; @@ -22,7 +21,6 @@ use rand::rand_bytes; use error::ErrorStack; use ffi; use nid::Nid; -use opaque::Opaque; use types::{OpenSslType, Ref}; #[cfg(ossl10x)] @@ -49,28 +47,20 @@ pub enum X509FileType { Default = ffi::X509_FILETYPE_DEFAULT, } -pub struct X509StoreContextRef(Opaque); - -impl X509StoreContextRef { - pub unsafe fn from_ptr<'a>(ctx: *mut ffi::X509_STORE_CTX) -> &'a X509StoreContextRef { - &*(ctx as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::X509_STORE_CTX { - self as *const _ as *mut _ - } +type_!(X509StoreContext, ffi::X509_STORE_CTX, ffi::X509_STORE_CTX_free); +impl Ref { pub fn error(&self) -> Option { unsafe { X509VerifyError::from_raw(ffi::X509_STORE_CTX_get_error(self.as_ptr()) as c_long) } } - pub fn current_cert(&self) -> Option<&X509Ref> { + pub fn current_cert(&self) -> Option<&Ref> { unsafe { let ptr = ffi::X509_STORE_CTX_get_current_cert(self.as_ptr()); if ptr.is_null() { None } else { - Some(X509Ref::from_ptr(ptr)) + Some(Ref::from_ptr(ptr)) } } } @@ -346,23 +336,13 @@ impl X509Generator { } } -/// A borrowed public key certificate. -pub struct X509Ref(Opaque); - -impl X509Ref { - /// Creates a new `X509Ref` wrapping the provided handle. - pub unsafe fn from_ptr<'a>(x509: *mut ffi::X509) -> &'a X509Ref { - &*(x509 as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::X509 { - self as *const _ as *mut _ - } +type_!(X509, ffi::X509, ffi::X509_free); - pub fn subject_name(&self) -> &X509NameRef { +impl Ref { + pub fn subject_name(&self) -> &Ref { unsafe { let name = ffi::X509_get_subject_name(self.as_ptr()); - X509NameRef::from_ptr(name) + Ref::from_ptr(name) } } @@ -437,7 +417,7 @@ impl X509Ref { } } -impl ToOwned for X509Ref { +impl ToOwned for Ref { type Owned = X509; fn to_owned(&self) -> X509 { @@ -448,15 +428,7 @@ impl ToOwned for X509Ref { } } -/// An owned public key certificate. -pub struct X509(*mut ffi::X509); - impl X509 { - /// Returns a new `X509`, taking ownership of the handle. - pub unsafe fn from_ptr(x509: *mut ffi::X509) -> X509 { - X509(x509) - } - /// Reads a certificate from DER. pub fn from_der(buf: &[u8]) -> Result { unsafe { @@ -480,49 +452,27 @@ impl X509 { } } -impl Deref for X509 { - type Target = X509Ref; - - fn deref(&self) -> &X509Ref { - unsafe { X509Ref::from_ptr(self.0) } - } -} - impl Clone for X509 { fn clone(&self) -> X509 { self.to_owned() } } -impl Drop for X509 { - fn drop(&mut self) { - unsafe { ffi::X509_free(self.as_ptr()) }; - } -} - -impl AsRef for X509 { - fn as_ref(&self) -> &X509Ref { +impl AsRef> for X509 { + fn as_ref(&self) -> &Ref { &*self } } -impl Borrow for X509 { - fn borrow(&self) -> &X509Ref { +impl Borrow> for X509 { + fn borrow(&self) -> &Ref { &*self } } -pub struct X509NameRef(Opaque); - -impl X509NameRef { - pub unsafe fn from_ptr<'a>(ptr: *mut ffi::X509_NAME) -> &'a X509NameRef { - &*(ptr as *mut _) - } - - pub fn as_ptr(&self) -> *mut ffi::X509_NAME { - self as *const _ as *mut _ - } +type_!(X509Name, ffi::X509_NAME, ffi::X509_NAME_free); +impl Ref { pub fn text_by_nid(&self, nid: Nid) -> Option { unsafe { let loc = ffi::X509_NAME_get_index_by_NID(self.as_ptr(), nid.as_raw(), -1); @@ -554,34 +504,13 @@ impl X509NameRef { } } -/// A certificate signing request -pub struct X509Req(*mut ffi::X509_REQ); - -impl X509Req { - pub unsafe fn from_ptr(handle: *mut ffi::X509_REQ) -> X509Req { - X509Req(handle) - } - - pub fn as_ptr(&self) -> *mut ffi::X509_REQ { - self.0 - } - - /// Reads CSR from PEM - pub fn from_pem(buf: &[u8]) -> Result { - let mem_bio = try!(MemBioSlice::new(buf)); - unsafe { - let handle = try!(cvt_p(ffi::PEM_read_bio_X509_REQ(mem_bio.as_ptr(), - ptr::null_mut(), - None, - ptr::null_mut()))); - Ok(X509Req::from_ptr(handle)) - } - } +type_!(X509Req, ffi::X509_REQ, ffi::X509_REQ_free); +impl Ref { /// Writes CSR as PEM pub fn to_pem(&self) -> Result, ErrorStack> { let mem_bio = try!(MemBio::new()); - if unsafe { ffi::PEM_write_bio_X509_REQ(mem_bio.as_ptr(), self.0) } != 1 { + if unsafe { ffi::PEM_write_bio_X509_REQ(mem_bio.as_ptr(), self.as_ptr()) } != 1 { return Err(ErrorStack::get()); } Ok(mem_bio.get_buf().to_owned()) @@ -591,15 +520,23 @@ impl X509Req { pub fn to_der(&self) -> Result, ErrorStack> { let mem_bio = try!(MemBio::new()); unsafe { - ffi::i2d_X509_REQ_bio(mem_bio.as_ptr(), self.0); + ffi::i2d_X509_REQ_bio(mem_bio.as_ptr(), self.as_ptr()); } Ok(mem_bio.get_buf().to_owned()) } } -impl Drop for X509Req { - fn drop(&mut self) { - unsafe { ffi::X509_REQ_free(self.0) }; +impl X509Req { + /// Reads CSR from PEM + pub fn from_pem(buf: &[u8]) -> Result { + let mem_bio = try!(MemBioSlice::new(buf)); + unsafe { + let handle = try!(cvt_p(ffi::PEM_read_bio_X509_REQ(mem_bio.as_ptr(), + ptr::null_mut(), + None, + ptr::null_mut()))); + Ok(X509Req::from_ptr(handle)) + } } } -- cgit v1.2.3 From dc4098bdd83e23703b2490741ee7461caea83375 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Mon, 31 Oct 2016 22:43:05 -0700 Subject: Clean up x509 name entries --- openssl/src/x509/mod.rs | 57 ++++++++++++++++++++++++++++++----------------- openssl/src/x509/tests.rs | 48 +++++++++++++-------------------------- 2 files changed, 52 insertions(+), 53 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index bb2c7544..28f2542f 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -12,9 +12,8 @@ use std::slice; use std::str; use {cvt, cvt_p}; -use asn1::Asn1Time; +use asn1::{Asn1String, Asn1Time}; use bio::{MemBio, MemBioSlice}; -use crypto::CryptoString; use hash::MessageDigest; use pkey::PKey; use rand::rand_bytes; @@ -473,33 +472,49 @@ impl Borrow> for X509 { type_!(X509Name, ffi::X509_NAME, ffi::X509_NAME_free); impl Ref { - pub fn text_by_nid(&self, nid: Nid) -> Option { - unsafe { - let loc = ffi::X509_NAME_get_index_by_NID(self.as_ptr(), nid.as_raw(), -1); - if loc == -1 { - return None; - } + pub fn entries_by_nid<'a>(&'a self, nid: Nid) -> X509NameEntries<'a> { + X509NameEntries { + name: self, + nid: nid, + loc: -1, + } + } +} - let ne = ffi::X509_NAME_get_entry(self.as_ptr(), loc); - if ne.is_null() { - return None; - } +pub struct X509NameEntries<'a> { + name: &'a Ref, + nid: Nid, + loc: c_int, +} - let asn1_str = ffi::X509_NAME_ENTRY_get_data(ne); - if asn1_str.is_null() { - return None; - } +impl<'a> Iterator for X509NameEntries<'a> { + type Item = &'a Ref; - let mut str_from_asn1: *mut u8 = ptr::null_mut(); - let len = ffi::ASN1_STRING_to_UTF8(&mut str_from_asn1, asn1_str); + fn next(&mut self) -> Option<&'a Ref> { + unsafe { + self.loc = ffi::X509_NAME_get_index_by_NID(self.name.as_ptr(), + self.nid.as_raw(), + self.loc); - if len < 0 { + if self.loc == -1 { return None; } - assert!(!str_from_asn1.is_null()); + let entry = ffi::X509_NAME_get_entry(self.name.as_ptr(), self.loc); + assert!(!entry.is_null()); - Some(CryptoString::from_raw_parts(str_from_asn1, len as usize)) + Some(Ref::from_ptr(entry)) + } + } +} + +type_!(X509NameEntry, ffi::X509_NAME_ENTRY, ffi::X509_NAME_ENTRY_free); + +impl Ref { + pub fn data(&self) -> &Ref { + unsafe { + let data = ffi::X509_NAME_ENTRY_get_data(self.as_ptr()); + Ref::from_ptr(data) } } } diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 1c248ba2..db93c3a8 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -113,58 +113,42 @@ fn test_save_der() { #[test] fn test_subject_read_cn() { let cert = include_bytes!("../../test/cert.pem"); - let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); + let cert = X509::from_pem(cert).unwrap(); let subject = cert.subject_name(); - let cn = match subject.text_by_nid(nid::COMMONNAME) { - Some(x) => x, - None => panic!("Failed to read CN from cert"), - }; - - assert_eq!(&cn as &str, "foobar.com") + let cn = subject.entries_by_nid(nid::COMMONNAME).next().unwrap(); + assert_eq!(cn.data().as_slice(), b"foobar.com") } #[test] fn test_nid_values() { let cert = include_bytes!("../../test/nid_test_cert.pem"); - let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); + let cert = X509::from_pem(cert).unwrap(); let subject = cert.subject_name(); - let cn = match subject.text_by_nid(nid::COMMONNAME) { - Some(x) => x, - None => panic!("Failed to read CN from cert"), - }; - assert_eq!(&cn as &str, "example.com"); - - let email = match subject.text_by_nid(nid::PKCS9_EMAILADDRESS) { - Some(x) => x, - None => panic!("Failed to read subject email address from cert"), - }; - assert_eq!(&email as &str, "test@example.com"); - - let friendly = match subject.text_by_nid(nid::FRIENDLYNAME) { - Some(x) => x, - None => panic!("Failed to read subject friendly name from cert"), - }; - assert_eq!(&friendly as &str, "Example"); + let cn = subject.entries_by_nid(nid::COMMONNAME).next().unwrap(); + assert_eq!(cn.data().as_slice(), b"example.com"); + + let email = subject.entries_by_nid(nid::PKCS9_EMAILADDRESS).next().unwrap(); + assert_eq!(email.data().as_slice(), b"test@example.com"); + + let friendly = subject.entries_by_nid(nid::FRIENDLYNAME).next().unwrap(); + assert_eq!(&*friendly.data().as_utf8().unwrap(), "Example"); } #[test] fn test_nid_uid_value() { let cert = include_bytes!("../../test/nid_uid_test_cert.pem"); - let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); + let cert = X509::from_pem(cert).unwrap(); let subject = cert.subject_name(); - let cn = match subject.text_by_nid(nid::USERID) { - Some(x) => x, - None => panic!("Failed to read UID from cert"), - }; - assert_eq!(&cn as &str, "this is the userId"); + let cn = subject.entries_by_nid(nid::USERID).next().unwrap(); + assert_eq!(cn.data().as_slice(), b"this is the userId"); } #[test] fn test_subject_alt_name() { let cert = include_bytes!("../../test/alt_name_cert.pem"); - let cert = X509::from_pem(cert).ok().expect("Failed to load PEM"); + let cert = X509::from_pem(cert).unwrap(); let subject_alt_names = cert.subject_alt_names().unwrap(); assert_eq!(3, subject_alt_names.len()); -- cgit v1.2.3 From 36bf0bb38750412e5c2700273a850f16398cc427 Mon Sep 17 00:00:00 2001 From: Lionel Flandrin Date: Mon, 31 Oct 2016 23:53:28 +0100 Subject: Replace GeneralNames by the new Stack API --- openssl/src/x509/mod.rs | 145 +++++----------------------------------------- openssl/src/x509/tests.rs | 6 +- 2 files changed, 19 insertions(+), 132 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 28f2542f..dcda5913 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -1,11 +1,10 @@ -use libc::{c_char, c_int, c_long, c_ulong, c_void}; +use libc::{c_char, c_int, c_long, c_ulong}; use std::borrow::Borrow; use std::cmp; 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::ptr; use std::slice; @@ -21,6 +20,7 @@ use error::ErrorStack; use ffi; use nid::Nid; use types::{OpenSslType, Ref}; +use stack::{Stack, Stackable}; #[cfg(ossl10x)] use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data}; @@ -346,7 +346,7 @@ impl Ref { } /// Returns this certificate's SAN entries, if they exist. - pub fn subject_alt_names(&self) -> Option { + pub fn subject_alt_names(&self) -> Option> { unsafe { let stack = ffi::X509_get_ext_d2i(self.as_ptr(), ffi::NID_subject_alt_name, @@ -356,7 +356,7 @@ impl Ref { return None; } - Some(GeneralNames { stack: stack as *mut _ }) + Some(Stack::from_ptr(stack as *mut _)) } } @@ -678,135 +678,18 @@ impl X509VerifyError { } } -/// A collection of OpenSSL `GENERAL_NAME`s. -pub struct GeneralNames { - stack: *mut ffi::stack_st_GENERAL_NAME, -} - -impl Drop for GeneralNames { - #[cfg(ossl10x)] - fn drop(&mut self) { - unsafe { - // This transmute is dubious but it's what openssl itself does... - let free: unsafe extern "C" fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free; - let free: unsafe extern "C" fn(*mut c_void) = mem::transmute(free); - ffi::sk_pop_free(&mut (*self.stack).stack, Some(free)); - } - } - - #[cfg(ossl110)] - fn drop(&mut self) { - unsafe { - // This transmute is dubious but it's what openssl itself does... - let free: unsafe extern "C" fn(*mut ffi::GENERAL_NAME) = ffi::GENERAL_NAME_free; - let free: unsafe extern "C" fn(*mut c_void) = mem::transmute(free); - ffi::OPENSSL_sk_pop_free(self.stack as *mut _, Some(free)); - } - } -} - -impl GeneralNames { - /// Returns the number of `GeneralName`s in this structure. - pub fn len(&self) -> usize { - self._len() - } - - #[cfg(ossl10x)] - fn _len(&self) -> usize { - unsafe { (*self.stack).stack.num as usize } - } - - #[cfg(ossl110)] - fn _len(&self) -> usize { - unsafe { ffi::OPENSSL_sk_num(self.stack as *const _) as usize } - } - - /// Returns the specified `GeneralName`. - /// - /// # Panics - /// - /// Panics if `idx` is not less than `len()`. - pub fn get<'a>(&'a self, idx: usize) -> GeneralName<'a> { - unsafe { - assert!(idx < self.len()); - GeneralName { - name: self._get(idx), - m: PhantomData, - } - } - } - - #[cfg(ossl10x)] - unsafe fn _get(&self, idx: usize) -> *const ffi::GENERAL_NAME { - *(*self.stack).stack.data.offset(idx as isize) as *const ffi::GENERAL_NAME - } - - #[cfg(ossl110)] - unsafe fn _get(&self, idx: usize) -> *const ffi::GENERAL_NAME { - ffi::OPENSSL_sk_value(self.stack as *const _, idx as c_int) as *mut _ - } - - /// Returns an iterator over the `GeneralName`s in this structure. - pub fn iter(&self) -> GeneralNamesIter { - GeneralNamesIter { - names: self, - idx: 0, - } - } -} - -impl<'a> IntoIterator for &'a GeneralNames { - type Item = GeneralName<'a>; - type IntoIter = GeneralNamesIter<'a>; - - fn into_iter(self) -> GeneralNamesIter<'a> { - self.iter() - } -} - -/// An iterator over OpenSSL `GENERAL_NAME`s. -pub struct GeneralNamesIter<'a> { - names: &'a GeneralNames, - idx: usize, -} - -impl<'a> Iterator for GeneralNamesIter<'a> { - type Item = GeneralName<'a>; - - fn next(&mut self) -> Option { - if self.idx < self.names.len() { - let name = self.names.get(self.idx); - self.idx += 1; - Some(name) - } else { - None - } - } +type_!(GeneralName, ffi::GENERAL_NAME, ffi::GENERAL_NAME_free); - fn size_hint(&self) -> (usize, Option) { - let size = self.names.len() - self.idx; - (size, Some(size)) - } -} - -impl<'a> ExactSizeIterator for GeneralNamesIter<'a> {} - -/// An OpenSSL `GENERAL_NAME`. -pub struct GeneralName<'a> { - name: *const ffi::GENERAL_NAME, - m: PhantomData<&'a ()>, -} - -impl<'a> GeneralName<'a> { +impl Ref { /// Returns the contents of this `GeneralName` if it is a `dNSName`. pub fn dnsname(&self) -> Option<&str> { unsafe { - if (*self.name).type_ != ffi::GEN_DNS { + if (*self.as_ptr()).type_ != ffi::GEN_DNS { return None; } - let ptr = ASN1_STRING_data((*self.name).d as *mut _); - let len = ffi::ASN1_STRING_length((*self.name).d as *mut _); + let ptr = ASN1_STRING_data((*self.as_ptr()).d as *mut _); + let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _); let slice = slice::from_raw_parts(ptr as *const u8, len as usize); // dNSNames are stated to be ASCII (specifically IA5). Hopefully @@ -819,18 +702,22 @@ impl<'a> GeneralName<'a> { /// Returns the contents of this `GeneralName` if it is an `iPAddress`. pub fn ipaddress(&self) -> Option<&[u8]> { unsafe { - if (*self.name).type_ != ffi::GEN_IPADD { + if (*self.as_ptr()).type_ != ffi::GEN_IPADD { return None; } - let ptr = ASN1_STRING_data((*self.name).d as *mut _); - let len = ffi::ASN1_STRING_length((*self.name).d as *mut _); + let ptr = ASN1_STRING_data((*self.as_ptr()).d as *mut _); + let len = ffi::ASN1_STRING_length((*self.as_ptr()).d as *mut _); Some(slice::from_raw_parts(ptr as *const u8, len as usize)) } } } +impl Stackable for GeneralName { + type StackType = ffi::stack_st_GENERAL_NAME; +} + #[test] fn test_negative_serial() { // I guess that's enough to get a random negative number diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index db93c3a8..2527d538 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -152,10 +152,10 @@ fn test_subject_alt_name() { let subject_alt_names = cert.subject_alt_names().unwrap(); assert_eq!(3, subject_alt_names.len()); - assert_eq!(Some("foobar.com"), subject_alt_names.get(0).dnsname()); - assert_eq!(subject_alt_names.get(1).ipaddress(), + assert_eq!(Some("foobar.com"), subject_alt_names[0].dnsname()); + assert_eq!(subject_alt_names[1].ipaddress(), Some(&[127, 0, 0, 1][..])); - assert_eq!(subject_alt_names.get(2).ipaddress(), + assert_eq!(subject_alt_names[2].ipaddress(), Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])); } -- cgit v1.2.3 From 8d0090faecea5dbcbf87a0446beb2e60828378bc Mon Sep 17 00:00:00 2001 From: Lionel Flandrin Date: Mon, 31 Oct 2016 23:55:00 +0100 Subject: Implement X509StoreContextRef::get_chain --- openssl/src/x509/mod.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index dcda5913..e27b03d1 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -67,6 +67,28 @@ impl Ref { pub fn error_depth(&self) -> u32 { unsafe { ffi::X509_STORE_CTX_get_error_depth(self.as_ptr()) as u32 } } + + pub fn get_chain(&self) -> Option<&Ref>> { + unsafe { + let chain = self._get_chain(); + + if chain.is_null() { + return None; + } + + Some(Ref::from_ptr(chain)) + } + } + + #[cfg(ossl110)] + unsafe fn _get_chain(&self) -> *mut ffi::stack_st_X509 { + ffi::X509_STORE_CTX_get0_chain(self.as_ptr()) + } + + #[cfg(ossl10x)] + unsafe fn _get_chain(&self) -> *mut ffi::stack_st_X509 { + ffi::X509_STORE_CTX_get_chain(self.as_ptr()) + } } #[allow(non_snake_case)] @@ -468,6 +490,10 @@ impl Borrow> for X509 { &*self } } + +impl Stackable for X509 { + type StackType = ffi::stack_st_X509; +} type_!(X509Name, ffi::X509_NAME, ffi::X509_NAME_free); -- cgit v1.2.3 From e67733cc4e16d4d060dd022765a577cbe7fa2dfe Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 1 Nov 2016 19:45:38 -0700 Subject: Cleanup X509StoreContext::chain --- openssl/src/x509/mod.rs | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index e27b03d1..67760b86 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -23,10 +23,11 @@ use types::{OpenSslType, Ref}; use stack::{Stack, Stackable}; #[cfg(ossl10x)] -use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data}; +use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data, X509_STORE_CTX_get_chain}; #[cfg(ossl110)] use ffi::{X509_set1_notBefore as X509_set_notBefore, X509_set1_notAfter as X509_set_notAfter, - ASN1_STRING_get0_data as ASN1_STRING_data}; + ASN1_STRING_get0_data as ASN1_STRING_data, + X509_STORE_CTX_get0_chain as X509_STORE_CTX_get_chain}; #[cfg(any(all(feature = "v102", ossl102), all(feature = "v110", ossl110)))] pub mod verify; @@ -68,9 +69,9 @@ impl Ref { unsafe { ffi::X509_STORE_CTX_get_error_depth(self.as_ptr()) as u32 } } - pub fn get_chain(&self) -> Option<&Ref>> { + pub fn chain(&self) -> Option<&Ref>> { unsafe { - let chain = self._get_chain(); + let chain = X509_STORE_CTX_get_chain(self.as_ptr()); if chain.is_null() { return None; @@ -79,16 +80,6 @@ impl Ref { Some(Ref::from_ptr(chain)) } } - - #[cfg(ossl110)] - unsafe fn _get_chain(&self) -> *mut ffi::stack_st_X509 { - ffi::X509_STORE_CTX_get0_chain(self.as_ptr()) - } - - #[cfg(ossl10x)] - unsafe fn _get_chain(&self) -> *mut ffi::stack_st_X509 { - ffi::X509_STORE_CTX_get_chain(self.as_ptr()) - } } #[allow(non_snake_case)] @@ -490,7 +481,7 @@ impl Borrow> for X509 { &*self } } - + impl Stackable for X509 { type StackType = ffi::stack_st_X509; } -- cgit v1.2.3 From 62a9f89fceca595c1868320974eb74c6a8f33307 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 3 Nov 2016 20:38:51 -0700 Subject: Avoid lhash weirdness --- openssl/src/x509/mod.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 67760b86..02bdcb01 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -213,17 +213,17 @@ impl X509Generator { let value = CString::new(value.as_bytes()).unwrap(); let ext = match exttype.get_nid() { Some(nid) => { - try!(cvt_p(ffi::X509V3_EXT_conf_nid(ptr::null_mut(), - mem::transmute(&ctx), - nid.as_raw(), - value.as_ptr() as *mut c_char))) + try!(cvt_p(ffi::X509V3_EXT_nconf_nid(ptr::null_mut(), + &mut ctx, + nid.as_raw(), + value.as_ptr() as *mut c_char))) } None => { let name = CString::new(exttype.get_name().unwrap().as_bytes()).unwrap(); - try!(cvt_p(ffi::X509V3_EXT_conf(ptr::null_mut(), - mem::transmute(&ctx), - name.as_ptr() as *mut c_char, - value.as_ptr() as *mut c_char))) + try!(cvt_p(ffi::X509V3_EXT_nconf(ptr::null_mut(), + &mut ctx, + name.as_ptr() as *mut c_char, + value.as_ptr() as *mut c_char))) } }; if ffi::X509_add_ext(x509, ext, -1) != 1 { -- cgit v1.2.3 From 6fe7dd3024e5c62fa12c2c3abd30af5c0235bba6 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 3 Nov 2016 21:15:47 -0700 Subject: Remove an enum --- openssl/src/x509/mod.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 02bdcb01..bffb193c 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -39,14 +39,18 @@ pub mod extension; #[cfg(test)] mod tests; -#[derive(Copy, Clone)] -#[repr(i32)] -pub enum X509FileType { - PEM = ffi::X509_FILETYPE_PEM, - ASN1 = ffi::X509_FILETYPE_ASN1, - Default = ffi::X509_FILETYPE_DEFAULT, +pub struct X509FileType(c_int); + +impl X509FileType { + pub fn as_raw(&self) -> c_int { + self.0 + } } +pub const X509_FILETYPE_PEM: X509FileType = X509FileType(ffi::X509_FILETYPE_PEM); +pub const X509_FILETYPE_ASN1: X509FileType = X509FileType(ffi::X509_FILETYPE_ASN1); +pub const X509_FILETYPE_DEFAULT: X509FileType = X509FileType(ffi::X509_FILETYPE_DEFAULT); + type_!(X509StoreContext, ffi::X509_STORE_CTX, ffi::X509_STORE_CTX_free); impl Ref { -- cgit v1.2.3 From 01ae978db0dc8620b2cc754c0d5cf94a68c1f549 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Fri, 4 Nov 2016 16:32:20 -0700 Subject: Get rid of Ref There's unfortunately a rustdoc bug that causes all methods implemented for any Ref to be inlined in the deref methods section :( --- openssl/src/x509/mod.rs | 78 ++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index bffb193c..c3ba9eae 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -11,16 +11,16 @@ use std::slice; use std::str; use {cvt, cvt_p}; -use asn1::{Asn1String, Asn1Time}; +use asn1::{Asn1StringRef, Asn1Time, Asn1TimeRef}; use bio::{MemBio, MemBioSlice}; use hash::MessageDigest; -use pkey::PKey; +use pkey::{PKey, PKeyRef}; use rand::rand_bytes; use error::ErrorStack; use ffi; use nid::Nid; -use types::{OpenSslType, Ref}; -use stack::{Stack, Stackable}; +use types::{OpenSslType, OpenSslTypeRef}; +use stack::{Stack, StackRef, Stackable}; #[cfg(ossl10x)] use ffi::{X509_set_notBefore, X509_set_notAfter, ASN1_STRING_data, X509_STORE_CTX_get_chain}; @@ -51,20 +51,20 @@ pub const X509_FILETYPE_PEM: X509FileType = X509FileType(ffi::X509_FILETYPE_PEM) pub const X509_FILETYPE_ASN1: X509FileType = X509FileType(ffi::X509_FILETYPE_ASN1); pub const X509_FILETYPE_DEFAULT: X509FileType = X509FileType(ffi::X509_FILETYPE_DEFAULT); -type_!(X509StoreContext, ffi::X509_STORE_CTX, ffi::X509_STORE_CTX_free); +type_!(X509StoreContext, X509StoreContextRef, ffi::X509_STORE_CTX, ffi::X509_STORE_CTX_free); -impl Ref { +impl X509StoreContextRef { pub fn error(&self) -> Option { unsafe { X509VerifyError::from_raw(ffi::X509_STORE_CTX_get_error(self.as_ptr()) as c_long) } } - pub fn current_cert(&self) -> Option<&Ref> { + pub fn current_cert(&self) -> Option<&X509Ref> { unsafe { let ptr = ffi::X509_STORE_CTX_get_current_cert(self.as_ptr()); if ptr.is_null() { None } else { - Some(Ref::from_ptr(ptr)) + Some(X509Ref::from_ptr(ptr)) } } } @@ -73,7 +73,7 @@ impl Ref { unsafe { ffi::X509_STORE_CTX_get_error_depth(self.as_ptr()) as u32 } } - pub fn chain(&self) -> Option<&Ref>> { + pub fn chain(&self) -> Option<&StackRef> { unsafe { let chain = X509_STORE_CTX_get_chain(self.as_ptr()); @@ -81,7 +81,7 @@ impl Ref { return None; } - Some(Ref::from_ptr(chain)) + Some(StackRef::from_ptr(chain)) } } } @@ -275,7 +275,7 @@ impl X509Generator { } /// Sets the certificate public-key, then self-sign and return it - pub fn sign(&self, p_key: &Ref) -> Result { + pub fn sign(&self, p_key: &PKeyRef) -> Result { ffi::init(); unsafe { @@ -327,7 +327,7 @@ impl X509Generator { } /// Obtain a certificate signing request (CSR) - pub fn request(&self, p_key: &Ref) -> Result { + pub fn request(&self, p_key: &PKeyRef) -> Result { let cert = match self.sign(p_key) { Ok(c) => c, Err(x) => return Err(x), @@ -352,13 +352,13 @@ impl X509Generator { } } -type_!(X509, ffi::X509, ffi::X509_free); +type_!(X509, X509Ref, ffi::X509, ffi::X509_free); -impl Ref { - pub fn subject_name(&self) -> &Ref { +impl X509Ref { + pub fn subject_name(&self) -> &X509NameRef { unsafe { let name = ffi::X509_get_subject_name(self.as_ptr()); - Ref::from_ptr(name) + X509NameRef::from_ptr(name) } } @@ -397,20 +397,20 @@ impl Ref { } /// Returns certificate Not After validity period. - pub fn not_after<'a>(&'a self) -> &'a Ref { + pub fn not_after<'a>(&'a self) -> &'a Asn1TimeRef { unsafe { let date = compat::X509_get_notAfter(self.as_ptr()); assert!(!date.is_null()); - Ref::from_ptr(date) + Asn1TimeRef::from_ptr(date) } } /// Returns certificate Not Before validity period. - pub fn not_before<'a>(&'a self) -> &'a Ref { + pub fn not_before<'a>(&'a self) -> &'a Asn1TimeRef { unsafe { let date = compat::X509_get_notBefore(self.as_ptr()); assert!(!date.is_null()); - Ref::from_ptr(date) + Asn1TimeRef::from_ptr(date) } } @@ -433,7 +433,7 @@ impl Ref { } } -impl ToOwned for Ref { +impl ToOwned for X509Ref { type Owned = X509; fn to_owned(&self) -> X509 { @@ -474,14 +474,14 @@ impl Clone for X509 { } } -impl AsRef> for X509 { - fn as_ref(&self) -> &Ref { +impl AsRef for X509 { + fn as_ref(&self) -> &X509Ref { &*self } } -impl Borrow> for X509 { - fn borrow(&self) -> &Ref { +impl Borrow for X509 { + fn borrow(&self) -> &X509Ref { &*self } } @@ -490,9 +490,9 @@ impl Stackable for X509 { type StackType = ffi::stack_st_X509; } -type_!(X509Name, ffi::X509_NAME, ffi::X509_NAME_free); +type_!(X509Name, X509NameRef, ffi::X509_NAME, ffi::X509_NAME_free); -impl Ref { +impl X509NameRef { pub fn entries_by_nid<'a>(&'a self, nid: Nid) -> X509NameEntries<'a> { X509NameEntries { name: self, @@ -503,15 +503,15 @@ impl Ref { } pub struct X509NameEntries<'a> { - name: &'a Ref, + name: &'a X509NameRef, nid: Nid, loc: c_int, } impl<'a> Iterator for X509NameEntries<'a> { - type Item = &'a Ref; + type Item = &'a X509NameEntryRef; - fn next(&mut self) -> Option<&'a Ref> { + fn next(&mut self) -> Option<&'a X509NameEntryRef> { unsafe { self.loc = ffi::X509_NAME_get_index_by_NID(self.name.as_ptr(), self.nid.as_raw(), @@ -524,25 +524,25 @@ impl<'a> Iterator for X509NameEntries<'a> { let entry = ffi::X509_NAME_get_entry(self.name.as_ptr(), self.loc); assert!(!entry.is_null()); - Some(Ref::from_ptr(entry)) + Some(X509NameEntryRef::from_ptr(entry)) } } } -type_!(X509NameEntry, ffi::X509_NAME_ENTRY, ffi::X509_NAME_ENTRY_free); +type_!(X509NameEntry, X509NameEntryRef, ffi::X509_NAME_ENTRY, ffi::X509_NAME_ENTRY_free); -impl Ref { - pub fn data(&self) -> &Ref { +impl X509NameEntryRef { + pub fn data(&self) -> &Asn1StringRef { unsafe { let data = ffi::X509_NAME_ENTRY_get_data(self.as_ptr()); - Ref::from_ptr(data) + Asn1StringRef::from_ptr(data) } } } -type_!(X509Req, ffi::X509_REQ, ffi::X509_REQ_free); +type_!(X509Req, X509ReqRef, ffi::X509_REQ, ffi::X509_REQ_free); -impl Ref { +impl X509ReqRef { /// Writes CSR as PEM pub fn to_pem(&self) -> Result, ErrorStack> { let mem_bio = try!(MemBio::new()); @@ -699,9 +699,9 @@ impl X509VerifyError { } } -type_!(GeneralName, ffi::GENERAL_NAME, ffi::GENERAL_NAME_free); +type_!(GeneralName, GeneralNameRef, ffi::GENERAL_NAME, ffi::GENERAL_NAME_free); -impl Ref { +impl GeneralNameRef { /// Returns the contents of this `GeneralName` if it is a `dNSName`. pub fn dnsname(&self) -> Option<&str> { unsafe { -- cgit v1.2.3 From f15c817c2d1fad288fe0f88d4e3995df4aa4a477 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 5 Nov 2016 10:54:17 -0700 Subject: Rustfmt --- openssl/src/x509/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index c3ba9eae..ec17cbe2 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -513,9 +513,8 @@ impl<'a> Iterator for X509NameEntries<'a> { fn next(&mut self) -> Option<&'a X509NameEntryRef> { unsafe { - self.loc = ffi::X509_NAME_get_index_by_NID(self.name.as_ptr(), - self.nid.as_raw(), - self.loc); + self.loc = + ffi::X509_NAME_get_index_by_NID(self.name.as_ptr(), self.nid.as_raw(), self.loc); if self.loc == -1 { return None; -- cgit v1.2.3 From 803725891331daf1839ea88e3035ae151e59cc2e Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sat, 5 Nov 2016 13:57:05 -0700 Subject: Return a Stack in Pkcs12 --- openssl/src/x509/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'openssl/src/x509') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index ec17cbe2..eb517f80 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -480,6 +480,12 @@ impl AsRef for X509 { } } +impl AsRef for X509Ref { + fn as_ref(&self) -> &X509Ref { + self + } +} + impl Borrow for X509 { fn borrow(&self) -> &X509Ref { &*self -- cgit v1.2.3