Commit 2afdc16f authored by Marco Huenseler's avatar Marco Huenseler
Browse files

Make X509NameRef provide an iterator over all X509NameEntries

parent 2c89ef52
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -589,6 +589,7 @@ 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_STORE_CTX_get_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;
+1 −0
Original line number Diff line number Diff line
@@ -959,6 +959,7 @@ 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_STORE_CTX_get_chain(ctx: *mut ::X509_STORE_CTX) -> *mut stack_st_X509;
+1 −0
Original line number Diff line number Diff line
@@ -198,6 +198,7 @@ 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 X509V3_EXT_nconf_nid(
+25 −5
Original line number Diff line number Diff line
@@ -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<Nid>,
    loc: c_int,
}

@@ -838,10 +847,21 @@ 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
                    self.loc =
                ffi::X509_NAME_get_index_by_NID(self.name.as_ptr(), self.nid.as_raw(), 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;
            }

+21 −0
Original line number Diff line number Diff line
@@ -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");