-
Notifications
You must be signed in to change notification settings - Fork 52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
verify_cert: correct handling of fatal errors. #168
Conversation
Codecov Report
@@ Coverage Diff @@
## main #168 +/- ##
==========================================
- Coverage 96.70% 96.64% -0.06%
==========================================
Files 15 16 +1
Lines 4549 4532 -17
==========================================
- Hits 4399 4380 -19
- Misses 150 152 +2
... and 4 files with indirect coverage changes 📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more 📢 Have feedback on the report? Share it here. |
d16d7aa
to
adb8c32
Compare
Maybe split the extraction of the is_fatal() method from the core fix to make it more obvious what the problem was? |
adb8c32
to
06a4ae1
Compare
Done. I also split the test helper refactoring into two parts. |
Sorry: if you add an is_fatal() helper it should happen in the same commit as starting to use it, so that we can verify that the logic remains the same, and then changing the logic should be a separate commit (either order could make sense). |
@djc Ah! Ok, will rework 👍 |
This commit adjusts the arguments to the `verify_chain` test helper to take references instead of moving the arguments. This makes it easier to use the same inputs for multiple `verify_chain` invocations.
This commit updates the `verify_chain` helper to allow providing an optional `Budget` argument (using the default if not provided). This makes it easier to write tests that need to customize the path building budget (e.g. `name_constraint_budget`).
This commit adds a method to `Error` for testing whether an error should be considered fatal, e.g. should stop any further path building progress. The existing consideration of fatal errors in `loop_while_non_fatal_error` is updated to use the `is_fatal` fn. Having this in a central place means we can avoid duplicating the match arms in multiple places, where they are likely to fall out-of-sync.
06a4ae1
to
1293561
Compare
Updated so the new helper is added in bcdd680 and immediately used to replace the existing fatal err handling in The change in error handling behaviour is now isolated to b5af2ce where the helper is added to the error handling between the two Hopefully that better matches what you were looking for 🤞 |
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).
1293561
to
b5af2ce
Compare
361dcf6
to
9fbc05a
Compare
The `loop_while_non_fatal_error` helper can return one of three things: * success, when a validated chain to a trust anchor was built. * a fatal error, e.g. when a `Budget` has been exceeded and no further path building should occur because we've exhausted a budget. * a non-fatal error, when a candidate chain results in an error condition, but other paths could be considered if the options are not exhausted. This commit attempts to express this in the type system, centralizing a check for what is/isn't a fatal error and ensuring that downstream callers to `loop_while_non_fatal_error` handle the fatal case appropriately.
9fbc05a
to
c69804e
Compare
I'd like to merge this to make progress on backports. If there's any late feedback I'm happy to iterate further! |
Description
This change fell out of an observation I made while back-porting the budget fixes in
main
to therel-0.100
release branch. In that branch the error handling for path building is simpler. Notably we don't carry forward aError
result from the firstloop_while_non_fatal_error
into the second, later ranking encountered errors to determine which to return.In the rel-0.100 branch there was existing logic for terminating for a fatal error from the first loop without carrying anything forward:
webpki/src/verify_cert.rs
Lines 89 to 94 in c8b8214
On
main
and inrel-0.101
we did not have that logic:webpki/src/verify_cert.rs
Lines 206 to 209 in 932ad95
All three branches should be terminating further path building when the first
loop_while_non_fatal_error
encounters a fatal err, but in practice onlyrel-0.100
handled this properly. This was demonstrated when that branch started failing the backportedtest_too_many_path_calls
test, because the first fatal error encountered is from expending the signature checking budget. Inmain
andrel-0.101
that error is ignored and we continue until the path building call budget is expended.This branch fixes the fatal error handling, and requires adjusting the
test_too_many_path_calls
test to do what it was intending to do in the presence of proper fatal error handling. I slightly refactored theverify_chain
helper to make this easier (and to let the existingname_constraint_budget
test also benefit from the shared helper).