Created
August 27, 2025 06:03
-
-
Save notmayo/003cb8208ad448d6ff502ea452dddfa1 to your computer and use it in GitHub Desktop.
Arch/CachyOS DoD Root Certs Installer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# arch_dod_root_certs.sh — DoD PKI -> Arch/CachyOS trust store (simple & robust) | |
set -euo pipefail | |
shopt -s nullglob | |
ZIP_URL="https://dl.dod.cyber.mil/wp-content/uploads/pki-pke/zip/unclass-certificates_pkcs7_DoD.zip" | |
ANCHORS_DIR="/etc/ca-certificates/trust-source/anchors" | |
ROOTS_ONLY=0 | |
while [[ $# -gt 0 ]]; do | |
case "$1" in | |
--roots-only) ROOTS_ONLY=1; shift;; | |
-h|--help) echo "Usage: $0 [--roots-only]"; exit 0;; | |
*) echo "Unknown option: $1"; exit 2;; | |
esac | |
done | |
need(){ command -v "$1" >/dev/null 2>&1; } | |
for b in curl unzip openssl sudo update-ca-trust python3; do need "$b" || sudo pacman -Sy --needed --noconfirm "$b" ca-certificates ca-certificates-utils p11-kit python >/dev/null 2>&1 || true; done | |
WORKDIR="$(mktemp -d)" | |
echo "[*] Workdir: $WORKDIR" | |
cd "$WORKDIR" | |
echo "[*] Downloading…" | |
curl -fsSL "$ZIP_URL" -o dod_pki.zip | |
echo "[*] Extracting…" | |
unzip -q dod_pki.zip | |
echo "[*] Building combined.pem…" | |
: > combined.pem | |
# Include any .pem in zip | |
find . -type f -name '*.pem' -print0 | while IFS= read -r -d '' pem; do | |
awk 'BEGIN{p=0} /BEGIN CERTIFICATE/ {p=1} p; /END CERTIFICATE/ {p=0}' "$pem" >> combined.pem || true | |
done | |
# Include all .p7b (PEM/DER) | |
find . -type f -name '*.p7b' -print0 | while IFS= read -r -d '' p7b; do | |
if grep -q "BEGIN PKCS7" "$p7b"; then INFORM="PEM"; else INFORM="DER"; fi | |
openssl pkcs7 -inform "$INFORM" -print_certs -in "$p7b" >> combined.pem | |
done | |
[[ -s combined.pem ]] || { echo "[!] combined.pem is empty"; exit 1; } | |
echo "[*] Splitting (Python)…" | |
python3 - <<'PY' | |
import re, pathlib | |
data = pathlib.Path('combined.pem').read_text(encoding='utf-8', errors='ignore') | |
blocks = re.findall(r'-----BEGIN CERTIFICATE-----(?:.|\n)+?-----END CERTIFICATE-----', data) | |
out = pathlib.Path('named'); out.mkdir(parents=True, exist_ok=True) | |
from subprocess import run, PIPE | |
import tempfile, os | |
for i,b in enumerate(blocks): | |
tmp = pathlib.Path('tmp.pem'); tmp.write_text(b) | |
# filename = SHA256 fingerprint (no colons) | |
fp = run(["openssl","x509","-in",str(tmp),"-noout","-fingerprint","-sha256"], stdout=PIPE, text=True).stdout | |
fp = fp.strip().split("=")[-1].replace(":","") if fp else f"UNKNOWN{i:04d}" | |
(out/f"dod_{fp}.crt").write_text(b) | |
tmp.unlink(missing_ok=True) | |
print(len(blocks)) | |
PY | |
COUNT_NAMED=$(ls -1 named/*.crt 2>/dev/null | wc -l | tr -d ' ') | |
echo "[*] Prepared $COUNT_NAMED cert file(s)." | |
# Optional: keep only self-signed roots | |
if [[ "$ROOTS_ONLY" -eq 1 ]]; then | |
echo "[*] Filtering to self-signed roots…" | |
mkdir -p roots | |
for f in named/*.crt; do | |
sub=$(openssl x509 -in "$f" -noout -subject -nameopt RFC2253 || true) | |
iss=$(openssl x509 -in "$f" -noout -issuer -nameopt RFC2253 || true) | |
[[ -n "$sub" && "$sub" == "$iss" ]] && cp -- "$f" roots/ | |
done | |
rm -f named/*.crt | |
mv roots/*.crt named/ 2>/dev/null || true | |
COUNT_NAMED=$(ls -1 named/*.crt 2>/dev/null | wc -l | tr -d ' ') | |
echo "[*] Roots kept: $COUNT_NAMED" | |
fi | |
echo "[*] Installing to $ANCHORS_DIR …" | |
sudo mkdir -p "$ANCHORS_DIR" | |
# Don’t let one bad file stop the loop | |
set +e | |
for f in named/*.crt; do | |
sudo cp -v -- "$f" "$ANCHORS_DIR/" | |
done | |
set -e | |
echo "[*] update-ca-trust…" | |
sudo update-ca-trust | |
echo "[✓] Done. Installed $(ls -1 "$ANCHORS_DIR"/dod_*.crt 2>/dev/null | wc -l | tr -d ' ') DoD cert files." | |
echo "[i] Verify: trust list | grep -i dod | head" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment