#!/usr/bin/env bash
#
# onx-ocsp-check — Domain için OCSP stapling durumunu kontrol et.
# `openssl s_client -status` ile canlı bağlantı kurar, OCSP staple parse eder.
#
# Stdin (JSON):
#   {"domain":"example.com","port":443}
#
# Stdout (JSON):
#   {
#     "ok": true,
#     "domain": "example.com",
#     "stapling_enabled": true,
#     "ocsp_status": "good" | "revoked" | "unknown" | "not_stapled",
#     "this_update": "2026-05-18T12:00:00Z",
#     "next_update": "2026-05-25T12:00:00Z",
#     "responder": "http://e7.o.lencr.org",
#     "must_staple": false
#   }
#
# Exit codes: 0 = ok (her durumda, "not_stapled" da ok), 1 = invalid input, 2 = connection fail

set -uo pipefail

SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
source "${SCRIPT_DIR}/_lib/common.sh"

onx_json_input
DOMAIN=$(onx_json_field "domain")
PORT=$(onx_json_field "port" "443")

[[ -z "${DOMAIN}" ]] && onx_die 1 "domain gerekli"
[[ "${DOMAIN}" =~ ^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$ ]] \
    || onx_die 1 "geçersiz domain: ${DOMAIN}"

command -v openssl >/dev/null 2>&1 || onx_die 2 "openssl bulunamadı"

# ── Connection + OCSP status check ─────────────────────────────────────────
OUT=$(echo "" | timeout 10 openssl s_client \
    -connect "${DOMAIN}:${PORT}" \
    -servername "${DOMAIN}" \
    -status \
    -verify_return_error \
    2>/dev/null || true)

if [[ -z "${OUT}" ]]; then
    onx_die 2 "TLS bağlantısı başarısız: ${DOMAIN}:${PORT}"
fi

# ── OCSP status parse ──────────────────────────────────────────────────────
STAPLING_ENABLED="false"
OCSP_STATUS="not_stapled"
THIS_UPDATE=""
NEXT_UPDATE=""
RESPONDER=""
MUST_STAPLE="false"

# OCSP Response içeriği var mı?
if grep -qE "OCSP Response Data:|OCSP response:" <<< "${OUT}"; then
    STAPLING_ENABLED="true"

    # Cert status
    if grep -qE "Cert Status:[[:space:]]*good" <<< "${OUT}"; then
        OCSP_STATUS="good"
    elif grep -qE "Cert Status:[[:space:]]*revoked" <<< "${OUT}"; then
        OCSP_STATUS="revoked"
    else
        OCSP_STATUS="unknown"
    fi

    # This Update + Next Update
    THIS_UPDATE_RAW=$(echo "${OUT}" | grep -E "This Update:" | head -1 | sed 's/.*This Update:[[:space:]]*//')
    NEXT_UPDATE_RAW=$(echo "${OUT}" | grep -E "Next Update:" | head -1 | sed 's/.*Next Update:[[:space:]]*//')

    if [[ -n "${THIS_UPDATE_RAW}" ]]; then
        THIS_UPDATE=$(date -d "${THIS_UPDATE_RAW}" -u +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || echo "")
    fi
    if [[ -n "${NEXT_UPDATE_RAW}" ]]; then
        NEXT_UPDATE=$(date -d "${NEXT_UPDATE_RAW}" -u +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || echo "")
    fi

    # Responder URL
    RESPONDER=$(echo "${OUT}" | grep -E "Responder ID:|Authority Information Access:" -A 3 | grep -E "OCSP - URI:" | head -1 | sed 's/.*OCSP - URI://' | xargs)
elif grep -qE "OCSP response: no response sent" <<< "${OUT}"; then
    STAPLING_ENABLED="false"
    OCSP_STATUS="not_stapled"
fi

# Must-Staple TLS Feature extension check
# Cert'de id-pe-tlsfeature OID (1.3.6.1.5.5.7.1.24) varsa must-staple aktif
if echo "" | timeout 5 openssl s_client -connect "${DOMAIN}:${PORT}" -servername "${DOMAIN}" 2>/dev/null \
   | openssl x509 -text -noout 2>/dev/null | grep -qE "1.3.6.1.5.5.7.1.24|TLS Feature|status_request"; then
    MUST_STAPLE="true"
fi

# ── Output ─────────────────────────────────────────────────────────────────
jq -nc \
    --arg dom "${DOMAIN}" \
    --argjson port "${PORT}" \
    --argjson en "${STAPLING_ENABLED}" \
    --arg status "${OCSP_STATUS}" \
    --arg this "${THIS_UPDATE}" \
    --arg next "${NEXT_UPDATE}" \
    --arg resp "${RESPONDER}" \
    --argjson must "${MUST_STAPLE}" \
    '{
        ok: true,
        domain: $dom,
        port: $port,
        stapling_enabled: $en,
        ocsp_status: $status,
        this_update: ($this | if . == "" then null else . end),
        next_update: ($next | if . == "" then null else . end),
        responder: ($resp | if . == "" then null else . end),
        must_staple: $must
    }'

exit 0
