I'm signing a .dmg
containing a .app
with a valid Developer ID profile. Everything is signed, frameworks included. When I run codesign -dvvv
, the right certificate appears and satisfies its Designated Requirement
. The application runs fine.
However, when I upload and download the .dmg
, the signature "disappears". When I run codesign -dvvv
, it says code object is not signed at all
. And GateKeeper naturally refuses to run the application.
Note: it sounds a lot like this issue but I'm definitely signing with the right Developer ID certificate, and the .dmg
does not appear "damaged".
[Note: the situation changed significantly in OS X v10.11.5 and v10.12; this answer has been updated to reflect that.]
In general, the thing you really need to sign is the files (mainly the app) inside the disk image, not the image itself. After the image is downloaded, the signature on the individual items will be checked as they are used. Starting in OS X 10.11.5, signing disk images is properly supported and sometimes required, but that's in addition to signing the relevant items inside it.
Through OS X v10.11.4, you could sign the disk image itself (with codesign -s "Developer ID Application: [your company]" example.dmg
), but the signature this creates is stored in the form of extended attributes attached to the image file. Actually, it creates three xattrs, named com.apple.cs.CodeDirectory
, com.apple.cs.CodeRequirements
, and com.apple.cs.CodeSignature
. The critical thing to realize is that these attributes are filesystem metadata -- that is, they're attached to the file, not part of the file's contents. The HTTP protocol has very limited support for filesystem metadata, so when you upload or download via HTTP (or FTP or...), it only transfers the file's contents, and the xattrs are lost.
You can see the xattrs with the ls -l@
command (and in even more detail with the xattr
command):
$ ls -l@ example.dmg
-rw-r--r--@ 1 gordon staff 338590 Nov 13 2013 example.dmg
com.apple.cs.CodeDirectory 120
com.apple.cs.CodeRequirements 172
com.apple.cs.CodeSignature 8515
com.apple.diskimages.fsck 20
com.apple.diskimages.recentcksum 81
After downloading, the image will have lost those attributes (and probably gained com.apple.quarantine
and com.apple.metadata:kMDItemWhereFroms
from the download process), and hence will not be considered signed. The files contained in it, on the other hand, should still be properly signed (since their signatures are part of the image file's contents.)
Starting in OS X v10.11.5, codesign
supports embedding the signature into the disk image itself, so that it will survive being downloaded over HTTP. Starting in v10.12, gatekeeper will enforce additional restrictions on apps in unsigned disk images that will prevent the app from loading additional content (mainly dynamic libraries) from the disk image, unless they're contained inside the app itself. If you don't know whether that's relevant to your app, go ahead and sign the disk image (actually, it's a good idea anyway), but be sure to run codesign
under 10.11.5 or later or the signature won't be in a useful format!