#!/bin/sh

set -e
#set -x

PKI_CONFIG_ROOT=/usr/share/supply-common/pki

# This script was made using the tutorial available at:
# http://pki-tutorial.readthedocs.io/en/latest/expert/index.html
# This script is made to run in non-interactive mode, with
# no password on the keyboard what so ever.
# It will create this:
#
# -----------        ---------------        ----------------
# | ROOT CA |   =>   | Supply CA 2 |   =>   | Server certs |
# -----------        ---------------        ----------------
#
#
# To change names and so on, simply edit config files in
# the /usr/share/supply-common/pki folder.
#
# By default we have:
#
# [ ca_dn ]
# countryName             = "CH"
# organizationName        = "Supply"
# organizationalUnitName  = "Supply Root CA org"
# commonName              = "Supply Root CA"
#
# for the root ca, and for Supply CA 2:
#
# [ ca_dn ]
# countryName             = "CH"
# organizationName        = "Supply"
# organizationalUnitName  = "Supply CA 2 CA org"
# commonName              = "Supply CA 2 Root CA"
#
# In production, you'd typically replace ROOT CA and Supply CA
# by real PKI infrastructure keys (ie: you'd only genreate keys
# for the Component CA).

print_header() {
    if [ -n "$(set | grep xtrace)" ]; then
      set +x
      local enable_xtrace='yes'
    fi
    echo "===================================================================================================="
    echo $1
    echo "===================================================================================================="
    if [ -n "${enable_xtrace}" ]; then
      set -x
    fi
}

cd ${PKI_CONFIG_ROOT}

print_header "1.1 create directories"
for i in ca/root-ca/private ca/root-ca/db crl certs ; do
	mkdir -p ${PKI_CONFIG_ROOT}/${i}
done

print_header "1.2 create database"
cp /dev/null ${PKI_CONFIG_ROOT}/ca/root-ca/db/root-ca.db
cp /dev/null ${PKI_CONFIG_ROOT}/ca/root-ca/db/root-ca.db.attr
echo 01 > ${PKI_CONFIG_ROOT}/ca/root-ca/db/root-ca.crt.srl
echo 01 > ${PKI_CONFIG_ROOT}/ca/root-ca/db/root-ca.crl.srl

print_header "1.3 Create CA request"
if ! [ -e ${PKI_CONFIG_ROOT}/ca/root-ca/private/root-ca.key ] ; then
	openssl req -new \
	    -nodes \
	    -config ${PKI_CONFIG_ROOT}/root-ca.conf \
	    -out ${PKI_CONFIG_ROOT}/ca/root-ca.csr \
	    -keyout ${PKI_CONFIG_ROOT}/ca/root-ca/private/root-ca.key
fi

print_header "1.4 Create CA certificate (self signed)"
if ! [ -e ${PKI_CONFIG_ROOT}/ca/root-ca.crt ] ; then
	(echo "y"; echo "y") | \
	openssl ca -selfsign \
	    -config ${PKI_CONFIG_ROOT}/root-ca.conf \
	    -in ${PKI_CONFIG_ROOT}/ca/root-ca.csr \
	    -out ${PKI_CONFIG_ROOT}/ca/root-ca.crt \
	    -extensions root_ca_ext \
	    -days 3650  \
	    -enddate 20301231235959Z \
	    -notext
fi

print_header "1.5 Create initial CRL"
if ! [ -e ${PKI_CONFIG_ROOT}/crl/root-ca.crl ] ; then
	openssl ca -gencrl \
	    -config ${PKI_CONFIG_ROOT}/root-ca.conf \
	    -out ${PKI_CONFIG_ROOT}/crl/root-ca.crl
fi

print_header "2. Create Supply CA"
print_header "2.1 Create directories"
mkdir -p ${PKI_CONFIG_ROOT}/ca/supply-ca/private ${PKI_CONFIG_ROOT}/ca/supply-ca/db
chmod 700 ${PKI_CONFIG_ROOT}/ca/supply-ca/private

