Skip to content

Commit 50a2930

Browse files
committed
verify_cert: correct handling of fatal errors
Previously the handling of fatal path building errors (e.g. those that should halt all further exploration of the path space) was mishandled such that we could hit the maximum signature budget and still pursue additional path building. This was demonstrated by the `test_too_many_path_calls` unit test which was hitting a `MaximumSignatureChecksExceeded` error, but yet proceeding until hitting a `MaximumPathBuildCallsExceeded` error. This commit updates the error handling between the first and second `loop_while_non_fatal_error` calls to properly terminate the search when a fatal error is encountered, instead of proceeding with further search. The existing `test_too_many_path_calls` test is updated to use an artificially large signature check budget so that we can focus on testing the limit we care about for that test without needing to invest in more complicated test case generation. This avoids hitting a `MaximumSignatureChecksExceeded` error early in the test (which now terminates further path building), instead allowing execution to continue until the maximum path building call budget is expended (matching the previous behaviour and intent of the original test).
1 parent 0651f72 commit 50a2930

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

src/verify_cert.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ fn build_chain_inner(
112112
// If the error is not fatal, then keep going.
113113
match result {
114114
Ok(()) => return Ok(()),
115-
err @ Err(Error::MaximumSignatureChecksExceeded)
116-
| err @ Err(Error::MaximumPathBuildCallsExceeded)
117-
| err @ Err(Error::MaximumNameConstraintComparisonsExceeded) => return err,
115+
// Fatal errors should halt further path building.
116+
res @ Err(err) if err.is_fatal() => return res,
117+
// Non-fatal errors should allow path building to continue.
118118
_ => {}
119119
};
120120

@@ -488,6 +488,7 @@ mod tests {
488488
fn build_degenerate_chain(
489489
intermediate_count: usize,
490490
trust_anchor_is_actual_issuer: TrustAnchorIsActualIssuer,
491+
budget: Option<Budget>,
491492
) -> Error {
492493
let ca_cert = make_issuer("Bogus Subject", None);
493494
let ca_cert_der = ca_cert.serialize_der().unwrap();
@@ -509,7 +510,7 @@ mod tests {
509510
&ca_cert_der,
510511
&intermediates,
511512
&make_end_entity(&issuer),
512-
None,
513+
budget,
513514
)
514515
.unwrap_err()
515516
}
@@ -518,7 +519,7 @@ mod tests {
518519
#[cfg(feature = "alloc")]
519520
fn test_too_many_signatures() {
520521
assert_eq!(
521-
build_degenerate_chain(5, TrustAnchorIsActualIssuer::Yes),
522+
build_degenerate_chain(5, TrustAnchorIsActualIssuer::Yes, None),
522523
Error::MaximumSignatureChecksExceeded
523524
);
524525
}
@@ -527,7 +528,17 @@ mod tests {
527528
#[cfg(feature = "alloc")]
528529
fn test_too_many_path_calls() {
529530
assert_eq!(
530-
build_degenerate_chain(10, TrustAnchorIsActualIssuer::No),
531+
build_degenerate_chain(
532+
10,
533+
TrustAnchorIsActualIssuer::No,
534+
Some(Budget {
535+
// Crafting a chain that will expend the build chain calls budget without
536+
// first expending the signature checks budget is tricky, so we artificially
537+
// inflate the signature limit to make this test easier to write.
538+
signatures: usize::MAX,
539+
..Budget::default()
540+
})
541+
),
531542
Error::MaximumPathBuildCallsExceeded
532543
);
533544
}

0 commit comments

Comments
 (0)