Hello! I'm dealing with a strange code signing issue which is preventing me from distributing a game through Steam. I'm able to sign and notarise the app in Xcode without any issues. I can verify that the app and all frameworks in /Contents/Frameworks/ are signed, and Gatekeeper allows the app to run without complaining.
$ spctl --assess -vvv ~/Temp/CodeSigningTest/GoodApp.app
/Users/ruairi/Temp/CodeSigningTest/GoodApp.app: accepted
source=Notarized Developer ID
origin=Developer ID Application: Ruairi Dorrity (3F97UA4BF8)
$ codesign --verify -vvv ~/Temp/CodeSigningTest/GoodApp.app
--prepared:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/ogg.framework/Versions/Current/.
--validated:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/ogg.framework/Versions/Current/.
--prepared:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/mpg123.framework/Versions/Current/.
--validated:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/mpg123.framework/Versions/Current/.
--prepared:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/libmodplug.framework/Versions/Current/.
--validated:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/libmodplug.framework/Versions/Current/.
--prepared:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/freetype.framework/Versions/Current/.
--validated:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/freetype.framework/Versions/Current/.
--prepared:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/Lua.framework/Versions/Current/.
--validated:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/Lua.framework/Versions/Current/.
--prepared:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/vorbis.framework/Versions/Current/.
--validated:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/vorbis.framework/Versions/Current/.
--prepared:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/OpenAL-Soft.framework/Versions/Current/.
--validated:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/OpenAL-Soft.framework/Versions/Current/.
--prepared:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/theora.framework/Versions/Current/.
--validated:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/theora.framework/Versions/Current/.
--prepared:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/love.framework/Versions/Current/.
--validated:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/love.framework/Versions/Current/.
--prepared:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/SDL2.framework/Versions/Current/.
--validated:/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/SDL2.framework/Versions/Current/.
/Users/ruairi/Temp/CodeSigningTest/GoodApp.app: valid on disk
/Users/ruairi/Temp/CodeSigningTest/GoodApp.app: satisfies its Designated Requirement
However, if I zip the app and upload it to Steam, the app that the Steam client downloads is blocked by Gatekeeper ("damaged and can't be opened") and re-running the above commands shows that the code signing seal has been broken somehow on the downloaded app:
$ spctl --assess -vvv ~/Temp/CodeSigningTest/BadApp.app
/Users/ruairi/Temp/CodeSigningTest/BadApp.app: cannot find code object on disk
$ codesign --verify -vvv ~/Temp/CodeSigningTest/BadApp.app
/Users/ruairi/Temp/CodeSigningTest/BadApp.app: code object is not signed at all
In subcomponent: /Users/ruairi/Temp/CodeSigningTest/BadApp.app/Contents/Frameworks/love.framework
The second command can be re-run, showing a seemingly random framework from /Contents/Frameworks/ each time e.g.
$ codesign --verify -vvv ~/Temp/CodeSigningTest/BadApp.app
/Users/ruairi/Temp/CodeSigningTest/BadApp.app: code object is not signed at all
In subcomponent: /Users/ruairi/Temp/CodeSigningTest/BadApp.app/Contents/Frameworks/ogg.framework
Further investigation shows that these frameworks are now unsigned, when they were signed before uploading and downloading:
$ codesign --verify -vvv ~/Temp/CodeSigningTest/BadApp.app/Contents/Frameworks/ogg.framework
/Users/ruairi/Temp/CodeSigningTest/BadApp.app/Contents/Frameworks/ogg.framework: code object is not signed at all
$ codesign --verify -vvv ~/Temp/CodeSigningTest/BadApp.app/Contents/Frameworks/love.framework
/Users/ruairi/Temp/CodeSigningTest/BadApp.app/Contents/Frameworks/love.framework: code object is not signed at all
...
$ codesign --verify -vvv ~/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/ogg.framework
/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/ogg.framework: valid on disk
/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/ogg.framework: satisfies its Designated Requirement
$ codesign --verify -vvv ~/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/love.framework
/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/love.framework: valid on disk
/Users/ruairi/Temp/CodeSigningTest/GoodApp.app/Contents/Frameworks/love.framework: satisfies its Designated Requirement
I'm stumped as to what's happening here. Is is possible that the app is being modified being the scenes by Steam, which breaks the code signing? This seems unfathomable because it would surely break code signing on every Mac game on Steam, but I really can't understand what else would be going on. I'm sure I need to expand my knowledge on code signing; any pointers, suggestions or assistance is greatly appreciated! Thank you!
Post
Replies
Boosts
Views
Activity
I'm attempting to notarize and distribute a game built with Love2D. Love2D is an engine which runs games written in Lua and bundled into .love files, which are identical to .zip files. Packaging a game for Mac distribution involves cloning the Love2D Xcode project, providing your built game.love file (the zipped game content), and then signing and notarizing as with any other Mac app (see more on the Love2D wiki: https://love2d.org/wiki/Game_Distribution#Creating_a_macOS_Application).
I'm encountering an issue because my game contains compiled C binaries which the game loads at runtime. These binaries are compiled for MacOS x86 and arm64, and work perfectly in development. I am able to successfully build and sign the game with my Developer ID Application certificate and provisioning profile, but notarization of the game fails because the compiled C binaries are not signed; below is an excerpt from the audit log:
{
"severity": "error",
"code": null,
"path": "Bang_Average_Football.zip/love.app/Contents/Resources/game.love/deps/gifcatlib_arm64.so",
"message": "The binary is not signed with a valid Developer ID certificate.",
"docUrl": "https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/resolving_common_notarization_issues#3087721",
"architecture": "arm64"
},
I can sign these binaries using codesign and the same certificate as the Mac app like so (with the correct name):
codesign --sign "Developer ID Application: Firstname Lastname" --verbose=4 gifcatlib_arm64.so
After signing the binaries, the app successfully builds, and is notarized successfully without reporting any code signing issues. Hooray! The issue is that the app doesn't actually run and crashes as soon as it attempts to use any of the now-signed binaries complaining that they haven't been signed correctly. Here's a link to the full crash log; the specific error is below:
Exception Type: EXC_BAD_ACCESS (SIGKILL (Code Signature Invalid))
Exception Codes: UNKNOWN_0x32 at 0x000000010a9c8000
Exception Codes: 0x0000000000000032, 0x000000010a9c8000
Exception Note: EXC_CORPSE_NOTIFY
Termination Reason: Namespace CODESIGNING, Code 2
The same error occurs even with Hardened Runtime disabled and 'Disable Library Validation' enabled.
Is there a likely cause of this crash? Why does notarization succeed but the app essentially instacrashes? Have I signed the binaries incorrectly? Is what I'm attempting not actually possible? (can signed and unsigned binaries not really be hotswapped like this?)
Please let me know if there's any more information I should provide.
Thanks,
Ruairi