/**
 * @file proxysql_sslkeylog.h
 * @brief SSL/TLS key logging support for ProxySQL
 *
 * This module implements SSL/TLS key logging functionality, which allows
 * decryption of encrypted traffic by tools like Wireshark. The key log file
 * contains the secrets needed to decrypt TLS 1.2 and TLS 1.3 connections.
 *
 * SECURITY WARNING: The key log file contains sensitive cryptographic secrets
 * that can decrypt all SSL/TLS traffic. Access to this file should be tightly
 * controlled. This feature should only be enabled for debugging purposes.
 *
 * @see https://wiki.wireshark.org/TLS#TLS_Decryption
 * @see https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format
 */

#ifndef __PROXYSQL_SSLKEYLOG_H
#define __PROXYSQL_SSLKEYLOG_H
#include "proxysql.h"

/**
 * @brief Initialize the SSL keylog subsystem
 *
 * Must be called once at ProxySQL startup to initialize the rwlock
 * that protects concurrent access to the keylog file.
 *
 * Thread-safety: Safe
 */
void proxysql_keylog_init();

/**
 * @brief Open and initialize the SSL keylog file
 *
 * Opens the specified file in append mode with line buffering.
 * If a keylog file is already open, it is closed first.
 *
 * The keylog file format follows the NSS Key Log Format:
 *   <Label> <ClientRandom> <Secret>
 *
 * @param keylog_file Path to the keylog file (can be absolute or relative)
 * @return true if the file was opened successfully, false on failure
 *
 * Thread-safety: Safe (uses internal rwlock)
 *
 * @note The file is opened with mode "a+" (append, read/write)
 * @note Line buffering (4096 bytes) is used for performance
 */
bool proxysql_keylog_open(const char* keylog_file);

/**
 * @brief Close the SSL keylog file
 *
 * Closes the currently open keylog file (if any) and sets the
 * file pointer to NULL. Thread-safe using rwlock.
 *
 * @param lock If true, acquires rwlock before closing (default: true)
 *             Set to false only if already holding the lock
 *
 * Thread-safety: Safe (uses internal rwlock when lock=true)
 */
void proxysql_keylog_close(bool lock = true);

/**
 * @brief Attach the keylog callback to an SSL context
 *
 * Registers proxysql_keylog_write_line_callback() as the keylog
 * callback for the given SSL context. This callback is invoked by
 * OpenSSL whenever TLS secrets are generated during handshake.
 *
 * The callback is only attached if no callback is already registered
 * to avoid overwriting user-defined callbacks.
 *
 * @param ssl_ctx The SSL context to attach the callback to
 *
 * Thread-safety: Safe (idempotent - won't attach if already present)
 *
 * @note This uses SSL_CTX_set_keylog_callback() (OpenSSL 1.1.1+)
 * @see proxysql_keylog_write_line_callback
 */
void proxysql_keylog_attach_callback(SSL_CTX* ssl_ctx);

/**
 * @brief OpenSSL callback for writing TLS secrets to the keylog file
 *
 * This callback is invoked by OpenSSL during TLS handshake to write
 * secrets (master secret, client traffic secret, etc.) to the keylog file.
 *
 * The callback follows the NSS Key Log Format:
 *   LABEL <space> ClientRandom <space> Secret <newline>
 *
 * Example lines:
 *   CLIENT_RANDOM 3a4b... <48-byte-master-secret>
 *   CLIENT_HANDSHAKE_TRAFFIC_SECRET 3a4b... <32-or-48-byte-secret>
 *   SERVER_HANDSHAKE_TRAFFIC_SECRET 3a4b... <32-or-48-byte-secret>
 *
 * @param ssl The SSL connection (unused, present for callback signature)
 * @param line The keylog line generated by OpenSSL (without newline)
 *
 * Thread-safety: Safe (uses internal rdlock)
 *
 * @note Line length is validated (max 254 bytes)
 * @note Lines are newline-terminated if not already present
 */
void proxysql_keylog_write_line_callback(const SSL* ssl, const char* line);

#endif // __PROXYSQL_SSLKEYLOG_H
