Created
March 19, 2024 13:44
-
-
Save thehunmonkgroup/6c3ab5c681c005520a5d31d3b9ef1c91 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| set -e | |
| # Set default values for variables | |
| BUILD_DIR="/tmp/stir-shaken" | |
| CA_DIR="${BUILD_DIR}/ca" | |
| SP_DIR="${BUILD_DIR}/sp" | |
| SP_CREATED_FILES_LIST="${SP_DIR}/stir_shaken_files.txt" | |
| IDENTIFIER=$(date +%s) | |
| DEBUG_MODE=0 | |
| SELF_SIGNED=0 | |
| CERT_COUNTRY="" | |
| CERT_STATE="" | |
| CERT_LOCALITY="" | |
| CERT_ORG="" | |
| CERT_OU="" | |
| CERT_CN="SHAKEN" | |
| # Default, 5 years. | |
| SP_PRIVKEY_EXPIRY_DAYS=${SP_PRIVKEY_EXPIRY_DAYS:-1825} | |
| # Default, 1 year. | |
| SP_PUBKEY_EXPIRY_DAYS=${SP_PUBKEY_EXPIRY_DAYS:-366} | |
| usage() { | |
| echo | |
| cat << EOF | |
| Usage: | |
| ${0} [-b BUILD_DIR] [-i IDENTIFIER] [-d] [-h] [-s] <CERT_COUNTRY> <CERT_STATE> <CERT_LOCALITY> <CERT_ORG> <CERT_OU> [CERT_CN] | |
| Arguments: | |
| -h : Show this help message | |
| -s : Generate self-signed certificate | |
| -i IDENTIFIER : Unique Key/Cert/CSR identifier (default: current timestamp) | |
| -d : Enable debug mode | |
| -b BUILD_DIR : Build directory (default: ${BUILD_DIR}) | |
| CERT_COUNTRY : Required. Certificate subject country | |
| CERT_STATE : Required. Certificate subject state | |
| CERT_LOCALITY : Required. Certificate subject locality | |
| CERT_ORG : Required. Certificate subject organization | |
| CERT_OU : Required. Certificate subject organizational unit | |
| CERT_CN : Certificate subject common name (default: SHAKEN) | |
| Environment overrides: | |
| SP_PRIVKEY_EXPIRY_DAYS: Default: ${SP_PRIVKEY_EXPIRY_DAYS} | |
| SP_PUBKEY_EXPIRY_DAYS: Default: ${SP_PUBKEY_EXPIRY_DAYS} | |
| EOF | |
| exit 1 | |
| } | |
| log() { | |
| echo "$1" | |
| } | |
| log_debug() { | |
| if [[ ${DEBUG_MODE} -eq 1 ]]; then | |
| echo "$1" | |
| fi | |
| } | |
| log_error() { | |
| echo "$1" >&2 | |
| } | |
| validate_cert_info() { | |
| if [[ -z "${CERT_COUNTRY}" || -z "${CERT_STATE}" || -z "${CERT_LOCALITY}" || -z "${CERT_ORG}" || -z "${CERT_OU}" || -z "${CERT_CN}" ]]; then | |
| echo | |
| log_error "ERROR: Incomplete certificate subject information." | |
| log_error "Please provide all of the following: CERT_COUNTRY, CERT_STATE, CERT_LOCALITY, CERT_ORG, CERT_OU" | |
| echo | |
| usage | |
| fi | |
| } | |
| make_build_dir() { | |
| log "Cleaning old certs" | |
| rm -rf "${BUILD_DIR}" | |
| mkdir -p "${BUILD_DIR}" | |
| } | |
| create_sp_key() { | |
| log "Creating SP key" | |
| local sp_key="stir_shaken_sp_key_${IDENTIFIER}.pem" | |
| mkdir -p "${SP_DIR}" | |
| cd "${SP_DIR}" | |
| openssl ecparam -noout -name prime256v1 -genkey -out ${sp_key} | |
| } | |
| create_self_signed_certs() { | |
| log "Creating CA certificate and key" | |
| local sp_key="stir_shaken_sp_key_${IDENTIFIER}.pem" | |
| local sp_csr="stir_shaken_sp_csr_${IDENTIFIER}.pem" | |
| local sp_cert="stir_shaken_sp_cert_${IDENTIFIER}.pem" | |
| local ca_key="stir_shaken_ca_key.pem" | |
| local ca_cert="stir_shaken_ca_cert.pem" | |
| mkdir -p "${CA_DIR}" | |
| cd "${CA_DIR}" | |
| openssl ecparam -noout -name prime256v1 -genkey -out ${ca_key} | |
| openssl req -x509 -new -nodes -key ${ca_key} -sha256 -days ${SP_PRIVKEY_EXPIRY_DAYS} -subj "/O=${CERT_ORG}/CN=${CERT_CN}" -out ${ca_cert} | |
| cd "${SP_DIR}" | |
| log "Configuring TNAuthList" | |
| cat >TNAuthList.conf << EOF | |
| asn1=SEQUENCE:tn_auth_list | |
| [tn_auth_list] | |
| field1=EXP:0,IA5:1001 | |
| EOF | |
| openssl asn1parse -genconf TNAuthList.conf -out TNAuthList.der | |
| cat >openssl.conf << EOF | |
| [ req ] | |
| distinguished_name = req_distinguished_name | |
| req_extensions = v3_req | |
| [ req_distinguished_name ] | |
| commonName = "${CERT_CN}" | |
| [ v3_req ] | |
| EOF | |
| od -An -t x1 -w TNAuthList.der | sed -e 's/ /:/g' -e 's/^/1.3.6.1.5.5.7.1.26=DER/' >> openssl.conf | |
| log "Creating SP certificate" | |
| openssl req -new -nodes -key ${sp_key} -keyform PEM -subj "/C=${CERT_COUNTRY}/ST=${CERT_STATE}/L=${CERT_LOCALITY}/O=${CERT_ORG}/OU=${CERT_OU}/CN=${CERT_CN}" -sha256 -config openssl.conf -out ${sp_csr} | |
| log "Signing SP certificate" | |
| openssl x509 -req -in ${sp_csr} -CA "${CA_DIR}/${ca_cert}" -CAkey "${CA_DIR}/${ca_key}" -CAcreateserial -days ${SP_PUBKEY_EXPIRY_DAYS} -sha256 -extfile openssl.conf -extensions v3_req -out ${sp_cert} | |
| log "Verifying CA certificate" | |
| if [[ ${DEBUG_MODE} -eq 1 ]]; then | |
| openssl x509 -in "${CA_DIR}/${ca_cert}" -text -noout | |
| else | |
| openssl x509 -in "${CA_DIR}/${ca_cert}" -noout > /dev/null 2>&1 | |
| fi | |
| if [[ $? -ne 0 ]]; then | |
| echo | |
| log_error "ERROR: CA certificate verification failed." | |
| echo | |
| exit 1 | |
| fi | |
| log "Verifying SP certificate" | |
| if [[ ${DEBUG_MODE} -eq 1 ]]; then | |
| openssl x509 -in "${SP_DIR}/${sp_cert}" -text -noout | |
| else | |
| openssl x509 -in "${SP_DIR}/${sp_cert}" -noout > /dev/null 2>&1 | |
| fi | |
| if [[ $? -ne 0 ]]; then | |
| echo | |
| log_error "ERROR: SP certificate verification failed." | |
| echo | |
| exit 1 | |
| fi | |
| log "Setting proper permissions on generated files" | |
| chmod 600 "${CA_DIR}/${ca_key}" "${SP_DIR}/${sp_key}" | |
| chmod 644 "${CA_DIR}/${ca_cert}" "${SP_DIR}/${sp_csr}" "${SP_DIR}/${sp_cert}" | |
| echo "Key: ${SP_DIR}/${sp_key}" > "${SP_CREATED_FILES_LIST}" | |
| echo "Certificate: ${SP_DIR}/${sp_cert}" >> "${SP_CREATED_FILES_LIST}" | |
| log "Self-signed STIR/SHAKEN certificate generated successfully!" | |
| log "Key: ${SP_DIR}/${sp_key}" | |
| log "Certificate: ${SP_DIR}/${sp_cert}" | |
| log "Created files list written to: ${SP_CREATED_FILES_LIST}" | |
| } | |
| create_csr() { | |
| log "Creating CSR for SP certificate" | |
| local sp_key="stir_shaken_sp_key_${IDENTIFIER}.pem" | |
| local sp_csr="stir_shaken_sp_csr_${IDENTIFIER}.pem" | |
| openssl req -new -nodes -key ${sp_key} -keyform PEM -subj "/C=${CERT_COUNTRY}/ST=${CERT_STATE}/L=${CERT_LOCALITY}/O=${CERT_ORG}/OU=${CERT_OU}/CN=${CERT_CN}" -sha256 -out ${sp_csr} | |
| log "Verifying CSR" | |
| if [[ ${DEBUG_MODE} -eq 1 ]]; then | |
| openssl req -in "${SP_DIR}/${sp_csr}" -text -noout | |
| else | |
| openssl req -in "${SP_DIR}/${sp_csr}" -noout > /dev/null 2>&1 | |
| fi | |
| if [[ $? -ne 0 ]]; then | |
| echo | |
| log_error "ERROR: CSR verification failed." | |
| echo | |
| exit 1 | |
| fi | |
| log "Setting proper permissions on generated files" | |
| chmod 600 "${SP_DIR}/${sp_key}" | |
| chmod 644 "${SP_DIR}/${sp_csr}" | |
| echo "Key: ${SP_DIR}/${sp_key}" > "${SP_CREATED_FILES_LIST}" | |
| echo "CSR: ${SP_DIR}/${sp_csr}" >> "${SP_CREATED_FILES_LIST}" | |
| log "STIR/SHAKEN CSR generated successfully!" | |
| log "Key: ${SP_DIR}/${sp_key}" | |
| log "CSR: ${SP_DIR}/${sp_csr}" | |
| log "Created files list written to: ${SP_CREATED_FILES_LIST}" | |
| } | |
| # Process script arguments | |
| while getopts ":b:i:dhs" opt; do | |
| case ${opt} in | |
| h) usage;; | |
| s) SELF_SIGNED=1;; | |
| i) IDENTIFIER="${OPTARG}";; | |
| d) DEBUG_MODE=1;; | |
| b) BUILD_DIR="${OPTARG}";; | |
| \?) log_error "Invalid option -${OPTARG}"; usage;; | |
| esac | |
| done | |
| shift $((OPTIND -1)) | |
| # Set certificate subject information from positional arguments | |
| CERT_COUNTRY="${1:-$CERT_COUNTRY}" | |
| CERT_STATE="${2:-$CERT_STATE}" | |
| CERT_LOCALITY="${3:-$CERT_LOCALITY}" | |
| CERT_ORG="${4:-$CERT_ORG}" | |
| CERT_OU="${5:-$CERT_OU}" | |
| CERT_CN="${6:-$CERT_CN}" | |
| validate_cert_info | |
| make_build_dir | |
| create_sp_key | |
| if [[ ${SELF_SIGNED} -eq 1 ]]; then | |
| create_self_signed_certs | |
| else | |
| create_csr | |
| fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment