#!/usr/bin/env bash # # install-browser-certs.sh — Import the mTLS client cert + root CA into # every browser's cert store on this Linux machine. # # Handles: # - Brave (Flatpak) — isolated NSS DB at ~/.var/app/com.brave.Browser/.pki/nssdb # - Chromium-family (rpm/deb, Brave-rpm) — ~/.pki/nssdb # - Firefox — each ~/.mozilla/firefox/*.default*/ profile # - System trust (optional, sudo) — /etc/pki/ca-trust (curl, wget, git, …) # # If only the modern (PBES2/AES-256) p12 exists, this script converts it to a # legacy bundle that NSS-based stores can actually parse. # # Also optionally writes the Brave enterprise policy # AutoSelectCertificateForUrls so Brave stops prompting on every page load. # # Usage: # scripts/install-browser-certs.sh [options] # --certs-dir PATH default: $HOME/.pi/agent/certs # --system-trust also install root CA into system trust store # --brave-policy also install AutoSelectCertificateForUrls # --auto-select-url URL default: https://ai.shahondin1624.de # --auto-select-issuer CN default: ShahODin Root CA # --help show this message set -euo pipefail CERTS_DIR="${CERTS_DIR:-$HOME/.pi/agent/certs}" DO_SYSTEM_TRUST=0 DO_BRAVE_POLICY=0 AUTO_SELECT_URL="https://ai.shahondin1624.de" AUTO_SELECT_ISSUER_CN="ShahODin Root CA" usage() { sed -n '2,/^$/p' "$0" | sed 's/^#\{0,1\} \{0,1\}//'; exit 0; } while [[ $# -gt 0 ]]; do case "$1" in --certs-dir) CERTS_DIR="$2"; shift 2 ;; --system-trust) DO_SYSTEM_TRUST=1; shift ;; --brave-policy) DO_BRAVE_POLICY=1; shift ;; --auto-select-url) AUTO_SELECT_URL="$2"; shift 2 ;; --auto-select-issuer) AUTO_SELECT_ISSUER_CN="$2"; shift 2 ;; -h|--help) usage ;; *) echo "Unknown arg: $1" >&2; exit 1 ;; esac done CLIENT_CRT="$CERTS_DIR/client.pem" CLIENT_KEY="$CERTS_DIR/client-key.pem" ROOT_CA="$CERTS_DIR/root-ca.pem" LEGACY_P12="$CERTS_DIR/client-legacy.p12" for f in "$CLIENT_CRT" "$CLIENT_KEY" "$ROOT_CA"; do [[ -f "$f" ]] || { echo "Missing: $f" >&2; exit 1; } done command -v pk12util >/dev/null || { echo "pk12util not found — install nss-tools (Fedora: 'sudo dnf install nss-tools')" >&2; exit 1; } command -v certutil >/dev/null || { echo "certutil not found — install nss-tools" >&2; exit 1; } command -v openssl >/dev/null || { echo "openssl not found" >&2; exit 1; } # Ensure a legacy-format p12 exists (required by NSS on most distros) if [[ ! -f "$LEGACY_P12" ]]; then echo "==> Generating legacy-format p12 for NSS stores" umask 077 tmp="$(mktemp)" trap 'shred -u "$tmp" 2>/dev/null || rm -f "$tmp"' EXIT cat "$CLIENT_CRT" "$CLIENT_KEY" "$ROOT_CA" > "$tmp" openssl pkcs12 -legacy -export -in "$tmp" \ -out "$LEGACY_P12" \ -name "Client (legacy)" \ -passout pass: chmod 600 "$LEGACY_P12" fi import_nss() { local db="$1" label="$2" [[ -d "$db" && -f "$db/cert9.db" ]] || { echo " [$label] no NSS DB at $db — skipping"; return 0; } echo "==> $label ($db)" if certutil -d "sql:$db" -L -n "$AUTO_SELECT_ISSUER_CN" >/dev/null 2>&1; then echo " root CA already present" else certutil -d "sql:$db" -A -t "CT,C,C" -n "$AUTO_SELECT_ISSUER_CN" -i "$ROOT_CA" echo " root CA imported" fi if certutil -d "sql:$db" -L 2>/dev/null | grep -q 'Client (legacy)'; then echo " client cert already present" else pk12util -d "sql:$db" -i "$LEGACY_P12" -W '' echo " client cert imported" fi } # 1) Brave Flatpak (isolated NSS DB) import_nss "$HOME/.var/app/com.brave.Browser/.pki/nssdb" "Brave (Flatpak)" # 2) Regular Chromium family (packaged Brave/Chrome/Chromium) and pki-aware CLIs import_nss "$HOME/.pki/nssdb" "Chromium-family NSS DB (~/.pki/nssdb)" # 3) Firefox profiles shopt -s nullglob for profile in "$HOME"/.mozilla/firefox/*.default* "$HOME"/.mozilla/firefox/*.default-release; do import_nss "$profile" "Firefox profile $(basename "$profile")" done shopt -u nullglob # 4) System trust (optional) if [[ $DO_SYSTEM_TRUST -eq 1 ]]; then anchor_name="$(basename "$ROOT_CA")" echo "==> Installing root CA into system trust (requires sudo)" sudo install -m 644 "$ROOT_CA" "/etc/pki/ca-trust/source/anchors/$anchor_name" sudo update-ca-trust extract fi # 5) Brave enterprise policy (optional) if [[ $DO_BRAVE_POLICY -eq 1 ]]; then echo "==> Installing Brave AutoSelectCertificateForUrls policy" if command -v flatpak >/dev/null && flatpak list 2>/dev/null | grep -q com.brave.Browser; then sudo flatpak override com.brave.Browser --filesystem=/etc/brave:ro fi sudo mkdir -p /etc/brave/policies/managed # Policy JSON has a JSON-string value inside an array. policy_tmp="$(mktemp)" cat > "$policy_tmp" </dev/null || pkill -x brave 2>/dev/null || true echo " policy installed; Brave was killed if running — relaunch to apply" fi echo echo "==> Done. Restart any already-running browser for NSS changes to take effect."