Skip to content

Commit

Permalink
Simplify signing, enable notarization
Browse files Browse the repository at this point in the history
I have simplified signing and enabled notarization in docker
with rcodesign (a Rust-based tool, fully open-source; but it does connect to Apple servers for notarization).

This tool enables notarization and signing fully in Docker on any OS,
so it should work in CLI too.

There is some prep-work that needs to be done on Mac OS side and on Apple website;
but after that, the signing and notarization works automatically.

It's not directly relevant to this commit, but I think you can also use it on Trezor Suite;
a cursory glance there tells me that Trezor Suit is using electron-notarize, which needs to be run on Mac OS;
rcodesign does not need that.

Note that we need to use ldflags -s because of this issue of rcodesign
https://github.com/indygreg/PyOxidizer/issues/636
  • Loading branch information
igor-hnizdo committed Sep 7, 2022
1 parent d73dac0 commit 7bf4b21
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 25 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ release/linux/privkey.asc
release/linux/build/
release/macos/cert0*
release/macos/key.pem
release/macos/certs/installer.passphrase
release/macos/certs/installer.p12
release/macos/certs/app.passphrase
release/macos/certs/app.p12
release/macos/certs/notarization-key-id
release/macos/certs/notarization-issuer-id
release/macos/certs/notarization-authkey.p8
release/macos/build/
release/windows/authenticode.*
release/windows/build/
4 changes: 3 additions & 1 deletion release/macos/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ RUN dnf update -y

# install tools

RUN dnf install -y gcc gcc-c++ git make gzip cpio findutils autoconf libxml2-devel openssl-devel
RUN dnf install -y gcc gcc-c++ git make gzip cpio findutils autoconf libxml2-devel openssl-devel cargo

# build bomutils and xar from sources with fixes

Expand All @@ -17,3 +17,5 @@ RUN cd xar && cd xar && ./autogen.sh --noconfigure && ./configure && make && mak

RUN git clone https://github.com/BC-SECURITY/bomutils
RUN cd bomutils && CFLAGS="-fsigned-char" make && make install

RUN cargo install apple-codesign
6 changes: 4 additions & 2 deletions release/macos/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,21 @@ clean:
.binary:
$(info Building with crossbuild ...)
mkdir -p build
# we need to use ldflags because of this issue
# https://github.com/indygreg/PyOxidizer/issues/636
docker run -it --rm \
-v $(IMPORT_PATH):/trezord \
-w /trezord \
-e CGO_ENABLED=1 \
docker.elastic.co/beats-dev/golang-crossbuild:1.19-darwin-debian10 \
--build-cmd "go build -o release/macos/build/trezord-amd64" \
--build-cmd "go build -o release/macos/build/trezord-amd64 -ldflags=-s" \
-p "darwin/amd64"
docker run -it --rm \
-v $(IMPORT_PATH):/trezord \
-w /trezord \
-e CGO_ENABLED=1 \
docker.elastic.co/beats-dev/golang-crossbuild:1.19-darwin-arm64-debian10 \
--build-cmd "go build -o release/macos/build/trezord-arm64" \
--build-cmd "go build -o release/macos/build/trezord-arm64 -ldflags=-s" \
-p "darwin/arm64"
docker run -it --rm \
-v $(IMPORT_PATH):/trezord \
Expand Down
Empty file added release/macos/certs/.empty
Empty file.
88 changes: 66 additions & 22 deletions release/macos/release.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
#!/bin/sh

# In order to get the necessary files for signing and notarization, we need to do a lot of work:
# 1) register as Apple developer, get signing certificate from Apple
# (can take months for organizations; it is fast for individuals, but costs money)
# 2) On Mac, install XCode, generate certificates with type "Developer ID Installer"
# 3) On Mac, still in XCode, right-click in on the cert and select "export", That creates installer.p12 file (with passphrase)
# 4) Put the file to installer.p12 in certs/ dir, so as `certs/installer.p12``
# 5) Put the passphrase to certs/installer.passphrase (without newline at the end)
# 6) Then do the same, but with type "Developer ID Application"
# 7) Put those to certs/app.passphrase and certs/app.p12
#
# You will need App Store Connect API. To do that:
# 8) Go to https://appstoreconnect.apple.com/access/api
# 9) Select a user
# 10) Click on "keys", "Request access", "agree", "submit", "gereate API key"
# 11) Select "Developer" role, "Generate"
# 12) you will need to save "Issuer ID", "Key ID" and the API key (which will be PEM)
# 13) now, save
# a) issuer ID to "certs/notarization-issuer-id"
# b) key ID to "certs/notarization-key-id"
# c) key to "certs/notarization-authkey.p8"

