206 lines
8.0 KiB
Bash
Executable File
206 lines
8.0 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# OCSP server configuration
|
|
# Defines where the OCSP responder will be accessible in the Docker network
|
|
OCSP_URL="http://ocsp.localhost.example:8888"
|
|
|
|
# Base directory for all certificate-related files
|
|
# All paths in this script will be relative to this directory
|
|
CERT_DIR="./_data/certs"
|
|
XMPP_BASE_DIR="./_data/xmpp"
|
|
|
|
# Check if OpenSSL is installed
|
|
if ! command -v openssl &> /dev/null; then
|
|
echo "Error: OpenSSL is not installed"
|
|
exit 1
|
|
fi
|
|
|
|
# Function to check which server directories exist
|
|
get_server_instances() {
|
|
local instances=()
|
|
# Look for numbered directories in the xmpp base directory
|
|
for dir in "$XMPP_BASE_DIR"/*/; do
|
|
if [[ -d "$dir" ]]; then
|
|
# Extract the number from the directory name
|
|
local num=$(basename "$dir")
|
|
if [[ "$num" =~ ^[0-9]+$ ]]; then
|
|
instances+=("$num")
|
|
fi
|
|
fi
|
|
done
|
|
echo "${instances[@]}"
|
|
}
|
|
|
|
# Create the PKI directory structure:
|
|
# We only need:
|
|
# - root-ca: Root Certificate Authority files
|
|
# - intermediate-ca: Intermediate Certificate Authority files
|
|
# - ocsp-responder: OCSP responder certificates
|
|
mkdir -p "${CERT_DIR}/ca/root-ca/private" \
|
|
"${CERT_DIR}/ca/intermediate-ca/private" \
|
|
"${CERT_DIR}/ca/ocsp-responder"
|
|
chmod 700 "${CERT_DIR}/ca/root-ca/private" "${CERT_DIR}/ca/intermediate-ca/private"
|
|
|
|
# Initialize the certificate databases and serial number counters
|
|
# index.txt acts as a database of all certificates
|
|
# serial defines the next certificate serial number
|
|
echo -n > "${CERT_DIR}/ca/intermediate-ca/index.txt"
|
|
echo 1000 > "${CERT_DIR}/ca/intermediate-ca/serial"
|
|
|
|
# Generate the Root CA private key and certificate
|
|
# This is the top-level certificate authority that signs the intermediate CA
|
|
openssl genrsa -out "${CERT_DIR}/ca/root-ca/private/ca.key" 4096
|
|
|
|
openssl req -new -x509 -key "${CERT_DIR}/ca/root-ca/private/ca.key" \
|
|
-out "${CERT_DIR}/ca/root-ca/ca.crt" -days 3650 \
|
|
-subj "/C=GB/ST=London/L=London/O=Test Openfire/CN=Test Openfire Root CA"
|
|
|
|
# Generate the Intermediate CA private key and certificate signing request (CSR)
|
|
# The intermediate CA will be used to sign the server and OCSP responder certificates
|
|
openssl genrsa -out "${CERT_DIR}/ca/intermediate-ca/private/intermediate.key" 4096
|
|
|
|
openssl req -new -key "${CERT_DIR}/ca/intermediate-ca/private/intermediate.key" \
|
|
-out "${CERT_DIR}/ca/intermediate-ca/intermediate.csr" \
|
|
-subj "/C=GB/ST=London/L=London/O=Test Openfire/CN=Test Openfire Intermediate CA"
|
|
|
|
# Sign the Intermediate CA certificate with the Root CA
|
|
# The certificate includes:
|
|
# - CA capabilities (basicConstraints)
|
|
# - Permission to sign certificates (keyUsage)
|
|
# - Location of the OCSP responder (authorityInfoAccess)
|
|
openssl x509 -req -in "${CERT_DIR}/ca/intermediate-ca/intermediate.csr" \
|
|
-CA "${CERT_DIR}/ca/root-ca/ca.crt" \
|
|
-CAkey "${CERT_DIR}/ca/root-ca/private/ca.key" -CAcreateserial \
|
|
-out "${CERT_DIR}/ca/intermediate-ca/intermediate.crt" -days 1825 \
|
|
-extfile <(printf 'basicConstraints=critical,CA:true,pathlen:0\nkeyUsage=critical,digitalSignature,keyCertSign,cRLSign\nauthorityInfoAccess=OCSP;URI:%s' "$OCSP_URL")
|
|
|
|
# Function to generate a server certificate and add it to the certificate database
|
|
# Parameters:
|
|
# $1: instance number (1, 2, or 3 for xmpp1/xmpp2/xmpp3)
|
|
generate_server_cert() {
|
|
local instance=$1
|
|
local server_name="xmpp${instance}"
|
|
|
|
# Generate server private key and CSR
|
|
openssl genrsa -out "${CERT_DIR}/${server_name}.key" 2048
|
|
|
|
# Create OpenSSL config file for SAN support
|
|
cat > "${CERT_DIR}/${server_name}.cnf" << EOF
|
|
[req]
|
|
distinguished_name = req_distinguished_name
|
|
req_extensions = v3_req
|
|
prompt = no
|
|
|
|
[req_distinguished_name]
|
|
C = GB
|
|
ST = London
|
|
L = London
|
|
O = Test Openfire
|
|
CN = ${server_name}.localhost.example
|
|
|
|
[v3_req]
|
|
basicConstraints = CA:FALSE
|
|
keyUsage = critical, digitalSignature, keyEncipherment
|
|
extendedKeyUsage = serverAuth
|
|
subjectAltName = @alt_names
|
|
|
|
[alt_names]
|
|
DNS.1 = ${server_name}.localhost.example
|
|
DNS.2 = *.${server_name}.localhost.example
|
|
EOF
|
|
|
|
# Generate CSR with the config file
|
|
openssl req -new -key "${CERT_DIR}/${server_name}.key" \
|
|
-out "${CERT_DIR}/${server_name}.csr" \
|
|
-config "${CERT_DIR}/${server_name}.cnf"
|
|
|
|
# Create OpenSSL config for certificate signing
|
|
cat > "${CERT_DIR}/${server_name}_sign.cnf" << EOF
|
|
basicConstraints = critical,CA:false
|
|
keyUsage = critical,digitalSignature,keyEncipherment
|
|
extendedKeyUsage = serverAuth
|
|
subjectAltName = @alt_names
|
|
authorityInfoAccess = OCSP;URI:${OCSP_URL}
|
|
|
|
[alt_names]
|
|
DNS.1 = ${server_name}.localhost.example
|
|
DNS.2 = *.${server_name}.localhost.example
|
|
EOF
|
|
|
|
# Sign the server certificate with the Intermediate CA
|
|
openssl x509 -req -in "${CERT_DIR}/${server_name}.csr" \
|
|
-CA "${CERT_DIR}/ca/intermediate-ca/intermediate.crt" \
|
|
-CAkey "${CERT_DIR}/ca/intermediate-ca/private/intermediate.key" -CAcreateserial \
|
|
-out "${CERT_DIR}/${server_name}.crt" -days 365 \
|
|
-extfile "${CERT_DIR}/${server_name}_sign.cnf"
|
|
|
|
# Create the full certificate chain
|
|
cat "${CERT_DIR}/${server_name}.crt" \
|
|
"${CERT_DIR}/ca/intermediate-ca/intermediate.crt" \
|
|
"${CERT_DIR}/ca/root-ca/ca.crt" > "${CERT_DIR}/${server_name}_chain.pem"
|
|
|
|
# Add to certificate database
|
|
SERIAL=$(openssl x509 -in "${CERT_DIR}/${server_name}.crt" -noout -serial | cut -d'=' -f2)
|
|
SUBJECT=$(openssl x509 -in "${CERT_DIR}/${server_name}.crt" -noout -subject | cut -d'=' -f2-)
|
|
printf 'V\t%s\t\t%s\tunknown\t%s\n' "$(date -u +%y%m%d%H%M%SZ)" "$SERIAL" "$SUBJECT" >> "${CERT_DIR}/ca/intermediate-ca/index.txt"
|
|
|
|
# Clean up temporary config files
|
|
rm -f "${CERT_DIR}/${server_name}.cnf" "${CERT_DIR}/${server_name}_sign.cnf"
|
|
|
|
# Display the certificate's subject and SANs for verification
|
|
echo "Certificate generated for ${server_name}:"
|
|
openssl x509 -in "${CERT_DIR}/${server_name}.crt" -noout -subject -ext subjectAltName
|
|
}
|
|
|
|
# Generate the OCSP responder certificate
|
|
# This certificate will be used to sign OCSP responses
|
|
openssl genrsa -out "${CERT_DIR}/ca/ocsp-responder/ocsp.key" 2048
|
|
|
|
openssl req -new -key "${CERT_DIR}/ca/ocsp-responder/ocsp.key" \
|
|
-out "${CERT_DIR}/ca/ocsp-responder/ocsp.csr" \
|
|
-subj "/C=GB/ST=London/L=London/O=Test Openfire/CN=ocsp.example.com"
|
|
|
|
# Sign the OCSP responder certificate
|
|
# The certificate includes:
|
|
# - Non-CA status (basicConstraints)
|
|
# - OCSP signing capability (extendedKeyUsage)
|
|
openssl x509 -req -in "${CERT_DIR}/ca/ocsp-responder/ocsp.csr" \
|
|
-CA "${CERT_DIR}/ca/intermediate-ca/intermediate.crt" \
|
|
-CAkey "${CERT_DIR}/ca/intermediate-ca/private/intermediate.key" -CAcreateserial \
|
|
-out "${CERT_DIR}/ca/ocsp-responder/ocsp.crt" -days 365 \
|
|
-extfile <(printf 'basicConstraints=critical,CA:false\nkeyUsage=critical,digitalSignature\nextendedKeyUsage=OCSPSigning')
|
|
|
|
# Get the list of server instances that exist
|
|
SERVER_INSTANCES=($(get_server_instances))
|
|
|
|
if [ ${#SERVER_INSTANCES[@]} -eq 0 ]; then
|
|
echo "Error: No server directories found in ${XMPP_BASE_DIR}"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Found server directories for instances: ${SERVER_INSTANCES[*]}"
|
|
|
|
# Generate certificates for each existing server instance
|
|
for instance in "${SERVER_INSTANCES[@]}"; do
|
|
echo "Generating certificates for xmpp${instance}"
|
|
generate_server_cert "$instance"
|
|
done
|
|
|
|
# Verify the certificate chain for all generated certificates
|
|
# This ensures that all certificates are properly signed and trusted
|
|
echo "Verifying certificates..."
|
|
openssl verify -CAfile "${CERT_DIR}/ca/root-ca/ca.crt" "${CERT_DIR}/ca/intermediate-ca/intermediate.crt"
|
|
|
|
# Verify each server certificate
|
|
for instance in "${SERVER_INSTANCES[@]}"; do
|
|
openssl verify -CAfile <(cat "${CERT_DIR}/ca/root-ca/ca.crt" "${CERT_DIR}/ca/intermediate-ca/intermediate.crt") \
|
|
"${CERT_DIR}/xmpp${instance}.crt"
|
|
done
|
|
|
|
openssl verify -CAfile <(cat "${CERT_DIR}/ca/root-ca/ca.crt" "${CERT_DIR}/ca/intermediate-ca/intermediate.crt") \
|
|
"${CERT_DIR}/ca/ocsp-responder/ocsp.crt"
|
|
|
|
printf '\nCertificate generation complete.'
|
|
printf '\nOCSP URL configured as: %s\n' "$OCSP_URL"
|
|
printf 'Generated certificates for servers: %s\n\n' "${SERVER_INSTANCES[*]}"
|