print

Code signing

App Store publishing

Certificates

Surprisingly enough, Apple names the certificate either by their type or by their name but never gives the correspondance between names and types.
I found it here: <http://jay0lu.github.io/2017/10/17/Apple-Mac-Certificate.html>;

Certificate type                  Certificate name                  Description

iOS DevelopmentiPhone Developer: Team Member NameUsed to run an iOS, tvOS, or watchOS app on devices and use certain app services during development.
iOS DistributioniPhone Distribution: Team NameUsed to distribute your iOS, tvOS, or watchOS app on designated devices for testing or to submit it to the store.
Apple DistributionApple Distribution: Member NameSign your apps for submission to the App Store or for Ad Hoc distribution. For use with Xcode 11 or later.
Mac DevelopmentMac Developer: Team Member NameUsed to enable certain app services for a Mac app during development and testing.
Mac App Distribution3rd Party Mac Developer Application: Team NameUsed to sign a Mac app before submitting it to the Mac App Store.
Mac Installer Distribution3rd Party Mac Developer Installer: Team NameUsed to sign and submit a Mac Installer Package, containing your signed app, to the Mac App Store.
Developer ID ApplicationDeveloper ID Application: Team NameUsed to sign a Mac app before distributing it outside the Mac App Store.
Developer ID InstallerDeveloper ID Installer: Team NameUsed to sign and distribute a Mac Installer Package, containing your signed app, outside the Mac App Store.
Intermediate signing certificateWorldwide Developer Relations CAIf missing, the above certificates are not taken as valid. https://www.apple.com/certificateauthority/

Trust and Validate Apple's certificates

If "security find-identity -p codesigning" says e.g. "3 identities found" but "1 valid identities found", several problems must be addessed.

Certificates not correctly trusted
Not enough to install certificates, they must be trusted in Keychain.app
     <https://support.apple.com/en-gb/guide/keychain-access/kyca11871/mac>
Error: "Warning: unable to build chain to self-signed root for signer"
      If certificate still"not valid" do not use "Always trust" but "Use System Defaults"

Intermediate signing certificate missing
https://www.apple.com/certificateauthority/
"Worldwide Developer Relations Certification Authority" or "Worldwide Developer Relations CA"
To use your certificates, you must have the intermediate signing certificate in your system keychain. This is automatically installed by Xcode. However, if you need to reinstall the intermediate signing certificate click the link below:
Worldwide Developer Relations Certificate Authority (Expiring 02/07/2023)
Worldwide Developer Relations Certificate Authority (Expiring 02/20/2030)
Worldwide Developer Relations - G4 (Expiring 12/10/2030) Developer ID - G2 (Expiring 09/17/2031)

Command line

For example:
codesign -d --keychain /Users/filhol/Library/Keychains/login.keychain --force --verbose -s "Developer ID Application: INSTITUT MAX VON LAUE - PAUL LANGEVIN (P65398CN49)" --entitlements Launcher.entitlements myTestApp.app

Codesign may refuse the certificat name in its string form if several certificactes have the same name. Below the workaround :

1- Cleanup files for resources and other detritus
    xattr -cr myTestApp.app
2- If codesign says "ambiguous certificate"
You probably have several valid certificates with the same name.
Get the hex identifier for the certificate you want to use by executing the command:
    security find-identity -p codesigning
   The code is machine dependent.
3- Codesign the application
--force: replace existing signature
--deep: sign frameworks, dylib, etc. even if not yet signed
--options runtime: binary hardening which is now compulsory
<certificate>: caution, not the same one for the App Store and for a notarized application distributed through a DMG.
    codesign -d --force --deep --options runtime --verbose=4 -s <certificate> myTestApp.app

Checking signatures and entitlements

For checking a bundle, use RB App Checker Lite.app or use the following command lines.

      $ codesign --verify --deep --strict --verbose=2 myApp.app -- mimics gatekeeper
      Error: a sealed resource is missing or invalid
      This means that one or more file listed in "_CodeSignature/CodeResources" is missing or has been modified.
      These resources are the whole list of files present in the folder containing the _CodeSignature folder.
      In other words, the lib or binary signature is not up-to-date, the context has changed since the last time it was signed.
      Warning: prior to Mavericks (10.9) the list of resources could be manually set using "codesign --resource-rules" but this is now deprecated or ignored.

      $ codesign -dvvv myApp.app
      $ codesign --display --verbose=4 myBinary

Test bundles, binaries, installer
      $ spctl --assess --continue --verbose=4 myApp.app -- strict but not talkative
      $ spctl -a -t open --continue --context context:primary-signature -vvvv myBundle_or_Binary -- rejects unnotarized bundles
      $ spctl -a -t execute --continue --context context:primary-signature -vvvv myBundle_or_Binary -- execute
      $ spctl -a -t install --continue --context context:primary-signature -vvvv myBundle_or_Binary -- installer

Entitlements
     $ codesign -d --entitlements :- Winteracter
          Executable=/Applications/TestAlert3-Xcode.app/Contents/MacOS/Winteracter
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
          <plist version="1.0">
          <dict/>           <--- This shows that the entitlement is missing
          </plist>

     $ codesign -d -v --entitlements :- $(pgrep <YourApp>)

     $ codesign -d --entitlements :- /path/to/executable
macOS 12
     $ codesign -d --entitlements - --xml /path/to/executable | plutil -convert xml1 -o - -

Packages
      pkgutil --check-signature /Path/to/Example.pkg

Removing signature ?
     undocumented option:  $ codesign --remove-signature HelloCodeSign.app
     https://github.com/steakknife/unsign
     https://github.com/alexzielenski/optool

