From f16871a0fd96a60f3178378b7d45e52734cac99f Mon Sep 17 00:00:00 2001 From: Ruben Date: Fri, 20 Feb 2026 23:02:45 +0100 Subject: [PATCH 1/4] Remove unused API key validation function Remove temp path directory creation Make fullchain PEM handling conditional Improve certificate update detection logic --- certman.sh | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/certman.sh b/certman.sh index 17131bb..0798e43 100755 --- a/certman.sh +++ b/certman.sh @@ -71,13 +71,8 @@ check_requirements() { done } -validate_api_key() { - local api_key=$1 - [[ $api_key =~ ^[A-Za-z0-9_-]{32,}$ ]] -} - setup_directories() { - local dirs=("$CERT_PATH" "$KEY_PATH" "$TEMP_PATH") + local dirs=("$CERT_PATH" "$KEY_PATH") for dir in "${dirs[@]}"; do if ! mkdir -p "$dir"; then echo -e "${RED}Error: Failed to create directory: $dir${NC}" @@ -111,17 +106,23 @@ download_and_verify_cert() { fi # Download fullchain PEM file + if [ "$FULLCHAIN_PEM" = "true" ]; then if ! curl -s -fL -o "$temp_pem" -H "X-API-Key: $cert_api_key.$key_api_key" \ "https://$CERTWARDEN_SERVER/certwarden/api/v1/download/privatecertchains/$domain"; then echo -e "${RED}Failed to download fullchain PEM file for $domain${NC}" return 1 fi + fi # Verify files are not empty - if [ ! -s "$temp_cert" ] || [ ! -s "$temp_key" ] || [ ! -s "$temp_pem" ]; then + if [ ! -s "$temp_cert" ] || [ ! -s "$temp_key" ]; then echo -e "${RED}Downloaded files are empty for $domain${NC}" return 1 fi + if [ "$FULLCHAIN_PEM" = "true" ] && [ ! -s "$temp_pem" ]; then + echo -e "${RED}Downloaded PEM file is empty for $domain${NC}" + return 1 + fi # Validate certificate and key match local cert_fingerprint @@ -131,19 +132,21 @@ download_and_verify_cert() { local key_fingerprint key_fingerprint=$(openssl pkey -in "$temp_key" -pubout -outform DER 2>/dev/null | openssl dgst -sha256) - local pem_fingerprint - pem_fingerprint=$(openssl x509 -in "$temp_pem" -noout -pubkey | - openssl pkey -pubin -outform DER 2>/dev/null | - openssl dgst -sha256) if [ "$cert_fingerprint" != "$key_fingerprint" ]; then echo -e "${RED}Certificate and key do not match for $domain${NC}" return 1 fi - if [[ "$cert_fingerprint" != "$pem_fingerprint" ]]; then - echo -e "${RED}Certificate and PEM file do not match for $domain${NC}" - return 1 + if [ "$FULLCHAIN_PEM" = "true" ]; then + local pem_fingerprint + pem_fingerprint=$(openssl x509 -in "$temp_pem" -noout -pubkey | + openssl pkey -pubin -outform DER 2>/dev/null | + openssl dgst -sha256) + if [[ "$cert_fingerprint" != "$pem_fingerprint" ]]; then + echo -e "${RED}Certificate and PEM file do not match for $domain${NC}" + return 1 + fi fi return 0 @@ -162,15 +165,13 @@ install_certificate() { # Check if certificate needs updating if [ "$FORCE_UPDATE" = "true" ]; then needs_reload=1 - elif [ "$FULLCHAIN_PEM" = "true" ] && [ -f "$final_pem" ]; then - if ! cmp -s "$final_pem" "$temp_pem"; then - needs_reload=1 - fi - elif [ -f "$final_cert" ]; then - if ! cmp -s "$final_cert" "$temp_cert"; then - needs_reload=1 - fi - else + elif [ ! -f "$final_cert" ] || [ ! -f "$final_key" ]; then + needs_reload=1 + elif ! cmp -s "$final_cert" "$temp_cert" || ! cmp -s "$final_key" "$temp_key"; then + needs_reload=1 + elif [ "$FULLCHAIN_PEM" = "true" ] && [ -f "$final_pem" ] && ! cmp -s "$final_pem" "$temp_pem"; then + needs_reload=1 + elif [ "$FULLCHAIN_PEM" = "true" ] && [ ! -f "$final_pem" ]; then needs_reload=1 fi From 44f1cec7ec24452d4c89ed6bfa794f4b4a1381ed Mon Sep 17 00:00:00 2001 From: Ruben Date: Fri, 20 Feb 2026 23:03:09 +0100 Subject: [PATCH 2/4] Use install for certificate file permissions and ownership Replace separate cp and chmod/chown operations with single install commands for certificate, key, and PEM files to simplify permission handling --- certman.sh | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/certman.sh b/certman.sh index 17131bb..2ed84ef 100755 --- a/certman.sh +++ b/certman.sh @@ -176,33 +176,20 @@ install_certificate() { # Install new certificate and key if [ $needs_reload -eq 1 ]; then - if ! cp -f "$temp_cert" "$final_cert" || ! cp -f "$temp_key" "$final_key"; then - echo -e "${RED}Failed to install certificate files for $domain${NC}" + if ! install -m "$CERT_PERMISSIONS" -o "$CERT_OWNER" -g "$CERT_GROUP" "$temp_cert" "$final_cert"; then + echo -e "${RED}Failed to install certificate for $domain${NC}" return 1 fi - - # Set permissions and ownership for cert and key separately - if ! chown "$CERT_OWNER:$CERT_GROUP" "$final_cert" || \ - ! chmod "$CERT_PERMISSIONS" "$final_cert"; then - echo -e "${RED}Failed to set permissions for $final_cert${NC}" - return 1 - fi - if ! chown "$CERT_OWNER:$CERT_GROUP" "$final_key" || \ - ! chmod "$KEY_PERMISSIONS" "$final_key"; then - echo -e "${RED}Failed to set permissions for $final_key${NC}" + if ! install -m "$KEY_PERMISSIONS" -o "$CERT_OWNER" -g "$CERT_GROUP" "$temp_key" "$final_key"; then + echo -e "${RED}Failed to install private key for $domain${NC}" return 1 fi if [ "$FULLCHAIN_PEM" = "true" ]; then - if ! cp -f "$temp_pem" "$final_pem"; then + if ! install -m "$KEY_PERMISSIONS" -o "$CERT_OWNER" -g "$CERT_GROUP" "$temp_pem" "$final_pem"; then echo -e "${RED}Failed to install PEM file for $domain${NC}" return 1 fi - if ! chown "$CERT_OWNER:$CERT_GROUP" "$final_pem" || \ - ! chmod "$KEY_PERMISSIONS" "$final_pem"; then - echo -e "${RED}Failed to set permissions for $final_pem${NC}" - return 1 - fi fi echo -e "${GREEN}Certificate updated for $domain${NC}" From 8d3291e01d4cfb6140887032c4fd54fd88c5247d Mon Sep 17 00:00:00 2001 From: Ruben Date: Fri, 20 Feb 2026 23:04:09 +0100 Subject: [PATCH 3/4] Add error handling for fingerprint extraction failures Improve certificate and key fingerprint comparison logic Add validation for PEM file fingerprint extraction --- certman.sh | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/certman.sh b/certman.sh index 0798e43..acbd38c 100755 --- a/certman.sh +++ b/certman.sh @@ -125,13 +125,17 @@ download_and_verify_cert() { fi # Validate certificate and key match - local cert_fingerprint + local cert_fingerprint key_fingerprint cert_fingerprint=$(openssl x509 -in "$temp_cert" -noout -pubkey | - openssl pkey -pubin -outform DER 2>/dev/null | - openssl dgst -sha256) - local key_fingerprint - key_fingerprint=$(openssl pkey -in "$temp_key" -pubout -outform DER 2>/dev/null | - openssl dgst -sha256) + openssl pkey -pubin -outform DER | + openssl dgst -sha256) || true + key_fingerprint=$(openssl pkey -in "$temp_key" -pubout -outform DER | + openssl dgst -sha256) || true + + if [ -z "$cert_fingerprint" ] || [ -z "$key_fingerprint" ]; then + echo -e "${RED}Failed to extract fingerprints for $domain${NC}" + return 1 + fi if [ "$cert_fingerprint" != "$key_fingerprint" ]; then echo -e "${RED}Certificate and key do not match for $domain${NC}" @@ -141,9 +145,13 @@ download_and_verify_cert() { if [ "$FULLCHAIN_PEM" = "true" ]; then local pem_fingerprint pem_fingerprint=$(openssl x509 -in "$temp_pem" -noout -pubkey | - openssl pkey -pubin -outform DER 2>/dev/null | - openssl dgst -sha256) - if [[ "$cert_fingerprint" != "$pem_fingerprint" ]]; then + openssl pkey -pubin -outform DER | + openssl dgst -sha256) || true + if [ -z "$pem_fingerprint" ]; then + echo -e "${RED}Failed to extract PEM fingerprint for $domain${NC}" + return 1 + fi + if [ "$cert_fingerprint" != "$pem_fingerprint" ]; then echo -e "${RED}Certificate and PEM file do not match for $domain${NC}" return 1 fi From ab59a58c550dfd0d8a432f6e384151188bb89e2b Mon Sep 17 00:00:00 2001 From: Ruben Date: Fri, 20 Feb 2026 23:07:44 +0100 Subject: [PATCH 4/4] Use install for certificate and key file installation Replace separate cp and chmod operations with single install commands for certificate, key, and PEM file installation to ensure proper permissions and ownership are set in one operation --- certman.sh | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/certman.sh b/certman.sh index acbd38c..291a807 100755 --- a/certman.sh +++ b/certman.sh @@ -185,33 +185,20 @@ install_certificate() { # Install new certificate and key if [ $needs_reload -eq 1 ]; then - if ! cp -f "$temp_cert" "$final_cert" || ! cp -f "$temp_key" "$final_key"; then - echo -e "${RED}Failed to install certificate files for $domain${NC}" + if ! install -m "$CERT_PERMISSIONS" -o "$CERT_OWNER" -g "$CERT_GROUP" "$temp_cert" "$final_cert"; then + echo -e "${RED}Failed to install certificate for $domain${NC}" return 1 fi - - # Set permissions and ownership for cert and key separately - if ! chown "$CERT_OWNER:$CERT_GROUP" "$final_cert" || \ - ! chmod "$CERT_PERMISSIONS" "$final_cert"; then - echo -e "${RED}Failed to set permissions for $final_cert${NC}" - return 1 - fi - if ! chown "$CERT_OWNER:$CERT_GROUP" "$final_key" || \ - ! chmod "$KEY_PERMISSIONS" "$final_key"; then - echo -e "${RED}Failed to set permissions for $final_key${NC}" + if ! install -m "$KEY_PERMISSIONS" -o "$CERT_OWNER" -g "$CERT_GROUP" "$temp_key" "$final_key"; then + echo -e "${RED}Failed to install private key for $domain${NC}" return 1 fi if [ "$FULLCHAIN_PEM" = "true" ]; then - if ! cp -f "$temp_pem" "$final_pem"; then + if ! install -m "$KEY_PERMISSIONS" -o "$CERT_OWNER" -g "$CERT_GROUP" "$temp_pem" "$final_pem"; then echo -e "${RED}Failed to install PEM file for $domain${NC}" return 1 fi - if ! chown "$CERT_OWNER:$CERT_GROUP" "$final_pem" || \ - ! chmod "$KEY_PERMISSIONS" "$final_pem"; then - echo -e "${RED}Failed to set permissions for $final_pem${NC}" - return 1 - fi fi echo -e "${GREEN}Certificate updated for $domain${NC}"