#!/usr/bin/bash

###
# Options, overide interactive prompts by setting environment variables:
#
#   - AUTHKEY_PASSPHRASE: authkey passphrase configured on a backup YubiHSM
#   - WRAPKEY_PASSPHRASE: wrapkey passphrase configured on a backup YubiHSM
###
authkey_passphrase=${AUTHKEY_PASSPHRASE:-}
wrapkey_passphrase=${WRAPKEY_PASSPHRASE:-}

###
# Internal
###
wrap_file_log=tmp.logsrv.wrapped
wrap_file_witness=tmp.witness.wrapped
log_pubkey_file=tmp.logsrv.pem
log_signature_file=tmp.logsrv.signature
witness_pubkey_file=tmp.witness.pem
witness_signature_file=tmp.witness.signature
message_file=tmp.message

# extract version X.Y.Z from "yubihsm-shell X.Y.Z" output
yubihsm_version=$(yubihsm-shell --version)
yubihsm_version=${yubihsm_version##"yubihsm-shell "}

# version_gt $a $b checks that $a > b$ as version numbers
function version_gt() {
    [[ "$1" != "$2" ]] && (echo "$1" ; echo "$2") | sort -rVC
}

echo -n "git.glasklar.is/sigsum/core/key-mgmt testonly" > "$message_file"
function clean_up() {
	set +eu

	shred -zun 12 "$wrap_file_log" >/dev/null 2>&1
	shred -zun 12 "$wrap_file_witness" >/dev/null 2>&1

	rm -f "$log_pubkey_file" "$log_signature_file"
	rm -f "$witness_pubkey_file" "$witness_signature_file"
	rm -f "$message_file"
}

function info() { echo "*** $*"      >&2;         }
function warn() { echo "WARNING: $*" >&2;         }
function die()  { echo "ERROR: $*"   >&2; exit 1; }

function yubihsm_probe() {
	info "INSERT YubiHSM $1"
	read -rp "ENTER to continue"

	num_yubihsm=$(lsusb | grep YubiHSM | wc -l)
	if [[ "$num_yubihsm" != 1 ]]; then
		die "keep exactly one yubihsm plugged in at a time, have: $num_yubihsm"
	fi

	bus=$(lsusb | grep YubiHSM | cut -d' ' -f2)
	device=$(lsusb | grep YubiHSM | cut -d' ' -f4)
	if [[ -z "$bus" ]] || [[ -z "$device" ]]; then
		die "failed to locate YubiHSM, is it plugged in?"
	fi

	serial_line=$(lsusb -vs "$bus:$device" | grep iSerial)
	serial_number=${serial_line##* }

	info "FOUND YubiHSM, serial number $serial_number"
	read -rp "ENTER to continue"

	echo "$serial_number"
}

function yubihsm_shell() {
	local pid
	local tmp

	[[ -z $(pidof yubihsm-connector) ]] || die "a yubihsm-connector is already running, please stop it and try again"

	yubihsm-connector >/dev/null 2>&1 &
	pid=$!

	tmp=$(mktemp)
	cat | yubihsm-shell 2>"$tmp"
	error=$(grep -e "Failed to create session" "$tmp" || true)

	rm -f "$tmp"
	kill "$pid" >/dev/null 2>&1
	[[ -z "$error" ]] || die "failed to run YubiHSM commands, incorrect credentials or factory-reset expected?"
}

function yubihsm_get_passphrase() {
	yubihsm_shell << EOF
		connect
		session open   "$1" "$2"
		get     random   0   16
		session close    0
EOF
}
