#!/usr/bin/env bash set -euo pipefail usage() { cat <<'EOF' Usage: scripts/setup_verified_crx_key.sh [--recipient GPG_RECIPIENT] [--out-dir DIR] Generates a dedicated RSA private key for Chrome Web Store verified CRX uploads, encrypts it to your GPG key, and writes the public key material for the Chrome Developer Dashboard. Chrome Web Store verified uploads require an RSA CRX signing key. A GPG/OpenPGP key cannot be used directly for CRX signing, but it can protect the RSA private key at rest. EOF } recipient="" out_dir="secrets/verified-crx" while [[ $# -gt 0 ]]; do case "$1" in --recipient) recipient="${2:-}" shift 2 ;; --out-dir) out_dir="${2:-}" shift 2 ;; -h|--help) usage exit 0 ;; *) echo "Unknown argument: $1" >&2 usage >&2 exit 2 ;; esac done if [[ -z "$recipient" ]]; then recipient="$(gpg --list-secret-keys --with-colons 2>/dev/null | awk -F: '$1 == "uid" { print $10; exit }')" fi if [[ -z "$recipient" ]]; then echo "No GPG recipient found. Pass --recipient ''." >&2 exit 1 fi mkdir -p "$out_dir" chmod 700 "$out_dir" private_key="$(mktemp)" public_pem="$out_dir/chrome-webstore-verified-crx-public-key.pem" public_der_b64="$out_dir/chrome-webstore-verified-crx-public-key.der.base64.txt" encrypted_private="$out_dir/chrome-webstore-verified-crx-private-key.pem.gpg" trap 'rm -f "$private_key"' EXIT if [[ -e "$encrypted_private" ]]; then echo "Refusing to overwrite existing encrypted private key: $encrypted_private" >&2 exit 1 fi openssl genrsa -out "$private_key" 2048 >/dev/null 2>&1 chmod 600 "$private_key" openssl rsa -in "$private_key" -pubout -out "$public_pem" >/dev/null 2>&1 openssl rsa -in "$private_key" -pubout -outform DER 2>/dev/null | base64 -w0 > "$public_der_b64" printf '\n' >> "$public_der_b64" gpg --encrypt --recipient "$recipient" --output "$encrypted_private" "$private_key" chmod 600 "$encrypted_private" cat < Package -> Verified uploads. Keep the encrypted private key. Do not commit or upload the decrypted PEM. EOF