Add code-signing scripts and encrypted keychain
Signed-off-by: George Lipov <gnl@lipov.net>
This commit is contained in:
parent
bd3f9570b3
commit
fe822e5bc8
|
@ -201,7 +201,16 @@ def bundleMacOS(type = 'nightly') {
|
|||
-qmldir='${workspace}/node_modules/react-native/ReactQt/runtime/src/qml/'
|
||||
"""
|
||||
sh 'rm -f Status.app.zip'
|
||||
sh "../node_modules/appdmg/bin/appdmg.js ../deployment/macos/status-dmg.json ${pkg}"
|
||||
|
||||
withCredentials([
|
||||
string(credentialsId: 'desktop-gpg-outer-pass', variable: 'GPG_PASS_OUTER'),
|
||||
string(credentialsId: 'desktop-gpg-inner-pass', variable: 'GPG_PASS_INNER'),
|
||||
string(credentialsId: 'desktop-keychain-pass', variable: 'KEYCHAIN_PASS')
|
||||
]) {
|
||||
sh '../scripts/sign-macos-pkg.sh Status.app ../deployment/macos/macos-developer-id.keychain-db.gpg'
|
||||
sh "../node_modules/appdmg/bin/appdmg.js ../deployment/macos/status-dmg.json ${pkg}"
|
||||
sh "../scripts/sign-macos-pkg.sh ${pkg} ../deployment/macos/macos-developer-id.keychain-db.gpg"
|
||||
}
|
||||
}
|
||||
return "${packageFolder}/${pkg}".drop(2)
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
KEYCHAIN="$1"
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo -e "encrypt-keychain.sh <path to keychain>"
|
||||
exit 10
|
||||
elif [ ! -f "$KEYCHAIN" ]; then
|
||||
echo -e "Keychain file does not exist."
|
||||
exit 20
|
||||
fi
|
||||
|
||||
INNER_CIPHER="CAMELLIA256"
|
||||
OUTER_CIPHER="AES256"
|
||||
|
||||
echo -e "\n### Double-encrypting ${KEYCHAIN}. Enter first inner, then outer passphrase..."
|
||||
gpg --symmetric --cipher-algo "$INNER_CIPHER" --s2k-digest-algo SHA256 --s2k-count 65011712 "${KEYCHAIN}"
|
||||
gpg --symmetric --cipher-algo "$OUTER_CIPHER" --s2k-digest-algo SHA256 --s2k-count 65011712 "${KEYCHAIN}.gpg"
|
||||
mv -f "${KEYCHAIN}.gpg.gpg" "${KEYCHAIN}.gpg"
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [ `uname` == 'Darwin' ]; then
|
||||
echo "
|
||||
Uh oh. We seem to be on macOS where I don't know how to bypass the
|
||||
PRNG and can't guarantee the entropy of the data. Run this on Linux or
|
||||
BSD, or use 'pwgen --secure 86' instead if using a PRNG is acceptable.
|
||||
"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "
|
||||
Generating random passphrases with 512 bits of entropy and a length
|
||||
of 86 characters, intended for publicly hosted private keys. This is
|
||||
total overkill even for AES-256, but we want some headroom if the RNG
|
||||
is less than perfect and they aren't meant for human memorisation.
|
||||
|
||||
If this hangs, move the mouse around, type into a different window and do
|
||||
some disk and network I/O to generate additional noise for the entropy pool.
|
||||
|
||||
When done, intersperse some random characters of your choice throughout the
|
||||
passphrases.
|
||||
"
|
||||
for PASS in INNER OUTER KEYCHAIN; do
|
||||
echo "$PASS"
|
||||
head -c 64 /dev/random | base64 | head -c 86
|
||||
echo -e "\n"
|
||||
done
|
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
DEV_ID="Developer ID Application: STATUS HOLDINGS PTE. LTD. (DTX7Z4U3YA)"
|
||||
|
||||
OBJECT="$1"
|
||||
GPG_ENCRYPTED_KEYCHAIN="$2"
|
||||
|
||||
if [ `uname` != 'Darwin' ]; then
|
||||
echo "This only works on macOS."
|
||||
exit 1
|
||||
elif [ $# -ne 2 ]; then
|
||||
echo "sign-macos-bundle.sh <path to .app bundle or .dmg image> <path to encrypted keychain>"
|
||||
exit 1
|
||||
elif [ ! -e "$OBJECT" ]; then
|
||||
echo "Object does not exist."
|
||||
exit 1
|
||||
elif [ ! -f "$GPG_ENCRYPTED_KEYCHAIN" ]; then
|
||||
echo "Encrypted keychain file does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Required env variables:
|
||||
|
||||
export GPG_PASS_OUTER
|
||||
export GPG_PASS_INNER
|
||||
export KEYCHAIN_PASS
|
||||
|
||||
[ -z "$GPG_PASS_OUTER" ] && echo 'Missing env var: GPG_PASS_OUTER' && exit 1
|
||||
[ -z "$GPG_PASS_INNER" ] && echo 'Missing env var: GPG_PASS_INNER' && exit 1
|
||||
[ -z "$KEYCHAIN_PASS" ] && echo 'Missing env var: KEYCHAIN_PASS' && exit 1
|
||||
|
||||
# If GPG hasn't been run on this host before, we run it once
|
||||
# quietly to make sure it creates the directories it needs first
|
||||
# and doesn't trip when trying to do the decryption further down
|
||||
script -q /dev/null gpg < /dev/null > /dev/null
|
||||
|
||||
set -e
|
||||
|
||||
echo -e "\n### Storing original keychain search list..."
|
||||
ORIG_KEYCHAIN_LIST="$(security list-keychains \
|
||||
| grep -v "/Library/Keychains/System.keychain" | xargs)"
|
||||
|
||||
echo -e "\n### Creating ramdisk..."
|
||||
RAMDISK="$(hdiutil attach -nomount ram://20480 | tr -d '[:blank:]')"
|
||||
MOUNTPOINT="$(mktemp -d)"
|
||||
KEYCHAIN="${MOUNTPOINT}/macos-developer-id.keychain-db"
|
||||
|
||||
function clean_up {
|
||||
local STATUS=$?
|
||||
|
||||
set +e
|
||||
|
||||
if [ $STATUS -eq 0 ]; then
|
||||
echo -e "\n###### DONE."
|
||||
else
|
||||
echo -e "\n###### ERROR. See above for details."
|
||||
fi
|
||||
|
||||
echo -e "\n###### Cleaning up..."
|
||||
|
||||
echo -e "\n### Locking keychain..."
|
||||
security lock-keychain "$KEYCHAIN"
|
||||
|
||||
echo -e "\n### Restoring original keychain search list..."
|
||||
security list-keychains -s $ORIG_KEYCHAIN_LIST
|
||||
security list-keychains
|
||||
|
||||
echo -e "\n### Wiping keychain file..."
|
||||
rm -P "$KEYCHAIN"
|
||||
|
||||
echo -e "\n### Destroying ramdisk..."
|
||||
diskutil umount force "$RAMDISK"
|
||||
diskutil eject "$RAMDISK"
|
||||
|
||||
exit $STATUS
|
||||
}
|
||||
|
||||
trap clean_up EXIT
|
||||
|
||||
echo -e "\n### Formatting and mounting ramdisk..."
|
||||
newfs_hfs "$RAMDISK"
|
||||
mount -t hfs "$RAMDISK" "$MOUNTPOINT"
|
||||
|
||||
echo -e "\n### Decrypting keychain to $KEYCHAIN ..."
|
||||
gpg --batch --passphrase "$GPG_PASS_OUTER" --pinentry-mode loopback \
|
||||
--decrypt "$GPG_ENCRYPTED_KEYCHAIN" \
|
||||
| gpg --batch --passphrase "$GPG_PASS_INNER" --pinentry-mode loopback \
|
||||
--decrypt > "$KEYCHAIN"
|
||||
|
||||
echo -e "\n### Adding code-signing keychain to search list..."
|
||||
security list-keychains -s $ORIG_KEYCHAIN_LIST "$KEYCHAIN"
|
||||
security list-keychains
|
||||
|
||||
echo -e "\n### Unlocking keychain..."
|
||||
security unlock-keychain -p "$KEYCHAIN_PASS" "$KEYCHAIN"
|
||||
|
||||
echo -e "\n### Signing object..."
|
||||
|
||||
# If `OBJECT` is a directory, we assume it's an app
|
||||
# bundle, otherwise we consider it to be a dmg.
|
||||
if [ -d "$OBJECT" ]; then
|
||||
codesign --sign "$DEV_ID" --deep --force --verbose=4 "$OBJECT"
|
||||
else
|
||||
codesign --sign "$DEV_ID" --force --verbose=4 "$OBJECT"
|
||||
fi
|
||||
|
||||
echo -e "\n### Verifying signature..."
|
||||
codesign --verify --strict=all --deep --verbose "$OBJECT"
|
||||
|
||||
echo -e "\n### Assessing Gatekeeper validation..."
|
||||
if [ -d "$OBJECT" ]; then
|
||||
spctl --assess --type execute --verbose=2 "$OBJECT"
|
||||
else
|
||||
spctl --assess --type open --context context:primary-signature --verbose=2 "$OBJECT"
|
||||
fi
|
Loading…
Reference in New Issue