#!/bin/bash
# ssl_key_generate
#	Small utility to generate a self-signed SSL key for Postgres

set -e

which openssl > /dev/null 2>&1
ERRNUM=$?
if [ $? != 0 ]; then
	echo "Could not found open ssl in PATH=$PATH"
	exit 1
fi

# Details of the server certificate
SSL_DOMAIN=127.0.0.1 # Use local address for development
SSL_COMMON_NAME=127.0.0.1 # Use local address for development
SSL_COUNTRY=ER
SSL_STATE=Earth
SSL_LOCALITY=Planet
SSL_ORGANIZATION=example.com
SSL_ORGANIZATIONAL_UNIT=IT
SSL_EMAIL=john.doe@example.com

# Output names
SSL_KEY=server.key # Key
SSL_CSR=server.csr # Request
SSL_CRT=server.crt # certificate

# Not mandatory
SSL_PASSWORD=some_password

# Configuration settings for client certificate
SSL_CA_CONF=$PGDATA/openssl-ca.cnf
SSL_CA_CSR=client.csr
SSL_CA_KEY=client.key
SSL_CA_CRT=client.crt

# 1) Generate a private key
openssl genrsa -des3 -passout pass:$SSL_PASSWORD -out $SSL_KEY 2048 -noout

# 2) Remove passphrase from the key. Comment the line out to keep the
# passphrase
openssl rsa -in $SSL_KEY -passin pass:$SSL_PASSWORD -out $SSL_KEY

# 3) Create the CSR request
openssl req -new -key $SSL_KEY -out $SSL_CSR -passin pass:$SSL_PASSWORD \
		-subj "/C=$SSL_COUNTRY/ST=$SSL_STATE/L=$SSL_LOCALITY/O=$SSL_ORGANIZATION/OU=$SSL_ORGANIZATIONAL_UNIT/CN=$SSL_COMMON_NAME/emailAddress=$SSL_EMAIL"

# 4) Generate the self-signed certificate
openssl x509 -req -days 365 -in $SSL_CSR -signkey $SSL_KEY -out $SSL_CRT

# Permission level needed by Postgres
chmod 600 $SSL_KEY

# Begin generation of a client certificate using the server stuff generated
# just previously.
# Such certificates are useful for obvious security reasons first. Now for
# development purposes they can prove to be useful as well to generate some
# information for MyProcPort->peer in a Postgres instance.
# In postgresql.conf, ssl_ca_file will need to be updated as well with
# the file name generated here, and ssl_ca_file = '$SSL_KEY'.
# Once generated this client certificate can be used to connect to Postgres
# with the following connection string or similar:
# host=127.0.0.1 sslmode=verify-full sslcert=$SSL_CA_CRT \
#   sslkey=$SSL_CA_KEY sslrootcert=$SSL_CRT
cat > $SSL_CA_CONF <<EOF
[ ssl_client ]
basicConstraints = CA:FALSE
nsCertType = client
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
EOF

# Client certificate, using extensions
openssl req -new -nodes -keyout $SSL_CA_KEY -out $SSL_CA_CSR \
		-subj "/C=$SSL_COUNTRY/ST=$SSL_STATE/L=$SSL_LOCALITY/O=$SSL_ORGANIZATION/OU=$SSL_ORGANIZATIONAL_UNIT/CN=$USER"
openssl x509 -req -CAcreateserial -in $SSL_CA_CSR -CA $SSL_CRT \
		-CAkey $SSL_KEY -out $SSL_CA_CRT -extfile $SSL_CA_CONF \
		-extensions ssl_client
chmod 600 $SSL_CA_KEY
