summaryrefslogtreecommitdiff
path: root/client_maker_erg.sh
diff options
context:
space:
mode:
Diffstat (limited to 'client_maker_erg.sh')
-rwxr-xr-xclient_maker_erg.sh316
1 files changed, 316 insertions, 0 deletions
diff --git a/client_maker_erg.sh b/client_maker_erg.sh
new file mode 100755
index 0000000..ed153f1
--- /dev/null
+++ b/client_maker_erg.sh
@@ -0,0 +1,316 @@
+#!/usr/bin/env bash
+##############################################################################
+# HEADER #
+##############################################################################
+# Script for generating SSL certificates.
+##############################################################################
+# END_OF_HEADER #
+##############################################################################
+
+usage() {
+ echo "Script name: $0";
+ echo "";
+ echo "Usage: $0 --key-type [ RSA | EC | EX25519 ]";
+ echo " --curve [ P-256 | P-384 | P512 ]";
+ echo " --rsa-bits [ 2048 | 4096 ]";
+ echo " --days <n>";
+ echo "";
+ echo "Options: ";
+ echo " --key-type [ RSA | EC | EC25519 ]";
+ echo " Note: Pico W can use EC or RSA keys only, not EC25519,";
+ echo " and Tasmota can only use 2048 bit RSA keys.";
+ echo " --curve [ P-256 | P-384 | P512 ]";
+ echo " --rsa-bits [ 2048 | 4096 ]";
+ echo " --days [ <integer> ]";
+ echo " --dir [ <mosquitto directory> ]";
+ echo " --output-format [ PEM | DER ]";
+ echo " --user <string>";
+ echo " --config <path-to-cnf-file>";
+ echo " --ca_key <path-to-CA_key>";
+ echo " --ca_cert <path-to-CA_cert>";
+ }
+
+TEMP="$(getopt -o hkcrd --long help,key-type:,curve:,rsa-bits:,days:,dir:,output-format:,user:,config:,ca_key:,ca_cert: -- "$@")"
+
+eval set -- "$TEMP"
+
+if [ $# == 0 ] ; then
+ usage;
+ exit 1;
+fi
+
+KEY_TYPE="EC"
+CURVE="P-256"
+RSA_BITS=2048
+DAYS=365
+MOSQUITTO_DIR="/home/erg/cert_test"
+OUTPUT_FORMAT=
+MOSQUITTO_USER=
+PKEYOPT=
+SSL_CNF=
+SSL_CA_KEY=
+SSL_CA_CRT=
+
+while true
+do
+ case "$1" in
+ -h|--help)
+ usage
+ exit 0;
+ ;;
+ --key-type) KEY_TYPE="$2"; echo "Key type: $KEY_TYPE"; shift 2;;
+ # Note: Pico W can use EC or RSA keys only, not EC25519, and Tasmota can only use 2048 bit RSA keys.
+ # Default choice of Key Types: RSA, EC, or ED25519
+ --curve) CURVE="$2"; echo "Curve: $CURVE"; shift 2;;
+ # Choice of NIST Curves for EC Keys: P-256, P-384 or P-521
+ --rsa-bits) RSA_BITS="$2"; echo "RSA bits: $RSA_BITS"; shift 2;;
+ # Choice of Bits for RSA Keys: 2048 or 4096
+ --days) DAYS="$2"; echo "Valid for: $DAYS"; shift 2;;
+ # How many days is the Cert valid for?
+ --dir) MOSQUITTO_DIR="$2"; echo "Working directory: $MOSQUITTO_DIR"; shift 2;;
+ --output-format) OUTPUT_FORMAT="$2"; echo "Output format: $OUTPUT_FORMAT"; shift 2;;
+ --user) MOSQUITTO_USER="$2"; echo "Mosquitto user: $MOSQUITTO_USER"; shift 2;;
+ --config) SSL_CNF="$2"; shift 2;;
+ --ca_key) SSL_CA_KEY="$2"; shift 2;;
+ --ca_cert) SSL_CA_CRT="$2"; shift 2;;
+ -- ) shift; break;;
+ * ) break;;
+ esac
+done
+
+##############################################################################
+# Checks that sane arguments passed: #
+##############################################################################
+
+# Check key type:
+if [ "$KEY_TYPE" != 'EC' ] && [ "$KEY_TYPE" != 'RSA' ] && [ "$KEY_TYPE" != 'EC25519' ]; then
+ echo "Wrong key type specified: '$KEY_TYPE'"
+ echo "Valid keys: [ EC | RSA | EC25519 ]"
+ usage
+ exit 1;
+fi
+
+# Set the specific PKEYOPT for the chosen algorithm (BLANK for ED25519)
+if [ "${KEY_TYPE}" == "EC" ]; then
+ echo 'Create EC Key'
+ PKEYOPT="-pkeyopt ec_paramgen_curve:${CURVE}"
+elif [ "${KEY_TYPE}" == "RSA" ]; then
+ echo 'Create RSA Key'
+ PKEYOPT="-pkeyopt rsa_keygen_bits:${RSA_BITS}"
+elif [ "${KEY_TYPE}" == "ED25519" ]; then
+ echo 'Create ED25519 Key'
+ PKEYOPT=""
+else
+ echo "Setting -PKEYOPT to defaults: -pkeyopt ec_paramgen_curve:${CURVE}"
+fi
+
+# Check curve:
+if [ "$CURVE" != 'P-256' ] && [ "$CURVE" != 'P-384' ] && [ "$CURVE" != 'P-521' ]; then
+ echo "Wrong NIST curve specified: '$CURVE'"
+ echo "Curve must be one of: [ P-256 | P-384 | P-521 ]"
+ usage
+ exit 1;
+fi
+
+# Check RSA bits:
+if [ "$RSA_BITS" != '2048' ] && [ "$RSA_BITS" != '4096' ]; then
+ echo "Wrong RSA bits specified: '$RSA_BITS'"
+ echo "Must be one of: [ 2048 | 4096 ]"
+ usage
+ exit 1;
+fi
+
+# Check days parameter is a number:
+if [ -n "$DAYS" ] && [ "$DAYS" -eq "$DAYS" ] 2>/dev/null; then
+ echo "Certificate will be valid for: '$DAYS' days"
+else
+ echo "Not a number: $DAYS"
+ usage
+ exit 1;
+fi
+
+# Check output format:
+if [ "${OUTPUT_FORMAT}" == 'PEM' ] || [ "${OUTPUT_FORMAT}" == 'pem' ]; then # I: Double quote to prevent globbing and word splitting.
+ OUTPUT_FORMAT="pem"
+elif [ "$OUTPUT_FORMAT" == 'DER' ] || [ "$OUTPUT_FORMAT" == 'der' ]; then # I: Double quote to prevent globbing and word splitting.
+ OUTPUT_FORMAT="der"
+else echo "Incorrect certificate format type specified: $OUTPUT_FORMAT";
+ usage
+ exit 1;
+fi
+
+# Check user supplied:
+if [ -z "$MOSQUITTO_USER" ] && [ "$MOSQUITTO_USER" != " " ]; then
+ echo "Specified: '$MOSQUITTO_USER' as user."
+ echo "Need to specify a non-empty username for the certificate!";
+ usage
+ exit 1;
+fi
+
+# Check CA key and cert exist:
+if [ ! -f ${SSL_CA_CRT} ] || [ ! -f ${SSL_CA_KEY} ]; then
+ echo "CA certificate does not exist, exiting!"
+ exit 1
+fi
+# Check CA certificate is still valid:
+# Date format we get from openssl:
+# Nov 18 13:47:56 2034 GMT
+# %b %d %H:%M:%S %Y %Z
+# compare dates from the CA cert and current one:
+CERT_VALID_UNTIL=$(openssl x509 -enddate -noout -in "${SSL_CA_CRT}" | cut -d'=' -f2)
+echo "CA certificate valid until: ${CERT_VALID_UNTIL}"
+if [ ! $(($(date -d "$CERT_VALID_UNTIL" +"%s") > $(date +"%s"))) ];then
+ echo "CA certificate expired, exiting!"
+ exit 1
+fi
+
+
+##############################################################################
+# Set up variables #
+##############################################################################
+
+# Set the algorithm
+ALGORITHM="-algorithm ${KEY_TYPE}"
+
+# Output client key, CSR request and certificate
+CLIENT_KEY="${MOSQUITTO_DIR}/certs/clients/${MOSQUITTO_USER}/${MOSQUITTO_USER}_key.${OUTPUT_FORMAT}"
+CLIENT_CSR="${MOSQUITTO_DIR}/certs/clients/${MOSQUITTO_USER}/${MOSQUITTO_USER}_req.csr"
+CLIENT_CERT="${MOSQUITTO_DIR}/certs/clients/${MOSQUITTO_USER}/${MOSQUITTO_USER}_crt.${OUTPUT_FORMAT}"
+
+##############################################################################
+# Locks #
+##############################################################################
+
+LOCK_FILE=/tmp/$SUBJECT.lock
+if [ -f "$LOCK_FILE" ]; then
+ echo "Script is already running"
+ exit
+fi
+
+trap 'rm -f $LOCK_FILE' EXIT
+touch "$LOCK_FILE"
+
+##############################################################################
+# Backup existing certs and create dir structure #
+##############################################################################
+
+# If our user certs dir already exists, rename it so we don't
+# overwrite anything important.
+
+time_stamp=$(date +"%Y-%m-%d_%H-%M")
+mv "${MOSQUITTO_DIR}/certs/csr_files/${MOSQUITTO_USER}_req.csr" "${MOSQUITTO_DIR}/certs/clients/${MOSQUITTO_USER}" 2>/dev/null
+mv "${MOSQUITTO_DIR}/certs/clients/${MOSQUITTO_USER}req" "${MOSQUITTO_DIR}/certs/clients/${MOSQUITTO_USER}-${time_stamp}" 2>/dev/null
+
+mkdir -p "${MOSQUITTO_DIR}/certs/clients/${MOSQUITTO_USER}"
+
+##############################################################################
+# Create the key in the requested format #
+##############################################################################
+
+echo "Running:"
+echo "
+openssl genpkey ${ALGORITHM} ${PKEYOPT} \
+-outform ${OUTPUT_FORMAT} \
+-out ${CLIENT_KEY} \
+-config ${SSL_CNF}
+"
+
+openssl genpkey ${ALGORITHM} ${PKEYOPT} \
+ -outform "${OUTPUT_FORMAT}" \
+ -out "${CLIENT_KEY}" \
+ -config "${SSL_CNF}"
+
+retval=$?
+if [ $retval -ne 0 ]; then
+ echo "Generating key failed!"
+ exit $retval
+fi
+printf '\n\n'
+echo "#######################################################################"
+printf '\n\n'
+echo "Successfully generated client key."
+##############################################################################
+# Create the cert signing request #
+##############################################################################
+
+
+echo "Running:"
+echo "
+openssl req \
+-new \
+-nodes \
+-key $CLIENT_KEY \
+-subj /CN=${MOSQUITTO_USER} \
+-out $CLIENT_CSR \
+-config ${SSL_CNF}
+"
+openssl req \
+ -new \
+ -nodes \
+ -key "${CLIENT_KEY}" \
+ -subj "/CN=${MOSQUITTO_USER}" \
+ -out "${CLIENT_CSR}" \
+ -config "${SSL_CNF}"
+
+retval=$?
+if [ $retval -ne 0 ]; then
+ echo "Generating CSR request failed!"
+ exit $retval
+fi
+echo "Successfully generated CSR request"
+
+printf '\n\n'
+echo "#######################################################################"
+printf '\n\n'
+
+##############################################################################
+# Cert signing and creation #
+##############################################################################
+
+echo "Running:"
+echo "openssl x509 \
+-req \
+-in ${CLIENT_CSR} \
+-CA ${SSL_CA_CRT} \
+-CAkey ${SSL_CA_KEY} \
+-CAcreateserial \
+-out ${CLIENT_CERT} \
+-outform ${OUTPUT_FORMAT} \
+-days ${DAYS} \
+-config ${SSL_CNF}
+"
+openssl x509 \
+ -req \
+ -in "${CLIENT_CSR}" \
+ -CA "${SSL_CA_CRT}" \
+ -CAkey "${SSL_CA_KEY}" \
+ -CAcreateserial \
+ -out "${CLIENT_CERT}" \
+ -outform "${OUTPUT_FORMAT}" \
+ -days "${DAYS}" \
+
+retval=$?
+if [ $retval -ne 0 ]; then
+ echo "Signing CSR and certificate creation failed!"
+ exit $retval
+fi
+echo "Successfully signed CSR and created client certificate."
+
+printf '\n\n'
+echo "#######################################################################"
+printf '\n\n'
+
+##############################################################################
+# Check the cert #
+##############################################################################
+
+printf '# This is your new client certificate\n\n\n'
+
+openssl x509 \
+ -text \
+ -in "${CLIENT_CERT}" \
+ -noout
+
+printf '\n\n'
+echo "#######################################################################"
+printf '\n\n'