How to check signatures on apps, installers, and packages

In case you haven’t noticed yet, the signing certificates on all Apple’s installers prior to mid-October have just expired. This article tackles the thorny question of how you can check whether an installer or other code is still good to use, or its certificates have expired or been revoked. Unfortunately, the answer is far from simple.

macOS error messages

Error messages which result from trying to run a recent macOS installer app with expired certificates are highly confusing:

codesign01

If you want to find out what’s really wrong, or check an installer without running it, you’ll need a utility or command tool.

Check apps

There are several GUI apps which can check the code signatures of apps. Max Inspect from the App Store is aimed primarily at developers, but can run full Gatekeeper checks on apps (and only apps) at the click of a button.

codesign02

My free tool Taccy runs two different checks on signatures, and its latest version (1.5) also works on Installer packages thoroughly. The error message it reports on an expired installer, for instance, reports that signature validation was rejected because “the resource envelope is obsolete”. It turns out this is irrelevant in this case: most or all of Apple’s installer apps fail its own signature checks in this way! To discover whether they have expired certificates, you need to inspect Installer packages contained within them.

If you want to check whole folders of apps and other executable code, my free tool Signet does that, and reports more specific errors. In this case,
Install macOS Mojave.app error -67013 resource envelope is obsolete (custom omit rules)
which is as confusing as that given in the Finder!

Taking to the command line, there are two options, codesign and spctl. Both commands are complex, and need particular care to perform validation.

Using codesign, a command like
codesign -dvvv /Users/hoakley/Documents/TaccyHard.app
returns a goodly paragraph of information. Within it are four relevant lines
CodeDirectory v=20500 size=3074 flags=0x10000(runtime) hashes=87+5 location=embedded
has a flags value which indicates the app has been hardened, and
Authority=Developer ID Application: Howard Oakley (QWY4LRW926)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Signed Time=7 Sep 2019 at 09:25:12
give you details of the certificate authorities and the time of signing, but don’t actually verify the signature.

For that, you’ll need to use
codesign -v Install\ macOS\ Mojave.app
which retuns the terse and misleading result
resource envelope is obsolete (custom omit rules)

To validate signatures using spctl, use a command like
spctl -a -vv /Users/hoakley/Documents/MyApp.app
which should return something like
/Users/hoakley/Documents/MyApp.app: accepted
source=Developer ID
origin=Developer ID Application: Howard Oakley (QWY4LRW926)

In the case of the expired Apple installer, you’ll see the same misleading error as that from codesign:
Install macOS Mojave.app: rejected (resource envelope is obsolete (custom omit rules))
origin=Software Signing

which is the same as that reported by Taccy.

Check command tools

Of the GUI apps, only Signet can check signatures on command tools, as far as I’m aware.

In Terminal, results are essentially identical to those for apps, using spctl or the correct codesign command to validate certificates properly.

Check Installer packages

A simple way to check each package is to open it in the Installer app and click on the padlock tool at the upper right of the window to inspect its signatures.

codesign03

If you already use Suspicious Package, that will perform the same checks, and deliver the same results, as well as doing a great deal more, of course.

codesign04

The latest version of Taccy (1.5) now checks packages thoroughly, and in this case reports that it’s “signed by a certificate that has since expired.” It also reveals the Certificate Chain, in which both the Software Update and Apple Software Update CA certificates have now expired.

In Terminal, codesign doesn’t appear to have any means of checking Installer packages, and the equivalent spctl command to that used on apps,
spctl -a -vv -t install macOSUpd10.14.1.pkg
doesn’t perform the same certificate check as it does for apps, and doesn’t notice that two certificates in the package have expired:
/Users/hoakley/Documents/macOSUpd10.14.1.pkg: accepted
source=Apple Installer
origin=Software Update

However, if you use pkgutil instead, in
pkgutil --check-signature macOSUpd10.14.1.pkg
this does perform validation and report the most informative result of all:
Package "macOSUpd10.14.1.pkg":
Status: signed by a certificate that has since expired

followed by the certificate chain. Unfortunately, pkgutil doesn’t appear able to check notarization, at least in Mojave, for which spctl is still required.

Summary

The best ways to check certificate validity are:

  • for apps – Max Inspect, Taccy 1.5, Signet, or spctl -a -vv;
  • for command tools – Signet or spctl -a -vv;
  • for Installer packages – Installer, Suspicious Package, Taccy 1.5, or pkgutil --check-signature, plus spctl -a -vv -t install to check notarization;
  • beware of codesign, which yields other valuable information about signatures, notarization, and hardening, but needs different options to check certificate validity properly.

Tools to check code signatures are like a patchwork quilt, rather than the product of coherent design.

Update

Version 1.6 of Taccy is now available from Downloads above, from its Product Page, and through its auto-update feature. It checks certificate validity on both apps and packages (but not command tools), and can readily tell you which Apple installers and updaters have expired certificates. I will give more details tomorrow morning. If you’ve got many installers to check, you might like to try this new version, as it should save you a lot of effort.

If you want to use Taccy 1.6 to check an installer app’s validity, please read this post which explains a pitfall in doing so, and how to get it right.

Updated 2030 UTC 26 October 2019.