pkgbuild affecting app codesigning, preventing notarization

Hello,


I am trying to notarize an application and I am running into an issue after using pkgbuild on the .app. Here are the steps in the build process:


1. Generate .app using xcodebuild install

2. Sign the .app

3. Create component with pkgbuild

4. Create installer product with productbuild

5. Sign product using productsign

6. Add .pkg to .dmg

7. Sign .dmg

8. Notarize .dmg


I codesigned the .app, and verified that it is signed properly. I was able to notarize the .app successfully (done as a test, I am not including the notarized app in the build process). The issue comes after running pkgbuild. After using pkgbuild, RB App Checker Lite shows the following:

"

Evaluating the folder “55DB092F-7846-4EE8-9AA0-381C2A899086” inside the XAR package.


The code signature is unreadable or missing.


Error details: “-67028: bundle format unrecognized, invalid, or unsuitable” {

The operation couldn’t be completed. (OSStatus error -67028.)

}


The folder is unsigned.

"


To get more data, I proceeded through the steps anyway and attempted to notarize the dmg, and here is the response:


{

"logFormatVersion": 1,

"jobId": "xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",

"status": "Invalid",

"statusSummary": "Archive contains critical validation errors",

"statusCode": 4000,

"archiveFilename": "MyApp.dmg",

"uploadDate": "2020-02-13T16:07:13Z",

"sha256": "9de80d3c39870bb249bbdbfb1f42c9755f22888e069f25d24cfd863373a4b803",

"ticketContents": null,

"issues": [

{

"severity": "error",

"code": null,

"path": "MyApp.dmg/MyApp.pkg/MyAppComponent.pkg Contents/Payload/Applications/MyCompany/MyApp.app/Contents/MacOS/MyApp",

"message": "The binary is not signed with a valid Developer ID certificate.",

"docUrl": null,

"architecture": "x86_64"

},

{

"severity": "error",

"code": null,

"path": "MyApp.dmg/MyApp.pkg/MyAppComponent.pkg Contents/Payload/Applications/MyCompany/MyApp.app/Contents/MacOS/MyApp",

"message": "The signature does not include a secure timestamp.",

"docUrl": null,

"architecture": "x86_64"

},

{

"severity": "error",

"code": null,

"path": "MyApp.dmg/MyApp.pkg/MyAppComponent.pkg Contents/Payload/Applications/MyCompany/MyApp.app/Contents/MacOS/libusb-1.0.0.dylib",

"message": "The binary is not signed with a valid Developer ID certificate.",

"docUrl": null,

"architecture": "x86_64"

},

{

"severity": "error",

"code": null,

"path": "MyApp.dmg/MyApp.pkg/MyAppComponent.pkg Contents/Payload/Applications/MyCompany/MyApp.app/Contents/MacOS/libusb-1.0.0.dylib",

"message": "The signature does not include a secure timestamp.",

"docUrl": null,

"architecture": "x86_64"

},

{

"severity": "error",

"code": null,

"path": "MyApp.dmg/MyApp.pkg/MyAppComponent.pkg Contents/Payload/Applications/MyCompany/MyApp.app/Contents/Frameworks/libswiftAppKit.dylib",

"message": "The binary is not signed with a valid Developer ID certificate.",

"docUrl": null,

"architecture": "x86_64"

},

{

"severity": "error",

"code": null,

"path": "MyApp.dmg/MyApp.pkg/MyAppComponent.pkg Contents/Payload/Applications/MyCompany/MyApp.app/Contents/Frameworks/libswiftAppKit.dylib",

"message": "The signature does not include a secure timestamp.",

"docUrl": null,

"architecture": "x86_64"

}


and continues with this error for all of the .dylibs included in the upload.


So to reiterate, I can see that the .app is signed and could be notarized, but the signing seems to be lost or affected after running pkgbuild. Any suggestions would be appreciated. Let me know if you need more information on the build, I'll be happy to provide anything I can.


Thanks,

Alex

Replies

It sounds like your app is not signed properly. I'm sorry, but I've seen so many crazy things people are doing in this forum that I have a hard time accepting that people are really doing what they say they are doing. If you could post the actual commands you are running and the actual results, that would be really helpful.


Do you have anything other than an app in this package? Do you really need an installer package and DMG? That install path in the pkg makes me suspicious.

Hi John,


Thanks for taking the time to respond. No need to be sorry, I'm certainly not infallible and just want to get to the correct solution.


1. I run the following command:

xcodebuild -project My\ App.xcodeproj -configuration Release install


This results in the .app being generated in /tmp/My App.dst/Applications/MyCompany/MyApp.app


2. codesign -s "Developer ID Application: MyCompany (XXXXXXXXXX)" --timestamp --keychain "/Users/3outchange/Library/Keychains/login.keychain-db" --options runtime --deep --entitlements ./MyApp.entitlements --force "/tmp/My App.dst/Applications/MyCompany/MyApp.app"


This prints to the console: /tmp/My App.dst/Applications/MyCompany/MyApp.app: replacing existing signature


At this point I'll check the app's codesiging and tell you about the structure of the .app bundle. I'm doing this with RB App Checker Lite, but if you would prefer I gather the info another way, please advise me.


Putting the app into RB App Checker Lite gives the following:


Evaluating the application “Spider V Remote”.


The application was signed by “Apple Root CA”, “Developer ID Application: MyCompany (XXXXXXXXXX)”.

Both the verified timestamp and the signing-time are: Feb 12, 2020 at 9:04:22 AM.

The object code format is “app bundle with Mach-O thin (x86_64)”.

The signature contains the Team ID “VCN535JA6Y”.

Both bundle and signing identifiers are “mycompany.My-App”.

The signature specifies implicit requirements. 

The requirements specify the Team ID “XXXXXXXXXX”.

This matches the Team ID contained in the signature.

The signature specifies resource rules (v1). 

The signature specifies resource rules (v2). 

Gatekeeper assessment: PASS (Developer ID). 

Requirements and resources validate correctly.


The code signature has the UUID “89E99E5F-43D2-BEE2-8D11-28B491250B3A”.

Executable code for x86_64 has the UUID “3E6AEADC-B680-3D06-8658-2831C77E076E”.


A signing-time snapshot of the application’s Info.plist was found. 

Version 2.00.9e (2.1.0) Copyright © 2020 MyCompany. All rights reserved.


The signature contains 3 certificates. 

Certificate “Apple Root CA”: 

Your keychain contains this trusted root certificate.

Will expire on Feb 9, 2035.

Certificate “Developer ID Certification Authority”: 

Will expire on Feb 1, 2027.

Certificate “Developer ID Application: MyCompany (XXXXXXXXXX)”: 

Will expire on Aug 17, 2023.

SHA1 fingerprint: “E7815216A15571AB8111B37FF2AEAA05FB1EEE3F”.

Team ID or Organizational Unit: “XXXXXXXXXX”.

This matches the Team ID contained in the signature.


The application is probably from an authorized Apple Developer.


The application is not sandboxed.


The code signature contains entitlements. 

Other entitlements:

com.apple.security.cs.disable-library-validation: YES.


The application is quarantined. 


16 auxiliary executables have been found. 

219 data files have executable permissions, but should not.  

16 executables are signed by “Apple Root CA”, “Developer ID Application: MyCompany (XXXXXXXXXX)”. 

One executable file has no executable permissions, but should.  


--------------------------------------------


The contents of MyApp.app are:

_CodeSignature -> CodeResources

Frameworks -> a bunch of libswiftXXXX.dylibs

Info.plist

MacOS -> libusb-1.0.0.dylib, MyApp

PkgInfo

Resources -> AppIcon,icns, .nib files, .html files, .json files, .storyboardc files, .png and .tiff files


3. pkgbuild --root /tmp/My App.dst/Applications/MyCompany/MyApp.app --component-plist MyApp.plist ./subfolder/MyAppComponent.pkg


pkgbuild: Reading components from MyApp.plist

pkgbuild: Adding component at Applications/MyCompany/MyApp.app

pkgbuild: Wrote package to ./subfolder/MyAppComponent.pkg


It is at this point that checking the MyAppComponent.pkg file shows the issue reported in the original post.


Regarding distributing via a dmg that contains a .pkg, that is how our other projects are released, so I was trying to adhere to that style. I assumed this was acceptable, since it is stated in 'Customizing the Notarization Workflow' that "[the notary service] processes nested containers as well, like packages inside a disk image." If there's other reasons to change to just delivering a .pkg, please let me know.

1. One easy way to sanity-check these things is to build from inside Xcode. Then notarize from Xcode. If that fails, then you have more of a standard environment, which should always succeed, where you can start debugging. Otherwise, you don't know if your problem is within your original build or bundle structure, or somewhere else. As an added bonus, Xcode gives you the logs for what it does. You can then copy those commands to your automated tasks.


2. Neither --deep nor --force are recommended. What happens if you omit them? If it breaks, then you can stop here and fix your project and/or bundle.


RB App Checker is a 3rd party tool. I used to use it but it started crashing one day. It hasn't been updated in almost 4 years. A lot has changed in that time. I wouldn't recommend it.


I've seen many, many variants of commands to verify signatures. It seems there are almost as many variants of the codesign command as there are ways to create an invalid bundle. For quick-n-dirty validations, I just use:

codesign --vv -R="anchor apple generic" /path/to/app

and

spctl -vv -a /path/to/app


If that fails, then go no further. Something's wrong.


A pkg in a dmg is "acceptable". It is more a question of user experience. For one thing, if you have a pkg, you really don't need a dmg. A pkg file is stand-alone and can be downloaded and installed by itself. The dmg just adds another layer of complexity. In some cases, you may need a pkg. If you are installing more than just an app, and/or need root, then you need a pkg. But if it is just an app, then a pkg is just another hurdle for your users to jump over. And if you need the pkg to install a kernel extension or something, then you'll need to look into recent developments and get that into a stand-alone app - and do it really soon.


My guess is that there is something wrong with your bundle. That is probably why you are doing that funky codesign command. And after reviewing your code structure, what's that dylib doing next to the executable? Why isn't it in Frameworks?


Another thing you can do is compare your app to some other notarized apps. Identify the things that your app does differently, like having that dylib in there.

Your use of

--deep
is probably the immediate cause of this problem. It has many problems, not least of which is that it does the wrong thing if you have nested your code incorrectly. And your notarisation log indicates that this is indeed the case. For examples, dynamic libraries, like
libusb-1.0.0.dylib
, should be placed in your
Contents/Frameworks
directory.

I recommend that you re-do your approach to code signing based on the advice in my Signing a Mac Product For Distribution post.

Share and Enjoy

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

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

Thank you both for your help. I'm working on getting the libusb dylib in the proper spot (having trouble with that, but it isn't relevant to this thread), and I'll refer to the post you've shared.