Files
mrcharles af7c0f3478 feat: port legacy TSYS-CA (admin-code PKI + tsys-bits) [#769][#783]
Excluded admin-code/*SECRETS.inc (real Nitrokey HSM PINs in the public
source repo) — SECRETS.inc.example template added in their place.
Rotation/history-purge ruling pending in #783. legacy-* trees exempt
from lint/pointer checks (historical verbatim code).

https://projects.knownelement.com/issues/769#note-4152
2026-09-04 07:01:46 -05:00

227 lines
8.6 KiB
Bash

#!/bin/bash
###########################################################################
#user Variables
#Must changes these variables
###########################################################################
###########################################################################
#Program Variables #
#Dont change these variables unless you know what you are doing) #
###########################################################################
# Which OpenSSL config file are we using for this
export OPENSSL_CONF=$PWD/openssl.cnf
# Changed because this device is already previously initialized.
export FACTORY_DEFAULT_SOPIN="1636511164917894"
#OEM Default SOPIN
#export FACTORY_DEFAULT_SOPIN="3537363231383830"
###########################################################################
#Function definitions #
###########################################################################
function exit_error()
{
echo
echo " FATAL ERROR: $1"
echo " Script aborted."
echo
echo "-------------------------------------------------------------------------------"
exit 1
}
###########################################################################
# Preflight work, exit on any errors #
###########################################################################
# Banner and instructions for the user.
/usr/bin/clear
echo "==============================================================================="
echo " Offline Root CA Generator"
echo
echo "FAILURE TO FOLLOW SECURITY PROCEDURES CAN AND WILL RESULT IN CONSEQUENCES UP TO"
echo "AND INCLUDING LEGAL ACTION. YOU ARE WARNED."
echo
echo " Right now, you should be sitting inside the SCIF, reading this on the computer formerly contained in the safe. Before we begin, ensure that the only devices plugged into this machine are:"
echo
echo " * The *RED* PNY 8GB USB thumbdrive, with a GREEN 'PKI' tag."
echo " * The *ORANGE* USB Thumbdrive that was in the safe with the former."
echo
echo " When the process begins, you will be prompted to insert the 'R' HSM USB device, and you will then be prompted for the USER PIN set for the device a total of THREE times."
echo
echo "You may hit CTRL-C now to cancel execution of this script."
echo
read -p "==============================================================================="
#Check for prerequiste packages
echo "Preflight: Checking installed packages"
echo "-------------------------------------------------------------------------------"
echo
PKG_LIST="libccid pcscd pcsc-tools opensc libengine-pkcs11-openssl openssl"
for pkg in $PKG_LIST; do
echo -n "Checking for package $pkg: ";
if [ $(dpkg -l | grep $pkg -c) -lt 1 ]; then
echo "missing!"
exit_error "Required package '$pkg' is not installed."
else
echo "found.";
fi
done
echo
echo "-------------------------------------------------------------------------------"
echo "Preflight: Checking configuration file"
echo "-------------------------------------------------------------------------------"
echo
# Load in the SECRET variables
. ./offline-SECRETS.inc
#Check the SOPIN
if [ $SECRET_SOPIN = "0000000000000000" ] ; then
exit_error "SOPIN is still default. Check offline-SECRETS.inc."
fi
export SECRET_SOPIN_LENGTH=$(echo $SECRET_SOPIN|wc -c)
if [ $SECRET_SOPIN_LENGTH -lt 17 ]; then
exit_error "HSM SOPIN is too short. Check offline-SECRETS.inc."
fi
#Check the USERPIN
if [ "$SECRET_USER_PIN" = "0000000000000000" ] ; then
exit_error "USER PIN is still default. Check offline-SECRETS.inc."
fi
export SECRET_USERPIN_LENGTH=$(echo $SECRET_USER_PIN|wc -c)
if [ $SECRET_USERPIN_LENGTH -lt 7 ]; then
exit_error "USER PIN is too short. Check offline-SECRETS.inc."
fi
echo
echo "Length and content check complete."
echo
#Create directories to hold the bits
echo "-------------------------------------------------------------------------------"
echo "Preflight: Creating certificate directory structure"
echo "-------------------------------------------------------------------------------"
if [ -d "ca" ]; then
exit_error "Certificate directory exists. Please remove manually."
fi
mkdir -vp ca/root/{certs,crl,csr,newcerts}
mkdir -vp ca/{client,server}/{certs,csr,pfx,private}
touch ca/root/database
echo 1000 | tee ca/root/{serial,crlnumber}
chmod -v 700 ca/{client,server}/private
echo
echo "-------------------------------------------------------------------------------"
echo "Preflight: Verifying absence of HSM"
echo "-------------------------------------------------------------------------------"
echo
# Detect HSMs and prompt until gone.
DETECTLOOP=1;
while [ $DETECTLOOP = 1 ]; do
if [ $(pkcs11-tool --module /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so -L 2>&1 | grep -c Slot) -gt 0 ]; then
read -p "WARNING: There is a hardware security module plugged into this machine. Please remove it now, and press ENTER."
echo
else
DETECTLOOP=0
fi
done
echo "No existing HSM present."
echo
echo "-------------------------------------------------------------------------------"
echo "==============================================================================="
echo "Offline Root CA Generation"
echo "==============================================================================="
echo
############################################################################
#offline Root HSM Stuff
############################################################################
read -p "Insert the Nitrokey HSM tagged as 'R' and press ENTER to continue."
echo
# Trust, but verify
if [ $(pkcs11-tool --module /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so -L 2>&1 | grep -c Slot) -lt 1 ]; then
exit_error "No Hardware HSM found."
fi
echo "Device found:"
echo
#List the nitrokey
pkcs11-tool --module /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so -L
echo
#Setup the HSM for use
echo "-------------------------------------------------------------------------------"
echo "Setting up the HSM for first use."
echo "-------------------------------------------------------------------------------"
echo
sc-hsm-tool --initialize --so-pin $FACTORY_DEFAULT_SOPIN --pin $SECRET_USER_PIN
pkcs11-tool --module /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so --login --login-type so --so-pin $FACTORY_DEFAULT_SOPIN --change-pin --new-pin $SECRET_SOPIN
#Create root key
echo "-------------------------------------------------------------------------------"
echo "Creating offline root key"
echo "-------------------------------------------------------------------------------"
echo
pkcs11-tool --module /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so --login --keypairgen --key-type EC:prime256v1 --label root
if [ "$?" -ne 0 ]; then exit_error "Key creation failed"; fi
#Create self-signed root certificate
echo "-------------------------------------------------------------------------------"
echo "Creating self-signed offline root certificate"
echo "-------------------------------------------------------------------------------"
echo
openssl req -engine pkcs11 -keyform engine -key label_root -new -extensions ext_root -out ca/root/certs/root.cert.pem -x509 -subj '/C=US/ST=Texas/O=TurnNetSystems/OU=Certificate Services/CN=TSYS Root CA' -days 10249
if [ "$?" -ne 0 ]; then exit_error "Certificate creation failed."; fi
echo "Changing permissions on root.cert.pm for sanity's sake"
chmod -v 444 ca/root/certs/root.cert.pem
#Verify root cert
echo "-------------------------------------------------------------------------------"
echo "Verifying root certificate generation"
echo "-------------------------------------------------------------------------------"
echo
openssl x509 -noout -text -in ca/root/certs/root.cert.pem
if [ "$?" -ne 0 ]; then exit_error "Verification failed."; fi
#Import root cert to root HSM
echo "-------------------------------------------------------------------------------"
echo "Importing offline root cert to HSM"
echo "-------------------------------------------------------------------------------"
echo
openssl x509 -in ca/root/certs/root.cert.pem -out ca/root/certs/root.cert.der -outform der
pkcs11-tool --module /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so --login --write-object ca/root/certs/root.cert.der --type cert --label root
if [ "$?" -ne 0 ]; then exit_error "Import failed."; fi
echo "-------------------------------------------------------------------------------"
echo "Visual certificate confirmation"
echo "-------------------------------------------------------------------------------"
echo
pkcs11-tool --module /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so -L -O
echo
echo "Done."
echo
echo "-------------------------------------------------------------------------------"