-
Notifications
You must be signed in to change notification settings - Fork 51
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
Perform more validation in extract_trust_anchor() #200
Comments
(Changed the title to refer to the functionality as named on the I think there is a general tendency in the webpki code base to defer validation until the time it used -- see also the extensive use of Your proposal in this issue would move us closer to "parse, don't validate" style (which I generally like/prefer), but I do see some potential downsides:
@briansmith can you comment on why you choose the deferred validation style? My guess would be that it's (a) allowing the current caller to validate the current state at the current point in time without relying on validation from an earlier time and (b) maybe legacy from when you implemented this in C++ and the culture of "parse don't validate" wasn't as obvious, or maybe hard to enforce. Personally I feel like if we are conscientious about making invalid states unrepresentable, "parse don't validate" style doesn't have many downsides (in that "earlier validation" would be ensured by the type system). Should we worry about side channel attack issues from short-circuiting certificate validation? My guess is no, since certificates themselves are public anyway. |
I don't know that's a fair representation of the current behaviour since it implies we do eventually validate the trust anchor has correct basic constraints, and that's not the case. Capturing more trust anchor state to defer validation would be possible, but also runs counter to webpki's trust anchor representation aiming to carry as little state as possible (e.g. vs keeping a full X.509 cert for each TA).
Agreed 👍
Indeed, I'm also open to the possibility I'm overlooking strong reasons the current approach is used. If this issue only serves to uncover those reasons and document them clearly I still think it was a worthwhile endeavor :-)
Making the fields private seems reasonable to me fwiw. In the case of the pki-types Let's let this sit a bit and see if we get any more input? |
Many CA root certificates are v1 (no extensions), and all of them are self-signed. |
Is there a reason to avoid enforcing the presence of the expected basic constraints extension for trust anchors that are v3? |
Any usage of this function where that check would matter sounds completely wrong. You've already manually verified that the (subject name, public key, name constraints) are trustworthy out-of-band. If you haven't, you're in big trouble. Though I am open to be proven wrong. |
Clarifying the comment on |
That's also my opinion on whether webpki should do such checks for end entity certificates in the list of root certs. You've already manually verified the trustworthiness of a certificate if you add it to the root store. If it's an end entity certificate, why should the library reject it. CAs only exist because it's not viable for the root store to contain all end entity certificates used in TLS, as a means to an end. In general, I find people reject using X.509 for things due to its complexity, and the view that you have to have separate CA and end entity certificates doesn't help. It's usually taught that way when explaining TLS. But often it's a misconception because libraries/software accepts also self signed certs in many instances. Software authors should keep accepting self signed certs, at least that's my opinion. |
I find the discussion a bit alarming and I worry people are not understanding what it means to construct a Please read briansmith/webpki#294. |
Indeed, I think we need to do a better job of documenting the discussion that's bubbling up here and in briansmith/webpki#294. I've clearly been confused, and so have several other folks. Here's an initial attempt to add some more guidance for downstream users: #201 Happy to iterate on that if I've still missed the mark. |
We landed that update, I don't think there are any other actions to take at this time. |
The TrustAnchor::try_from_cert_der fn does not perform any validation of the provided certificate - it simply extracts the minimum necessary metadata (subject, subject public key information, and optionally, name constraints) to represent a trust anchor internally in webpki. The associated rustdoc comment explains:
The original commit that introduced the helper in 2015 did not offer any explicit rationale for why this validation isn't performed.
In particular, not enforcing the presence of a true
cA
basic constraint when building aTrustAnchor
this way means that while we advertise an intentional limitation for webpki to not support self-signed certificates this isn't strictly true.If a self-signed end-entity certificate includes a basic constraints extension that asserts a true
cA
bool then we will reject the certificate incheck_issuer_independent_properties
when path building, returningError::CaUsedAsEndEntity
. This happens even if the same self-signed certificate is configured as a trust anchor. The advertised limitation holds.However, if a self-signed end-entity certificate omits the basic constraints extension (or includes one w/ a false
cA
bool) then we will not reject it as a CA used as an end-entity incheck_issuer_independent_properties
. SinceTrustAnchor::try_from_cert_der
doesn't enforce the presence of a truecA
bool in its input it will also not error if given the self-signed certificate DER. The end result is that it is possible for path building to succeed if such a self-signed end entity certificate is also configured as aTrustAnchor
created withTrustAnchor::try_from_cert_der
. This is in contrast to the advertised limitation of not supporting self-signed certificates.On the topic of basic constraints extensions RFC 5280 4.2.1.9 says:
My reading here is that we're acting in contradiction to a normative MUST NOT in 5280: We're using a trust anchor certificate without an asserted
cA
boolean's public key to verify the end-entity certificate signature.If folks agree with my interpretation, I think we should update
TrustAnchor::try_from_cert_der
to perform more validation. Trust anchors participating in the web pki should all have the correct basic constraint extension present.If folks disagree with my interpretation, I think we should update the limitation description to clarify this situation since there's more nuance than advertised in the README.
The text was updated successfully, but these errors were encountered: