Skip to content

Instantly share code, notes, and snippets.

@sindarina
Created October 11, 2017 18:17
Show Gist options
  • Save sindarina/efde7e11d33077963294e2e65f68d8e7 to your computer and use it in GitHub Desktop.
Save sindarina/efde7e11d33077963294e2e65f68d8e7 to your computer and use it in GitHub Desktop.
Generate a self-signed certificate, with SAN override
#!/bin/bash
#
# Generates a proper non-CA self-signed certificate for testing, default
# server stanzas, and so on. Based on Heroku tutorial here;
#
# https://devcenter.heroku.com/articles/ssl-certificate-self
#
# Single use only; generates a time-stamped server certificate, removes
# the root and CSR afterwards.
#
umask 177
# How long does the certificate need to be valid for (in days)? We assume
# a default of a year + 14 days, in case one wants to do yearly refreshes.
#
VALID_UNTIL=1100
echo "#
# This script will generate a self-signed, non-CA SHA2 certificate for use
# in testing, default server stanzas, and so on. Use at your own risk.
#"
DTAG="$( date "+%Y%m%d-%H%M%S" )"
CERT_NAME="self-signed-localhost-${DTAG}"
CERT_CONF="$( mktemp generate-self-signed.XXXXX )"
# The hash is used to give each generated certificate a unique CN.
#
DTAG_HASH="$( echo ${DTAG} | openssl md5 | sed 's/(stdin)= //' | cut -c 2-12 | tr '[:lower:]' '[:upper:]' )"
# Variables for 'subjectAltName' (SAN) settings
#
SAN="DNS:localhost,IP:127.0.0.1"
SAN_OVERRIDE="${1}"
# Small function to do proper cleanup on errors
#
gssc_error(){
echo -e "\nAn error occurred, cleaning up ...\n"
rm ${CERT_CONF}
rm ${CERT_NAME}.*
exit 1
}
# Pick up the commandline argument, if it was specified
#
if [ "x${SAN_OVERRIDE}" == 'x' ]; then
echo "# The default setting for 'subjectAltName' is '${SAN}'.
#
# You can specify a different value by passing it to the script as a quoted
# argument, like so;
#
# $ ${0} '${SAN}'"
else
SAN="${SAN_OVERRIDE}"
fi
# Set up the temporary OpenSSL configuration file, to make sure we
# are not inheriting custom settings from elsewhere on the system.
#
cat > ${CERT_CONF} << EOF
[ req ]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[ req_distinguished_name ]
O = Strategic Homeland Intervention
OU = Enforcement and Logistics Division
CN = Self-Signed Certificate - ${DTAG_HASH}
[v3_req]
basicConstraints = CA:FALSE
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = ${SAN}
EOF
# Go through the motions of creating the various keys, the CSR,
# and finally create the self-signed certificate.
#
echo
openssl genrsa -des3 -passout pass:t3mp -out ${CERT_NAME}.pass.key 2048
openssl rsa -passin pass:t3mp -in ${CERT_NAME}.pass.key \
-out ${CERT_NAME}.key && rm ${CERT_NAME}.pass.key
echo -e "\n# Generating CSR\n#"
openssl req -new -key ${CERT_NAME}.key -out ${CERT_NAME}.csr \
-config ${CERT_CONF} || gssc_error
openssl req -text -noout -in ${CERT_NAME}.csr
echo -e "\n# Generating self-signed certificate\n#"
openssl x509 -req -sha256 -days ${VALID_UNTIL} -in ${CERT_NAME}.csr \
-signkey ${CERT_NAME}.key -out ${CERT_NAME}.pem \
-extensions v3_req -extfile ${CERT_CONF} || gssc_error
openssl x509 -text -noout -in ${CERT_NAME}.pem
# Clean up on success
#
rm ${CERT_NAME}.csr
rm ${CERT_CONF}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment