Adobe-Runtime-Support
Adobe-Runtime-Support copied to clipboard
CodeSign, Notarize, Staple
I know there are fragments of this in many posts, but it needs to be pulled together. Ideally, a shell script that prompts or has a header that collects the variables and then accomplishes the entire signing for Mac distribution. I've spent days beating my head on this. Stuck again, but close enough to know it's possible. I'll share my script when I break through.
For now, I'm stuck at getting the .app notarized and I believe its because the .app is not properly signed. I also get
The signature of the binary is invalid.
What elements of the framework do I need sign? Currently, I sign the two internal pieces below and then the .app itself. The commented line was from a previous post, but my bundle does not have that (seems obsolete).
Is this all of the code in the bundle? My codesign all works, but it won't notarize.
# paths and strings
appPath="/pathToMy.app"
framework="Contents/Frameworks/Adobe AIR.framework"
v1Res="Versions/1.0/Resources"
# Code-signing the pieces
#codesign --timestamp --deep -f -v -s "$certApp" "$appPath/$framework/$v1Res/Flash Player.plugin/Contents/MacOS/FlashPlayer-10.6"
codesign --timestamp --deep -f -v -s "$certApp" --options runtime "$appPath/$framework/$v1Res/A2712Enabler"
codesign --timestamp --deep -f -v -s "$certApp" "$appPath/$framework"
From Apple, this is the most comprehensive instruction sheet It also says sign the pieces from the inside out. What order should we sign the framework pieces?
So many discrepancies.
- #1015 says to remove A2712Enabler, but a few lines down, it says to codesign it.
- It also uses --deep, but the apple forum above says never to use it.
- The apple forum guide also says to notarize the final wrapper only (e.g. dmg, pkg or zip), but not the contents.
- Shouldn't the compiled bundle have the following? Apple guide says yes.
Contents/embedded.provisionprofile
There's been great progress on the SDK, but the final mile is full of potholes. I'm broke-down again after hitting this one. Thanks for your help.
We've been trying to make this a little easier by providing the ability to sign the application bundle, which includes going through and signing all relevant components/frameworks within this. So e.g.
adt -sign -storetype KeyChainStore -alias "Developer ID Application" -target bundle main.app signed.app
This copies the original application bundle (main.app) and then signs it in the new location (signed.app) so then you should be able to package this and notarize it. From memory, we may have 'deep' on there but I was under the impression it didn't actually do anything now. We also thought that including a provisioning profile was optional, we don't have that on any of the apps we distribute (afaik, I may have to check that now!)
We also only notarize a package e.g. when we create installers via pkgbuild, or the AIR runtime dmg file, as the Apple tools break these open to scan the contents anyway. When we were first putting together our scripts, the process was basically:
- try code-signing stuff
- submit for notarization
- when it fails, look at the log which tells us which components are not properly code-signed
- adjust the code-signing script and repeat...
Plus of course, although in practice you'd only notarize the distributable, there's no reason you can't zip up and submit the .app folder for notarization to eliminate any packaging issues from this loop.
Hope that helps... I would actually hope that if you sign an app that was generated by the AIR SDK using that adt -sign utility, then the notarization would succeed: that's our aim, anyway, so if you find things that aren't working we should adjust it so that it does!
thanks
@ajwfrost I don't use or know adt. I've been working with all of the xcode command line utilities. I start with the .app produced by captive runtime bundle. Then, I'm using codesign, productsign, packagesbuild, productsign, xcrun, spctl.
According to this Apple post, you need to codesign each executable in the bundle and you need to know whether it is Bundled, or Standalone, a main executable or a library. These answers inform how you sign the code. He gives a great example. Do we know these answers (where all the code is) forthe bundle created?
Have you (or anyone else) successfully codesigned all the way through a standalone package that allows installation without relaxing security?
If the bundle was put together as an AIR application then it should have used adt, so you should have this (in the AIR SDK) - it's a command-line tool under the "bin" folder of the SDK.
Within adt, it does the following if you use the -sign command:
find "MyApp.app" -name "*.framework" -exec codesign --entitlements app.entitlements -s 'Developer ID Application' -f -o runtime --strict --timestamp --deep -v {} \;
find "MyApp.app" -name "*.dylib" -exec codesign --entitlements app.entitlements -s 'Developer ID Application' -f -o runtime --strict --timestamp --deep -v {} \;
find "MyApp.app" -name "*.plugin" -exec codesign --entitlements app.entitlements -s 'Developer ID Application' -f -o runtime --strict --timestamp --deep -v {} \;
find "MyApp.app" -name "*.dylib" -exec codesign --entitlements app.entitlements -s 'Developer ID Application' -f -o runtime --strict --timestamp --deep -v {} \;
find "MyApp.app" -name "A2712Enabler" -exec codesign --entitlements app.entitlements -s 'Developer ID Application' -f -o runtime --strict --timestamp --deep -v {} \;
codesign --entitlements app.entitlements -s 'Developer ID Application' -f -o runtime --strict --timestamp --deep -v MyApp.app
where the entitlements are a combination of some standard ones (below) plus whatever you added in the app descriptor file.
allow-jit -> true
allow-dyld-environment-variables -> true
allow-unsigned-executable-memory -> true
disable-library-validation -> true
And yes we've used that to sign a bundle and then check the notarization works.. thanks
Would be a good idea to get the current process together for the docs site.
I know that IntelliJ compiles with adt. I just mean that I don't know where it gets that scripting so I start my process with the .app that it builds. The signing list above helps. It also answers the A2712Enabler question because the other post said to remove it.
Not to be contrary, just noticing discrepancies between the above and what I've unearthed, as any nuance can shift the bytes to where Apple doesn't like them.
- Apple says sign from the inside out. Your script signs the app first instead of the inside code.
- Apple says don't use --deep. Hopefully, it does nothing of consequence.
- Apple says each codesign is unique with its own entitlements. Your script treats them all the same.
- I see additional executable code in the bundle (e.g. "Adobe Air")
Good news: my app is passing notarization and staple. Bad news after installation (with mild warning) the installed app says:
You do not have permission to open the application.
I've verified that its coming from the codesign and before the notarization and staple. The codesigned app exhibits the 'no permission' behavior before it's notarized. Very close.
To cover those:
- we do start from the inside out, the script uses 'find' to pick out the relevant elements from inside the package (although I guess dylib files may be within the resources of a framework...) -> but the final line is to sign the 'app' (i.e. the main application executable)
- agree re "deep", we left it in as it didn't seem to affect things
- I would kind of agree with Apple, we went for simplicity a bit here.. but most of those default entitlements could be needed by each of the binaries. The additional ones from the app descriptor may be only relevant to the main binary though. To grant more entitlements than is necessary could be seen as a bit of a security risk so I get where Apple are coming from.
- the "Adobe AIR" binary should be signed when you sign the "*.framework" (it should be under the framework folder structure where Apple expect it to be for that package type)
Good for it to get notarized! but "you do not have permissions" is an interesting one... Are you running on a device with Apple Silicon / M1? If so, you could try setting it to use Rosetta in case that makes a difference. Alternatively, we did have an issue with file permission flags a while ago, can you try looking at each of the binary files with ls -la to check that they all have the x (executable bit) set? You can do find MyApp.app -type f -exec ls -la {} \; to list every file with its permissions... then chmod a+x filename to add the executable permission to the relevant ones...
thanks
@ajwfrost Running on a Mini Mac i7. I don't think its a linux file issue. I've run the signing script line by line and 'no permission' happens immediately after I code sign the app. The permission bits are unchanged before and after the codesign.
Here are my codesign commands.
echo "$yellow\nCodesign the pieces...$end"
codesign --entitlements "$pkgPath/$appPlist" -s "$certApp" -f -o runtime --timestamp -v "$appPath/$framework"
codesign --entitlements "$pkgPath/$appPlist" -s "$certApp" -f -o runtime --timestamp -v "$appPath/$framework/$v1Res/A2712Enabler"
codesign --entitlements "$pkgPath/$appPlist" -s "$certApp" -f -o runtime --timestamp -v "$appPath/$framework/$v1Res/WebKit.dylib"
codesign --entitlements "$pkgPath/$appPlist" -s "$certApp" -f -o runtime --timestamp -v "$appPath/$framework/$vCur/Adobe Air"
echo "$yellow\nCodesign the app...$end"
codesign --force --deep --entitlements "$pkgPath/$appPlist" -s "$certApp" -f -o runtime --strict --timestamp -v "$appPath/"
I've selectively run each and tried running the app after each. If I sign only the piece-parts inside I immediately get 'app requires a verson of Adobe Air which cannot be found'. Once I sign the app, it turns to 'no permission'. Did the find as suggested and the executables inside are all rwxr-xr-x.
Okay thanks... sounds like it may be the entitlements then? Do you have these two set up?
- allow-unsigned-executable-memory -> true
- disable-library-validation -> true
And also if you do a "codesign -v -vvv" and/or "codesign -dvvv" on the framework folder, does it look okay?
If you're getting "requires a version of Air which cannot be found" it implies it can't open the AIR library/framework; which probably has the same root cause as the application failing to even start opening once you've signed it.
I'm also wondering whether it's objecting to you code-signing just the "Adobe Air" binary file rather than the framework as a whole, I think it might be better re-ordered perhaps so that the below is the final one of those four parts:
codesign --entitlements "$pkgPath/$appPlist" -s "$certApp" -f -o runtime --timestamp -v "$appPath/$framework"
(assuming that "$framework" is the folder Contents/Frameworks/Adobe AIR.framework)
thanks
When talking about entitlements... I'm just not trying to figure out, where I should put com.apple.developer.ubiquity-container-identifiers and com.apple.developer.ubiquity-kvstore-identifier which I need for iCloud key-value storage extension?
Yes, I have those entitlements and I've learned to do them in the Xcode editor. Yes, $framework is the folder you named. I've tried to only codesign the framework folder (hoping its recursive) and I've tried to sign each piece with the main first or last in the list. Each of those leads to 'apps requires Air...'. If I take the additional step of signing the app, the issue switches to 'no permission'. I've literally tried to add/remove each of the codesign switches. When at 'no permission' state, chmod has no effect. I've also turned off Gatekeeper, but that's not where the block is coming from either.
@Oldes you can add things into macOS.Entitlements in your app descriptor - see https://airsdk.dev/docs/building/application-descriptor-files/elements/macOS. These would be picked up if you sign the app using the adt -sign options (or provide native signing options on the command line, I don't think the IDEs do that yet though).
@chazhenry sounds frustrating! it seems like you're doing everything right.. I am not sure whether there's any tool that can provide any more details on why macOS is failing to load the framework. Did you try the codesign -v -vvvv thing on MyApp.app/Contents/Frameworks/Adobe\ AIR.framework in case that is showing anything suspicious?
@ajwfrost when using:
adt -sign -storetype KeyChainStore -alias "3rd Party Mac Developer..." -target bundle my.app signed.app
I get:
Native signing on mac needs to use KeychainStore type
What does it means?
@Oldes sorry, it looks like it's case sensitive -> KeychainStore would work but your storetype is KeyChainStore ... not sure that it's actually meant to be case sensitive looking at how the code actually works, it's just the check on the type which is doing a string comparison....
@ajwfrost Ah... interesting.. it is not complaining when used with -package.
Unfortunately when trying to run the signed result, I get You do not have permission to open the application “signed”.
(I'm on M1 Mac now)
Hmmm... so can you please double-check the file permissions, I thought we'd fixed them but if you do something like:
find signed.app/Contents/MacOS -type f -exec ls -la {} \;
and check it's got the x flags?
The flags looks ok... isn't it because of missing provision profile?
Btw... when I run on freshly made app:
codesign --verbose=4 --verify My.app
I get:
My.app: invalid Info.plist (plist or signature have been modified)
In architecture: arm64
Is this ok?
If it's a freshly made app then it implies there's a left-over code signature in some component that's not valid, it would be better if it said it wasn't signed at all... but not sure that should make a difference after we re-apply the new signing process.
On the signed app, can you perhaps try something similar but checking all the components:
find "MyApp.app" -name "*.framework" -exec codesign --verbose=4 --verify {} \;
find "MyApp.app" -name "*.dylib" -exec codesign --verbose=4 --verify {} \;
find "MyApp.app" -name "*.plugin" -exec codesign --verbose=4 --verify {} \;
find "MyApp.app" -name "A2712Enabler" -exec codesign --verbose=4 --verify {} \;
thanks
Ok.. it looks that my extension is a problem:
My.app/Contents/Resources/META-INF/AIR/extensions/xxx/META-INF/ANE/MacOS-x86-64/MyMac.framework: bundle format is ambiguous (could be app or framework)
How should I resolve it? The same message is also with the signed app after the adt -sign ... step.
I'm giving up on Mac support. I've spent days 'programming' something that should be automatic. This took me 30 mins on the PC. I don't consider the SDK cross platform at this point. I couldn't get Mac or Android working. I also tried to upgrade to premium with Harman and instead of getting a web page where I could pay, I got a screen telling me they'd send me an invoice. It never came. Who does that for a small bill that can be paid online? I can't see this working in the long run. Maybe I'll find a Mac person and come back. I've quit before. Either way, thanks for your help.
@ajwfrost I'm getting the invalid Info.plist message even on basic fresh app without any extension.
find "Test.app" -name "*.framework" -exec codesign --verbose=4 --verify {} \;
Test.app/Contents/Frameworks/Adobe AIR.framework: valid on disk
Test.app/Contents/Frameworks/Adobe AIR.framework: satisfies its Designated Requirement
find "Test.app" -name "*.dylib" -exec codesign --verbose=4 --verify {} \;
Test.app/Contents/Frameworks/Adobe AIR.framework/Versions/1.0/Resources/WebKit.dylib: valid on disk
Test.app/Contents/Frameworks/Adobe AIR.framework/Versions/1.0/Resources/WebKit.dylib: satisfies its Designated Requirement
find "Test.app" -name "*.plugin" -exec codesign --verbose=4 --verify {} \;
find "Test.app" -name "A2712Enabler" -exec codesign --verbose=4 --verify {} \;
Test.app/Contents/Frameworks/Adobe AIR.framework/Versions/1.0/Resources/A2712Enabler: valid on disk
Test.app/Contents/Frameworks/Adobe AIR.framework/Versions/1.0/Resources/A2712Enabler: satisfies its Designated Requirement
No issues above, but...
codesign --verbose=4 --verify "Test.app"
Test.app: invalid Info.plist (plist or signature have been modified)
In architecture: arm64
@ajwfrost But bigger issue is, that I can run the Test.app, but when I do:
java \
-jar /Users/oldes/GIT/AIRSDK_Harman_795/lib/adt.jar \
-sign -storetype KeychainStore -alias "Mac Developer: ..." \
-target bundle \
./Test.app ./Test-signed.app
I cannot run the signed version anymore (because of the permissions message), although it looks ok:
find "./Test-signed.app" -name "*.framework" -exec codesign --verbose=4 --verify {} \;
./Test-signed.app/Contents/Frameworks/Adobe AIR.framework: valid on disk
./Test-signed.app/Contents/Frameworks/Adobe AIR.framework: satisfies its Designated Requirement
find "./Test-signed.app" -name "*.dylib" -exec codesign --verbose=4 --verify {} \;
./Test-signed.app/Contents/Frameworks/Adobe AIR.framework/Versions/1.0/Resources/WebKit.dylib: valid on disk
./Test-signed.app/Contents/Frameworks/Adobe AIR.framework/Versions/1.0/Resources/WebKit.dylib: satisfies its Designated Requirement
find "./Test-signed.app" -name "*.plugin" -exec codesign --verbose=4 --verify {} \;
find "./Test-signed.app" -name "A2712Enabler" -exec codesign --verbose=4 --verify {} \;
./Test-signed.app/Contents/Frameworks/Adobe AIR.framework/Versions/1.0/Resources/A2712Enabler: valid on disk
./Test-signed.app/Contents/Frameworks/Adobe AIR.framework/Versions/1.0/Resources/A2712Enabler: satisfies its Designated Requirement
codesign --verbose=4 --verify "./Test-signed.app"
--prepared:./Test-signed.app/Contents/Frameworks/Adobe AIR.framework/Versions/Current/.
--validated:./Test-signed.app/Contents/Frameworks/Adobe AIR.framework/Versions/Current/.
./Test-signed.app: valid on disk
./Test-signed.app: satisfies its Designated Requirement
open -n ./Test-signed.app
The application cannot be opened for an unexpected reason, error=Error Domain=NSOSStatusErrorDomain Code=-10826 "kLSNoLaunchPermissionErr: User doesn't have permission to launch the app (managed networks)" UserInfo={_LSFunction=_LSLaunchWithRunningboard, _LSLine=2561, NSUnderlyingError=0x14bf096c0 {Error Domain=RBSRequestErrorDomain Code=5 "Launch failed." UserInfo={NSLocalizedFailureReason=Launch failed., NSUnderlyingError=0x14bf0a0d0 {Error Domain=NSPOSIXErrorDomain Code=153 "Unknown error: 153" UserInfo={NSLocalizedDescription=Launchd job spawn failed with error: 153}}}}}
@chazhenry don't blame AIR... it is Apple's ever changing complexity of all requirements fault. Internet is full of examples that we are not the only one to suffer.
I can run the app when I re-sign the signed app using codesign --force --deep --sign - ./Test-signed.app. Can anybody explain it?
@ajwfrost I completely blame Apple and to clarify, I can no longer support a Mac version.
One last thought occurs to me. I'm completely subject to whatever IntelliJ is doing. Best I can tell it runs adl and not adt. Not knowing Mac, I got that to work quickly and trusted it to work (until it didn't). Wondering if by taking over the compile, it would change the internal executable? Otherwise, no idea what to try.
@Oldes I found that I had to edit plist.info with Xcode. Once I touched the file it wrote with a text editor, it was corrupt. Supposed to be XML, but in typical Apple BS, a flavor only their tool can read. Hope that helps.
ADL is a debug launcher. To make a version for distribution, you must use ADT, which is the developer tool
@Oldes Thanks. Then I assume that when I compile as captive runtime, its using adt. I just don't get to see that command as it does it all under the covers. For months, it has built an app that I could run. Just don't know exactly what its doing or how I could get to the IntelliJ script that is driving the compile.
@Oldes I've asked in multiple posts, but never got an answer. What is the best pipeline? What do you use to develop? I'm using IntelliJ because the 2019 version had a plugin that correctly builds a captive runtime bundle. It also can run the app in debug mode. I can't do the same on the Mac side since the app itself won't run until entitlements are applied. Wondering if my dev pipeline on Mac needs to be more hands on as the blackbox compile is not working.
@ajwfrost How would I compile my existing app to a mac captive runtime with adt?