///|
/// One attribute inside a relative distinguished name.
pub struct AttributeTypeAndValue {
oid : @asn1.ObjectIdentifier
value : String
}
///|
/// A relative distinguished name: a set of attributes that must all hold.
pub struct RelativeDistinguishedName {
attributes : Array[AttributeTypeAndValue]
}
///|
/// An X.501 name as it appears in a certificate: a sequence of RDNs.
pub struct Name {
rdns : Array[RelativeDistinguishedName]
}
///|
/// Whether the name has no components.
pub fn Name::is_empty(self : Name) -> Bool {
self.rdns.is_empty()
}
///|
/// Renders the name in the RFC 4514 form, for example
/// `CN=example.com,O=Acme,C=CN`.
///
/// RFC 4514 prints the components in the reverse of their DER order, so the
/// most specific attribute comes first.
pub fn Name::to_string(self : Name) -> String {
let buffer = StringBuilder()
let count = self.rdns.length()
for i in 0.. 0 {
buffer.write_string(",")
}
let rdn = self.rdns[count - 1 - i]
let mut first = true
for attribute in rdn.attributes {
if !first {
buffer.write_string("+")
}
first = false
buffer.write_string(attribute_display_name(attribute.oid))
buffer.write_string("=")
buffer.write_string(attribute.value)
}
}
buffer.to_string()
}
///|
/// Returns the value of the first attribute with the given short name, for
/// example `"CN"`.
pub fn Name::find(self : Name, short_name : String) -> String? {
for rdn in self.rdns {
for attribute in rdn.attributes {
if attribute_short_name(attribute.oid) == Some(short_name) {
return Some(attribute.value)
}
}
}
None
}