#!/bin/bash
STEP=00
DATE=$(date +%Y-%m-%d-%H.%M.%S-%N)
CERTDIR="$(pwd)/$DATE"
CA=$1
CABASE=$CA
CADIR=$CERTDIR/$CA
SVR=$2
SERVER=serverconfig
CLIENT=clientconfig
CONFIG=config
SERVERCONFIG=$CERTDIR/$SERVER.cnf
CLIENTCONFIG=$CERTDIR/$CLIENT.cnf
OPENSSLCONFIG=$CERTDIR/$CONFIG.cnf
#CACONFIG="-config $OPENSSLCONFIG"
CACONFIG=
LOGFILE=$(uuidgen).log
KEYTYPE=rsa
KEYLENGHT=2048
SUCCESS=0
WRONG_ARGS=65
OK=OK
KO=KO
CACRT=$KO
CAKEY=$KO
CAISOK=$KO
DAYSCA=120
DAYSCRT=$(expr $DAYSCA / 3)
#KEYTOOL=/usr/java/latest/bin/keytool
KEYTOOL=keytool
PASS=testpassword
#CA
CA_C="IT"
CA_ST="MyState"
CA_L="MyTown"
#CA_O="Example S.p.A."
CA_O="ACME I.n.c."
CA_OU="CA Organization Unit"
#CA_OU="CA organization Unit"
CA_emailAddress="ca@example.com"
#Server
SVR_C="IT"
SVR_ST="MyState"
SVR_L="MyTown"
SVR_O="Example S.p.A."
SVR_OU="Server Organization Unit"
SVR_emailAddress="server@example.com"
#Client
CLN_C="IT"
CLN_ST="MyState"
CLN_L="MyTown"
CLN_O="Example S.p.A."
CLN_OU="Client Organization Unit"
CLN_emailAddress="client@example.com"
FERROR ()
{
cat << EOF
 echo STEP=$STEP
 echo "Missing ca and certificate name:"
 echo "Usage: $(basename $0) ca certificato"
 echo "IE: $(basename $0) ca www.example.com"
 echo "Entering $(basename $0) ca default
 echo "ca-$(hostname -f) will be the ca and $(hostname -f) will be the server"
 echo "To use the same ca for signing new certificates type:"
 echo "$(basename $0) ca www.example.com"
 echo "Where ca is the full path and filename of .crt file. .crt and .key files must exist"
 echo "IE: /somewhere/path/cert.crt"
EOF
}
STEP=01
[ ! $(which openssl 2>/dev/null) ] && echo missing openssl, please install openssl and retry && exit 1
[ $# -ne 2 ] && FERROR && exit $WRONG_ARGS
#[ "$2" = "default" ] && CA=ca-$(hostname -f) && SVR=$(hostname -f) && CADIR=$CERTDIR/ca
[ ! -d "$CERTDIR" ] && mkdir -p "$CERTDIR"
echo STEP=02 >>$CERTDIR/$LOGFILE
[ "$2" = "default" ] && SVR=$(hostname -f)
COMMONNAME=$SVR
SUBJECTALTNAME=$SVR
SUBJECTALTNAME2=${SVR#*.}
CA_CN="$CA"
SVR_CN="$SVR"
CLN_CN="$(tr -cd 'A-Z0-9' < /dev/urandom | head -c 16)"
echo STEP=03 >>$CERTDIR/$LOGFILE
[ -f $CA ] && INPUT=$(cd $(dirname $CA); pwd)/$(basename $CA) && CADIR=${INPUT%/*} && CABASE=$(basename $CA .crt)
[ -f $CADIR/$CABASE.key -a -f $CADIR/$CABASE.crt ] && CAISOK=$OK || CAISOK=$CAISOK
echo STEP=04 >>$CERTDIR/$LOGFILE
[ "$CAISOK" = "$OK" ] && [ "$(openssl x509 -noout -modulus -in $CADIR/$CABASE.crt 2>>$CERTDIR/$LOGFILE| openssl sha1)" = "$(openssl rsa -noout -modulus -in $CADIR/$CABASE.key 2>>$CERTDIR/$LOGFILE|openssl sha1)" ] && CAISOK=$OK || CAISOK=$KO >>$CERTDIR/$LOGFILE 2>&1
echo STEP=05 >>$CERTDIR/$LOGFILE
[ "$CAISOK" = "$OK" ] && CA_CN="$(openssl x509 -noout -in $CADIR/$CABASE.crt -subject|awk -F "/|=" '/CN=/ {print $10}')" >>$CERTDIR/$LOGFILE 2>&1
[ -f $CADIR/$CABASE.key -a -f $CADIR/$CABASE.crt -a -f $CADIR/$CABASE.srl ] && CAcreateserial= || CAcreateserial="-CAcreateserial"
#exit 0
echo STEP=06 >>$CERTDIR/$LOGFILE
echo "SVR=$SVR\nCERTDIR=$CERTDIR\nCA=$CA\nCADIR=$CADIR\nSUBJECTALTNAME=$SUBJECTALTNAME\nSUBJECTALTNAME2=$SUBJECTALTNAME2\nCABASE=$CABASE\nCAcreateserial=$CAcreateserial\nCAISOK=$CAISOK\nCA_CN=$CA\nSVR_CN=$SVR\nCLN_CN=$CLN_CN" >>$CERTDIR/$LOGFILE 2>&1
#exit 0
echo STEP=07 >>$CERTDIR/$LOGFILE
cat <<EOF >> $OPENSSLCONFIG
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
basicConstraints = CA:true
subjectAltName=email:move
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = IT
localityName = Locality Name (eg, city)
organizationalUnitName = Organizational Unit Name (eg, section)
commonName = Common Name (eg, YOUR name)
commonName_max = 64
emailAddress = Email Address
[v3_req_client]
basicConstraints = critical,CA:FALSE
#keyUsage = keyEncipherment, dataEncipherment, digitalSignature
keyUsage = nonRepudiation, keyEncipherment, digitalSignature
extendedKeyUsage = serverAuth, clientAuth
subjectKeyIdentifier = hash
#authorityKeyIdentifier = keyid
subjectAltName = @alt_names
[alt_names]
DNS.1   = $SUBJECTALTNAME
DNS.2   = client.$SUBJECTALTNAME
#IP.1    = 192.168.1.1
#IP.2    = 192.168.69.144
[v3_req_server]
basicConstraints = critical,CA:FALSE
keyUsage = keyEncipherment, dataEncipherment, digitalSignature
extendedKeyUsage = serverAuth, clientAuth
subjectKeyIdentifier = hash
#authorityKeyIdentifier = keyid
subjectAltName = @alt_names
[alt_names]
DNS.1   = $SUBJECTALTNAME
DNS.2   = *.$SUBJECTALTNAME2
#IP.1    = 10.2.3.4
#IP.2    = 192.168.3.12
EOF
echo STEP=08 >>$CERTDIR/$LOGFILE
[ $CAISOK = $OK ] && echo "1a Using $CA CA" >>$CERTDIR/$LOGFILE 2>&1
echo STEP=09 >>$CERTDIR/$LOGFILE
[ $CAISOK = $KO ] && echo "1a CA does not exist: Creating a self signed demo CA" >>$CERTDIR/$LOGFILE 2>&1 && mkdir -p $CADIR && openssl req -x509 $CACONFIG -extensions v3_ca -nodes -days $DAYSCA -subj "/C=$CA_C/ST=$CA_ST/L=$CA_L/CN=$CA_CN/O=$CA_O/OU=$CA_OU/emailAddress=$CA_emailAddress" -newkey $KEYTYPE:$KEYLENGHT -keyout $CADIR/$CABASE.key -out $CADIR/$CABASE.crt >>$CERTDIR/$LOGFILE 2>&1
echo STEP=0A >>$CERTDIR/$LOGFILE
echo "1b Creating server request" >>$CERTDIR/$LOGFILE 2>&1
openssl req -nodes -config $OPENSSLCONFIG -reqexts v3_req_server -subj "/C=$SVR_C/ST=$SVR_ST/L=$SVR_L/CN=$SVR_CN/O=$SVR_O/OU=$SVR_OU/emailAddress=$SVR_emailAddress" -newkey $KEYTYPE:$KEYLENGHT -keyout $CERTDIR/$SVR.key -out $CERTDIR/$SVR.csr >>$CERTDIR/$LOGFILE 2>&1
echo STEP=0B >>$CERTDIR/$LOGFILE
echo "1c Creating client request" >>$CERTDIR/$LOGFILE 2>&1
openssl req -nodes -config $OPENSSLCONFIG -reqexts v3_req_client -subj "/C=$CLN_C/ST=$CLN_ST/L=$CLN_L/CN=$CLN_CN/O=$CLN_O/OU=$CLN_OU/emailAddress=$CLN_emailAddress" -newkey $KEYTYPE:$KEYLENGHT -keyout $CERTDIR/$SVR-client.key -out $CERTDIR/$SVR-client.csr >>$CERTDIR/$LOGFILE 2>&1
#
echo STEP=0C >>$CERTDIR/$LOGFILE
echo "2a Validating server request with CA certificate" >>$CERTDIR/$LOGFILE 2>&1
openssl x509 -req -days $DAYSCRT -in $CERTDIR/$SVR.csr -extensions v3_req_server -extfile $OPENSSLCONFIG -CA $CADIR/$CABASE.crt -CAkey $CADIR/$CABASE.key $CAcreateserial -CAserial $CADIR/$CABASE.srl -out $CERTDIR/$SVR.crt >>$CERTDIR/$LOGFILE 2>&1
echo STEP=0D >>$CERTDIR/$LOGFILE
echo "2b Validating client request with CA certificate" >>$CERTDIR/$LOGFILE 2>&1
openssl x509 -req -days $DAYSCRT -in $CERTDIR/$SVR-client.csr -extensions v3_req_client -extfile $OPENSSLCONFIG -CA $CADIR/$CABASE.crt -CAkey $CADIR/$CABASE.key $CAcreateserial -CAserial $CADIR/$CABASE.srl -out $CERTDIR/$SVR-client.crt >>$CERTDIR/$LOGFILE 2>&1
#
#echo "4 Convert from pem to der"
#for i in $(ls $CERTDIR/*.crt); do openssl x509 -inform pem -outform der -in $i -out $CERTDIR/${i##*/}.der; done
#
echo STEP=0E >>$CERTDIR/$LOGFILE
echo "3a For VMware: exporting the certificate and key file together to PFX format, with password included in file $CERTDIR/vmware/rui.pass" >>$CERTDIR/$LOGFILE 2>&1
#openssl pkcs12 -rand $CERTDIR/randomfile -export -in $CERTDIR/$SVR.crt -inkey $CERTDIR/$SVR.key -name rui -passout pass:testpassword -out $CERTDIR/rui.pfx 2>/dev/null
echo STEP=0F >>$CERTDIR/$LOGFILE
mkdir -p $CERTDIR/vmware
openssl pkcs12 -export -in $CERTDIR/$SVR.crt -inkey $CERTDIR/$SVR.key -name rui -passout pass:$PASS -out $CERTDIR/vmware/rui.p12 >>$CERTDIR/$LOGFILE 2>&1
echo $PASS > $CERTDIR/vmware/rui.pass
echo STEP=10 >>$CERTDIR/$LOGFILE
mkdir -p $CERTDIR/client
echo "3b For client: exporting the certificate and key file together to PFX format, with password included in file $CERTDIR/client/client.pass" >>$CERTDIR/$LOGFILE 2>&1
openssl pkcs12 -export -in $CERTDIR/$SVR-client.crt -inkey $CERTDIR/$SVR-client.key -name $SVR-client -passout pass:$PASS -out $CERTDIR/client/$SVR-client.p12 >>$CERTDIR/$LOGFILE 2>&1
echo STEP=11 >>$CERTDIR/$LOGFILE
echo "3c For client: building a keystore with private and public key of the client and the server public key, with password included in file $CERTDIR/client/client.pass" >>$CERTDIR/$LOGFILE 2>&1
$KEYTOOL -importkeystore -srckeystore $CERTDIR/client/$SVR-client.p12 -srcstorepass $PASS -destkeystore $CERTDIR/client/$SVR-client.jks -srcstoretype pkcs12 -storepass $PASS >>$CERTDIR/$LOGFILE 2>&1
echo STEP=12 >>$CERTDIR/$LOGFILE
echo "3d For client: add server public key to the keystore" >>$CERTDIR/$LOGFILE 2>&1
$KEYTOOL -import -trustcacerts -alias server.public -file $CERTDIR/$SVR.crt -keystore $CERTDIR/client/$SVR-client.jks -storepass $PASS -noprompt >>$CERTDIR/$LOGFILE 2>&1
echo $PASS > $CERTDIR/client/$SVR-client.pass
echo STEP=13 >>$CERTDIR/$LOGFILE
echo "DONE:\nThe Public Keys\n$(ls $CERTDIR/$SVR.crt $CERTDIR/$SVR-client.crt)\nand the Private Keys\n$(ls $CERTDIR/$SVR.key $CERTDIR/$SVR-client.key)\nfor the Host: $SVR\nhave been created successfully.\nThe logs are stored in $CERTDIR/$LOGFILE"
echo STEP=14 >>$CERTDIR/$LOGFILE
