-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
crypto/x509: support DirectoryName name constraints #15196
Comments
Assigning to @agl to decide the fate of this. His last comment on CL 3230 was:
|
Not handling directory names is against RFC 5280 section 4.2.1.10:
Handeling these name constraints should have minimal impact as the extension is only processed when actually present in the certificate and we are processing a part of the extension currently anyway. Partly processing makes it confusing, I think we should support name constraints with all it's attributes or not support them at all. |
Has there been any more thought regarding this issue? We are seeing public CA certificates issued with critical name constraint (per RFC 5280) and Excluded subtrees for IP addresses (per the Baseline requirements https://cabforum.org/baseline-requirements-documents/). I think x509 should be able to parse BR-compliant CAs. |
@tadukurow can you paste an example for testing? I thought that I had done this but I see that I forgot to hit submit on https://go-review.googlesource.com/c/36900/. Also, that only supports it for names so I suspect that I'll want to extend it first. |
Here is an example for a CA which does not allow ips in the san of its leaf certificates as per baseline requirements.
|
Hi @agl, I see that ExcludedDNSDomains is included in the beta for 1.9, but what about the remaining name constraints?
These name constraints are needed to parse publicly trusted CA certs, here I have listed just some random publicly trusted CA certificates from different roots that together include all these types of name constraints: https://ssl-tools.net/certificates/7ea2490df8ea1f80134498caf93dde770c4e195a.txt |
As also required by the Mozilla Root Store Policy:
|
The other types did not make it into 1.9, which is now frozen I'm afraid. Shouldn't be a stretch for 1.10, although we do not support validating against emails or directory names so some thought is required about how that would be exposed. (I.e. don't expose and ignore them, even if critical, since we'll never use them in the stdlib and let people extract the extension if they care?) |
@agl Directory names are used to chain certificates together issuer<->subject, so directory name constraints are always relevant. Also the name constraint enforcement is supposed to be done independently of what kind of name is being validated. That is, if there is an email address constraint and that constraint is violated, then the certificate chain should be rejected even if you're validating a TLS server name. |
That's the "word of God" approach to certificate validation. I.e. that once validated, everything in the certificate is valid. Go does not take that approach and always considers validity in a specific context. |
I absolutely don't like the approach of ignoring the critical flag, these constraints and the flag is there with a good reason. While I see your argument that Go does not follow the "word of God", which is fine. Let's instead verify what "God" tells us and do more on top of that where possible. If we start leaving out parts of the standards and validation logic the mess is only getting bigger. We can't say that the users need to parse the extension them selfs as this would mean that they also have to perform the full chain validation and certificate handling them self which is not even possible in all use cases. Name constraints are a key part of the certificate chain validation. Instead of exposing all name constraint details in the x509.Certificate struct I can imagine that we would prefer to put the name constraints in its own linked struct like pkix.Name. We could also decide to include verification options in x509.VerifyOptions that let users choose to disable name constraint checking. Another approach is to add a hook to the certificate validation logic to handle 'unknown' or override/extend known extension handling. This way users can fulfill any type of critial extension (also thinking about OCSP must-staple) and perform full name constraints validation in the certificate chain without the need to rewrite the x509 package. |
Hi Adam, you probably already know this, but the design, (lack of) documentation, and code of the For example, IIUC, It also seems reasonable to call I think if you want to continue doing things as you suggest then it might be better to do the name constraint check in Sorry if I'm misunderstanding something. |
Brian, you're not misunderstanding. (Although I don't think Paul's argument that context-dependent validation is ok but ignoring these constraints is not, is sound. One implies the other unless we're adding contexts for email and so on.) When the Go X.509 library was first written it was quite unclear whether context-dependent validations were going to be the norm or not, mostly because of DANE. With a DNSSEC-based system, it's not possible to implement a Voice of God-style validation because the authority is inherently limited. But, as you note, the API was frozen long ago and isn't well demarcated. And, for a long time, it didn't really matter whether people got it right or not. I've written a CL previously to switch Go over to Voice of God but it didn't end up landing because it was somewhat large and I was overtaken by other stuff. VOG is less surprising and, after Google decided to buttress X.509 rather than replace it, and with Let's Encrypt eliminating most of the friction for large numbers of people, VOG is looking fairly dominant. So reviving that effort might be a sensible prereq here. I assume it would make Paul happy because VOG implies checking all constraints up-and-down the chain at verification time. (Although there's still some wooly thinking happening from what I can see. If intermediates need to have negative constraints for all the common other SAN types, then how do new name types ever get added? By that scheme, it would need every constrained intermediate to be updated before it would be safe. At best, I guess, we can declare that all the existing name types got this wrong but, for new ones, any name constraints implicitly exclude them.) |
I've heard off-issue from some people working with SPIFFE that need URI-based Name Constraints, and SPIFFE in turn is hopefully going to be written in Go and used by a variety of systems, including gRPC and Istio. I'm trying to understand the current state here. @agl, it sounds like you are okay with moving to the VOG approach to X.509 validation, and he may still have an old CL doing much of the work. The issue is titled "add Name Constraints", though. How would moving to VOG address that issue, or what new API would be needed? Thanks. |
I spoke to @agl, and he confirmed that he believes moving to VOG is the right thing to do. He hopes to do that for Go 1.10, and then adding URI-based Name Constraints would follow. If there are crypto experts who want to help, please let us know. |
@rsc, @agl, my previously submitted patch to implement this can't merge and anymore but I can contribute some coding and/or testing time to fix this patch or to create something new. Have there been any further thoughts about the implementation? I was thinking that instead of creating a list for 'each' general name type in x509.Certificate it might be cleaner to create one GeneralName interface in crypto/x509/pkix? crypto/x509 type NameConstraints struct {
Permitted pkix.GeneralName
Excluded pkix.GeneralName
}
// Permitted verifies if the given GeneralName is allowed to be used according to the
// name constraint rules. The name must be explicitly be Permitted or no other names
// of the given type must be listed as permitted or excluded.
func (n *NameConstraints) Permitted(pkix.GeneralName) bool {
...
}
type Certificate struct {
...
NameConstraintsCritical bool // if true then the name constraints are marked critical
NameConstraints NameConstraints
...
} NameConstraintsCritical could also be exposed as function Critital() on NameConstraints? crypto/x509/pkix type GeneralName interface{
String() string
}
type RFC822Name string
type DNSName string
type DirectoryName pkix.Name
type UniformResourceIdentifier net.URL
type IPAddress net.IP
... |
Change https://golang.org/cl/62693 mentions this issue: |
@agl thanks for working on this, can we please include directoryName too? directoryName is used a key restriction to prevent constrained sub-CAs to issue under a non-validated/allowed subject DN. |
Change https://golang.org/cl/71030 mentions this issue: |
Based on internal feedback from people who know more about X.509 than I, directoryName constraints were less useful and so I didn't include them in the first CL. The other thing that needs to get done this cycle is EKU checking at chain building time (in order to match the constraints behaviour). After that, it's possible but November is past approaching. |
…RI constraints This change makes crypto/x509 enforce name constraints for all names in a leaf certificate, not just the name being validated. Thus, after this change, if a certificate validates then all the names in it can be trusted – one doesn't have a validate again for each interesting name. Making extended key usage work in this fashion still remains to be done. Updates #15196 Change-Id: I72ed5ff2f7284082d5bf3e1e86faf76cef62f9b5 Reviewed-on: https://go-review.googlesource.com/62693 Run-TryBot: Adam Langley <agl@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
crypto/x509 has always enforced EKUs as a chain property (like CAPI, but unlike the RFC). With this change, EKUs will be checked at chain-building time rather than in a target-specific way. Thus mis-nested EKUs will now cause a failure in Verify, irrespective of the key usages requested in opts. (This mirrors the new behaviour w.r.t. name constraints, where an illegal name in the leaf will cause a Verify failure, even if the verified name is permitted.). Updates #15196 Change-Id: Ib6a15b11a9879a9daf5b1d3638d5ebbbcac506e5 Reviewed-on: https://go-review.googlesource.com/71030 Run-TryBot: Adam Langley <agl@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
Besides the usage of name constraints in internal CA, there are lots of public CA using directory name constraints (https://censys.io/certificates?q=%28%28parsed.extensions.name_constraints.excluded_directory_names%3A*+OR+parsed.extensions.name_constraints.permitted_directory_names%3A*%29%29+AND+tags.raw%3A+%22unexpired%22+). However, I could not find any certificate that sets name_constraints as critical: https://censys.io/certificates/help?q=parsed.extensions.name_constraints.critical%3A+true They might have opted to let it be a "best effort" restriction as there are TLS implementations that does not support all kinds of constraints. Go shouldn't be one of those to be blamed. |
Hello, I'm very interested in the support of critical name constraints. I am stuck accessing a system with a cert using a critical name constraint! |
@cwawak , it does not seem that go staff thinks that this is important. If you are building the software and you can patch the go used, I have patches since 1.14 that you can apply and build your own "go" that actually works. https://github.com/luizluca/go/tree/1.14/nameconstraint https://github.com/luizluca/go/tree/nameconstraint (master) Just pick the version you need. That is the best I can do for now. Update: I found I also had the 1.14 patch and I also updated the master patch. |
Fixes golang#15196 Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
I still think this should be supported by Go core, but maybe we can also think about a different approach, for example by extending the core implementation with a registrable extension handler. In this case a handler could be registered for each extension object identifier, if registered, that package will be used for verification and/or parsing and prevent failures for unknown critical extensions. An Extension interface could provide these optional Verify and Parse functionalities which would be called by the relevant certificate functions or the user directly. |
Hi @vanbroup
If you are suggesting a change in API, then that would need to go through the proposal process. If this would not need to go through the proposal process, would you mind very briefly elaborating on why not? (Sorry, just a quick comment, and I haven't looked at any of the details here). |
The suggestion of an API change is only because go is failing to implement parts of RFC5280 like, in this case, the MANDATORY directoryName name constraint RFC5280:
Even the dNSName is optional, but not the directoryName. |
Currently this search returns at list trusted CA certificates with name constraints critical and a directory name included: |
Adam Langley implemented the optional part of name constraints (9e76ce7) left the directory name validation, which is a mandatory part of RFC5280, section 4.2.1.10. Fixes golang#15196
This issue has been open for about 7+ years, it followed the same process as for other name constraints implementations. This is a minor modification to the implementation of name constraints which retains API compatibility. It extends the Without proper validation of (directory) name constraints the process should fail (with critical name constraints) or would continue otherwise, putting the user at risk when the constraints are not fullfilled. |
Hi Go team, what would be the next steps toward a fix for this issue? A few comments in a PR indicate that a decision should be made in the issue tracker before proceeding. Is there sufficient information in this thread to make that call? Would it be better to open a separate formal change proposal? Thanks! |
I would like to request for the adoption of change 3230 which is in code review for a long time.
https://go-review.googlesource.com/#/c/3230/
Change-Id: Idaa7abafec372d5eb444cad7ee2ea5794aee3424
To be able to validate all certificates issued according to the CA / Browser Forum Baseline Requirements the full set of name constraints need to be available in GO.
A recent version of the CA / Browser Forum Baseline Requirements states that Technical Constraints in Subordinate CA Certificates MUST be applied via Name Constraints. To support strong and strict certificate path validation and to allow users to see the actual constraints it's important that GO supports the required Name Constraints.
Section 9.7 of the baseline requirements states:
The full requirements can be found on: https://cabforum.org/baseline-requirements-documents/
The DirectoryName is also needed in some Microsoft environments. Forbidding all directory names would enforce domain validated certificates even if all certificates under a specific root are used and issued by the same organisation. Or could enforce all certificates to be issued with the same OV certificate details. Email addresses are not specifically handled by the CABForum because they don't cover client auth or s/mime certificates currently but likely to have the same requirements and make the set of constraints supported complete.
The text was updated successfully, but these errors were encountered: