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

Continued webpki CRL support. #66

Merged
merged 11 commits into from
Jun 15, 2023
Merged

Continued webpki CRL support. #66

merged 11 commits into from
Jun 15, 2023

Conversation

cpu
Copy link
Member

@cpu cpu commented May 17, 2023

Description

This branch adds support for verifying certificates are not revoked by consulting CRLs provided through implementations of a simple provider trait. Trust anchor revocation status is not considered.

In general I've tried to adapt to the existing webpki code without making any significant invasive changes to the path building logic. There's not a lot of test coverage in this area of the codebase and it's a tricky problem domain with many pitfalls.

Points for discussion

There are some rough edges left to be figured out as follow-up work:

  • Error messages for revocation related events are incorrect. All error states are reported as "UnknownIssuer". See Options for improving build_chain error specificity #79

  • There is no enforcement of the current time being greater than the CRL's NextUpdate. I found most implementations I surveyed chose not to treat this as a hard error so for now I've omitted any enforcement. Maybe this should be configurable?

  • There are some optimizations left on the table. Providing a relevant CRL is handled by a trait that could do some kind of caching if desired, but the actual act of iterating the relevant CRL to find a particular serial is handled by webpki and done with a naive linear scan. Some implementations (like BoringSSL) support maintaining a sorted list to allow faster search. We can probably rework the trait to support this but it will be trickier so for now I've left the simple solution in place. Pulled out to a separate issue: CRL optimization: rework to avoid linear scan of CRL contents #80

  • Similarly we perform CRL signature validation per-usage instead of once up-front. Pulled out to a separate issue: CRL optimization: verify CRL signatures once, up-front. #81

  • None of the revocation interface/checking is exposed for server cert validation, it's strictly for client cert validation. I think that's the most important use case and we can adapt the existing code for server cert chains pretty easily once stabilized.

Related to rustls/rustls#1164, #57. Continues from #44.

src/verify_cert.rs Outdated Show resolved Hide resolved
@codecov
Copy link

codecov bot commented May 17, 2023

Codecov Report

Merging #66 (239cc88) into main (fab5190) will increase coverage by 0.00%.
The diff coverage is 92.94%.

@@           Coverage Diff           @@
##             main      #66   +/-   ##
=======================================
  Coverage   95.59%   95.59%           
=======================================
  Files          15       15           
  Lines        2907     2953   +46     
=======================================
+ Hits         2779     2823   +44     
- Misses        128      130    +2     
Impacted Files Coverage Δ
src/error.rs 25.00% <ø> (ø)
src/signed_data.rs 100.00% <ø> (ø)
src/cert.rs 94.32% <50.00%> (-4.13%) ⬇️
src/crl.rs 99.55% <100.00%> (+1.35%) ⬆️
src/der.rs 96.64% <100.00%> (ø)
src/end_entity.rs 100.00% <100.00%> (ø)
src/verify_cert.rs 92.79% <100.00%> (+1.42%) ⬆️

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

@cpu cpu changed the title Continued webpki CRL parsing support. Continued webpki CRL support. May 17, 2023
@cpu
Copy link
Member Author

cpu commented May 26, 2023

Rebased to resolve conflicts. Fixed clippy errs with some temp. rustdocs. Updated PR desc to reflect this only builds on 1 outstanding PR now (the CRL parsing pt1 work).

@cpu cpu self-assigned this May 31, 2023
src/verify_cert.rs Outdated Show resolved Hide resolved
src/verify_cert.rs Outdated Show resolved Hide resolved
src/verify_cert.rs Outdated Show resolved Hide resolved
@cpu
Copy link
Member Author

cpu commented Jun 12, 2023

cpu force-pushed the cpu-crl-support-pt2 branch from bb5d3da to 8425fa3

Rebased, updated PR desc, and addressed the simple feedback.

@cpu
Copy link
Member Author

cpu commented Jun 12, 2023

I pulled out a separate issue for the error specificity: #79

Of the discussion topics this one feels like the largest blocker to getting a CRL support feature completed. Key usage is handled for intermediates in this branch, implementing that for trust anchors won't be very difficult if we decide its worthwhile. Similar for the NextUpdate question, and extending support to the server certificate context.

@cpu cpu marked this pull request as ready for review June 13, 2023 14:19
@cpu
Copy link
Member Author

cpu commented Jun 13, 2023

cpu force-pushed the cpu-crl-support-pt2 branch from 8425fa3 to 91c2fef

Just some small non-functional changes (PR desc updated as well):

  • removed a TODO I don't think is relevant anymore.
  • added pointers to the optimization issues I filed.

