#!/bin/bash

# Bash shell script for generating self-signed certs.

failIfError() {
    if [ "$1" != "0" ]; then
        echo "some error has occured when trying to generate certificate"
        echo $1
        unset PASSPHRASE
        exit 2
    fi
}

usage() {
    echo "Usage: ${0##*/} [-d | --domain] [-t | --days] [-f | --fqdn] [-h | --hostname] [-k | --keylen] [-o | --outdir] [-s | --selfsigned] [-v | --verbose] [-?|--help]"
}

#try to autodetect defaults
OUTDIR="/data"
HOSTNAME="$(cat /etc/hostname | awk '{print tolower($0)}')"
DOMAIN="$(cat /etc/resolv.conf | grep search | sed 's/search //g')"
DOMAIN=${DOMAIN// /}
SELFSIGNED=0
VERBOSE=0
KEYLEN=4096
DAYS=730

ARGS=$(getopt -o d:f:h:k:o:st:v --long domain,days,help,hostname,fqdn,keylen,outdir,selfsigned,verbose -n "${0##*/}" -- "$@")
if [ $? != 0 ]; then
    echo "Terminating..." >&2
    exit 1
fi

# Note the quotes around `$TEMP': they are essential!
eval set -- "$ARGS"
while true; do
    case "$1" in
    -d | --domain)
        DOMAIN=$2
        shift 2
        ;;
    -t | --days)
        DOMAIN=$2
        shift 2
        ;;
    -f | --fqdn)
        FQDN=$2
        shift 2
        ;;
    -h | --hostname)
        HOSTNAME=$2
        shift 2
        ;;
    -k | --hostname)
        KEYLEN=$2
        shift 2
        ;;
    -o | --outdir)
        OUTDIR=$2
        shift 2
        ;;
    -s | --selfsigned)
        SELFSIGNED=1
        shift 1
        ;;
    -v | --verbose)
        VERBOSE=1
        shift 1
        ;;
    --help)
        usage
        exit
        ;;
    --)
        shift
        break
        ;;
    *)
        echo "Internal error!"
        exit 1
        ;;
    esac
done

if [ -z "$DOMAIN" ]; then
    echo "no domain given"
    usage
    exit 3
fi

if [ -z "$HOSTNAME" ]; then
    echo "no hostname given"
    usage
    exit 4
fi

if [ -z ${FQDN} ]; then
    FQDN="${HOSTNAME}.${DOMAIN}"
fi

if [ -z "${FQDN}" ]; then
    echo "no fqdn given"
    usage
    exit 5
fi

SAN="DNS:${FQDN},DNS:${HOSTNAME}"
SUBJECT="CN=${FQDN}"

#for j in $(for i in $(omgsysteminfo --filter="ip.*.scope=global" | cut -d "=" -f 1); do omgsysteminfo --filter=${i/scope/address} --val; done); do
for j in $(ip addr | grep global | sed -e "s/  //g" | cut -d " " -f 2 | cut -d "/" -f 1); do
    SAN="${SAN},IP:${j}"
done

if [ "${VERBOSE}" == "1" ]; then
    echo "hostname=\"${HOSTNAME}\""
    echo "  domain=\"${DOMAIN}\""
    echo "    fqdn=\"${FQDN}\""
    echo "     san=\"${SAN}\""
fi

#prepare conf file
CONFFILE=$(mktemp)
if [ -z "${CONFFILE}" ]; then
    echo "can't create tmp file"
fi
trap "rm -f ${CONFFILE}" 0 2 3 15

cat >${CONFFILE} <<EOF

[ req ]
prompt = no
distinguished_name = req_distinguished_name
string_mask = nombstr
req_extensions = v3_req
x509_extensions = v3_req

[ req_distinguished_name ]
${SUBJECT}

[ v3_req ]
subjectAltName = ${SAN}

EOF

if [ "${VERBOSE}" == "1" ]; then
    echo "############################"
    cat ${CONFFILE}
    echo "############################"
fi

if [ "$SELFSIGNED" == "1" ]; then
    if [ "${VERBOSE}" == "1" ]; then
        echo "openssl req -x509 -nodes -sha256 -days 365 -newkey rsa:${KEYLEN} -keyout ${OUTDIR}/key.pem -out ${OUTDIR}/cert.pem -config ${CONFFILE}"
    fi

    openssl req -x509 -nodes -sha256 -days ${days} -newkey rsa:${KEYLEN} -keyout ${OUTDIR}/key.pem -out ${OUTDIR}/cert.pem -config ${CONFFILE}
    rc=$?

    if [ "${VERBOSE}" == "1" ]; then
        openssl x509 -in ${OUTDIR}/cert.pem -text -noout
    fi

else
    if [ "${VERBOSE}" == "1" ]; then
        echo "openssl req -new -newkey rsa:${KEYLEN} -nodes -out ${OUTDIR}/certreq.csr -keyout ${OUTDIR}/key.pem -config ${CONFFILE}"
    fi

    openssl req -new -newkey rsa:${KEYLEN} -nodes -out ${OUTDIR}/req.pem -keyout ${OUTDIR}/key.pem -config ${CONFFILE}
    rc=$?

    cp ${OUTDIR}/key.pem ${OUTDIR}/tmpkey.pem
    cp ${CONFFILE} ${OUTDIR}/cert.config

    if [ "${VERBOSE}" == "1" ]; then
        openssl req -in ${OUTDIR}/req.pem -text -noout -verify
    fi
fi

rm ${CONFFILE}

failIfError ${rc}