# In all, there should be those 8 files in certs
# 1. installer.passphrase
# 2. installer.p12
# 3. app.passphrase
# 4. app.p12
# 5. notarization-authkey.p8
# 6. notarization-issuer-id
# 7. notarization-key-id
# 8. .empty (invisible file to keep folder in git)




# Recommended reading for flat packages:
# https://matthew-brett.github.io/docosx/flat_packages.html
# http://bomutils.dyndns.org/tutorial.html
Expand All @@ -9,6 +43,12 @@

set -ex

PATH=$PATH:~/.cargo/bin
SIGN_APP_PASSPHRASE_F=/release/certs/app.passphrase
SIGN_APP_CERT=/release/certs/app.p12
SIGN_INSTALLER_PASSPHRASE_F=/release/certs/installer.passphrase
SIGN_INSTALLER_CERT=/release/certs/installer.p12

cd $(dirname $0)

TARGET=$1
Expand Down Expand Up @@ -47,6 +87,11 @@ cd ..

rm -rf /release/build/flat-uninstall

if [ -r $SIGN_INSTALLER_PASSPHRASE_F ]; then
rcodesign sign --p12-file $SIGN_INSTALLER_CERT --p12-password-file $SIGN_INSTALLER_PASSPHRASE_F uninstall.pkg
fi


# second, make installer and add trezord and uninstaller

rm -rf /release/build/flat-install
Expand All @@ -60,6 +105,10 @@ rm -r scripts
mv Scripts-zip Scripts
cd payload

if [ -r $SIGN_INSTALLER_APP_F ]; then
rcodesign sign --p12-file $SIGN_APP_CERT --p12-password-file $SIGN_APP_PASSPHRASE_F --code-signature-flags runtime /release/build/trezord
fi

cp /release/build/trezord Applications/Utilities/TREZOR\ Bridge/
cp ../../../uninstall.pkg Applications/Utilities/TREZOR\ Bridge/

Expand Down Expand Up @@ -87,29 +136,24 @@ rm uninstall.pkg

mv install.pkg $INSTALLER

# In order to get the necessary files for signing, do the following:
# 1) register as Apple developer, get signing certificate from Apple (can take months)
# 2) On Mac, install XCode, generate certificates with type "Developer ID Installer"
# 3) On Mac, still in XCode, right-click in on the cert and select "export", That creates cert.p12 file (with passphrase)
# 4) On Mac, do `productsign --sign 'Developer ID Installer: YourDeveloperId' 'unsigned-package.pkg' 'signed-package.pkg'`
# where YourDeveloperId is your developer ID and unsigned-package is an unsigned package (this needs to be done only once)
# 5) Copy the cert.p12 and signed-package.pkg to Linux
# 6) On linux, do `mkdir certs ; xar -f signed-package.pkg --extract-certs certs`, that puts cert00, cert01 and cert02 in the certs dir
# 7) On linux, do `openssl pkcs12 -in cert.p12 -nodes | openssl rsa -out key.pem`, that creates key.pem

# The cert00, cert01 and cert02 files can now be used for pkg signing.
# sign the installer

if [ -r $SIGN_INSTALLER_PASSPHRASE_F ]; then
rcodesign sign --p12-file $SIGN_INSTALLER_CERT --p12-password-file $SIGN_INSTALLER_PASSPHRASE_F $INSTALLER
fi

# sign the installer
PRIVKEY=/release/key.pem
if [ -r $PRIVKEY ]; then
SIGNLEN=$(: | openssl dgst -sign $PRIVKEY -binary | wc -c)
xar --sign -f $INSTALLER --digestinfo-to-sign digestinfo.dat \
--sig-size $SIGNLEN \
--cert-loc /release/cert00 \
--cert-loc /release/cert01 \
--cert-loc /release/cert02
openssl rsautl -sign -inkey $PRIVKEY -in digestinfo.dat -out signature.dat
xar --inject-sig signature.dat -f $INSTALLER
rm -f signature.dat digestinfo.dat
NOT_KEY_ID_F=/release/certs/notarization-key-id
NOT_ISSUER_ID_F=/release/certs/notarization-issuer-id
NOT_AUTHKEY=/release/certs/notarization-authkey.p8
if [ -r $NOT_KEY_ID_F ]; then
NOT_KEY_ID=$(cat $NOT_KEY_ID_F)
NOT_ISSUER_ID=$(cat $NOT_ISSUER_ID_F)
NOT_JSON=not-data.json
rcodesign encode-app-store-connect-api-key -o $NOT_JSON $NOT_ISSUER_ID $NOT_KEY_ID $NOT_AUTHKEY
rcodesign notary-submit \
--api-key-path $NOT_JSON \
--staple \
$INSTALLER
rm $NOT_JSON
fi

0 comments on commit 7bf4b21

Please sign in to comment.