#!/bin/sh

# Kioubit Certificate Authority client script
# Version 1.1.2

set -eu

ENDPOINT="https://dn42.g-load.eu/utilityAPI/ca/v1/request"
TOKEN_FILE="${TOKEN_FILE:-token.txt}"

# Check for required programs
for cmd in curl openssl; do
    if ! command -v "$cmd" >/dev/null 2>&1; then
        echo "Error: Required command '$cmd' not found in PATH"
        exit 1
    fi
done

performRequest() {
  csr_data="$1"

  if [ -z "$csr_data" ]; then
      echo "Error: CSR data is empty."
      exit 1
  fi

  if [ ! -f "$TOKEN_FILE" ]; then
    echo "Error: Token file '$TOKEN_FILE' is missing. It must be generated once on the webpage and then saved as a file called '$TOKEN_FILE'"
    exit 2
  fi

  api_token=$(cat "$TOKEN_FILE")

  exit_code=0
  result=$(curl --fail-with-body --silent "$ENDPOINT" -F "csr=$csr_data" -F "token=$api_token") || exit_code=$?
  if [ $exit_code -ne 0 ]; then
    echo "Error: Remote error message:"
    echo "$result"
    exit 1
  fi

  echo "$result" > signed.crt
  echo "Saved signed certificate to 'signed.crt'"
  echo "Success"
  echo "--- The following files need to be configured in your webserver ---"
  echo "Private key: server.key"
  echo "Signed certificate: signed.crt"
}


sign_existing_csr() {
  csr_path="$1"
  if [ ! -f "$csr_path" ]; then
    echo "Certificate signing request (CSR) missing. It needs to be present under the filename '$csr_path'"
    echo "You can generate a CSR using this command:"
    echo 'openssl req -nodes -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -keyout server.key -out request.csr -subj "/CN=your-domain.dn42" -addext "subjectAltName = DNS:your-domain.dn42, DNS:*.your-domain.dn42"'
    exit 2
  fi
  csr_content=$(cat "$csr_path")
  performRequest "$csr_content"
}

get_certificate() {
  domain="$1"
  case "$domain" in *"*"*)
    echo "Warning: The domain contains '*'. This script will already generate a wildcard certificate by default."
  esac
  echo "CSR request for: ${domain}, *.${domain}. If you need to customize this, create a custom CSR and then use the 'sign_csr' command"
  echo "Generating private key and CSR..."
  csr_content=$(openssl req -nodes -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -keyout server.key -out - -subj "/CN=${domain}" -addext "subjectAltName = DNS:${domain}, DNS:*.${domain}" 2>/dev/null)
  performRequest "$csr_content"
}

print_usage() {
    cat << EOF
Usage: $0 [command] [domain]

Commands:
  get_certificate <domain.dn42>       Generates a new key and requests a cert. The cert includes a wildcard SAN.
  sign_csr  <optional path to CSR>    Signs an existing 'request.csr'.

Environment Variables:
  TOKEN_FILE   Path to your token file (default: token.txt)
EOF
}

if [ -z ${1+x} ]; then
    print_usage
    exit 0
fi


case "$1" in
  ("get_certificate")
    if [ -z "${2-}" ]; then
      echo "Error: Domain argument missing"
      exit 2
    fi
    get_certificate "$2"
    exit 0
    ;;

  ("sign_csr")
    sign_existing_csr "${2:-request.csr}"
    exit 0
    ;;

  (*)
    print_usage
    exit 0
    ;;
esac
