Skip to content

Commit

Permalink
Add notarize target to the makefile.
Browse files Browse the repository at this point in the history
Added `notarize` target, with a chain of targets working backwards:

    notarize --> stapled.stamp.txt --> notarized.stamp.txt -->
        notarization-log.json --> submission-id.txt -->
        submit-log.json --> xz-$(version).pkg

Added the overridable makefile variable `NOTARIZATION_KEYCHAIN_PROFILE`
to point to the notarization credentials.

Added missing codesigning steps for the libraries `liblzma.a` and
`liblzma.5.dylib`.

Added additional steps to the `check` target to verify the libraries.

Updated the readme file with a "Prerequisites" section, info on the
`NOTARIZATION_KEYCHAIN_PROFILE` variable, a description of the
`notarize` target and a section on signing and notarization credentials.
  • Loading branch information
donmccaughey committed Oct 27, 2021
1 parent a913a32 commit 283daea
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 6 deletions.
53 changes: 52 additions & 1 deletion Makefile
@@ -1,5 +1,6 @@
APP_SIGNING_ID ?= Developer ID Application: Donald McCaughey
INSTALLER_SIGNING_ID ?= Developer ID Installer: Donald McCaughey
NOTARIZATION_KEYCHAIN_PROFILE ?= Donald McCaughey
TMP ?= $(abspath tmp)

version := 5.2.5
Expand All @@ -14,6 +15,10 @@ archs := arm64 x86_64
all : xz-$(version).pkg


.PHONY : notarize
notarize : $(TMP)/stapled.stamp.txt


.PHONY : clean
clean :
-rm -f xz-*.pkg
Expand All @@ -26,10 +31,14 @@ check :
test "$(shell lipo -archs $(TMP)/install/usr/local/bin/lzmainfo)" = "x86_64 arm64"
test "$(shell lipo -archs $(TMP)/install/usr/local/bin/xz)" = "x86_64 arm64"
test "$(shell lipo -archs $(TMP)/install/usr/local/bin/xzdec)" = "x86_64 arm64"
test "$(shell lipo -archs $(TMP)/install/usr/local/lib/liblzma.a)" = "x86_64 arm64"
test "$(shell lipo -archs $(TMP)/install/usr/local/lib/liblzma.5.dylib)" = "x86_64 arm64"
codesign --verify --strict $(TMP)/install/usr/local/bin/lzmadec
codesign --verify --strict $(TMP)/install/usr/local/bin/lzmainfo
codesign --verify --strict $(TMP)/install/usr/local/bin/xz
codesign --verify --strict $(TMP)/install/usr/local/bin/xzdec
codesign --verify --strict $(TMP)/install/usr/local/lib/liblzma.a
codesign --verify --strict $(TMP)/install/usr/local/lib/liblzma.5.dylib
pkgutil --check-signature xz-$(version).pkg
spctl --assess --type install xz-$(version).pkg
xcrun stapler validate xz-$(version).pkg
Expand Down Expand Up @@ -92,6 +101,20 @@ $(TMP)/xzdec-signed.stamp.txt : $(TMP)/install/usr/local/bin/xzdec | $$(dir $$@
$<
date > $@

$(TMP)/liblzma.a-signed.stamp.txt : $(TMP)/install/usr/local/lib/liblzma.a | $$(dir $$@)
xcrun codesign \
--sign "$(APP_SIGNING_ID)" \
--options runtime \
$<
date > $@

$(TMP)/liblzma.5.dylib-signed.stamp.txt : $(TMP)/install/usr/local/lib/liblzma.5.dylib | $$(dir $$@)
xcrun codesign \
--sign "$(APP_SIGNING_ID)" \
--options runtime \
$<
date > $@

$(TMP)/xz.pkg : \
$(TMP)/install/etc/paths.d/xz.path \
$(TMP)/install/usr/local/bin/uninstall-xz \
Expand All @@ -102,7 +125,9 @@ $(TMP)/xz.pkg : \
$(TMP)/lzmadec-signed.stamp.txt \
$(TMP)/lzmainfo-signed.stamp.txt \
$(TMP)/xz-signed.stamp.txt \
$(TMP)/xzdec-signed.stamp.txt
$(TMP)/xzdec-signed.stamp.txt \
$(TMP)/liblzma.a-signed.stamp.txt \
$(TMP)/liblzma.5.dylib-signed.stamp.txt
pkgbuild \
--root $(TMP)/install \
--identifier cc.donm.pkg.xz \
Expand Down Expand Up @@ -192,3 +217,29 @@ $(TMP) \
$(TMP)/resources :
mkdir -p $@


##### notarization ##########

$(TMP)/submit-log.json : xz-$(version).pkg | $$(dir $$@)
xcrun notarytool submit $< \
--keychain-profile "$(NOTARIZATION_KEYCHAIN_PROFILE)" \
--output-format json \
--wait \
> $@

$(TMP)/submission-id.txt : $(TMP)/submit-log.json | $$(dir $$@)
jq --raw-output '.id' < $< > $@

$(TMP)/notarization-log.json : $(TMP)/submission-id.txt | $$(dir $$@)
xcrun notarytool log "$$(<$<)" \
--keychain-profile "$(NOTARIZATION_KEYCHAIN_PROFILE)" \
$@

$(TMP)/notarized.stamp.txt : $(TMP)/notarization-log.json | $$(dir $$@)
test "$$(jq --raw-output '.status' < $<)" = "Accepted"
date > $@

$(TMP)/stapled.stamp.txt : xz-$(version).pkg $(TMP)/notarized.stamp.txt
xcrun stapler staple $<
date > $@

69 changes: 64 additions & 5 deletions README.md
Expand Up @@ -7,8 +7,21 @@ the source distribution for XZ Utils 5.2.5.

[1]: http://tukaani.org/xz/ "XZ Utils"

## Prerequesites

A recent version of Xcode and the [`jq`][2] command are needed to build and
notarize this installer package. An [Apple Developer][3] account is required
to generate the credentials needed to sign and notarize.

Building was last tested on an Apple Silicon Mac with macOS Big Sur 11.6 and
Xcode 13. Installation was last tested on both Intel and Apple Silicon Macs
running Big Sur.

[2]: https://stedolan.github.io/jq/
[3]: https://developer.apple.com

## Building
The [`Makefile`][2] in the project root directory builds the installer package.
The [`Makefile`][4] in the project root directory builds the installer package.
The following makefile variables can be set from the command line:

- `APP_SIGNING_ID`: The name of the
Expand All @@ -17,27 +30,73 @@ The following makefile variables can be set from the command line:
machine's Keychain. Defaults to "Developer ID Application: Donald
McCaughey" if not specified.
- `INSTALLER_SIGNING_ID`: The name of the
[Apple _Developer ID Installer_ certificate][3] used to sign the
[Apple _Developer ID Installer_ certificate][5] used to sign the
installer. The certificate must be installed on the build machine's
Keychain. Defaults to "Developer ID Installer: Donald McCaughey" if
not specified.
- `NOTARIZATION_KEYCHAIN_PROFILE`: The name of the notarization credentials
stored on the build machine's Keychain. Use the `notarytool
store-credentials` command to create this profile. Defaults to "Donald
McCaughey" if not specified.
- `TMP`: The name of the directory for intermediate files. Defaults to
"`./tmp`" if not specified.

[2]: https://github.com/donmccaughey/pkg-config_pkg/blob/master/Makefile
[3]: https://developer.apple.com/account/resources/certificates/list
[4]: https://github.com/donmccaughey/xz_pkg/blob/master/Makefile
[5]: https://developer.apple.com/account/resources/certificates/list

To build and sign the executable and installer, run:

$ make [APP_SIGNING_ID="<cert name 1>"] [INSTALLER_SIGNING_ID="<cert name 2>"] [TMP="<build dir>"]

Intermediate files are generated in the temp directory; the signed installer
package is written into the project root with the name `pkg-config-0.29.2.pkg`.
package is written into the project root with the name `xz-5.2.5.pkg`.

To notarize the signed installer package, run:

$ make notarize [NOTARIZATION_KEYCHAIN_PROFILE="<profile name>"] [TMP="<build dir>"]

This will submit the installer package for notarization and staple it on
success. Check the file `$(TMP)/notarization-log.json` for detailed
information if notarization fails. The signed installer is stapled in place
if notarization succeeds. Use the command:

$ xcrun stapler validate --verbose xz-5.2.5.pkg

to check the notarization state of the installer package.

To remove all generated files (including the signed installer), run:

$ make clean

## Signing and Notarizing Credentials

Three sets of credentials are needed to sign and notarize this package:
- A "Developer ID Application" certificate (for signing the `nginx` executable)
- A "Developer ID Installer" certificate (for signing the installer package)
- An App Store Connect API key (for notarizing the signed installer)

The two certificates are obtained from the [Apple Developer portal][6]; use the
[Keychain Access app][7] to create the certificate signing requests. Add the
certificates to the build machine's Keychain.

The App Store Connect API key is obtained from the [App Store Connect site][8].
After the key is created, get the _Issuer ID_ (a UUID), the _Key ID_
(an alphanumeric string) and download the API key, which comes as a file named
`AuthKey_<key id>.p8`. To add the API key to the build machine's Keychain,
use the `store-credentials` subcommand of `notarytool`:

$ xcrun notarytool store-credentials "<keychain profile name>" \
--key ~/.keys/AuthKey_<key id>.p8 \
--key-id <key id> \
--issuer <issuer id> \
--sync

The `--sync` option adds the credentials to the user's iCloud Keychain.

[6]: https://developer.apple.com/account/resources/certificates/add
[7]: https://help.apple.com/developer-account/#/devbfa00fef7
[8]: https://appstoreconnect.apple.com/access/api

## License

The installer and related scripts are copyright (c) 2021 Don McCaughey.
Expand Down

0 comments on commit 283daea

Please sign in to comment.