-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: crypto/x509: support Inhibit Any-policy and Policy Constraints #68484
Comments
What certificates make use of these extensions? |
Hi @seankhliao , DOD certificates make use of these extensions. eg. |
cc @golang/security |
We don't support policy constraints because they are basically unused in the webpki, and impose somewhat complicated constraints on path building. Federal PKI is notorious for using complex/obscure RFC 5280 features, for better or worse, which are generally unused in the wider webpki, so it doesn't surprise me that we fail to parse/process some of their hierarchies. While I'm not aware of any restrictions on using them in publicly trusted certificates, without significant usage in webpki certificates I'm not convinced that we should add the necessary path building complexity to support policy constraints. |
ok, thanks a lot team. |
Sounds like we can close this for now. If things change in the future and there is a necessity for support this, we can reopen. Thanks. |
We're seeing this in other branches of the US government as well, all Go programs can't make TLS connections due to these attributes. Would like some sort of solution or workaround, most recently IRS. |
Wanted to chime in that we see this as broadly important to the Golang ecosystem at HashiCorp. Users and customers in the Federal space have more advanced uses of PKI that are standards compliant, but beyond the typical commercial use cases. Lack of support prevents those organizations from being able to build applications using Golang, and impacts vendors like us supporting them. |
This proposal has been added to the active column of the proposals project |
After some discussions it looks like, due to the current prevalence of this and the indications that FPKI is going all-in on it, we are probably going to need to support it. I think the only external API changes will need to be adding fields for the parsed extensions. Internally we'll implement the validation logic as specified in https://datatracker.ietf.org/doc/html/draft-ietf-lamps-x509-policy-graph, rather than the 5280 logic, since that is vulnerable to a trivial DoS. I'll propose a concrete API change this week. |
Concrete proposal below. This copies the pattern we use for MaxPathLen/MaxPathLenZero, which is necessary because the zero value is meaningful. It feels like there should be a better way to do this, but it is not obvious to me. Ideally we'd use a pointer, but requiring users to create an int and then construct a pointer to it is not exactly user friendly. We may not need the VerifyOptions change, but it allows users to specify the initial acceptable policy, which may be useful.
|
This seems unfortunate but probably also the best we can do. Any thoughts @FiloSottile? |
Are these extensions ever used for non-zero values? If not, we could start with just the Also, if the use case we are targeting is supporting FPKI certificates for TLS, it feels like we could do without the VerifyOptions field, at least for now. I assume they still only use EKUs for designating server auth? (What's type PolicyMapping for? It's not referenced by any other APIs.) |
A good question, the answer to which is.... unclear. The (FPKI certificate policy)[https://www.idmanagement.gov/docs/fpki-x509-cert-policy-common.pdf] seems to indicate that inhibitPolicyMapping may be non zero, but InhibitAnyPolicy and requireExplicitPolicy should only ever be zero if set. That said, I'm having a slightly painful time actually trying to verify if that is true in practice. FPKI certificates are not particularly as well mapped in the same way web PKI ones are. I'm happy to just leave out InhibitAnyPolicy and RequireExplicitPolicy, keeping just the Zero fields for the initial implementation. There is a question of what to do when we parse a certificate containing these extensions with non-zero values though. Probably we should fail since we couldn't safely do the verification? (or at least how we treat it internally would diverge from the what the user sees) 🤷
Yeah I was of two minds about this. Likely all we really want is to verify basic policy (or, really, just parse the extensions), but the FPKI has it's whole own set of weird policy OIDs beyond those specified in the web PKI (in the id-fpki-certpcy tree). It's possible that users may want, or be required, to verify compliance with a specific one of these. I think at least for the first implementation of this we should just leave the verification stuff out, but I wanted to include it in the proposal so we can be ready to implement it if it is necessary.
Bah I managed to skip that extension in the proposal. Updated the comment. |
Just to add a little bit of context, our interested parties definitely want to be able to do more than just parse the extensions. They expect to verify policy. How deeply, whether basic (likely) or being able to validate particular policies isn't super clear to us at this time, but we'd probably appreciate the ability to satisfy this so as to not to be caught off guard and to not need to try to workaround or interrupt Go development to be able to provide compliance in this space. |
The next step on this is that @rolandshoemaker is planning to try implementing the API in #68484 (comment) to "see how painful it is." |
Implemented in CL 628616. It turns out to not be as terrible as I expected, other than the ton of new fields on Certificate.
Updated #68484 (comment) to reflect the final API. |
Change https://go.dev/cl/628616 mentions this issue: |
Amazingly we need one more API change. Updated #68484 (comment). Since we filter chains post-building, we need a new InvalidReason const for the error return, since we may return no chains for a new reason.
|
Went back and forth in review, and looked for ways to reduce either the API surface or the attack surface of "regular" chain validation, and we came up pretty much short. This is a terrible feature of X.509, and if we need to support it, I think this is the best we can do. |
Re-opening since the proposal is still inflight. We landed this under the assumption it would be accepted after the freeze. If the committee decides not to accept the proposal we will revert the change. |
Change https://go.dev/cl/618415 mentions this issue: |
This vendors the vectors (generated using [0], derived from the BoringSSL script which generates their test headers) and all of the certs, but only runs the subset of the suite that is focused on policy validation. In the future we may want to run more of the suite, since it is focused on path validation, not path building, the way it interacts with our hybrid path builder/validator is kind of complicated. Updates #68484 Updates #45857 [0] https://gist.github.com/rolandshoemaker/a4efa9d65c2cef74a46ea40f47f0729e Change-Id: Ic04323dcd76aa5cbd6372c8cb1c44ccb91ccbca4 Reviewed-on: https://go-review.googlesource.com/c/go/+/618415 Reviewed-by: Russ Cox <rsc@golang.org> Reviewed-by: Filippo Valsorda <filippo@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Thanks for doing the exercise! @rolandshoemaker is our only expert in this stuff on the proposal committee, so I wanted to make sure we got a second expert opinion before moving forward with this. |
Based on the discussion above, this proposal seems like a likely accept. The proposal details are in #68484 (comment). |
Important
The current proposal is #68484 (comment).
Go version
go version go1.20.4 windows/amd64
Output of
go env
in your module/workspace:What did you do?
To validate/verify the X509 certificates that contain the following X509 critical extensions using https://github.com/golang/go/blob/master/src/crypto/x509/verify.go#L753
What did you see happen?
It throws the error saying
"x509: unhandled critical extension"
What did you expect to see?
Certificate Verification done successfully with out any error.
Additional info:
This is because of the following code.
https://github.com/golang/go/blob/master/src/crypto/x509/parser.go#L780
https://github.com/golang/go/blob/master/src/crypto/x509/verify.go#L565
as the following Extensions OIDs are not handled in the above mentioned GO Lang code.
2.5.29.54 (Require Explicit Policy:0, Inhibit Policy Mapping:0)
2.5.29.36 (X509v3 Inhibit Any Policy: critical)
The text was updated successfully, but these errors were encountered: