Can't sign kext in Mavericks/Yosemite?

2020-05-29 04:50发布

Goal: to sign my own packages, and my own kernel extensions. "My own" in the context means "that I wrote, or that I picked elsewhere, recompiled myself from their sources, and want to install on my machine.

Problem: Mavericks does not accept my signature with Code Signing Failure: code signature is invalid (but loads the kext), Yosemite won't even load it.

I have my own CA, and code-signing certs. I've been able to successfully sign code and set up policies that would allow code signed by the given certs to be installed and executed - both codesign and spctl like it, as you see in the output below. However, that does not seem to apply to kext (kernel extensions) - kextutil insists that the signature is invalid. Here's the output I'm getting:

$ codesign --verify -vvvv /opt/local/Library/Filesystems/osxfusefs.fs/Support/osxfusefs.kext
/opt/local/Library/Filesystems/osxfusefs.fs/Support/osxfusefs.kext: valid on disk
/opt/local/Library/Filesystems/osxfusefs.fs/Support/osxfusefs.kext: satisfies its Designated Requirement

$ spctl -a -vvv -t exec /opt/local/Library/Filesystems/osxfusefs.fs/Support/osxfusefs.kext
/opt/local/Library/Filesystems/osxfusefs.fs/Support/osxfusefs.kext: accepted
source=XXXXXCode
origin=XXXXXCoder
$ spctl -a -vvv -t install /opt/local/Library/Filesystems/osxfusefs.fs/Support/osxfusefs.kext
/opt/local/Library/Filesystems/osxfusefs.fs/Support/osxfusefs.kext: accepted
source=XXXXXInstall
origin=XXXXXCoder

$ kextutil -tn /opt/local/Library/Filesystems/osxfusefs.fs/Support/osxfusefs.kext
Diagnostics for /opt/local/Library/Filesystems/osxfusefs.fs/Support/osxfusefs.kext:
Code Signing Failure: code signature is invalid
/opt/local/Library/Filesystems/osxfusefs.fs/Support/osxfusefs.kext appears to be loadable (including linkage for on-disk libraries).

On Mavericks this kext loads with a warning message, on Yosemite it will not.

I noticed here and in Apple CA CPS Developer ID that the cert must have the following extension: ( 1.2.840.113635.100.6.1.18 ) to designate it as kext-signing certificate. Mine does not have it. I suspect it to be the cause of my problem, but don't know how to resolve it. There does not seem to be an type option in spctl to create a policy designating a given cert as a kext-signing one.

How do I add this extension (preferably within Keychain Certificate Assist, though an OpenSSL-based solution would be fine too), short of paying Apple annual "usage fee" of $100?

3条回答
爷、活的狠高调
2楼-- · 2020-05-29 04:51

To request a Kext signing certificate from Apple, you need to use this form.

查看更多
Root(大扎)
3楼-- · 2020-05-29 05:02

Anyone can generate certificates with whatever OIDs that they want. In fact, OIDs are being added all the time. You can head over to IANA, request an OID and hack gnutls/openssl source code to start generating certificates for your new fangled field. The relevant OIDs for code signing that need to be in the certificate are documented. That should take handle the generation of personal CA and intermediary certificates that can sign kexts. Have a look at the patches against OpenSSL that enable it to generate RPKI certificaes

The next task is figuring out how Apple will recognise your CA as an anchor certificate. My guess here is that you'll need to import the generated CA cert using KeyChain Access. If apple somehow hardcodes the CAs (unlikely and would be stupid), we would be doomed. Otherwise, they must be loading the certificate anchors from some filesystem resource. Use dtruss to find out. My initial investigation points at /System/Library/Keychains/

查看更多
老娘就宠你
4楼-- · 2020-05-29 05:06

Only Apple can generate certificates with this OID and have it considered as valid for the kernel.

See What's New in Kext Development at tonymacx86.com for a more-detailed explanation. Here are the relevant parts.

The OID 1.2.840.113635 is Apple's company prefix, and the rest of the OID describes what specific property must exist in certificate "leaf" (the signing certificate) to allow the kernel extension to load. This means that a valid, signed kernel extension can only be created with a certificate provided by Apple as part of their $99/yr Developer program, and additionally that interested parties must fill out a special form explaining why they require the certificate; kext certificates are only provided upon request and approval.

While it is possible to generate a certificate with a specific OID and sign it with your own CA, OS X will only recognize Apple's CA for kernel extensions. Gatebreak's documentation briefly mentions this.

change the code requirements embedded in kextutil, kextd, and kextcache so they allow root certificates other than Apple's

查看更多
登录 后发表回答