I also noticed I accidentally dropped the KeyUsage processing in one of my force pushes. Since this branch has a +1 from ctz and that work introduces new code across a few files I'm going to bring that back as a separate follow up. It's a change set that stands on its own so I think it will be easier to review in isolation from this larger work.

@cpu
Copy link
Member Author

cpu commented Jun 13, 2023

I also noticed I accidentally dropped the KeyUsage processing in one of my force pushes. Since this branch has a +1 from ctz and that work introduces new code across a few files I'm going to bring that back as a separate follow up.

#82

src/cert.rs Show resolved Hide resolved
src/end_entity.rs Show resolved Hide resolved
src/verify_cert.rs Show resolved Hide resolved
src/verify_cert.rs Outdated Show resolved Hide resolved
src/verify_cert.rs Outdated Show resolved Hide resolved
src/verify_cert.rs Outdated Show resolved Hide resolved
@cpu
Copy link
Member Author

cpu commented Jun 14, 2023

cpu force-pushed the cpu-crl-support-pt2 branch from a232fdb to 3df6ae7

I removed the key usage specific test suite from generate.py (and the generated test cases) so that I could pull them into #82 to better demonstrate the key usage enforcement.

cpu added 10 commits June 15, 2023 08:50
Crate-internal consumers of `build_chain` always pass `0` as the sub CA
count, only the `verify_cert.rs` internal recursion changes this
parameter.

This commit separates the external interface from the internal
recursion to remove one extra parameter from an already complicated
interface.
Previously the `Cert` type was not exported through `lib.rs` for
external usage. This commit relaxes this slightly in preparation for
passing `Cert` objects to external code to use for sourcing relevant
CRLs:

* We export `Cert`, but keep the inner fields crate-visible only. This
  matches the existing usage and keeps `untrusted::Input` out of our
  public API.
* We export `EndEntityOrCa`.
* We add public methods that allow access to the cert's DER encoded
  serial, issuer, and subject as `&[u8]`. We also allow access to the
  `EndEntityOrCa` enum for determining if the cert is a leaf, or an
  issuer.
* Lastly, some unreachable item clippy warnings in `der.rs` and
  `signed_data.rs` that emerge after making these changes are addressed
  by changing a few `pub` items to `pub(crate)`.
Based on discussions on other PRs I think we can say we favour up-front
detection of invalid DER for CRLs as opposed to discovering these errors
at the time we scan through the CRL looking for revoked certificates.

That's already what is implemented so this commit removes a TODO that
was there as a placeholder for discussion.
This commit adds a comment and a pointer to an issue in the issue
tracker about replacing the linear scan of CRL contents with an
optimized version that can be gated by the alloc feature.
Provides a mechanism for specifying whether revocation checking with
CRLs is performed when building a chain, and how the CRLs will be
provided.

To start we only expose this as an optional argument in the public
interface for checking the validity of a client certificate. It is not
yet consulted during chain building.
In preparation for needing more than just the TrustAnchor SPKI this
commit updates `check_signatures` to accept a reference to the full
`TrustAnchor` instead of just the SPKI input.
This commit starts to connect up the pieces that will be required for
revocation checking during path building. Presently the CRL checking is
a `todo!` to be continued in subsequent commits.
* Find the relevant CRL by invoking the crl provider with the cert.
* Verify the relevant CRL's signature using the cert's issuer's SPKI.
* Use the verified CRL contents to determine if the cert is revoked.

Left to do: enforce that the CRL issuer has the correct KU for CRL
signing, or no KU at all.
This commit adds a generator for a number of client cert validation test
cases. These test cases cover:

* Revocation checking when no CRLs are provided.
* Revocation checking when no relevant CRLs are provided.
* Revocation checking when a relevant CRL is provided, but no
  certificates in the chain are listed as revoked.
* Revocation checking when the CRL signature can't be validated.
* Revocation checking when a certificate is revoked and the CRL issuer
  doesn't specify any key usage.

All of these test scenarios are tested both for revocation checking at
the depth of just the end entity certificate, and for the EE cert and
any intermediates in use. Root certificates are not checked for
revocation.
Created by running:
```
cd tests
./generate.py --no-tls-server-certs --no-signatures --no-clientauth
```
@cpu
Copy link
Member Author

cpu commented Jun 15, 2023

cpu force-pushed the cpu-crl-support-pt2 branch from 3df6ae7 to 239cc88

Rebased to incorporate #83

I'm going to merge this when CI completes after checking with Ctz out-of-band that he's happy with this as-is.

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.

3 participants