Merge pull request #937 from marcoh00/iterable-x509names
X509NameRef: Provide an iterator over all entries
This commit is contained in:
commit
1392b006e2
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -79,6 +79,30 @@ 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.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() {
|
||||
assert!(false);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nid_uid_value() {
|
||||
let cert = include_bytes!("../../test/nid_uid_test_cert.pem");
|
||||
|
|
|
|||
Loading…
Reference in New Issue