From 8431da594750d4a949457c649a40fd6db4aee489 Mon Sep 17 00:00:00 2001 From: John Hartley Date: Wed, 26 May 2021 18:00:51 +0100 Subject: [PATCH] Add script to create TLS client cert and CA Problem: We need to demonstrate how to create a CA certificate and client certificates suitable for RKVST TLS client authentication. Solution: Simple shell scripts demonstrating creation and use of a TLS client certificate. Signed-off-by: John Hartley --- .gitignore | 5 ++ Taskfile.yml | 2 +- scripts/example.sh | 5 -- scripts/tls_client_auth/certificateauth.sh | 64 +++++++++++++++++ scripts/tls_client_auth/combined.cnf | 57 +++++++++++++++ .../tls_client_auth/make-tls-client-cert.sh | 71 +++++++++++++++++++ 6 files changed, 198 insertions(+), 6 deletions(-) create mode 100644 .gitignore delete mode 100644 scripts/example.sh create mode 100755 scripts/tls_client_auth/certificateauth.sh create mode 100644 scripts/tls_client_auth/combined.cnf create mode 100755 scripts/tls_client_auth/make-tls-client-cert.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..566672c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.token +*.req +*.key +*.pem +*.tar.gz diff --git a/Taskfile.yml b/Taskfile.yml index 8e04667..58497c8 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -5,7 +5,7 @@ tasks: check: desc: Standard linting of shell scripts cmds: - - shellcheck scripts/*.sh + - find scripts -type f -name '*.sh' | xargs shellcheck clean: desc: Clean git repo diff --git a/scripts/example.sh b/scripts/example.sh deleted file mode 100644 index 9282bdf..0000000 --- a/scripts/example.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# -# Example script to just prove all the github hooks and actions work -# -echo "Running example script - please delete me once other scripts have been added" diff --git a/scripts/tls_client_auth/certificateauth.sh b/scripts/tls_client_auth/certificateauth.sh new file mode 100755 index 0000000..e6c11cf --- /dev/null +++ b/scripts/tls_client_auth/certificateauth.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +set -eu + +SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +SCRIPTNAME=$(basename "$0") + +# check that the required tools are installed +type openssl 2>/dev/null || ( echo >&2 "openssl command not found, please install or add to PATH" && exit 1 ) + +case $1 in + gen-ca) + openssl req \ + -config "$SCRIPTDIR/combined.cnf" \ + -newkey rsa:4096 \ + -sha256 \ + -keyform PEM \ + -keyout "$2.key" \ + -nodes \ + -x509 \ + -days 3650 \ + -outform PEM \ + -out "$2.pem" \ + -subj "/C=GB/CN=$2-$(uuidgen)" \ + -extensions x509v3_CA + ;; + gen-client) + openssl genrsa \ + -out "$2.key" \ + 2048 + openssl req \ + -new \ + -key "$2.key" \ + -out "$2.req" \ + -sha256 \ + -nodes \ + -subj "/C=GB/CN=$2" + openssl x509 \ + -req \ + -in "$2.req" \ + -sha256 \ + -CA "$3.pem" \ + -CAkey "$3.key" \ + -set_serial 101 \ + -extensions client \ + -days 365 \ + -outform PEM \ + -out "$2.pem" + ;; + + print) + openssl x509 \ + -in "$2.pem" \ + -text + ;; + + verify) + openssl verify \ + -CAfile "$3.pem" \ + "$2.pem" + ;; + + *) echo >&2 "Usage: $SCRIPTNAME (gen-ca NAME | gen-client NAME CANAME | print NAME | verify NAME CANAME)" && exit 1 +esac diff --git a/scripts/tls_client_auth/combined.cnf b/scripts/tls_client_auth/combined.cnf new file mode 100644 index 0000000..abbf20b --- /dev/null +++ b/scripts/tls_client_auth/combined.cnf @@ -0,0 +1,57 @@ +# default settings +CERTPATHLEN = 1 +CERTUSAGE = digitalSignature,keyCertSign,cRLSign +EXTCERTUSAGE = serverAuth,clientAuth +CERTIP = 0.0.0.0 +CERTFQDN = nohost.nodomain + +[ req ] +default_bits = 4096 +default_md = sha256 +#default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_min = 2 +countryName_max = 2 +stateOrProvinceName = State or Province Name (full name) +localityName = Locality Name (eg, city) +0.organizationName = Organization Name (eg, company) +organizationalUnitName = Organizational Unit Name (eg, section) +commonName = Common Name (eg, fully qualified host name) +commonName_max = 64 +emailAddress = Email Address +emailAddress_max = 64 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 + +# This section should be referenced when building an x509v3 CA +# Certificate. +# The default path length and the key usage can be overridden +# modified by setting the CERTPATHLEN and CERTUSAGE environment +# variables. +[x509v3_CA] +basicConstraints=critical,CA:true,pathlen:1 +keyUsage=critical,keyCertSign,digitalSignature,dataEncipherment,keyEncipherment,keyAgreement +extendedKeyUsage=serverAuth,clientAuth +#subjectKeyIdentifier=hash +#authorityKeyIdentifier=hash + +# This section should be referenced to add an IP Address +# as an alternate subject name, needed by isakmpd +# The address must be provided in the CERTIP environment variable +[x509v3_IPAddr] +subjectAltName=IP:$ENV::CERTIP +extendedKeyUsage=$ENV::EXTCERTUSAGE + +# This section should be referenced to add a FQDN hostname +# as an alternate subject name, needed by isakmpd +# The address must be provided in the CERTFQDN environment variable +[x509v3_FQDN] +subjectAltName=DNS:$ENV::CERTFQDN +extendedKeyUsage=$ENV::EXTCERTUSAGE diff --git a/scripts/tls_client_auth/make-tls-client-cert.sh b/scripts/tls_client_auth/make-tls-client-cert.sh new file mode 100755 index 0000000..0190bee --- /dev/null +++ b/scripts/tls_client_auth/make-tls-client-cert.sh @@ -0,0 +1,71 @@ +#!/bin/bash +set -eu + +SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +SCRIPTNAME=$(basename "$0") + +AUTHORITY="test" +ARCHIVIST_HOST="rkvst.poc.jitsuin.io" +TLSARCHIVIST_HOST="auth.$ARCHIVIST_HOST" + +# check that the required tools are installed +type curl 2>/dev/null || ( echo >&2 "curl command not found, please install or add to PATH" && exit 1 ) + +usage() { + cat >&2 <&2 "Must supply common name" && exit 1 ) + +COMMON_NAME="$1" +shift + +echo "Checking certficate authority..." +[ -f "$AUTHORITY-ca.pem" ] || "$SCRIPTDIR"/certificateauth.sh gen-ca "$AUTHORITY-ca" + +echo "Checking user cert..." +[ -f "$COMMON_NAME-client.pem" ] || "$SCRIPTDIR"/certificateauth.sh gen-client "$COMMON_NAME-client" "$AUTHORITY-ca" + +echo "Verifying that certs are coherent" +"$SCRIPTDIR"/certificateauth.sh verify "$COMMON_NAME-client" "$AUTHORITY-ca" + +echo "Add root cert ($AUTHORITY-ca.pem) to archivist and press any key to continue ..." +read -r + +echo "Testing client cert" + +curl -fSs --cert "$COMMON_NAME-client.pem" --key "$COMMON_NAME-client.key" \ + -H "Content-Type: application/json" \ + https://$TLSARCHIVIST_HOST/archivist/v2/assets + +echo +echo + +echo "Done - client key: $COMMON_NAME-client.key certificate: $COMMON_NAME-client.pem"