diff options
| author | Steven Fackler <[email protected]> | 2016-07-31 15:15:47 -0700 |
|---|---|---|
| committer | Steven Fackler <[email protected]> | 2016-07-31 15:15:47 -0700 |
| commit | f0ffa246b83102d70bc59f76d136981efdafb1e7 (patch) | |
| tree | 0f6036a20ba4eb7b333986206962abeb4bab6c2f /openssl/src/x509 | |
| parent | Revert "Add a new trait based Nid setup" (diff) | |
| parent | Merge pull request #402 from bbatha/feat/dsa-ffi (diff) | |
| download | rust-openssl-f0ffa246b83102d70bc59f76d136981efdafb1e7.tar.xz rust-openssl-f0ffa246b83102d70bc59f76d136981efdafb1e7.zip | |
Merge remote-tracking branch 'origin/master' into breaks
Diffstat (limited to 'openssl/src/x509')
| -rw-r--r-- | openssl/src/x509/mod.rs | 46 | ||||
| -rw-r--r-- | openssl/src/x509/tests.rs | 43 |
2 files changed, 64 insertions, 25 deletions
diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index a928b533..05d8221e 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -379,7 +379,9 @@ impl X509Generator { ffi::X509_set_issuer_name(x509.handle, name); for (exttype, ext) in self.extensions.iter() { - try!(X509Generator::add_extension_internal(x509.handle, &exttype, &ext.to_string())); + try!(X509Generator::add_extension_internal(x509.handle, + &exttype, + &ext.to_string())); } let hash_fn = self.hash_type.evp_md(); @@ -530,6 +532,17 @@ impl<'ctx> X509<'ctx> { } io::copy(&mut mem_bio, writer).map(|_| ()) } + + /// Returns a DER serialized form of the certificate + pub fn save_der(&self) -> Result<Vec<u8>, ErrorStack> { + let mut mem_bio = try!(MemBio::new()); + unsafe { + ffi::i2d_X509_bio(mem_bio.get_handle(), self.handle); + } + let mut v = Vec::new(); + drop(io::copy(&mut mem_bio, &mut v)); + Ok(v) + } } extern "C" { @@ -539,9 +552,9 @@ extern "C" { impl<'ctx> Clone for X509<'ctx> { fn clone(&self) -> X509<'ctx> { unsafe { rust_X509_clone(self.handle) } - /* FIXME: given that we now have refcounting control, 'owned' should be uneeded, the 'ctx - * is probably also uneeded. We can remove both to condense the x509 api quite a bit - */ + // FIXME: given that we now have refcounting control, 'owned' should be uneeded, the 'ctx + // is probably also uneeded. We can remove both to condense the x509 api quite a bit + // X509::new(self.handle, true) } } @@ -609,6 +622,10 @@ impl X509Req { X509Req { handle: handle } } + pub fn get_handle(&self) -> *mut ffi::X509_REQ { + self.handle + } + /// Reads CSR from PEM pub fn from_pem<R>(reader: &mut R) -> io::Result<X509Req> where R: Read @@ -635,6 +652,17 @@ impl X509Req { } io::copy(&mut mem_bio, writer).map(|_| ()) } + + /// Returns a DER serialized form of the CSR + pub fn save_der(&self) -> Result<Vec<u8>, ErrorStack> { + let mut mem_bio = try!(MemBio::new()); + unsafe { + ffi::i2d_X509_REQ_bio(mem_bio.get_handle(), self.handle); + } + let mut v = Vec::new(); + drop(io::copy(&mut mem_bio, &mut v)); + Ok(v) + } } impl Drop for X509Req { @@ -671,7 +699,7 @@ impl Extensions { pub fn add(&mut self, ext: Extension) { let ext_type = ext.get_type(); - if let Some(index) = self.indexes.get(&ext_type) { + if let Some(index) = self.indexes.get(&ext_type) { self.extensions[*index] = ext; return; } @@ -693,7 +721,7 @@ impl Extensions { /// extension in the collection. struct ExtensionsIter<'a> { current: usize, - extensions: &'a Vec<Extension> + extensions: &'a Vec<Extension>, } impl<'a> Iterator for ExtensionsIter<'a> { @@ -798,9 +826,7 @@ pub struct GeneralNames<'a> { impl<'a> GeneralNames<'a> { /// Returns the number of `GeneralName`s in this structure. pub fn len(&self) -> usize { - unsafe { - (*self.stack).stack.num as usize - } + unsafe { (*self.stack).stack.num as usize } } /// Returns the specified `GeneralName`. @@ -823,7 +849,7 @@ impl<'a> GeneralNames<'a> { pub fn iter(&self) -> GeneralNamesIter { GeneralNamesIter { names: self, - idx: 0 + idx: 0, } } } diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 0032d108..5d9b30ab 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -3,7 +3,7 @@ use std::io; use std::path::Path; use std::fs::File; -use crypto::hash::Type::SHA256; +use crypto::hash::Type::SHA1; use crypto::pkey::PKey; use x509::{X509, X509Generator}; use x509::extension::Extension::{KeyUsage, ExtKeyUsage, SubjectAltName, OtherNid, OtherStr}; @@ -17,7 +17,7 @@ fn get_generator() -> X509Generator { .set_bitlength(2048) .set_valid_period(365 * 2) .add_name("CN".to_string(), "test_me".to_string()) - .set_sign_hash(SHA256) + .set_sign_hash(SHA1) .add_extension(KeyUsage(vec![DigitalSignature, KeyEncipherment])) .add_extension(ExtKeyUsage(vec![ClientAuth, ServerAuth, @@ -56,9 +56,10 @@ fn test_cert_gen_extension_ordering() { #[test] fn test_cert_gen_extension_bad_ordering() { let result = get_generator() - .add_extension(OtherNid(Nid::AuthorityKeyIdentifier, "keyid:always".to_owned())) - .add_extension(OtherNid(Nid::SubjectKeyIdentifier, "hash".to_owned())) - .generate(); + .add_extension(OtherNid(Nid::AuthorityKeyIdentifier, + "keyid:always".to_owned())) + .add_extension(OtherNid(Nid::SubjectKeyIdentifier, "hash".to_owned())) + .generate(); assert!(result.is_err()); } @@ -83,19 +84,28 @@ fn test_cert_loading() { .expect("Failed to open `test/cert.pem`"); let cert = X509::from_pem(&mut file).ok().expect("Failed to load PEM"); - let fingerprint = cert.fingerprint(SHA256).unwrap(); + let fingerprint = cert.fingerprint(SHA1).unwrap(); - // Hash was generated as SHA256 hash of certificate "test/cert.pem" - // in DER format. - // Command: openssl x509 -in test/cert.pem -outform DER | openssl dgst -sha256 - // Please update if "test/cert.pem" will ever change - let hash_str = "db400bb62f1b1f29c3b8f323b8f7d9dea724fdcd67104ef549c772ae3749655b"; + let hash_str = "E19427DAC79FBE758394945276A6E4F15F0BEBE6"; let hash_vec = hash_str.from_hex().unwrap(); assert_eq!(fingerprint, hash_vec); } #[test] +fn test_save_der() { + let cert_path = Path::new("test/cert.pem"); + let mut file = File::open(&cert_path) + .ok() + .expect("Failed to open `test/cert.pem`"); + + let cert = X509::from_pem(&mut file).ok().expect("Failed to load PEM"); + + let der = cert.save_der().unwrap(); + assert!(!der.is_empty()); +} + +#[test] fn test_subject_read_cn() { let cert_path = Path::new("test/cert.pem"); let mut file = File::open(&cert_path) @@ -109,7 +119,7 @@ fn test_subject_read_cn() { None => panic!("Failed to read CN from cert"), }; - assert_eq!(&cn as &str, "test_cert") + assert_eq!(&cn as &str, "foobar.com") } #[test] @@ -166,7 +176,8 @@ 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(), Some(&[127, 0, 0, 1][..])); + assert_eq!(subject_alt_names.get(1).ipaddress(), + Some(&[127, 0, 0, 1][..])); assert_eq!(subject_alt_names.get(2).ipaddress(), Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])); } @@ -178,8 +189,10 @@ fn test_subject_alt_name_iter() { let subject_alt_names = cert.subject_alt_names().unwrap(); let mut subject_alt_names_iter = subject_alt_names.iter(); - assert_eq!(subject_alt_names_iter.next().unwrap().dnsname(), Some("foobar.com")); - assert_eq!(subject_alt_names_iter.next().unwrap().ipaddress(), Some(&[127, 0, 0, 1][..])); + assert_eq!(subject_alt_names_iter.next().unwrap().dnsname(), + Some("foobar.com")); + assert_eq!(subject_alt_names_iter.next().unwrap().ipaddress(), + Some(&[127, 0, 0, 1][..])); assert_eq!(subject_alt_names_iter.next().unwrap().ipaddress(), Some(&b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01"[..])); assert!(subject_alt_names_iter.next().is_none()); |