diff --git a/cert-functions.sh b/cert-functions.sh index 12f1eee..256a2dd 100755 --- a/cert-functions.sh +++ b/cert-functions.sh @@ -274,41 +274,107 @@ function make_server_cert() { } function make_pfx() { - local CERT_DIR="$1" - local CERT_NAME="$2" - local PFX_PASSWORD="${3:-}" + local CA_DIR="" + local CA_FILE_PREFIX="" + local CERT_PATH="" + local PFX_PASSWORD="" + + while [[ $# -gt 0 ]]; do + case "$1" in + --ca-dir) + if [[ -z "$2" ]]; then + echo "ERROR: Missing value for --ca-dir." >&2 + return 1 + fi + CA_DIR="$2" + shift 2 + ;; + --issuing-ca) + if [[ -z "$2" ]]; then + echo "ERROR: Missing value for --issuing-ca." >&2 + return 1 + fi + if [[ "$2" == "ca" ]]; then + echo "ERROR: --issuing-ca cannot be 'ca' as it is reserved for the root CA." >&2 + return 1 + fi + CA_FILE_PREFIX="$2" + shift 2 + ;; + --path) + if [[ -z "$2" ]]; then + echo "ERROR: Missing value for certificate path." >&2 + return 1 + fi + CERT_PATH="$2" + shift 2 + ;; + --password) + if [[ -z "$2" ]]; then + echo "ERROR: Missing value for --password." >&2 + return 1 + fi + PFX_PASSWORD="$2" + shift 2 + ;; + *) break ;; + esac + done + + local ROOT_CA_CERT="ca_cert.pem" + local ROOT_CA_KEY="ca_key.pem" + local CA_CERT="${CA_FILE_PREFIX:-ca}_cert.pem" + local CA_KEY="${CA_FILE_PREFIX:-ca}_key.pem" + local CERT_DIR="$(dirname "$CERT_PATH")" + local CERT_NAME="$(basename "$CERT_PATH" _cert.pem)" + local KEY_PATH="$CERT_DIR/${CERT_NAME}_key.pem" if [[ -z "$CERT_DIR" || ! -d "$CERT_DIR" ]]; then echo "ERROR: Certificate directory $CERT_DIR does not exist." return 1 fi - if [[ -z "$CERT_NAME" ]]; then - echo "ERROR: Certificate name is required." >&2 + if [[ -z "$CA_DIR" || ! -d "$CA_DIR" ]]; then + echo "ERROR: CA directory $CA_DIR does not exist." return 1 fi - if [[ ! -f "$CERT_DIR/${CERT_NAME}_cert.pem" || ! -f "$CERT_DIR/${CERT_NAME}_key.pem" ]]; then - echo "ERROR: Server certificate and key not found in $CERT_DIR. Please call make_server_cert first." >&2 + if [[ ! -f "$CERT_PATH" || ! -f "$KEY_PATH" ]]; then + echo "ERROR: Server certificate or key not found." >&2 return 1 fi - if [[ ! -f "$CERT_DIR/ca_cert.pem" || ! -f "$CERT_DIR/ca_key.pem" ]]; then - echo "ERROR: CA certificate and key not found in $CERT_DIR. Please call make_ca first." >&2 + if [[ ! -f "$CA_DIR/$ROOT_CA_CERT" || ! -f "$CA_DIR/$ROOT_CA_KEY" ]]; then + echo "ERROR: CA certificate or key not found in $CA_DIR." >&2 return 1 fi + if [[ ! -z "$CA_FILE_PREFIX" ]]; then + if [[ ! -f "$CA_DIR/$CA_CERT" || ! -f "$CA_DIR/$CA_KEY" ]]; then + echo "ERROR: Issuing CA certificate or key not found in $CA_DIR." >&2 + return 1 + fi + fi + if [[ -z "$PFX_PASSWORD" ]]; then PFX_PASSWORD="changeit" fi if [[ ! -f "$CERT_DIR/${CERT_NAME}.pfx" ]]; then echo -n "Generating PKCS#12 (PFX) file..." + + CHAIN_FILE=$(mktemp) + trap "rm -f $CHAIN_FILE" EXIT QUIT KILL INT HUP + + cat "$CA_DIR/$ROOT_CA_CERT" > "$CHAIN_FILE" + if [[ ! -z "$CA_FILE_PREFIX" ]]; then + cat "$CA_DIR/$CA_CERT" >> "$CHAIN_FILE" + fi if ! openssl pkcs12 \ -export -out "$CERT_DIR/${CERT_NAME}.pfx" \ - -inkey "$CERT_DIR/${CERT_NAME}_key.pem" \ - -in "$CERT_DIR/${CERT_NAME}_cert.pem" \ - -certfile "$CERT_DIR/ca_cert.pem" \ + -inkey "$KEY_PATH" \ + -in "$CERT_PATH" \ + -certfile "$CHAIN_FILE" \ -password pass:"$PFX_PASSWORD"; then echo "ERROR: Failed to generate PKCS#12 (PFX) file." >&2 return 1 diff --git a/run-tests.sh b/run-tests.sh index 25518f9..53807e3 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -99,3 +99,16 @@ fi # List the generated server certificate and key for verification display_certificate "$CERT_DIR/test_cert.pem" + +# Create a PKCS#12 (PFX) file for the server certificate +if ! make_pfx --ca-dir "$CA_DIR" --issuing-ca "issuing_ca" --path "$CERT_DIR/test_cert.pem" --password "s3cr3t"; then + echo "ERROR: Failed to create PKCS#12 (PFX) file." >&2 + exit 1 +fi + +# Read the generated PKCS#12 (PFX) file to verify its contents +echo -e "\nVerifying contents of generated PKCS#12 (PFX) file ($CERT_DIR/test.pfx):" +if ! openssl pkcs12 -in "$CERT_DIR/test.pfx" -noout -info -password pass:"s3cr3t"; then + echo "ERROR: Failed to read PKCS#12 (PFX) file." >&2 + exit 1 +fi