diff --git a/src/error.rs b/src/error.rs index 5a8efe1c..3593e7f2 100644 --- a/src/error.rs +++ b/src/error.rs @@ -257,6 +257,18 @@ impl Error { Error::UnknownIssuer => 0, } } + + /// Returns true for errors that should be considered fatal during path building. Errors of + /// this class should halt any further path building and be returned immediately. + #[inline] + pub(crate) fn is_fatal(&self) -> bool { + matches!( + self, + Error::MaximumSignatureChecksExceeded + | Error::MaximumPathBuildCallsExceeded + | Error::MaximumNameConstraintComparisonsExceeded + ) + } } impl fmt::Display for Error { diff --git a/src/verify_cert.rs b/src/verify_cert.rs index a534187a..d9b34757 100644 --- a/src/verify_cert.rs +++ b/src/verify_cert.rs @@ -746,9 +746,10 @@ where for v in values { match f(v) { Ok(()) => return Ok(()), - err @ Err(Error::MaximumSignatureChecksExceeded) - | err @ Err(Error::MaximumPathBuildCallsExceeded) - | err @ Err(Error::MaximumNameConstraintComparisonsExceeded) => return err, + // Fatal errors should halt further looping. + res @ Err(err) if err.is_fatal() => return res, + // Non-fatal errors should be ranked by specificity and only returned + // once all other path-building options have been exhausted. Err(new_error) => error = error.most_specific(new_error), } }