print_header "2.2 Create database"
if ! [ -e ${PKI_CONFIG_ROOT}/ca/supply-ca/db/supply-ca.db ] ; then
	cp /dev/null ${PKI_CONFIG_ROOT}/ca/supply-ca/db/supply-ca.db
fi
if ! [ -e ${PKI_CONFIG_ROOT}/ca/supply-ca/db/supply-ca.db.attr ] ; then
	cp /dev/null ${PKI_CONFIG_ROOT}/ca/supply-ca/db/supply-ca.db.attr
fi
if ! [ -e ${PKI_CONFIG_ROOT}/ca/supply-ca/db/supply-ca.crt.srl ] ; then
	echo 01 > ${PKI_CONFIG_ROOT}/ca/supply-ca/db/supply-ca.crt.srl
fi
if ! [ -e ${PKI_CONFIG_ROOT}/ca/supply-ca/db/supply-ca.crl.srl ] ; then
	echo 01 > ${PKI_CONFIG_ROOT}/ca/supply-ca/db/supply-ca.crl.srl
fi

print_header "2.3 Create CA request"
if ! [ -e ${PKI_CONFIG_ROOT}/ca/supply-ca/private/supply-ca.key ] ; then
	openssl req -new \
	    -nodes \
	    -config ${PKI_CONFIG_ROOT}/supply-ca.conf \
	    -out ${PKI_CONFIG_ROOT}/ca/supply-ca.csr \
	    -keyout ${PKI_CONFIG_ROOT}/ca/supply-ca/private/supply-ca.key
fi

print_header "2.4 Create CA certificate (sign with root CA)"
if ! [ -e ${PKI_CONFIG_ROOT}/ca/supply-ca.crt ] ; then
	(echo "y"; echo "y") | \
	openssl ca \
	    -config ${PKI_CONFIG_ROOT}/root-ca.conf \
	    -in ${PKI_CONFIG_ROOT}/ca/supply-ca.csr \
	    -out ${PKI_CONFIG_ROOT}/ca/supply-ca.crt \
	    -enddate 20301231235959Z \
	    -notext
fi

print_header "2.6 Create PEM bundle"
cat ${PKI_CONFIG_ROOT}/ca/root-ca.crt ${PKI_CONFIG_ROOT}/ca/supply-ca.crt \
    >${PKI_CONFIG_ROOT}/ca/supply-ca-chain.pem

print_header "7. Publish Certificates"
print_header "7.1 Create DER certificate"
if ! [ -e ${PKI_CONFIG_ROOT}/ca/root-ca.cer ] ; then
	openssl x509 \
	    -in ${PKI_CONFIG_ROOT}/ca/root-ca.crt \
	    -out ${PKI_CONFIG_ROOT}/ca/root-ca.cer \
	    -outform der
fi

print_header "Copying ca certs to be copied to slave nodes"

# When provisionning servers, all of the certs in this folder will end up in
# the slave nodes in /etc/ssl/certs. So we just push our 3 CA's certs there.
CLIENT_KEYS_FOLDER=/var/lib/supply/ssl
mkdir -p ${CLIENT_KEYS_FOLDER}/ca
cp ${PKI_CONFIG_ROOT}/ca/root-ca.crt ${CLIENT_KEYS_FOLDER}/ca/supply-pki-root-ca.pem
cp ${PKI_CONFIG_ROOT}/ca/supply-ca.crt ${CLIENT_KEYS_FOLDER}/ca/supply-pki-supply-ca.pem
cp ${PKI_CONFIG_ROOT}/ca/supply-ca-chain.pem ${CLIENT_KEYS_FOLDER}/ca/supply-pki-supply-ca-chain.pem
chown -R www-data:www-data ${CLIENT_KEYS_FOLDER}/ca
chgrp www-data /var/lib/supply
chgrp www-data /var/lib/supply/ssl
