Notarizing a flat package?

Hi,


I'm having some trouble notarizing a package with a single app bundle in it. The application is actually a binary that is run as a LaunchDaemon as root. Originally our package installer just deployed two Mach-O binaries (executable and a dylib) to a directory along with the LaunchDaemon plist.


With notarization requiring an App Bundle, we've moved our two Mach-O binaries to the required App Bundle structure and successfully signed & notarized the App Bundle itself. A side note - we're not working with a typical Xcode setup. The binary is written in Rust and we're signing/notarizing manually with automation.


However, now that I'm attempting to build the flat PKG installer with the App Bundle, we're failing notarization for a reason that doesn't really make sense. The error we're getting from the notarization service is:


{
  "logFormatVersion": 1,
  "jobId": "91ca9fc8-50b4-4008-b691-xxxxxxx",
  "status": "Invalid",
  "statusSummary": "Archive contains critical validation errors",
  "statusCode": 4000,
  "archiveFilename": "xxxxxxxxx-0.2.1-signed.pkg",
  "uploadDate": "2019-04-29T20:39:03Z",
  "sha256": "xxxxxxxxx",
  "ticketContents": null,
  "issues": [
    {
      "severity": "error",
      "code": null,
      "path": "xxxxxxxx-0.2.1-signed.pkg/xxxxxxxx-0.2.1.pkg Contents/Payload/Applications/RedCanary.app/Contents/MacOS/xxxxsvcd",
      "message": "The signature of the binary is invalid.",
      "docUrl": null,
      "architecture": "x86_64"
    }
  ]
}

However, before building the PKG installer, I verified the signing of the `xxxxsvcd` binary both before and after. If I use pkgutil to unpack the binary, I get the following output for the App Bundle:


~/C/R/c/t/C/Applications ❯❯❯ codesign -dv --strict --verbose=4 -r- SomeApp.app
Executable=/Users/xxxxxxx/Code/some-repo/tmp/xxxxxxx-0.2.1.pkg/Applications/SomeApp.app/Contents/MacOS/cfsvcd
Identifier=com.xxxxxx.xxxxxxxx
Format=app bundle with Mach-O thin (x86_64)
CodeDirectory v=20500 size=74336 flags=0x10000(runtime) hashes=2316+3 location=embedded
VersionPlatform=1
VersionMin=658944
VersionSDK=658944
Hash type=sha256 size=32
CandidateCDHash sha256=70605df0e529d0c74f5b59aa28931ac3f5e8ef4e
Hash choices=sha256
Page size=4096
CDHash=70605df0e529d0c74f5b59aa28931ac3f5e8ef4e
Signature size=8929
Authority=Developer ID Application: XXXXXXXXXXX ()
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=Apr 29, 2019 at 1:37:44 PM
Info.plist entries=9
TeamIdentifier=
Runtime Version=10.14.0
Sealed Resources version=2 rules=13 files=2
designated => identifier "com.xxxxxx.xxxxxxxx" and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] =

If I run the codesign command specifically against xxxxxsvcd binary, I get similar output stating the signing state is fine.


Additionally, if I run "spctl", I get the following:


~/C/R/xxxxxxxx ❯❯❯ spctl -a -t exec -vvv --raw pkg-root/payload/Applications/SomeApp.app
pkg-root/payload/Applications/SomeApp.app: accepted




  assessment:authority
  
  assessment:authority:flags
  2
  assessment:authority:row
  6
  assessment:authority:source
  Developer ID
  
  assessment:originator
  Developer ID Application: XXXXXXXX ()
  assessment:remote
  
  assessment:verdict
  


origin=Developer ID Application: XXXXXXX ()


========================


That said, *after* packaging the app bundle, if I unpack it and run the "spctl -a -vvv SomeApp.app" command again, it fails with rejected. It seems something with the packaging phase is stripping whatever signature has been applied to the app bundle previously.


Prior to moving to the App Bundle we weren't having any trouble with signing verification.


In summary

  • Moved from a two signed Mach-O files in a directory to an App Bundle
  • Now signing & notarizing App Bundle. The App Bundle reports valid signing signatures as well as passing "spctl -a" for Gatekeeper checks.
  • After packaging, the App Bundle is invalidated and no longer works as expected.
  • Because the signing information is invalidated on the App Bundle, the package cannot be notarized.


Could someone help me understand what might be going wrong here with the packaging process?

I should clarify - we're currently using the munkipkg tool for packaging which has been working fine prior to this.

Accepted Answer

It seems something with the packaging phase is stripping whatever signature has been applied to the app bundle previously.

Stripping? Or breaking? The most common cause of the latter is inappropriately nested code. Earlier you wrote:

Originally our package installer just deployed two Mach-O binaries (executable and a dylib) to a directory along with the LaunchDaemon plist.

so nested code does come into play here. Here did you place that

.dylib
? Nested frameworks and shared libraries are supposed to go into
Content/Frameworks/
.

ps You can find this and many other helpful tidbits in Technote 2206 macOS Code Signing In Depth.

Share and Enjoy

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

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

Regarding: "so nested code does come into play here. Here did you place that

.dylib
? Nested frameworks and shared libraries are supposed to go into
Content/Frameworks/
."


Ok that makes sense. That said, why was I able to build an App Bundle that was signed and notarized if I had a dylib in the MacOS directory instead of the Frameworks directory?


I will try separating it out per the documentation linked.

why was I able to build an App Bundle that was signed and notarized if I had a dylib in the MacOS directory instead of the Frameworks directory?

My experience with bundles and then code signing and then Gatekeeper and then notarisation is that the rules about what is allowed where are very loose. Thus, each subsystem has its own interpretation of the rules, so that fact that somethings works at one level doesn’t necessarily mean that it’ll work at another, or continue working as the system evolves. This is why my colleague added the Nested Code section to TN2206, and why I keep requiring it as a first step. The information there represents a baseline that we all agree should work.

This isn’t to say that fixing this problem will fix your notarisation problem, just that fixing it is the first step in that process.

I will try separating it out per the documentation linked.

Thanks!

Share and Enjoy

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

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

I see - well thanks for the insight!


After stringently following the nested code section and putting dylibs in Frameworks, other stuff in Resources, I was able to:


  • sign the App Bundle
  • notarize the App Bundle
  • build the package
  • sign the package
  • notarize the package


Thanks very much for your help.

It's a relief to see that you were able to notarize a pkg, as I'm having trouble doing so, I have a thread up in this same section on Forums. I hope I can post as your last post here someday soon.

Notarizing a flat package?
 
 
Q