OXYGENHUB
◆ v0.1.7 oxygenhub-android / scripts / release-check.sh
3.5 KiB · Bourne Again Shell (bash) · executable · last changed release-check says why keytool cannot open the keystore (refs #7) 7 days ago source blame history raw
1
#!/usr/bin/env bash
2
# The release's secrets checked without a build (#7), by the release-check
3
# job in seconds and by scripts/release.sh before its own: the keystore's
4
# SHA-256 and the entry its password opens (compare with the keystore you
5
# hold: `sha256sum FILE`, `keytool -list`), and that Firebase's settings
6
# are whole JSON. Never prints a key, a password or the settings.
7
#   KEYSTORE_B64=path PASSWORD_FILE=path [FIREBASE_CONFIG=path] scripts/release-check.sh
8
set -euo pipefail
9
b64=${KEYSTORE_B64:-/run/secrets/android-keystore}
10
password=${PASSWORD_FILE:-/run/secrets/android-keystore-password}
11
firebase=${FIREBASE_CONFIG:-/run/secrets/firebase-config}
12
for f in "$b64" "$password"; do
13
    [ -s "$f" ] || { echo "release-check: no $f: the job needs the android-keystore secrets" >&2; exit 1; }
14
done
15
16
keys=$(mktemp -d)
17
trap 'rm -rf "$keys"' EXIT
18
chmod 700 "$keys"
19
base64 -d "$b64" > "$keys/release.p12" || { echo "release-check: the android-keystore secret is not base64 (base64 -w0 FILE.p12)" >&2; exit 1; }
20
echo "release-check: keystore sha256 $(sha256sum < "$keys/release.p12" | cut -d' ' -f1)"
21
keytool=$(command -v keytool || (ls /opt/gradle-home/jdks/*/bin/keytool 2>/dev/null || true) | head -1)
22
if [ -z "$keytool" ]; then
23
    echo "release-check: no keytool here, so the password is not checked" >&2
24
else
25
    # As the build reads it: the whole file, trimmed.
26
    tr -d '\r' < "$password" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | head -c 4096 > "$keys/pass"
27
    if ! "$keytool" -list -keystore "$keys/release.p12" -storetype PKCS12 -storepass:file "$keys/pass" > "$keys/list" 2>&1; then
28
        # keytool's own reason (it never prints the password).
29
        echo "release-check: keytool cannot open the keystore: $(grep -m1 -i 'error\|exception' "$keys/list" | head -c 300)" >&2
30
        exit 1
31
    fi
32
    grep -E 'PrivateKeyEntry|SHA-256\)' "$keys/list" || { echo "release-check: the keystore holds no private key" >&2; exit 1; }
33
    "$keytool" -list -keystore "$keys/release.p12" -storetype PKCS12 -storepass:file "$keys/pass" 2>/dev/null | grep -q '^oxygenhub,' \
34
        || { echo "release-check: the keystore has no entry named oxygenhub, which the build signs with" >&2; exit 1; }
35
    # Signing reads the private key with the same password: a request for a
36
    # certificate uses the key, so it fails just as signing would.
37
    "$keytool" -certreq -alias oxygenhub -keystore "$keys/release.p12" -storetype PKCS12 \
38
        -storepass:file "$keys/pass" -keypass:file "$keys/pass" > /dev/null 2> "$keys/certreq.err" \
39
        || { echo "release-check: the key oxygenhub cannot be read with the keystore's password, as signing needs: $(head -c 300 "$keys/certreq.err")" >&2; exit 1; }
40
    echo "release-check: the key oxygenhub opens with the password"
41
    if [ "$(wc -l < "$password")" -gt 1 ]; then
42
        echo "release-check: the password secret has more than one line; the build reads all of it" >&2
43
    fi
44
fi
45
46
if [ -s "$firebase" ]; then
47
    if command -v python3 > /dev/null; then
48
        python3 -I -c 'import json,sys; json.load(open(sys.argv[1]))' "$firebase" 2>/dev/null \
49
            || { echo "release-check: the firebase-config secret is not whole JSON (is its last } missing?)" >&2; exit 1; }
50
    elif [ "$(tr -d '[:space:]' < "$firebase" | tail -c 1)" != "}" ]; then
51
        echo "release-check: the firebase-config secret does not end with } (is its last line missing?)" >&2
52
        exit 1
53
    fi
54
    echo "release-check: firebase-config reads as JSON"
55
else
56
    echo "release-check: no $firebase: a release takes no alerts" >&2
57
fi
58
echo "release-check: ok"