Gatekeeper bypass
     $ sudo xattr -dr com.apple.quarantine /path/to/myAppName.app

"Resource fork, Finder information, or similar detritus not allowed"

The Apple answer to this codesign error is here: Technical Q&A QA1940.

This is a security hardening change that was introduced with iOS 10, macOS Sierra, watchOS 3, and tvOS 10.
Code signing no longer allows any file in an app bundle to have an extended attribute containing a resource fork or Finder info.
To see which files are causing this error, run this command in Terminal:
     xattr -lr <path_to_app_bundle>
You can also remove all extended attributes from your app bundle with the xattr command:
     xattr -cr <path_to_app_bundle>

Gatekeeper says "unidentified developer"

While XCode codesigned the application, Gatekeeper still complains "unidentified developer". Why ?

The bundle had the following organisation:
     MacOS folder
            a binary
            a shell script
     Resources folder
            32 auxiliary binaries

This was Okay with Xcode 7 but not with Xcode 8.
GateKeeper now says the App is from an “unidentified developer” while the Archive validation tool says the archive is Okay and Xcode 8 signed it as a “Developer ID-signed application" without complaining.

RB App Checker Lite.app identified the issue :
     33 binaries are signed by  “Apple Root CA”, “Developer ID Application: xxxxxxx”
     One executable is signed by  “Apple Root CA”, “Mac Developer: xxxxxx”    <— and this one is the shell script !
In other words, Xcode 8 wrongly used a different certificate for the script.

If the shell script is moved to the Resources folder, Xcode signs it with the right certificate.
Yes, having a script in the MacOS folder is strictly correct (TP40005929-CH4-TNTAG201, see below) however the Archive Validation Tool should have detected the mistake and Xcode 8 should not sign the app without complaining. This is a BUG.

More details
TP40005929-CH4-TNTAG201 says "put the files where they should be". Mach-O executables shouldn’t be in Contents/Resources; that’s where your shell script goes.

The system expects these locations to contain only code. When evaluating an app bundle’s code signature, the system will reject arbitrary data files found in these locations because they’re unsigned. Conversely, the code signing machinery considers anything not in one of these directories, including code, to be a resource. Any code not in one of these directories is therefore sealed twice: once as code, and once as a resource in the outer signature. This wastes both signing and verification time and storage space. Also, this can break the outer signature of apps that use their own update mechanisms to replace nested code. If this nested code is being treated as a resource, the outer signature doesn’t know that this nested content is actually code.

Do not use custom subdirectories inside the code nesting directories shown in Table 3-1. For example, place all your XPC services directly in the Contents/XPCServices directory. Do not organize them into subdirectories like Contents/XPCServices/Net and Contents/XPCServices/Math. Creating a custom directory hierarchy in one of these locations can break the code signing machinery, depending on the names of the subdirectories, and while it may appear to work in some cases, it is not a supported practice.

Store Python, Perl, shell, and other script files, and other non-Mach-O executables in your app’s Contents/Resources directory. While it’s possible to sign such executables and store them in Contents/MacOS, this is not recommended. This is because code signing uses extended attributes to store signatures in non-Mach-O executables such as script files. If the extended attributes are lost, the program’s signature will be broken. Many file transfer techniques do not preserve extended attributes, nor are they preserved when uploading to the Mac App Store. When you put the script in the Contents/Resources directory, codesign stores the associated signature in the Contents/_CodeSignature/CodeResources file, which is preserved. Thus, in practice, a properly signed app that has all of its files in the correct places does not contain any signatures stored as extended attributes.

Codesign says: "Warning: unable to build chain to self-signed root for signer ..."

from <https://developer.apple.com/forums/thread/86161>;
This worked for me !

Identifying the bad certificate:
From you Keychains select Login
From Category select Certificates
Find any Apple Certificate that has the blue +
Double click on the certificate.
Expand the Trust
If it's messed up then the "When using this certificate" is set to "Always Trust" along with the blue +
Fixing the bad certificate:
Just set it to "Use System Defaults" and close it.
You'll get a pop up. Type in your password to update settings.
Close KeyChain. Go back to your project, clean and run. Problem should have gone away.
If that didn't work then go back to Keychain and just double check and see if there are any other Apple certificates that are set to Always Trust and repeat the process.

Auxiliary binaries

See projects FullProf4Mac and Esmeralda4Mac

Nested bundles

See projects NeutronEncyclopedia, Takin and iFit

"A timestamp was expected but was not found"

Codesigning from inside the ILL now fails since the upgrade to Xcode 8.3.1 and the last "command line developer tools".

Both Xcode 8.3.1 and the terminal command “codesign” gives the error message:
     A timestamp was expected but was not found.
Both work perfectly if the proxy server is bypassed.

 “Wireshark.app” was used to analyse the network packets and we found that “codesign” superbly ignores the proxy. It tries to access Apple’s timestamp server (17.252.44.89, 17.252.44.94, etc.) directly.
The following commands:
    $ export http_proxy=“http://193.xx.yy.zz:8888"
    $ export https_proxy=“http://193.xx.yy.zz:8888"
marginally improves the situation; codesign has more transactions with the proxy but not enough to solve the case.

Is this a bug from Apple ? See next section

Segmentation fault 11

Xcode updated to 8.3.2
Codesign no longer complains for a timestamp but finds twice the same certificat and then gives the error "Segmentation fault: 11"

Get the hex identifier for your certificates executing this command:
    $ security find-identity -p codesigning
Then
    codesign -d --force --deep --verbose=4 -s <hex identifier> myApp.app

This solved both the timestamp en segmentation fault errors