#!/bin/bash
# SPDX-License-Identifier: MIT
# Copyright contributors to the libzpc project

export OPENSSL_CONF=${OPENSSL_CONF:-"build/openssl.conf"}
OPENSSL=${OPENSSL:-"openssl"}
ZPC_SEC_DIR=${ZPC_SEC_DIR:-"."}
ZPC_KEY_DIR=${ZPC_KEY_DIR:-"."}
V=${V:-"0"}

ALGS=( "prime256v1" "secp384r1" "secp521r1" "ED25519"     "ED448" )
ZPCS=( "p-256"      "p-384"     "p-521"     "ed25519"     "ed448" )
CLRS=( "p256"       "p384"      "p521"      "ed25519"     "ed448" )

TTMPDIR=$(mktemp -d)
MSG="${TTMPDIR}/msg"
SIG="${TTMPDIR}/msg.sig"

tap13() {
	local rc="$1"
	local idx="$2"
	local text="$3"
	local log="$4"

	case ${rc} in
	0)
		echo "ok ${idx} - ${text}"
		if [ ${V} -eq 1 ]; then
			echo " ---"
			echo "${log}"
			echo " ---"
		fi
		;;
	77)
		echo "ok ${idx} # SKIP"
		;;
	*)
		echo "not ok ${idx} - ${text}"
		echo " ---"
		echo "${log}"
		echo " ---"
		;;
	esac

	return 0
}

sign_verify() {
	local sigkey="$1"
	local verkey="$2"
	local prvkey="$3"
	local digest="$4"

	[ -r "${sigkey}" ] || return 77
	[ -r "${verkey}" ] || return 77

	rm -f ${SIG}

	${OPENSSL} dgst			\
	  -sign ${sigkey}		\
	  ${DIGEST}			\
	  -out "${SIG}"			\
	  "${MSG}"			\
	2>&1				\
	|| return 99
	echo "sign ok"

	${OPENSSL} dgst			\
	  -verify ${verkey}		\
	  ${DIGEST}			\
	  -signature "${SIG}"		\
	  "${MSG}"			\
	2>&1				\
	|| return 99
	echo "verify ok"

	[ -z "${prvkey}" ] && return 0

	${OPENSSL} dgst			\
	  -prverify ${prvkey}		\
	  ${DIGEST}			\
	  -signature "${SIG}"		\
	  "${MSG}"			\
	2>&1				\
	|| return 99
	echo "prverify ok"

	return 0
}

uv_sign_verify() {
	dd			\
	  if=/dev/random	\
	  of=${MSG}		\
	  bs=1K			\
	  count=1K		\
	> /dev/null 2>&1	\
	|| return 1

	fail=0
	tc=0
	for ((i=0; i<${#ALGS[@]}; i++)); do
		ALG="${ALGS[$i]}"
		ZPC="${ZPCS[$i]}"
		CLR="${CLRS[$i]}"
		ZPC_PEM="${ZPC_KEY_DIR}/${ZPC}-hbkzpc.pem"
		CLR_PEM="${ZPC_SEC_DIR}/${CLR}.key"
		CLR_PUB_PEM="${ZPC_KEY_DIR}/${CLR}-pub.pem"

		if $(echo "${ALG}" | grep -iq "^ed") ; then
			DIGEST=""
		else
			DIGEST="-sha256"
		fi

		tc=$(( ${tc} + 1 ))
		log=$(sign_verify "${ZPC_PEM}" "${ZPC_PEM}" "${ZPC_PEM}" "${DIGEST}")
		rc="$?"
		[ ${rc} -ne 0 ] && fail=1
		tap13 "${rc}" "${tc}" "Sign/verify (zpc/zpc) for ${ALG}" "${log}"

		tc=$(( ${tc} + 1 ))
		log=$(sign_verify "${ZPC_PEM}" "${CLR_PUB_PEM}" "${CLR_PEM}" "${DIGEST}")
		rc="$?"
		[ ${rc} -ne 0 ] && fail=1
		tap13 "${rc}" "${tc}" "Sign/verify (zpc/clr) for ${ALG}" "${log}"

		tc=$(( ${tc} + 1 ))
		log=$(sign_verify "${CLR_PEM}" "${ZPC_PEM}" "${ZPC_PEM}" "${DIGEST}")
		rc="$?"
		[ ${rc} -ne 0 ] && fail=1
		tap13 "${rc}" "${tc}" "Sign/verify (clr/zpc) for ${ALG}" "${log}"
	done

	rm -rf ${TTMPDIR}
	return ${fail}
}

if [[ "$0" == "${BASH_SOURCE[0]}" ]]; then
	uv_sign_verify
	exit $?
fi
