#include "../curl_setup.h"
#if defined(USE_OPENSSL) || \
defined(USE_GNUTLS) || \
defined(USE_WOLFSSL) || \
(defined(USE_NGTCP2) && defined(USE_NGHTTP3)) || \
defined(USE_QUICHE) || \
defined(USE_RUSTLS)
#include "keylog.h"
#include <curl/curl.h>
#include "../escape.h"
#include "../curlx/fopen.h"
#include "../curl_memory.h"
#include "../memdebug.h"
static FILE *keylog_file_fp;
void
Curl_tls_keylog_open(void)
{
char *keylog_file_name;
if(!keylog_file_fp) {
keylog_file_name = curl_getenv("SSLKEYLOGFILE");
if(keylog_file_name) {
keylog_file_fp = curlx_fopen(keylog_file_name, FOPEN_APPENDTEXT);
if(keylog_file_fp) {
#ifdef _WIN32
if(setvbuf(keylog_file_fp, NULL, _IONBF, 0))
#else
if(setvbuf(keylog_file_fp, NULL, _IOLBF, 4096))
#endif
{
curlx_fclose(keylog_file_fp);
keylog_file_fp = NULL;
}
}
Curl_safefree(keylog_file_name);
}
}
}
void
Curl_tls_keylog_close(void)
{
if(keylog_file_fp) {
curlx_fclose(keylog_file_fp);
keylog_file_fp = NULL;
}
}
bool
Curl_tls_keylog_enabled(void)
{
return keylog_file_fp != NULL;
}
bool
Curl_tls_keylog_write_line(const char *line)
{
size_t linelen;
char buf[256];
if(!keylog_file_fp || !line) {
return FALSE;
}
linelen = strlen(line);
if(linelen == 0 || linelen > sizeof(buf) - 2) {
return FALSE;
}
memcpy(buf, line, linelen);
if(line[linelen - 1] != '\n') {
buf[linelen++] = '\n';
}
buf[linelen] = '\0';
fputs(buf, keylog_file_fp);
return TRUE;
}
bool
Curl_tls_keylog_write(const char *label,
const unsigned char client_random[CLIENT_RANDOM_SIZE],
const unsigned char *secret, size_t secretlen)
{
size_t pos, i;
unsigned char line[KEYLOG_LABEL_MAXLEN + 1 + 2 * CLIENT_RANDOM_SIZE + 1 +
2 * SECRET_MAXLEN + 1 + 1];
if(!keylog_file_fp) {
return FALSE;
}
pos = strlen(label);
if(pos > KEYLOG_LABEL_MAXLEN || !secretlen || secretlen > SECRET_MAXLEN) {
return FALSE;
}
memcpy(line, label, pos);
line[pos++] = ' ';
for(i = 0; i < CLIENT_RANDOM_SIZE; i++) {
Curl_hexbyte(&line[pos], client_random[i]);
pos += 2;
}
line[pos++] = ' ';
for(i = 0; i < secretlen; i++) {
Curl_hexbyte(&line[pos], secret[i]);
pos += 2;
}
line[pos++] = '\n';
line[pos] = '\0';
fputs((char *)line, keylog_file_fp);
return TRUE;
}
#endif