From 1757dc054ab2d301170503bfc764419ff640b290 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 6 Jan 2025 14:08:27 +0100 Subject: [PATCH] Simplify NameIterator state --- src/cert.rs | 2 +- src/subject_name/dns_name.rs | 4 ++-- src/subject_name/ip_address.rs | 4 ++-- src/subject_name/mod.rs | 40 ++++++++++++++++------------------ 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/cert.rs b/src/cert.rs index 966e22b3..3b3c8b5e 100644 --- a/src/cert.rs +++ b/src/cert.rs @@ -139,7 +139,7 @@ impl<'a> Cert<'a> { /// /// [EndEntityCert::verify_is_valid_for_subject_name]: crate::EndEntityCert::verify_is_valid_for_subject_name pub fn valid_dns_names(&self) -> impl Iterator { - NameIterator::new(Some(self.subject), self.subject_alt_name).filter_map(|result| { + NameIterator::new(self.subject_alt_name, true).filter_map(|result| { let presented_id = match result.ok()? { GeneralName::DnsName(presented) => presented, _ => return None, diff --git a/src/subject_name/dns_name.rs b/src/subject_name/dns_name.rs index 7b732356..6ec53849 100644 --- a/src/subject_name/dns_name.rs +++ b/src/subject_name/dns_name.rs @@ -26,7 +26,7 @@ use crate::error::{Error, InvalidNameContext}; pub(crate) fn verify_dns_names(reference: &DnsName<'_>, cert: &Cert<'_>) -> Result<(), Error> { let dns_name = untrusted::Input::from(reference.as_ref().as_bytes()); - let result = NameIterator::new(Some(cert.subject), cert.subject_alt_name).find_map(|result| { + let result = NameIterator::new(cert.subject_alt_name, true).find_map(|result| { let name = match result { Ok(name) => name, Err(err) => return Some(Err(err)), @@ -58,7 +58,7 @@ pub(crate) fn verify_dns_names(reference: &DnsName<'_>, cert: &Cert<'_>) -> Resu { Err(Error::CertNotValidForName(InvalidNameContext { expected: ServerName::DnsName(reference.to_owned()), - presented: NameIterator::new(Some(cert.subject), cert.subject_alt_name) + presented: NameIterator::new(cert.subject_alt_name, true) .filter_map(|result| Some(format!("{:?}", result.ok()?))) .collect(), })) diff --git a/src/subject_name/ip_address.rs b/src/subject_name/ip_address.rs index 8e9dd066..8dfdb9e6 100644 --- a/src/subject_name/ip_address.rs +++ b/src/subject_name/ip_address.rs @@ -29,7 +29,7 @@ pub(crate) fn verify_ip_address_names(reference: &IpAddr, cert: &Cert<'_>) -> Re IpAddr::V6(ip) => untrusted::Input::from(ip.as_ref()), }; - let result = NameIterator::new(None, cert.subject_alt_name).find_map(|result| { + let result = NameIterator::new(cert.subject_alt_name, false).find_map(|result| { let name = match result { Ok(name) => name, Err(err) => return Some(Err(err)), @@ -58,7 +58,7 @@ pub(crate) fn verify_ip_address_names(reference: &IpAddr, cert: &Cert<'_>) -> Re { Err(Error::CertNotValidForName(InvalidNameContext { expected: ServerName::from(*reference), - presented: NameIterator::new(None, cert.subject_alt_name) + presented: NameIterator::new(cert.subject_alt_name, false) .filter_map(|result| Some(format!("{:?}", result.ok()?))) .collect(), })) diff --git a/src/subject_name/mod.rs b/src/subject_name/mod.rs index 30f388c6..c1a7d606 100644 --- a/src/subject_name/mod.rs +++ b/src/subject_name/mod.rs @@ -16,6 +16,7 @@ use alloc::string::String; #[cfg(feature = "alloc")] use core::fmt; +use core::mem; use crate::der::{self, FromDer}; use crate::error::{DerTypeId, Error}; @@ -53,20 +54,19 @@ pub(crate) fn check_name_constraints( let excluded_subtrees = parse_subtrees(constraints, der::Tag::ContextSpecificConstructed1)?; for path in path.iter() { - let result = NameIterator::new(Some(path.cert.subject), path.cert.subject_alt_name) - .find_map(|result| { - let name = match result { - Ok(name) => name, - Err(err) => return Some(Err(err)), - }; + let result = NameIterator::new(path.cert.subject_alt_name, true).find_map(|result| { + let name = match result { + Ok(name) => name, + Err(err) => return Some(Err(err)), + }; - check_presented_id_conforms_to_constraints( - name, - permitted_subtrees, - excluded_subtrees, - budget, - ) - }); + check_presented_id_conforms_to_constraints( + name, + permitted_subtrees, + excluded_subtrees, + budget, + ) + }); if let Some(Err(err)) = result { return Err(err); @@ -203,19 +203,17 @@ enum Subtrees { pub(crate) struct NameIterator<'a> { subject_alt_name: Option>, - subject_directory_name: Option>, + directory_name: bool, } impl<'a> NameIterator<'a> { pub(crate) fn new( - subject: Option>, subject_alt_name: Option>, + directory_name: bool, ) -> Self { - NameIterator { + Self { subject_alt_name: subject_alt_name.map(untrusted::Reader::new), - - // If `subject` is present, we always consider it as a `DirectoryName`. - subject_directory_name: subject, + directory_name, } } } @@ -240,14 +238,14 @@ impl<'a> Iterator for NameIterator<'a> { // Make sure we don't yield any items after this error. self.subject_alt_name = None; - self.subject_directory_name = None; + self.directory_name = false; return Some(Err(err)); } else { self.subject_alt_name = None; } } - if self.subject_directory_name.take().is_some() { + if mem::take(&mut self.directory_name) { return Some(Ok(GeneralName::DirectoryName)); }