aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2018-07-07 20:20:45 -0700
committerGitHub <[email protected]>2018-07-07 20:20:45 -0700
commit1392b006e2af882fa2a12eeaf9967988ac119c53 (patch)
treed4b9baf098fd26bbb98a887f2f0c6c5db0614e80
parentClean up IGE example (diff)
parentOnly grab the name entry count when needed (diff)
downloadrust-openssl-1392b006e2af882fa2a12eeaf9967988ac119c53.tar.xz
rust-openssl-1392b006e2af882fa2a12eeaf9967988ac119c53.zip
Merge pull request #937 from marcoh00/iterable-x509names
X509NameRef: Provide an iterator over all entries
-rw-r--r--openssl-sys/src/libressl/mod.rs2
-rw-r--r--openssl-sys/src/openssl/v10x.rs2
-rw-r--r--openssl-sys/src/openssl/v110.rs2
-rw-r--r--openssl/src/x509/mod.rs47
-rw-r--r--openssl/src/x509/tests.rs24
5 files changed, 70 insertions, 7 deletions
diff --git a/openssl-sys/src/libressl/mod.rs b/openssl-sys/src/libressl/mod.rs
index c65f6464..b9732cdd 100644
--- a/openssl-sys/src/libressl/mod.rs
+++ b/openssl-sys/src/libressl/mod.rs
@@ -593,8 +593,10 @@ extern "C" {
loc: c_int,
set: c_int,
) -> c_int;
+ pub fn X509_NAME_entry_count(n: *mut ::X509_NAME) -> c_int;
pub fn X509_NAME_get_entry(n: *mut ::X509_NAME, loc: c_int) -> *mut ::X509_NAME_ENTRY;
pub fn X509_NAME_ENTRY_get_data(ne: *mut ::X509_NAME_ENTRY) -> *mut ::ASN1_STRING;
+ pub fn X509_NAME_ENTRY_get_object(ne: *mut ::X509_NAME_ENTRY) -> *mut ::ASN1_OBJECT;
pub fn X509_STORE_CTX_get_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;
pub fn X509V3_EXT_nconf_nid(
conf: *mut ::CONF,
diff --git a/openssl-sys/src/openssl/v10x.rs b/openssl-sys/src/openssl/v10x.rs
index c22bb7fc..92ad295c 100644
--- a/openssl-sys/src/openssl/v10x.rs
+++ b/openssl-sys/src/openssl/v10x.rs
@@ -959,8 +959,10 @@ extern "C" {
ppval: *mut *mut c_void,
alg: *mut ::X509_ALGOR,
);
+ pub fn X509_NAME_entry_count(n: *mut ::X509_NAME) -> c_int;
pub fn X509_NAME_get_entry(n: *mut ::X509_NAME, loc: c_int) -> *mut ::X509_NAME_ENTRY;
pub fn X509_NAME_ENTRY_get_data(ne: *mut ::X509_NAME_ENTRY) -> *mut ::ASN1_STRING;
+ pub fn X509_NAME_ENTRY_get_object(ne: *mut ::X509_NAME_ENTRY) -> *mut ::ASN1_OBJECT;
pub fn X509_STORE_CTX_get_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;
pub fn X509V3_EXT_nconf_nid(
conf: *mut ::CONF,
diff --git a/openssl-sys/src/openssl/v110.rs b/openssl-sys/src/openssl/v110.rs
index 493385da..3c633491 100644
--- a/openssl-sys/src/openssl/v110.rs
+++ b/openssl-sys/src/openssl/v110.rs
@@ -198,8 +198,10 @@ extern "C" {
ppval: *mut *const c_void,
alg: *const ::X509_ALGOR,
);
+ pub fn X509_NAME_entry_count(n: *const ::X509_NAME) -> c_int;
pub fn X509_NAME_get_entry(n: *const ::X509_NAME, loc: c_int) -> *mut ::X509_NAME_ENTRY;
pub fn X509_NAME_ENTRY_get_data(ne: *const ::X509_NAME_ENTRY) -> *mut ::ASN1_STRING;
+ pub fn X509_NAME_ENTRY_get_object(ne: *const ::X509_NAME_ENTRY) -> *mut ::ASN1_OBJECT;
pub fn X509V3_EXT_nconf_nid(
conf: *mut ::CONF,
ctx: *mut ::X509V3_CTX,
diff --git a/openssl/src/x509/mod.rs b/openssl/src/x509/mod.rs
index a07fc1f1..876f373a 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 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<Nid>,
loc: c_int,
}
@@ -838,11 +847,22 @@ 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);
-
- if self.loc == -1 {
- return None;
+ 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);
+ if self.loc == -1 {
+ return None;
+ }
+ }
+ None => {
+ // Iterate over all `Nid`s
+ self.loc += 1;
+ if self.loc >= ffi::X509_NAME_entry_count(self.name.as_ptr()) {
+ return None;
+ }
+ }
}
let entry = ffi::X509_NAME_get_entry(self.name.as_ptr(), self.loc);
@@ -875,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 42859c97..7b3f2569 100644
--- a/openssl/src/x509/tests.rs
+++ b/openssl/src/x509/tests.rs
@@ -80,6 +80,30 @@ fn test_nid_values() {
}
#[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.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"[email protected]");
+
+ 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() {
+ assert!(false);
+ }
+}
+
+#[test]
fn test_nid_uid_value() {
let cert = include_bytes!("../../test/nid_uid_test_cert.pem");
let cert = X509::from_pem(cert).unwrap();