Line data Source code
1 : /* SPDX-License-Identifier: GPL-3.0-or-later */
2 : /* Copyright 2026 Peter Csaszar */
3 :
4 : /**
5 : * @file telegram_server_key.c
6 : * @brief Runtime RSA public key store — no compiled-in default.
7 : *
8 : * The application refuses to start unless the user has provided an rsa_pem
9 : * entry in config.ini. See telegram_server_key.h for details.
10 : *
11 : * Tests link tests/mocks/telegram_server_key.c instead (DIP, ADR-0004).
12 : */
13 :
14 : #include "telegram_server_key.h"
15 : #include "crypto.h"
16 : #include "logger.h"
17 :
18 : #include <stdlib.h>
19 : #include <string.h>
20 :
21 : static char *g_pem = NULL;
22 : static uint64_t g_fingerprint = 0;
23 :
24 : /**
25 : * Expand literal \\n sequences (backslash + 'n') to real newline characters.
26 : * Returns a heap-allocated string; caller must free.
27 : */
28 0 : static char *expand_newlines(const char *src) {
29 0 : size_t src_len = strlen(src);
30 0 : char *dst = malloc(src_len + 1);
31 0 : if (!dst) return NULL;
32 :
33 0 : size_t di = 0;
34 0 : for (size_t si = 0; si < src_len; si++) {
35 0 : if (src[si] == '\\' && si + 1 < src_len && src[si + 1] == 'n') {
36 0 : dst[di++] = '\n';
37 0 : si++;
38 : } else {
39 0 : dst[di++] = src[si];
40 : }
41 : }
42 0 : dst[di] = '\0';
43 0 : return dst;
44 : }
45 :
46 6 : const char *telegram_server_key_get_pem(void) {
47 6 : return g_pem;
48 : }
49 :
50 0 : uint64_t telegram_server_key_get_fingerprint(void) {
51 0 : return g_fingerprint;
52 : }
53 :
54 0 : int telegram_server_key_set_override(const char *pem) {
55 0 : if (!pem) {
56 0 : free(g_pem);
57 0 : g_pem = NULL;
58 0 : g_fingerprint = 0;
59 0 : return 0;
60 : }
61 :
62 0 : char *expanded = expand_newlines(pem);
63 0 : if (!expanded) return -1;
64 :
65 0 : uint64_t fp = 0;
66 0 : if (crypto_rsa_fingerprint(expanded, &fp) != 0) {
67 0 : logger_log(LOG_ERROR,
68 : "telegram_server_key: rsa_pem cannot be parsed — "
69 : "check the rsa_pem entry in config.ini");
70 0 : free(expanded);
71 0 : return -1;
72 : }
73 :
74 0 : free(g_pem);
75 0 : g_pem = expanded;
76 0 : g_fingerprint = fp;
77 :
78 0 : logger_log(LOG_INFO,
79 : "telegram_server_key: RSA key loaded (fingerprint 0x%016llx)",
80 : (unsigned long long)fp);
81 0 : return 0;
82 : }
|