From 2afdc16fc96e4a45baadab8bfa91dc91104f00f0 Mon Sep 17 00:00:00 2001 From: Marco Huenseler Date: Mon, 28 May 2018 11:18:17 +0200 Subject: Make X509NameRef provide an iterator over all X509NameEntries --- openssl/src/x509/mod.rs | 30 +++++++++++++++++++++++++----- openssl/src/x509/tests.rs | 21 +++++++++++++++++++++ 2 files changed, 46 insertions(+), 5 deletions(-) (limited to 'openssl/src') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 5c1bb23f..b0519856 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -820,16 +820,25 @@ impl X509NameRef { pub fn entries_by_nid<'a>(&'a self, nid: Nid) -> X509NameEntries<'a> { X509NameEntries { name: self, - nid: nid, + nid: Some(nid), loc: -1, } } + + /// Returns an iterator over all `X509NameEntry` values + pub fn all_entries<'a>(&'a self) -> X509NameEntries<'a> { + X509NameEntries { + name: self, + nid: None, + loc: -1 + } + } } /// A type to destructure and examine an `X509Name`. pub struct X509NameEntries<'a> { name: &'a X509NameRef, - nid: Nid, + nid: Option, loc: c_int, } @@ -838,10 +847,21 @@ 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); + let entry_count = ffi::X509_NAME_entry_count(self.name.as_ptr()); + + match self.nid { + Some(nid) => { + // There is a `Nid` specified to search for + self.loc = + ffi::X509_NAME_get_index_by_NID(self.name.as_ptr(), nid.as_raw(), self.loc); + } + None => { + // Iterate over all `Nid`s + self.loc += 1; + } + } - if self.loc == -1 { + if self.loc == -1 || self.loc >= entry_count { return None; } diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 42859c97..3e2ead9d 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -79,6 +79,27 @@ fn test_nid_values() { assert_eq!(&**friendly.data().as_utf8().unwrap(), "Example"); } +#[test] +fn test_nameref_iterator() { + let cert = include_bytes!("../../test/nid_test_cert.pem"); + let cert = X509::from_pem(cert).unwrap(); + let subject = cert.subject_name(); + let mut all_entries = subject.all_entries(); + + let email = all_entries.next().unwrap(); + assert_eq!(email.data().as_slice(), b"test@example.com"); + + let cn = all_entries.next().unwrap(); + assert_eq!(cn.data().as_slice(), b"example.com"); + + let friendly = all_entries.next().unwrap(); + assert_eq!(&**friendly.data().as_utf8().unwrap(), "Example"); + + if let Some(_) = all_entries.next() { + assert!(false); + } +} + #[test] fn test_nid_uid_value() { let cert = include_bytes!("../../test/nid_uid_test_cert.pem"); -- cgit v1.2.3 From f5e6d57c4774c3f58fd03fa2520d8ec915ca1827 Mon Sep 17 00:00:00 2001 From: Marco Huenseler Date: Mon, 28 May 2018 11:20:18 +0200 Subject: Provide an Asn1Object getter method for X509NameEntryRef --- openssl/src/x509/mod.rs | 13 +++++++++++++ openssl/src/x509/tests.rs | 3 +++ 2 files changed, 16 insertions(+) (limited to 'openssl/src') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index b0519856..697aba6f 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -895,6 +895,19 @@ impl X509NameEntryRef { Asn1StringRef::from_ptr(data) } } + + /// Returns the `Asn1Object` value of an `X509NameEntry`. + /// This is useful for finding out about the actual `Nid` when iterating over all `X509NameEntries`. + /// + /// This corresponds to [`X509_NAME_ENTRY_get_object`]. + /// + /// [`X509_NAME_ENTRY_get_object`]: https://www.openssl.org/docs/man1.1.0/crypto/X509_NAME_ENTRY_get_object.html + pub fn object(&self) -> &Asn1ObjectRef { + unsafe { + let object = ffi::X509_NAME_ENTRY_get_object(self.as_ptr()); + Asn1ObjectRef::from_ptr(object) + } + } } /// A builder used to construct an `X509Req`. diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index 3e2ead9d..bfc50899 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -87,12 +87,15 @@ fn test_nameref_iterator() { let mut all_entries = subject.all_entries(); let email = all_entries.next().unwrap(); + assert_eq!(email.object().nid().as_raw(), Nid::PKCS9_EMAILADDRESS.as_raw()); assert_eq!(email.data().as_slice(), b"test@example.com"); let cn = all_entries.next().unwrap(); + assert_eq!(cn.object().nid().as_raw(), Nid::COMMONNAME.as_raw()); assert_eq!(cn.data().as_slice(), b"example.com"); let friendly = all_entries.next().unwrap(); + assert_eq!(friendly.object().nid().as_raw(), Nid::FRIENDLYNAME.as_raw()); assert_eq!(&**friendly.data().as_utf8().unwrap(), "Example"); if let Some(_) = all_entries.next() { -- cgit v1.2.3 From 14b543934720132fd7c60b8bc842150cf3f17aaf Mon Sep 17 00:00:00 2001 From: Marco Huenseler Date: Sun, 3 Jun 2018 15:37:18 +0200 Subject: Rename X509NameRef::all_entries and refactor end-of-iterator checks --- openssl/src/x509/mod.rs | 12 +++++++----- openssl/src/x509/tests.rs | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'openssl/src') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 697aba6f..0b6c6b3d 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -826,7 +826,7 @@ impl X509NameRef { } /// Returns an iterator over all `X509NameEntry` values - pub fn all_entries<'a>(&'a self) -> X509NameEntries<'a> { + pub fn entries<'a>(&'a self) -> X509NameEntries<'a> { X509NameEntries { name: self, nid: None, @@ -854,17 +854,19 @@ impl<'a> Iterator for X509NameEntries<'a> { // There is a `Nid` specified to search for self.loc = ffi::X509_NAME_get_index_by_NID(self.name.as_ptr(), nid.as_raw(), self.loc); + if self.loc == -1 { + return None; + } } None => { // Iterate over all `Nid`s self.loc += 1; + if self.loc >= entry_count { + return None; + } } } - if self.loc == -1 || self.loc >= entry_count { - return None; - } - let entry = ffi::X509_NAME_get_entry(self.name.as_ptr(), self.loc); assert!(!entry.is_null()); diff --git a/openssl/src/x509/tests.rs b/openssl/src/x509/tests.rs index bfc50899..7b3f2569 100644 --- a/openssl/src/x509/tests.rs +++ b/openssl/src/x509/tests.rs @@ -84,7 +84,7 @@ fn test_nameref_iterator() { let cert = include_bytes!("../../test/nid_test_cert.pem"); let cert = X509::from_pem(cert).unwrap(); let subject = cert.subject_name(); - let mut all_entries = subject.all_entries(); + let mut all_entries = subject.entries(); let email = all_entries.next().unwrap(); assert_eq!(email.object().nid().as_raw(), Nid::PKCS9_EMAILADDRESS.as_raw()); -- cgit v1.2.3 From 07c49e517ec577a2624aa139404f0b7d76fe30e2 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Tue, 26 Jun 2018 22:31:10 -0700 Subject: Only grab the name entry count when needed --- openssl/src/x509/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'openssl/src') diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs index 0b6c6b3d..3cfb0856 100644 --- a/openssl/src/x509/mod.rs +++ b/openssl/src/x509/mod.rs @@ -847,8 +847,6 @@ impl<'a> Iterator for X509NameEntries<'a> { fn next(&mut self) -> Option<&'a X509NameEntryRef> { unsafe { - let entry_count = ffi::X509_NAME_entry_count(self.name.as_ptr()); - match self.nid { Some(nid) => { // There is a `Nid` specified to search for @@ -861,7 +859,7 @@ impl<'a> Iterator for X509NameEntries<'a> { None => { // Iterate over all `Nid`s self.loc += 1; - if self.loc >= entry_count { + if self.loc >= ffi::X509_NAME_entry_count(self.name.as_ptr()) { return None; } } -- cgit v1.2.3