Skip to content
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

v0.101.5 preparation #170

Merged
merged 28 commits into from
Sep 12, 2023
Merged

v0.101.5 preparation #170

merged 28 commits into from
Sep 12, 2023

Conversation

cpu
Copy link
Member

@cpu cpu commented Sep 8, 2023

Description

This branch targets a base of rel-0.101 to prepare a point release in the v0.101.x series.

It brings in:

I won't call out each individual commit this time since there are many :-)

In terms of required adjustments for backporting none of the commits in this branch required extensive changes. Principally much of the work was in avoiding the pki-types usages that are throughout main. The change in 65eb6a0 probably required the most adjustment to accommodate the difference in name iteration (this branch doesn't have a0e6434).

Proposed Release Notes

  • Path building complexity is now limited to a maximum budget of path finding operations, avoiding exponential processing time when encountering certificate chains containing many certificates with the same subject/issuer distinguished name but different subject public key information.
  • Name constraints evaluation is now limited to a maximum number of comparison operations, avoiding exponential processing time when encountering certificate chains containing many name constraints and subject alternate names.
  • Subject common names are no longer parsed for name iteration, or applying name constraints. Webpki only uses Subject Alternate Names when validating certificates, and the common name handling was buggy, producing Error::BadDer when iterating certificates with printable string subject common names, or omitted common names encoded as an empty sequence.

ctz and others added 28 commits September 6, 2023 12:46
This wasn't an actual issue, but the fix is equivalent.
This allows new errors to have minimal diffs.
This is executing a TODO when the chain length exceeds 6 issuers deep.
This commit renames the `check_signatures` fn, as it is doing more than
simply verifying signatures. It also checks revocation status w/ CRLs
when appropriate.
This commit updates the name constraint validation done during path
building to apply a budget for the maximum allowed number of name
constraint checks.

We use the same limit that golang crypto/x509 applies by default:
250,000 comparisons.

Note: this commit applies the budget during path building in a manner
that means certificates _not_ part of the built path can consume
comparisons from the budget even though they will not be present in the
complete validated path. Similarly name constraints are evaluated before
signatures, meaning a certificate that doesn't verify to a trusted root
still has its constraints parsed and evaluated. A subsequent commit
will adjust these shortcomings.
This commit updates the path building process such that name constraints
are only evaluated against a complete path where signatures on the chain
have been checked successfully to a trust anchor. This avoids:

* Parsing name constraints before signatures are validated.
* Evaluating name constraints and consuming name constraint comparison
  budget for certificates that are not part of the
  built path.

In the future it could be possible to interleave the name constraint
checking with the signature checking, however the logic for this is more
complicated. For an initial fix let's prefer a simpler solution that
walks the built + validated path to check name constraints from the
trust anchor to the end entity certificate.
This commit adds a pair of tests reproducing issue rustls#167,
where the `EndEntityCert::dns_names()` method returns an error
incorrectly on some certificate DER encodings. In particular,
`dns_names` fails if the CN is a `PrintableString`, or if it's an empty
`SEQUENCE`, rather than a `SEQUENCE` containing an empty `SET`.

The test for the `PrintableString` common name uses an end-entity
certificate generated using `rcgen`, while the test for empty `SEQUENCE`
CN required a hand-crafted DER using `ascii2der`. The text file that
generated the `ascii2der` cert is also included.
This commit removes parsing of the subject common name field from
`NameIterator`, since `rustls-webpki` does not actually verify subject
common names except when enforcing name constraints. This fixes issues
with common names in formats that `rustls-webpki` doesn't currently
support, by removing this code entirely.

Fixes rustls-webpki/webpki#167
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.
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).
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.
@codecov
Copy link

codecov bot commented Sep 8, 2023

Codecov Report

Merging #170 (702d57f) into rel-0.101 (d7f6aa4) will increase coverage by 0.20%.
The diff coverage is 94.00%.

@@              Coverage Diff              @@
##           rel-0.101     #170      +/-   ##
=============================================
+ Coverage      94.89%   95.09%   +0.20%     
=============================================
  Files             15       16       +1     
  Lines           3504     3711     +207     
