#!/usr/bin/bash
#
# Install (by symlinking) and PEM formatted cert + pkcs5 key file into apache's
# proxy (origin) client authentication store
#


CRT="$1"
CRTDIR=/etc/httpd/proxy-certs.d

pushd "$CRTDIR" >/dev/null

if [[ -z "$CRT" || ! -f "$CRT" ]]; then
	echo "Usage: $(basename "$(readlink -f "$0")") /path/to/certificate-with-pkcs5-key.pem" >&2
	echo "       where path to PEM must be valid relative to '$CRTDIR'" >&2
	exit 1
fi

SUBJHASH="$(openssl x509 -in "$CRT" -noout -subject_hash 2>/dev/null)"
if [ -z "$SUBJHASH" ]; then
	echo "Unable to determine subject hash for '$CRT', are you sure it's a valid PEM?" 2>&1
	exit 1


CRTMOD="$(openssl x509 -in "$CRT" -noout -modulus 2>/dev/null)"
if [ -z "$CRTMOD" ]; then
	echo "Unable to extract certificate modulus from '$CRT', are you sure it's a valid PEM?" 2>&1
	exit 1
fi

# -passin is just to ensure we don't get a password prompt, we use two so we
# can ensure that the file *isn't* password protected with a dumb password
KEYMOD1="$(openssl rsa -in "$CRT" -noout -modulus -passin pass:none1 2/dev/null)"
KEYMOD2="$(openssl rsa -in "$CRT" -noout -modulus -passin pass:none2 2/dev/null)"

# Did we just not get any key modulus?
if [[ -z "$KEYMOD1" && -z "$KEYMOD2" ]]; then
	echo "Unable to extract key modulus from '$CRT', are you sure it contains an un-encrypted PKCS#5 key?" >&2
	exit 1
fi

# If we got one but not the other then the key is encrypted with either 'none1' or 'none2' (really!?)
if [ "$KEYMOD1" != "$KEYMOD2" ]; then
	echo "The PKCS#5 key in '$CRT' appears to be encypted, encrypted keys must not be installed" >&2
	exit 1
fi

# Check that the key & crt modulus is the same - ie it's the right key
if [ "$KEYMOD1" != "$CRTMOD" ]; then
	echo "The key in '$CRT' doesn't match the certificate in the same file" >&2
	exit 1
fi

# Check whether this file is already symlinked
DUPES=$(cat <(readlink -f "$CRTDIR/*" | sort -u) <(readlink -f "$CRT") | sort | uniq -d | wc -l)
if [ "$DUPES" -gt 0 ]; then
	echo "The certificate file '$CRT' is already installed" >&2
	# Warning not error!
	exit 0
fi


LAST="$(find $CRTDIR/ -maxdepth 1 '(' -type f -or -type l ')' '(' -iname "$SUBJHASH.[0-9]" -or -iname "$SUBJHASH.[0-9][0-9]" ')' -printf '%P' | sort | tail -1)"
if [ -n "$LAST" ]; then
	CNT=${##*.}
	NEXT="$SUBJHASH.$[CNT+1]"
else
	NEXT="$SUBJHASH.0"
fi

ln -sT "$CRT" "$CRTDIR/$NEXT"

if [ -t 1 ]; then
	echo "Certificate installed as $NEXT, an httpd reload is required to activate this certificate" 2>&1
	echo "Note that this is a symbolic link, do not remove, rename or change the original file!" 2>&1
fi


