1

I am trying to sign a kernel extension file "abc.kext". I have a kext enabled certificate and tried to sign my "abc.kext" using:

codesign --sign "Developer ID Application: MyCompany (XXXXXXXX)" -a "x86_64" abc.kext

To verify that the signing is successful I run:

codesign --verify -vvvv abc.kext 

and the output is:

abc.kext: code object is not signed at all

Also run:

spct -a -v --type install abc.kext 

and the output is:

abc.kext:rejected
source: no usable signature

If I run:

kextutil -tn abc.kext

output is:

abc.kext appears to be loadable (including linkage for on-disk libraries).

Can somebody help me to find what I am doing wrong?

KoKa
  • 797
  • 1
  • 14
  • 31
  • Modified the command `codesign --verify -vvvv abc.kext` to `codesign --verify -vvvv -a "x86_64" abc.kext` and output is: `abc.kext: valid on disk abc.kext: satisfies its Designated Requirement` – KoKa Mar 10 '15 at 16:06

1 Answers1

1

You don't explicitly say so, but from the outputs you're getting, it looks like you're trying to codesign a multi-architecture kext? If so, don't do that!

The command codesign --verify -vvvv abc.kext works for kexts I've built and signed, no explicit architecture required. kextutil -n is a very good indicator on any incompatibilities, including code signing, but it only applies to the running version of OS X, so you need to check it with all versions you plan to support.

If for some reason you need to create a signed version of a kext based on not source code but an existing universal binary, you will need to extract the 64-bit portion of the binary, create a kext bundle from that and sign that. Your installer can then place this signed 64-bit kext in /Library/Extensions, and if the installer detects it is installing on a volume containing OS X 10.8 or older, additionally place the existing universal kext in /System/Library/Extensions. (Additionally so that if/when an upgrade happens, the kext won't suddenly stop working or generate signing warnings.)

To extract the 64-bit binary, use:

lipo -thin x86_64 abc.kext/Contents/MacOS/abc -output ./abc-64.kext/Contents/MacOS/abc

where abc.kext is the original universal kext and abc-64.kext is the new kext that you'll be signing. You should give the signed kext the same bundle identifier, but a higher bundle version number than the universal one, even though they're functionally identical. The higher-versioned one will be chosen if it's loadable by the OS.

An overview of kext requirements in different OS X versions:

Signed kexts will only load on OS X 10.8 and newer, and those versions all ship with 64-bit only kernels. If you want to support older versions of OS X, you'll need a separate kext for those versions. OS X 10.6 and 10.7 kernels can be either 32 or 64-bit, so if you want to support those versions, use an unsigned universal kext. A kext where the 64-bit portion is signed might load in a 32-bit kernel, but definitely will not load on a 64-bit 10.6/10.7 kernel. 10.5 and earlier only have 32-bit kernels, although of course they exist as both PowerPC and i386 variants (the latter from 10.4 on only). I don't know if it's possible to create a 3-architecture kext, but I suspect it is. Just don't sign it.

Signing is only required on 10.9 and newer, so you have a little bit of flexibility on what versions each kext covers. (10.8 will also happily load the 64-bit portion of an unsigned universal kext)

By the way, when building kexts, use the OS X SDK corresponding to the oldest supported OS X version of that build. The deployment target mechanism doesn't work for kexts. (for the most part)

pmdj
  • 22,018
  • 3
  • 52
  • 103
  • It is a multi-architecture kext which I want to sign only for OS X 10.9 and 10.10. The kext is signed on a OS X 10.10.2 machine. As you see from kextutil output abc.kext appears to be loadable. I have used codesign tool to explicitly sign the file for "x86_64" because the OS in which I am interested support only this architecture. When tried to sign without -a argument I got error: `codesign_allocate: can't allocate code signature data for: path_to_kext because larger updated load commands do not fit (the program must be relinked using a larger -headerpad value)` – KoKa Mar 11 '15 at 09:26
  • If it works on all platforms you want to support, great. (But then why the question?) But as I explained in the answer, a signed universal kext is completely pointless, as it won't load on 64-bit versions of OSX 10.6 and 10.7. (Those versions' kext loaders don't understand the code signing Mach-O commands in the binary and assume the binary is faulty) Meanwhile, the 32-bit part is useless on anything newer than 10.7, so it's not clear to me what you're trying to achieve with this. – pmdj Mar 11 '15 at 09:36
  • There will be two versions of the kext file, one unsigned for OS X 10.8 and earlier which will support x86_64 and i386 and one signed only for OS X 10.9 and newer. The question is why a kext file that seems to be correctly signed(codesign and kextutil output) is rejected by spctl tool. As you can see the output of spctl is `abc.kext:rejected source: no usable signature` and this is what makes me think that maybe I did something wrong when signing. – KoKa Mar 11 '15 at 10:19
  • What linker command are you using? Have you investigated the -headerpad issue? – pmdj Mar 11 '15 at 16:15
  • I didn't make the kext, so I don't know the linker command used. – KoKa Mar 12 '15 at 08:18
  • Ohhh, that makes more sense. So let me get this straight: 1. You have an old universal kext binary from pre-codesigning days; 2. You need to create a new kext that will work on 10.9/10.10 without rebuilding from source? Correct. Why not mention that in the question? :-) I suggest you extract the x86-64 part from the kext binary, using `lipo -thin x86_64 abc.kext/Contents/MacOS/abc -output ./abc-64.kext/Contents/MacOS/abc` where abc.kext is the original and abc-64.kext is the new kext that you'll be signing. Once you have the new kext set up, sign it with codesign --sign (no -a) – pmdj Mar 12 '15 at 09:41
  • Yes, actually that is what I want! :) Sign the old .kext file in order to work on 10.9/10.10 OS. I didn't know that this info was important, so I didn mention it! I am not sure if there is the need to extract the x86_64 part from the kext, since it is working, I am just curious why a kext file that seems to be correctly signed and works is rejected by spctl tool! – KoKa Mar 18 '15 at 10:30
  • There was some problem with the .kext I was trying to sign related with the architecture, this is why when I signed the file using ```codesign --sign "Developer ID Application: MyCompany (XXXXXXXX)" -a "x86_64" abc.kext``` then ```spct -a -v --type install abc.kext ``` failed. I followed your advice and extracted the x86-64 part from the kext binary, signed it and verified that signature is valid. Could you please add this as answer to my question? Thanks. – KoKa Jan 07 '16 at 09:14
  • Glad you got that all sorted in the end. I've amended my answer! – pmdj Jan 07 '16 at 11:13