=============================================
+ Hits            3325     3529     +204     
- Misses           179      182       +3     
Files Changed Coverage Δ
src/der.rs 98.37% <ø> (-0.02%) ⬇️
src/error.rs 56.89% <47.50%> (+4.72%) ⬆️
src/verify_cert.rs 97.24% <99.58%> (+0.76%) ⬆️
src/crl.rs 100.00% <100.00%> (ø)
src/end_entity.rs 77.24% <100.00%> (+8.97%) ⬆️
src/signed_data.rs 100.00% <100.00%> (ø)
src/subject_name/verify.rs 97.11% <100.00%> (+0.56%) ⬆️
src/test_utils.rs 100.00% <100.00%> (ø)

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

📢 Have feedback on the report? Share it here.

Copy link
Contributor

@hawkw hawkw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you so much for the backports!

@cpu cpu mentioned this pull request Sep 8, 2023
hawkw added a commit to linkerd/linkerd2-proxy that referenced this pull request Sep 11, 2023
This commit changes the `linkerd-meshtls-rustls` crate to use the
upstream `rustls-webpki` crate, maintained by Rustls, rather than our
fork of `briansmith/webpki` from GitHub. Since `rustls-webpki` includes
the change which was the initial motivation for the `linkerd/webpki`
fork (rustls/webpki#42), we can now depend on upstream.

Currently, we must take a Git dependency on `rustls-webpki`, since a
release including a fix for an issue (rustls/webpki#167) which prevents
`rustls-webpki` from parsing our test certificates has not yet been
published. Once v0.101.5 of `rustls-webpki` is published (PR see
rustls/webpki#170), we can remove the Git dep. For now, I've updated
`cargo-deny` to allow the Git dependency.
hawkw added a commit to linkerd/linkerd2 that referenced this pull request Sep 11, 2023
This commit changes the `linkerd-meshtls-rustls` crate to use the
upstream `rustls-webpki` crate, maintained by Rustls, rather than our
fork of `briansmith/webpki` from GitHub. Since `rustls-webpki` includes
the change which was the initial motivation for the `linkerd/webpki`
fork (rustls/webpki#42), we can now depend on upstream.

Currently, we must take a Git dependency on `rustls-webpki`, since a
release including a fix for an issue (rustls/webpki#167) which prevents
`rustls-webpki` from parsing our test certificates has not yet been
published. Once v0.101.5 of `rustls-webpki` is published (PR see
rustls/webpki#170), we can remove the Git dep. For now, I've updated
`cargo-deny` to allow the Git dependency.

---

* use `rustls-webpki` instead of `linkerd/webpki` (linkerd/linkerd2-proxy#2465)

Signed-off-by: Eliza Weisman <[email protected]>
hawkw added a commit to linkerd/linkerd2 that referenced this pull request Sep 11, 2023
This commit changes the `linkerd-meshtls-rustls` crate to use the
upstream `rustls-webpki` crate, maintained by Rustls, rather than our
fork of `briansmith/webpki` from GitHub. Since `rustls-webpki` includes
the change which was the initial motivation for the `linkerd/webpki`
fork (rustls/webpki#42), we can now depend on upstream.

Currently, we must take a Git dependency on `rustls-webpki`, since a
release including a fix for an issue (rustls/webpki#167) which prevents
`rustls-webpki` from parsing our test certificates has not yet been
published. Once v0.101.5 of `rustls-webpki` is published (PR see
rustls/webpki#170), we can remove the Git dep. For now, I've updated
`cargo-deny` to allow the Git dependency.

---

* use `rustls-webpki` instead of `linkerd/webpki` (linkerd/linkerd2-proxy#2465)

Signed-off-by: Eliza Weisman <[email protected]>
@djc djc added this pull request to the merge queue Sep 12, 2023
Merged via the queue into rustls:rel-0.101 with commit 7cb6c64 Sep 12, 2023
21 of 22 checks passed
@djc
Copy link
Member

djc commented Sep 12, 2023

Published 0.101.5 to crates.io and published release notes.

@cpu
Copy link
Member Author

cpu commented Sep 12, 2023

Thanks djc 👍

@cpu cpu deleted the cpu-0.101.5-prep branch September 12, 2023 13:31
hawkw added a commit to linkerd/linkerd2-proxy that referenced this pull request Sep 18, 2023
This commit changes the `linkerd-meshtls-rustls` crate to use the
upstream `rustls-webpki` crate, maintained by Rustls, rather than our
fork of `briansmith/webpki` from GitHub. Since `rustls-webpki` includes
the change which was the initial motivation for the `linkerd/webpki`
fork (rustls/webpki#42), we can now depend on upstream.

Currently, we must take a Git dependency on `rustls-webpki`, since a
release including a fix for an issue (rustls/webpki#167) which prevents
`rustls-webpki` from parsing our test certificates has not yet been
published. Once v0.101.5 of `rustls-webpki` is published (PR see
rustls/webpki#170), we can remove the Git dep. For now, I've updated
`cargo-deny` to allow the Git dependency.
hawkw added a commit to linkerd/linkerd2-proxy that referenced this pull request Sep 18, 2023
This commit changes the `linkerd-meshtls-rustls` crate to use the
upstream `rustls-webpki` crate, maintained by Rustls, rather than our
fork of `briansmith/webpki` from GitHub. Since `rustls-webpki` includes
the change which was the initial motivation for the `linkerd/webpki`
fork (rustls/webpki#42), we can now depend on upstream.

Currently, we must take a Git dependency on `rustls-webpki`, since a
release including a fix for an issue (rustls/webpki#167) which prevents
`rustls-webpki` from parsing our test certificates has not yet been
published. Once v0.101.5 of `rustls-webpki` is published (PR see
rustls/webpki#170), we can remove the Git dep. For now, I've updated
`cargo-deny` to allow the Git dependency.
adamshawvipps pushed a commit to adamshawvipps/linkerd2 that referenced this pull request Sep 18, 2023
This commit changes the `linkerd-meshtls-rustls` crate to use the
upstream `rustls-webpki` crate, maintained by Rustls, rather than our
fork of `briansmith/webpki` from GitHub. Since `rustls-webpki` includes
the change which was the initial motivation for the `linkerd/webpki`
fork (rustls/webpki#42), we can now depend on upstream.

Currently, we must take a Git dependency on `rustls-webpki`, since a
release including a fix for an issue (rustls/webpki#167) which prevents
`rustls-webpki` from parsing our test certificates has not yet been
published. Once v0.101.5 of `rustls-webpki` is published (PR see
rustls/webpki#170), we can remove the Git dep. For now, I've updated
`cargo-deny` to allow the Git dependency.

---

* use `rustls-webpki` instead of `linkerd/webpki` (linkerd/linkerd2-proxy#2465)

Signed-off-by: Eliza Weisman <[email protected]>
adamshawvipps pushed a commit to adamshawvipps/linkerd2 that referenced this pull request Sep 18, 2023
This commit changes the `linkerd-meshtls-rustls` crate to use the
upstream `rustls-webpki` crate, maintained by Rustls, rather than our
fork of `briansmith/webpki` from GitHub. Since `rustls-webpki` includes
the change which was the initial motivation for the `linkerd/webpki`
fork (rustls/webpki#42), we can now depend on upstream.

Currently, we must take a Git dependency on `rustls-webpki`, since a
release including a fix for an issue (rustls/webpki#167) which prevents
`rustls-webpki` from parsing our test certificates has not yet been
published. Once v0.101.5 of `rustls-webpki` is published (PR see
rustls/webpki#170), we can remove the Git dep. For now, I've updated
`cargo-deny` to allow the Git dependency.

---

* use `rustls-webpki` instead of `linkerd/webpki` (linkerd/linkerd2-proxy#2465)

Signed-off-by: Eliza Weisman <[email protected]>
Signed-off-by: Adam Shaw <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants