Skip to content

Instantly share code, notes, and snippets.

@jmkim
Created October 8, 2016 07:58
Show Gist options
  • Save jmkim/6568ab3a50c7355f7d9123dc6657b63b to your computer and use it in GitHub Desktop.
Save jmkim/6568ab3a50c7355f7d9123dc6657b63b to your computer and use it in GitHub Desktop.
#!/bin/bash
# This script will create you CA-signed client certificate.
#
# First, please follow these steps:
# - Create the root pair
# - Create the intermediate pair
# in https://jamielinux.com/docs/openssl-certificate-authority/
#
# Second, this script will NOT use attributes defined in your
# `openssl.cnf'. Define your C, ST, and O to the head of this
# script.
#
# Usage: script_name [commonName]
# script_name [subjectAltName1] [subjectAltName2] [subjectAltName3] ...
#
# openssl attributes
export C="GB" # Country Name (2 letter code)
export ST="England" # State or Province Name
export O="Alice Ltd" # Organization Name
export SLEEPTIME=10 # Sleeping time (sec)
newcert()
{
# openssl attributes (which were passed as parameter)
export CN=$1 # commonName
export SAN="DNS:$1" # subjectAltName
for host in "${@:2}"; do
export SAN="$SAN,DNS:$host" # subjectAltName (append in loop)
done
# Script environment variables
export BASE_DIR="intermediate" # Base directory (your intermediate CA directory)
export CONFIG_FILE="$BASE_DIR/openssl.cnf" # Location of your intermediate CA configuration file (intermediate/openssl.cnf)
export KEY_FILE="$BASE_DIR/private/$CN.key.pem" # Private key output location
export KEY_SIZE=2048 # Size of private key (bit)
export CSR_FILE="$BASE_DIR/csr/$CN.csr.pem" # CSR output location
export CERT_FILE="$BASE_DIR/certs/$CN.cert.pem" # Certificate output location
export CERT_DAYS=3750 # Certificate validity period (day)
# Echo for double-checking
echo -e "List of parameters:\n\t$1"
for host in "${@:2}"; do
echo -e "\t$host"
done
echo -e "\nList of openssl attributes:\n" \
"\tcountryName\t\t" "$C\n" \
"\tstateOrProvinceName\t" "$ST\n" \
"\torganizationName\t" "$O\n" \
"\tcommonName\t\t" "$CN\n" \
"\tsubjectAltName\t\t" "$SAN\n"
echo -e "List of script environment variables:\n" \
"\tBASE_DIR\t" "$BASE_DIR\n" \
"\tCONFIG_FILE\t" "$CONFIG_FILE\n" \
"\tKEY_FILE\t" "$KEY_FILE\n" \
"\tKEY_SIZE\t" "$KEY_SIZE\n" \
"\tCSR_FILE\t" "$CSR_FILE\n" \
"\tCERT_FILE\t" "$CERT_FILE\n" \
"\tCERT_DAYS\t" "$CERT_DAYS\n"
echo -e "I will sleep for $SLEEPTIME seconds.. (Press Ctrl-C to terminate)\n"
sleep $SLEEPTIME
# Create a private key
openssl genrsa -out $KEY_FILE $KEY_SIZE
EXITCODE=$?
if [[ $EXITCODE != 0 ]]; then
error_exit 2 $EXITCODE
fi
chmod 400 $KEY_FILE
# Create a certificate signing request (interactive)
openssl req \
-subj "/countryName=$C/stateOrProvinceName=$ST/organizationName=$O/commonName=$CN" \
-config <(cat $CONFIG_FILE <(printf "[san]\nsubjectAltName=$SAN")) \
-extensions san -key $KEY_FILE -new -sha256 -out $CSR_FILE
EXITCODE=$?
if [[ $EXITCODE != 0 ]]; then
error_exit 3 $EXITCODE
fi
# Create a certificate and do signing using intermediate CA
openssl ca \
-config $CONFIG_FILE -extfile <(cat $CONFIG_FILE <(printf "[san]\nsubjectAltName=$SAN")) \
-extensions server_cert -extensions san -days $CERT_DAYS -notext -md sha256 -in $CSR_FILE -out $CERT_FILE
EXITCODE=$?
if [[ $EXITCODE != 0 ]]; then
error_exit 4 $EXITCODE
fi
chmod 444 $CERT_FILE
# Verify the certificate
openssl x509 -noout -text -in $CERT_FILE
return 0
}
error_exit()
{
MESSAGE="Error: "
case $1 in
2) MESSAGE="${MESSAGE}Failed to create private key.";;
3) MESSAGE="${MESSAGE}Failed to create certificate signing request.";;
4) MESSAGE="${MESSAGE}Failed to create certificate.";;
esac
MESSAGE="${MESSAGE} (exit code: $2)"
(>&2 echo "$MESSAGE")
exit $2
}
if [[ $# < 1 ]]; then
echo "Usage: $0 [commonName]"
echo " $0 [subjectAltName1] [subjectAltName2] [subjectAltName3] ... "
exit 1
else
newcert "$@"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment