#!/bin/bash
allowcred.awk &
CREDPID=$!
if [ -z "$XCATDEST" ]; then
	XCATDEST=$1
fi
# doxcat runs getcert in the foreground and ignores its status, so a wait with no bound stops
# the boot and prints nothing.
give_up() {
	logger -s -t xcat -p local4.err "getcert: $1"
	kill $CREDPID
	exit 1
}

if ! command -v openssl > /dev/null 2>&1; then
	give_up "this Genesis image carries no openssl, so no certificate is requested"
fi

#retry in case certkey.pem is not right, yet
# doxcat writes /etc/xcat/certkey.pem in the background with a 4096 bit key, so the first
# requests fail. An emulated node needs minutes for that key.
CSR_TIMEOUT=${GETCERT_CSR_TIMEOUT:-600}
CSR_DEADLINE=$((SECONDS + CSR_TIMEOUT))
while ! openssl req -new -key /etc/xcat/certkey.pem -out /tmp/tls.csr -subj "/CN=$(hostname)" >& /dev/null; do
	if [ "$SECONDS" -ge "$CSR_DEADLINE" ]; then
		give_up "no certificate request after ${CSR_TIMEOUT}s; /etc/xcat/certkey.pem is not usable"
	fi
	sleep 1
done
echo "<xcatrequest>
<command>getcredentials</command>
<arg>x509cert</arg>
<callback_port>300</callback_port>
<csr>" > /tmp/certreq.xml
cat /tmp/tls.csr >> /tmp/certreq.xml
echo "</csr>
<sha512sig>
</sha512sig>
</xcatrequest>" >> /tmp/certreq.xml
openssl dgst -sha512 -out /tmp/certreq.sha512 -sign /etc/xcat/privkey.pem /tmp/certreq.xml #chain off the switch published key
openssl enc -e -a -in /tmp/certreq.sha512  > /tmp/certreq.b64sig
while read -r line; do
        if [ "$line" = "</sha512sig>" ]; then
                cat /tmp/certreq.b64sig >> /tmp/certreq.xml.new
        fi
        echo "$line" >> /tmp/certreq.xml.new
done < /tmp/certreq.xml
mv /tmp/certreq.xml.new /tmp/certreq.xml
rm /tmp/certreq.b64sig /tmp/certreq.sha512
openssl s_client -connect "$XCATDEST" -quiet 2> /dev/null < /tmp/certreq.xml > /tmp/certresp.xml
if grep 'BEGIN CERTIFICATE' /tmp/certresp.xml > /dev/null; then
	awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/' < /tmp/certresp.xml > /etc/xcat/cert.pem
	#stop transmitting sysDesc, allowing the public key to age out of validity
	for iface in $(grep '^  e' /var/lib/lldpad/lldpad.conf|awk '{print $1}'); do
		lldptool -T -i "$iface" -V sysDesc enableTx=no >& /dev/null
	done
fi
rm /tmp/certreq.xml
rm /tmp/certresp.xml
kill $CREDPID
