Last active 1 month ago

admin revised this gist 1 month ago. Go to revision

2 files changed, 150 insertions

create_cert.sh(file created)

@@ -0,0 +1,75 @@
1 + #!/usr/bin/env bash
2 + # create_cert.sh — creates a local self-signed Mac code-signing certificate
3 + # Run once. Requires no Apple Developer account.
4 +
5 + set -euo pipefail
6 +
7 + CERT_NAME="${1:-"Local Mac Developer"}"
8 + KEYCHAIN_NAME="build.keychain"
9 + KEYCHAIN_PASS="keychain_pass" # change this
10 + P12_PASS="p12_pass" # change this
11 +
12 + echo "==> Creating build keychain: $KEYCHAIN_NAME"
13 +
14 + security delete-keychain "$KEYCHAIN_NAME" 2>/dev/null || true
15 + security create-keychain -p "$KEYCHAIN_PASS" "$KEYCHAIN_NAME" 2>/dev/null || true
16 + security set-keychain-settings -lut 21600 "$KEYCHAIN_NAME" # lock after 6 h
17 + security unlock-keychain -p "$KEYCHAIN_PASS" "$KEYCHAIN_NAME"
18 +
19 + # Add to keychain search list so tools can find it
20 + security list-keychains -d user -s "$KEYCHAIN_NAME" $(security list-keychains -d user | tr -d '"')
21 +
22 + echo "==> Generating self-signed certificate: '$CERT_NAME'"
23 + # Use Keychain Access UI approach (most reliable for self-signed)
24 + cat >/tmp/cert_req.cfg <<EOF
25 + [ req ]
26 + default_bits = 2048
27 + prompt = no
28 + default_md = sha256
29 + distinguished_name = dn
30 + x509_extensions = v3_req
31 +
32 + [ dn ]
33 + CN = $CERT_NAME
34 +
35 + [ v3_req ]
36 + keyUsage = digitalSignature
37 + extendedKeyUsage = codeSigning
38 + EOF
39 +
40 + # Generate key + cert via openssl, then import
41 + openssl req -x509 -newkey rsa:2048 -days 3650 -nodes \
42 + -keyout /tmp/codesign.key \
43 + -out /tmp/codesign.crt \
44 + -config /tmp/cert_req.cfg
45 +
46 + # Bundle into PKCS#12
47 + openssl pkcs12 -export \
48 + -inkey /tmp/codesign.key \
49 + -in /tmp/codesign.crt \
50 + -out /tmp/codesign.p12 \
51 + -passout pass:"$P12_PASS" \
52 + -legacy \
53 + -keypbe PBE-SHA1-3DES \
54 + -certpbe PBE-SHA1-3DES \
55 + -macalg sha1
56 +
57 + # Import into build keychain (trust for code signing)
58 + security import /tmp/codesign.p12 \
59 + -k "$KEYCHAIN_NAME" \
60 + -P "$P12_PASS" \
61 + -T /usr/bin/codesign \
62 + -T /usr/bin/security
63 +
64 + # Grant codesign permission without UI prompt
65 + security set-key-partition-list \
66 + -S apple-tool:,apple:,codesign: \
67 + -s -k "$KEYCHAIN_PASS" "$KEYCHAIN_NAME"
68 +
69 + # Clean up temp files
70 + rm -f /tmp/codesign.key /tmp/codesign.crt /tmp/codesign.p12 /tmp/cert_req.cfg
71 +
72 + echo ""
73 + echo "✅ Certificate '$CERT_NAME' created in '$KEYCHAIN_NAME'."
74 + echo " Use this identity string in sign.sh:"
75 + security find-identity -v -p codesigning "$KEYCHAIN_NAME" | grep "$CERT_NAME" | head -1

sign.sh(file created)

@@ -0,0 +1,75 @@
1 + #!/usr/bin/env bash
2 + # sign.sh — sign a single binary executable for local use or distribution
3 + # Usage: ./sign.sh path/to/mybinary
4 +
5 + set -euo pipefail
6 +
7 + # ── CONFIG ────────────────────────────────────────────────────────────────────
8 + BINARY_PATH="${1:?Usage: $0 path/to/mybinary}"
9 + CERT_IDENTITY="Local Mac Developer" # must match CN in create_cert.sh
10 + # for real Apple certs use:
11 + # "Developer ID Application: Your Name (TEAMID)"
12 + KEYCHAIN_PATH="build.keychain-db"
13 + KEYCHAIN_PASS="build_keychain_password" # must match create_cert.sh
14 +
15 + # For notarization (optional, set NOTARIZE=true to enable):
16 + NOTARIZE=false
17 + APPLE_ID="longnghia2.00@gmail.com"
18 + APPLE_TEAM_ID="PaulCoding"
19 + APPLE_APP_PASSWORD="some_password" # app-specific password from appleid.apple.com
20 + # ── END CONFIG ────────────────────────────────────────────────────────────────
21 +
22 + if [ ! -f "$BINARY_PATH" ]; then
23 + echo "❌ File not found: $BINARY_PATH"
24 + exit 1
25 + fi
26 +
27 + BINARY_NAME="$(basename "$BINARY_PATH")"
28 + ZIP_PATH="$(dirname "$BINARY_PATH")/${BINARY_NAME}.zip"
29 +
30 + echo "==> Unlocking build keychain"
31 + security unlock-keychain -p "$KEYCHAIN_PASS" "$KEYCHAIN_PATH"
32 + security list-keychains -d user -s "$KEYCHAIN_PATH" \
33 + $(security list-keychains -d user | tr -d '"')
34 +
35 + # ── Sign ──────────────────────────────────────────────────────────────────────
36 + echo "==> Signing binary: $BINARY_NAME"
37 + codesign --sign "$CERT_IDENTITY" \
38 + --keychain "$KEYCHAIN_PATH" \
39 + --timestamp \
40 + --options runtime \
41 + --force \
42 + "$BINARY_PATH"
43 +
44 + # ── Verify ────────────────────────────────────────────────────────────────────
45 + echo "==> Verifying signature"
46 + codesign --verify --strict --verbose=4 "$BINARY_PATH"
47 +
48 + echo "==> Signature details"
49 + codesign --display --verbose=4 "$BINARY_PATH" 2>&1
50 +
51 + echo "==> Gatekeeper assessment (self-signed certs will show 'rejected' — expected)"
52 + spctl --assess --type execute --verbose "$BINARY_PATH" 2>&1 || true
53 +
54 + # ── Optional: notarize ────────────────────────────────────────────────────────
55 + if [ "$NOTARIZE" = "true" ]; then
56 + echo "==> Zipping binary for notarization submission"
57 + ditto -c -k --keepParent "$BINARY_PATH" "$ZIP_PATH"
58 +
59 + echo "==> Submitting to Apple notary service"
60 + xcrun notarytool submit "$ZIP_PATH" \
61 + --apple-id "$APPLE_ID" \
62 + --team-id "$APPLE_TEAM_ID" \
63 + --password "$APPLE_APP_PASSWORD" \
64 + --wait
65 +
66 + echo "==> Stapling notarization ticket"
67 + xcrun stapler staple "$BINARY_PATH"
68 + xcrun stapler validate "$BINARY_PATH"
69 +
70 + rm -f "$ZIP_PATH"
71 + fi
72 +
73 + echo ""
74 + echo "✅ Done: $BINARY_PATH"
75 + codesign -dv "$BINARY_PATH" 2>&1 | grep -E "^(Authority|TeamIdentifier|Signature size|Hash|CDHash)"
Newer Older