Notarizing a package

Hello,


I successfully codesigned app bundle and it was accepted by notary service. Then I created a package using pkgbuild/productbuild commands and codesigned it using Installer identity. The installer works fine.


I'm now trying to notarize the .pkg file but no success. It always returns invalid status with just one error:


severity"error"
codenull
path"<package internal path>.pkg Contents/Payload/Contents/MacOS/<executable>"
message"The signature of the binary is invalid."
docUrlnull
architecture"x86_64"


(I replaced real paths above).


However, when the application is installed, both codesign and spctl return OK status. I use XCode 10.1 on macos 10.14.2.


Any suggestions how to satisfy notary service?

Replies

Does the package contain the notarized app?

No, the package contains codesigned app. I'm trying to notarize only final package file. I tried to notarize application bundle only for testing purpose. So, to clarify:


Case 1:

- I tried to notarize application bundle. Notary service is ok with it. I used ditto command to compress it.


Case 2:

- I created a package which contains non-notarized (but codesigned) application bundle using pkgbuild/productbuild commands. Notary service rejects it.

- If I try to install application using this package, it works ok. Both spctl and codesign returns ok for installed app.

I finally found issue, it is related to scripts located in Contents/Helpers of my app bundle. If I move the scripts from the bundle, final package passes notary validation.

So, for now it is not clear how is better to ship script files inside app bundle. Currently I ship it inside Contents/Helpers subfolder and it works good except notary service does not accept the package. However, I use undocumented "--preserve-xattr" option to pkgbuild command to preserve extended attributes. It is required because codesign appends codesign info using extended attributes.


So, I see two possible solutions how to ship scripts inside app bundle and pass notarization:

- Convert script files to executables using shc command. Works good for me.

- Move script files to Contents/Resources subdirectory. Codesign skips this directory as I know. Apple docs suggests to put script files to avoid issues with extended attributes - https://developer.apple.com/library/archive/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG206. However, it is a bit strange that runnable code is placed to Contents/Resources, it is not correct directory. Also, I want my scripts to be signed as well.


I suspect there is an error in Apple notary service since it accepts zipped bundle but doesn't accept package which contains the same app.


Steps to reproduce the issue:

  1. Create simple app bundle, place some scripts to Contents/Helpers directory.
  2. Codesign the bundle. Scripts will have extended attributes.
  3. Zip the package using ditto which preservers extended attirbutes.
  4. Pass zip file to notary service, validation is passed.
  5. Create flat package (pkgbuild/productbuild) using codesigned app from previous step.
  6. Pass the package to notary service, validation is failed. It says that signature of main executable is wrong.
  7. Remove Contents/Helpers directory, repeat steps 2, 5. Notarization passed.

Codesign skips this directory as I know. … I want my scripts to be signed as well.

You seem to be labouring under a false premise here. Code signing does not skip

Contents/Resources/
. It is most definitely signed, it’s just not signed as code. Rather, it’s signed as a resource under the seal of the parent bundle. This is vital because many things inside
Contents/Resources/
are tantamount to code — the most obvious example being nibs — and so skipping them would compromise the whole code signing story.

Consider this:

$ codesign -v -v xxom.app
xxom.app: valid on disk
xxom.app: satisfies its Designated Requirement
$ cat xxom.app/Contents/Resources/Test.sh 
#!/bin/sh

echo "Hello Cruel World!"
$ … make a change to the script …
$ cat xxom.app/Contents/Resources/Test.sh 
#!/bin/sh

echo "Goodbye Cruel World!"
$ codesign -v -v xxom.app
xxom.app: a sealed resource is missing or invalid
file modified: …/xxom.app/Contents/Resources/Test.sh

When you put your script in

Contents/Helpers/
it is signed as code. The problem is that your script doesn’t have a convenient place to hold the code signature (that is, there’s no equivalent of the
LC_CODE_SIGNATURE
load command in Mach-O) and thus the signature has to be stored in an extended attribute. This puts you way off the beaten path, and it’s something we recommend against.

So, my advice: Put your script in

Contents/Resources/
and move on.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hello,

Thanks for the info. I was wrong with my assumption that Resources are not codesigned. I tried this sample locally, it confirms that resources are signed as well. Only disadvantage for me is that I wouldn't like to see scripts under Resources. Not big issue though.


However, any thoughts about converting scripts to executable and put under Helpers? For me it works ok when I convert bash script to executable using shc compiler, although I'll revert this solution in case any doubts. Perhaps this question is out of this thread, but I want to resolve it in case someone have the same issue.

Only disadvantage for me is that I wouldn't like to see scripts under Resources.

Yeah, I understand where you’re coming from here. Conceptually the script is executable code, and thus it really makes sense to sign it as code. Alas, that’s not a good idea given the way things are currently designed.

However, any thoughts about converting scripts to executable and put under Helpers?

I’m not familiar with

shc
, so I can’t offer any opinion on that front. Conceptually, however, this should be fine. As long as the things in
Contents/Helpers/
are Mach-O, and thus can hold their own code signature without the need for extended attributes, code signing and everything that depends on it should be happy.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for clarifying it.


I'll keep using my current approach when scripts are converted to executables and placed to Contents/Helpers. For me it works ok, the application is codesigned and notarized without any issues. Moving scripts to Contents/Resources will be used as alternative option in case I find any issue.