#!/bin/sh
# The mesh's internal certificate authority, trusted by this machine.
#
# Written by the mesh from the ca-trust module's manifest (novox/hq ADR 0147).
# Editing it here lasts until the next apply.
#
# There is no prior trust to verify the fetch against — this is the thing that
# establishes it — so it is made over the mesh's own private network, which is
# what authenticates it (novox/hq ADR 0098, the same reasoning that lets the
# route proxy fetch this root for itself). What comes back is checked here: a
# body that is not a certificate is refused now, rather than believed and then
# failed by whatever reads the trust store next.
set -eu

ROOTS='https://${bound:internal-acme-ca:at}:${bound:internal-acme-ca:port}${bound:internal-acme-ca:roots}'
ANCHORS=/etc/ca-certificates/trust-source/anchors
ANCHOR="$ANCHORS/mesh-internal-ca.crt"

# Arch's layout, said out loud rather than assumed: a machine that keeps its
# anchors elsewhere fails here, visibly, instead of writing a file nothing
# reads. That failure is the signal that this belongs in the host, where one
# operating system's difference lives (novox/hq ADR 0147, option 2).
[ -d "$ANCHORS" ] || {
	echo "this machine keeps no trust anchors in $ANCHORS; ca-trust is written for that layout" >&2
	exit 1
}

case "${1:-}" in
install)
	tmp=$(mktemp)
	trap 'rm -f "$tmp"' EXIT
	# The authority may still be starting, or this machine may have come up
	# before it: two minutes of asking, then an honest failure.
	n=0
	while [ "$n" -lt 60 ]; do
		if curl --fail --silent --show-error --insecure --max-time 10 \
			--output "$tmp" "$ROOTS" &&
			grep -q 'BEGIN CERTIFICATE' "$tmp"; then
			install -m 0644 "$tmp" "$ANCHOR"
			update-ca-trust
			exit 0
		fi
		n=$((n + 1))
		sleep 2
	done
	echo "the authority at $ROOTS did not serve a certificate within two minutes" >&2
	exit 1
	;;
remove)
	# What stopping the unit does, and therefore what being unassigned does.
	rm -f "$ANCHOR"
	update-ca-trust
	;;
*)
	echo "usage: $(basename "$0") install|remove" >&2
	exit 2
	;;
esac
