-
Notifications
You must be signed in to change notification settings - Fork 18k
crypto/x509: properly handle errSecInvalidTrustSettings in macOS roots #38888
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
Comments
Likewise, we should figure out what to do when there are both user policies and admin policies, but none of the user policy dictionaries apply.
|
@henvic out of interest, how did you distrust these certificates on your system? When I use Keychain Access to manually de-trust a root (setting "When using this certificate: Never Trust") my That said there does seem to still be a mismatch between the behavior in the no-cgo and cgo implementations here. When the no-cgo implementation hits this weird parsing issue it returns |
Ah, I see what is happening here, cgo |
I've done some spelunking in the apple sources with some help from @sleevi. Various comments on the comments in the CGO version (which have mostly been copied into the direct call version): go/src/crypto/x509/root_cgo_darwin_amd64.go Lines 38 to 42 in 0242d46
Ignoring go/src/crypto/x509/root_cgo_darwin_amd64.go Lines 47 to 49 in 0242d46
SecTrustServer.c is from old-macOS, the current policy is described in https://opensource.apple.com/source/Security/Security-59306.41.2/trust/headers/SecTrustSettings.h.auto.html and this specific quote appears to be from There is a mismatch here between the CGO (and apple) implementations and the direct call implementation. Errors when retrieving the user or admin trust settings appear to just be thrown away, and a NULL CFArrayRef is returned (causing go/src/crypto/x509/root_cgo_darwin_amd64.go Lines 55 to 56 in 0242d46
This comment appears to be in the wrong place, the fallback to admin domain has already happened if the user settings are NULL, if there are neither user nor admin trust settings go/src/crypto/x509/root_cgo_darwin_amd64.go Lines 105 to 109 in 0242d46
It's hard to pin down how apple treats this, but it appears to just return the first constraint that applies (see A more high level comment: probably we should be ignoring dicts that contain keys we don't parse/don't know how to parse, since they are likely to contain policy we cannot apply in go. go/src/crypto/x509/root_cgo_darwin_amd64.go Lines 119 to 125 in 0242d46
Referring back, trust settings are attached to the cert independent of it's evaluation, so there doesn't appear to be any fallback from one domain to another if no settings apply to the cert. Apple source seems to imply that in the case that no trust settings apply to a cert then Generally I think both implementations are mostly matching the apple approach, although in a few places the golang implementation feels a bit more liberal than it perhaps should be. |
Sidenote: there are a handful of times in the comments that references are made to places in the apple source, but without any links (or even file names) it's very hard to track down what they are talking about. It would be extremely valuable to add explicit references to what is being talked about. |
@rolandshoemaker, I distrusted them in Keychain probably the same way you did a long time ago after opening it as a regular (non-sudoer) user (at some point I was prompted for authentication with an admin account). |
Hrm, interesting. I wonder if this is a case of Apple pulling the rug out from beneath themselves by changing the schema at some point and not properly migrating it or something... ¯\_(ツ)_/¯ Thanks for the info! |
@henvic you might want to try to re-distrust those specific certs if you really don't want them used, it's possible apple is sticking them in the intermediate pool for chain validation, which could cause very strange chains using them to be built... |
Change https://golang.org/cl/233360 mentions this issue: |
… roots This change makes the direct call darwin loadSystemRoots implementation match the existing cgo implementation, which in turn _mostly_ matches the Apple implementation. The main change here is that when SecTrustSettingsCopyTrustSettings the error is ignored, and can either cause a fallback to check admin trust settings, or cause the certificate to be marked kSecTrustSettingsResultUnspecified. As well as updating the implementation to match the cgo one, this change also updates the documentation of how the fallbacks work and how they match the Apple implementations. References are made to the Apple source where appropriate. This change does not update the existing comments in the cgo implementation, since the goal is to delete that code once the direct call implementation is matured. Updates #38888 Change-Id: Id0344ea9d2eede3b715f341e9cbd3c1c661b7a90 Reviewed-on: https://go-review.googlesource.com/c/go/+/233360 Run-TryBot: Filippo Valsorda <filippo@golang.org> Reviewed-by: Filippo Valsorda <filippo@golang.org>
Kindly paging @katiehockman @rolandshoemaker @FiloSottile, about this issue. Should we perhaps move this to Go1.17? |
Yep, definitely not happening for 1.16, thanks! |
Thanks @rolandshoemaker for the update! Moving it to Go1.17. |
Moving to backlog as it will probably be cleared by #46287. |
Change https://golang.org/cl/353132 mentions this issue: |
Looks like when a trust setting is invalid it drops trust in the certificate, overriding wider domains. All of this is documented nowhere else than in the macOS sources, so it will be a pain to figure out.
This came up in a report by @henvic while testing CL 227037. The tests still passed because the cgo and the direct call implementations behave the same, but they used to disagree with the exec one, which for once looks like it might have been the correct one.
https://gist.github.com/henvic/ab28a19631d18135ade7f9507c67feda
https://gist.github.com/henvic/68d9d64bd0120cb74464c5df53c692c0
Not fixing it in CL 227037 and deferring to Go 1.16 because it's been like this forever, and I'd like to focus on getting the port from cgo right, without changing behaviors at the same time.
The text was updated successfully, but these errors were encountered: