#!/usr/bin/bash
#
# Monitor the IDP certificate for an OCA instance, including optionally the expiry of future certificates which can be chained with the current one.
#
# Usage: $0 <oca-instance> <property>
#
# <instance> := <oca-instance-name>
# <property> := ^(next-)?((start|end)date|serial|subject|issuer|fingerprint|(issuer|subject)_hash|modulus|ocsp(id|_uri)|certificate)$
#

function usage  {
	cat <<-EOD >&2

        NIF Mutual TLS Client Certificate montoring

            $0 <nif-instance-name> <nif-branch> <certificate-property>

            Where <certificate-property> can be one of:

                * startdate          - The certificate's notBefore date as unix epoch seconds
                * enddate            - The certificate's notAfter date as unix epoch seconds
                * serial             - The certificate's serial number
                * subject            - The certificate's subject in the form /A=B/D=C/ (eg /C=AU/ST=...)
                * fingerprint        - The certificate's fingerprint
                * issuer             - The certificate's issuer in the form /A=B/D=C/ (eg /C=AU/ST=...)
                * keylen             - The certificate's key length (in bits)
                * sigalgo            - The certificate's signature algorithm (eg md5WithRSAEncryption, sha1With.., sha256With... etc)
                * subject_hash       - The certificate's openssl subject hash value
                * issuer_hash        - The certificate's openssl issuer hash value
                * modulus            - The certificate's public key modulus of the certificate
                * ocspid             - The certificate's OCSP responder ID(s)
                * ocsp_uri           - The certificate's OCSP responder URI(s)
                * certificate        - The actual PEM encoded X.509 certificate
                * verify             - Verify a sha256sum of the certificate and private key moduli match

	EOD
	exit 1
}

[ $# -ne 3 ] && usage

# Name our arguments for sanity
INSTANCE="$1"
BRANCH="$2"
PROPERTY="$3"

if [[ ! "${INSTANCE}" =~ ^[-_A-Za-z0-9]+$ ]]; then
        echo "Illegal instance name '${INSTANCE}'" >&2
        echo -n "ZBX_NOTSUPPORTED"
        exit 2
fi

PEM="/home/${INSTANCE}/certs/${BRANCH}_client.pem"

if [[ ! -r $PEM ]]; then
        echo "Could not find readable PEM file '${PEM}'" >&2
        echo -n "ZBX_NOTSUPPORTED"
        exit 3
fi

# Strip next- we've handled this in the PEM retrieval
PROPERTY="${PROPERTY#next-}"

if [[ "${PROPERTY}" == 'certificate' ]]; then

    echo "${PEM}"

elif [[ "${PROPERTY}" == 'keylen' ]]; then

    openssl x509 -noout -text <<<"${PEM}" 2>/dev/null | sed -nre 's/^[ \t]+Public-Key: \(([0-9]+) bit\)[ \t]*$/\1/  p'

elif [[ "${PROPERTY}" == 'sigalgo' ]]; then

    openssl x509 -noout -text <<<"${PEM}" 2>/dev/null | awk '/Signature Algorithm: /{print $3; exit;}'

elif [[ "${PROPERTY}" =~ ^((start|end)date|serial|subject|issuer|fingerprint|(issuer|subject)_hash|modulus|ocsp(id|_uri))$ ]]; then

    RESULT="$(openssl x509 -in "${PEM}" -noout "-${PROPERTY}" | sed -re 's/.*=//g')"

    if [[ "${PROPERTY}" =~ ^(start|end)date$ ]]; then
        RESULT="$(date --date="$RESULT" +%s)"
    elif [[ "${PROPERTY}" == 'modulus' ]]; then
        RESULT="$(sha256sum <<<"${RESULT}" | cut -d\  -f1)"
    fi

    echo "${RESULT}"

elif [[ "${PROPERTY}" == 'verify' ]]; then
        CERTMOD="$(openssl x509 -in "${PEM}" -noout -modulus | sha256sum)"
        KEYMOD="$(openssl rsa -in "${PEM}" -noout -modulus | sha256sum)"
        if [[ $CERTMOD = "$KEYMOD" ]]; then
            echo 0
        else
            echo 1
        fi

else
    usage "Unknown/Unsupported certificate property '${PROPERTY}'"
    exit 1
fi
