Skip to content

Commit cd7bbfd

Browse files
committed
end_entity: make dns_names infallible
The purpose of the `dns_names` helper on an `EndEntityCert` is to provide users the opportunity to get information on the dNSName SAN values in a certificate for **non-validation** purposes. Checking that a certificate is valid for a particular name should always be done with `verify_is_valid_for_at_least_one_dns_name`. With that use-case in mind, we can make the `dns_names` helper easier for consumers to use by filtering out invalid general names, returning an `Iterator<Item = &'a str>` unconditionally, instead of a `Result`. This better matches the updated name validation semantics where we ignore `MalformedDnsIdentifier` errors to continue to try to find a valid name to validate against.
1 parent 7ffbabe commit cd7bbfd

File tree

3 files changed

+26
-34
lines changed

3 files changed

+26
-34
lines changed

src/end_entity.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ impl<'a> EndEntityCert<'a> {
154154
/// Checking that a certificate is valid for a given subject name should always be done with
155155
/// [EndEntityCert::verify_is_valid_for_subject_name].
156156
#[cfg(feature = "alloc")]
157-
pub fn dns_names(&'a self) -> Result<impl Iterator<Item = &'a str>, Error> {
157+
pub fn dns_names(&'a self) -> impl Iterator<Item = &'a str> {
158158
subject_name::list_cert_dns_names(self)
159159
}
160160
}
@@ -212,9 +212,7 @@ mod tests {
212212
let cert =
213213
EndEntityCert::try_from(der).expect("should parse end entity certificate correctly");
214214

215-
let mut names = cert
216-
.dns_names()
217-
.expect("should get all DNS names correctly for end entity cert");
215+
let mut names = cert.dns_names();
218216
assert_eq!(names.next().map(<&str>::from), Some(name));
219217
assert_eq!(names.next().map(<&str>::from), None);
220218
}

src/subject_name/verify.rs

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -320,42 +320,36 @@ impl<'a> Iterator for NameIterator<'a> {
320320
#[cfg(feature = "alloc")]
321321
pub(crate) fn list_cert_dns_names<'names>(
322322
cert: &'names crate::EndEntityCert<'names>,
323-
) -> Result<impl Iterator<Item = &'names str>, Error> {
323+
) -> impl Iterator<Item = &'names str> {
324324
let cert = &cert.inner();
325325
let mut names = Vec::new();
326326

327-
let result =
328-
NameIterator::new(Some(cert.subject), cert.subject_alt_name).find_map(&mut |result| {
329-
let name = match result {
330-
Ok(name) => name,
331-
Err(err) => return Some(err),
332-
};
327+
NameIterator::new(Some(cert.subject), cert.subject_alt_name).for_each(|result| {
328+
let name = match result {
329+
Ok(name) => name,
330+
Err(_) => return,
331+
};
333332

334-
let presented_id = match name {
335-
GeneralName::DnsName(presented) => presented,
336-
_ => return None,
337-
};
333+
let presented_id = match name {
334+
GeneralName::DnsName(presented) => presented,
335+
_ => return,
336+
};
338337

339-
let dns_name = DnsNameRef::try_from_ascii(presented_id.as_slice_less_safe())
340-
.map(GeneralDnsNameRef::DnsName)
341-
.or_else(|_| {
342-
WildcardDnsNameRef::try_from_ascii(presented_id.as_slice_less_safe())
343-
.map(GeneralDnsNameRef::Wildcard)
344-
});
345-
346-
// if the name could be converted to a DNS name, add it; otherwise,
347-
// keep going.
348-
if let Ok(name) = dns_name {
349-
names.push(name.into())
350-
}
338+
let dns_name = DnsNameRef::try_from_ascii(presented_id.as_slice_less_safe())
339+
.map(GeneralDnsNameRef::DnsName)
340+
.or_else(|_| {
341+
WildcardDnsNameRef::try_from_ascii(presented_id.as_slice_less_safe())
342+
.map(GeneralDnsNameRef::Wildcard)
343+
});
351344

352-
None
353-
});
345+
// if the name could be converted to a DNS name, add it; otherwise,
346+
// keep going.
347+
if let Ok(name) = dns_name {
348+
names.push(name.into())
349+
}
350+
});
354351

355-
match result {
356-
Some(err) => Err(err),
357-
_ => Ok(names.into_iter()),
358-
}
352+
names.into_iter()
359353
}
360354

361355
// It is *not* valid to derive `Eq`, `PartialEq, etc. for this type. In

tests/integration.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,5 +340,5 @@ fn expect_cert_dns_names<'name>(
340340
let cert = webpki::EndEntityCert::try_from(&der)
341341
.expect("should parse end entity certificate correctly");
342342

343-
assert!(cert.dns_names().unwrap().eq(expected_names))
343+
assert!(cert.dns_names().eq(expected_names))
344344
}

0 commit comments

Comments
 (0)