ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
discovery_keys.h File Reference

Discovery Server Public Key Trust Management. More...

Go to the source code of this file.

Macros

#define ACDS_OFFICIAL_SERVER   ACDS_OFFICIAL_SERVER_HOSTNAME
 Official ACDS server hostname (automatic HTTPS key trust).
#define ACDS_OFFICIAL_KEY_SSH_URL   "https://discovery.ascii-chat.com/key.pub"
 Default HTTPS URLs for official ACDS keys.
#define ACDS_OFFICIAL_KEY_GPG_URL   "https://discovery.ascii-chat.com/key.gpg"
#define ACDS_KEYS_CACHE_DIR   "acds_keys"
 Key cache directory (relative to config dir).

Functions

asciichat_error_t discovery_keys_verify (const char *acds_server, const char *key_spec, uint8_t pubkey_out[32])
 Verify and load ACDS server public key.
asciichat_error_t discovery_keys_download_https (const char *url, uint8_t pubkey_out[32])
 Download key from HTTPS URL.
asciichat_error_t discovery_keys_load_file (const char *file_path, uint8_t pubkey_out[32])
 Load key from local file.
asciichat_error_t discovery_keys_get_cache_path (const char *acds_server, char *path_out, size_t path_size)
 Get cached key path for ACDS server.
asciichat_error_t discovery_keys_load_cached (const char *acds_server, uint8_t pubkey_out[32])
 Check if cached key exists and load it.
asciichat_error_t discovery_keys_save_cached (const char *acds_server, const uint8_t pubkey[32])
 Save key to cache.
asciichat_error_t discovery_keys_verify_change (const char *acds_server, const uint8_t old_pubkey[32], const uint8_t new_pubkey[32])
 Verify key change with user.
asciichat_error_t discovery_keys_clear_cache (const char *acds_server)
 Clear cached key for ACDS server.

Detailed Description

Discovery Server Public Key Trust Management.

This module handles verification and trust management for ACDS server public keys. It provides functionality to:

  • Download keys from HTTPS URLs using lib/crypto/http_client.h
  • Load keys from local files (SSH/GPG formats)
  • Special-case automatic trust for discovery-service.ascii-chat.com
  • Cache keys locally and detect changes (requires user verification)
  • Parse github:user and gitlab:user.gpg key specifications

Trust Model

Official ACDS Server (discovery-service.ascii-chat.com):

  • Automatically trusts keys downloaded from https://discovery-service.ascii-chat.com/key.pub or /key.gpg
  • First connection: downloads and caches key
  • Subsequent connections: uses cached key
  • Key changes: requires user verification (prevents MITM attacks)

Third-Party ACDS Servers:

  • Requires explicit –discovery-service-key configuration
  • Can be HTTPS URL, local file path, or github:user/gitlab:user specification
  • Keys are cached after first successful download/verification
  • Key changes require user verification

Usage

// Download and verify key from HTTPS URL
uint8_t pubkey[32];
asciichat_error_t result = discovery_keys_verify("acds.example.com",
"https://acds.example.com/key.pub",
pubkey);
// Automatic trust for official server
result = discovery_keys_verify("discovery-service.ascii-chat.com", NULL, pubkey);
// Load from local file
result = discovery_keys_verify("acds.example.com", "/path/to/key.pub", pubkey);
// GitHub key
result = discovery_keys_verify("acds.example.com", "github:zfogg", pubkey);
asciichat_error_t discovery_keys_verify(const char *acds_server, const char *key_spec, uint8_t pubkey_out[32])
Verify and load ACDS server public key.
unsigned char uint8_t
Definition common.h:60
asciichat_error_t
Error and exit codes - unified status values (0-255).
Definition error_codes.h:44
Author
Zachary Fogg me@zf.nosp@m.o.gg
Date
January 2026

Definition in file discovery_keys.h.

Macro Definition Documentation

◆ ACDS_KEYS_CACHE_DIR

#define ACDS_KEYS_CACHE_DIR   "acds_keys"

Key cache directory (relative to config dir).

Definition at line 80 of file discovery_keys.h.

Referenced by discovery_keys_get_cache_path().

◆ ACDS_OFFICIAL_KEY_GPG_URL

#define ACDS_OFFICIAL_KEY_GPG_URL   "https://discovery.ascii-chat.com/key.gpg"

Definition at line 75 of file discovery_keys.h.

Referenced by discovery_keys_verify().

◆ ACDS_OFFICIAL_KEY_SSH_URL

#define ACDS_OFFICIAL_KEY_SSH_URL   "https://discovery.ascii-chat.com/key.pub"

Default HTTPS URLs for official ACDS keys.

Definition at line 74 of file discovery_keys.h.

Referenced by discovery_keys_verify().

◆ ACDS_OFFICIAL_SERVER

#define ACDS_OFFICIAL_SERVER   ACDS_OFFICIAL_SERVER_HOSTNAME

Official ACDS server hostname (automatic HTTPS key trust).

References the authoritative definition from network/acip/acds.h

Definition at line 69 of file discovery_keys.h.

Referenced by discovery_keys_verify().

Function Documentation

◆ discovery_keys_clear_cache()

asciichat_error_t discovery_keys_clear_cache ( const char * acds_server)

Clear cached key for ACDS server.

Removes the cached key for the given ACDS server. Useful for testing or forcing key re-download.

Parameters
acds_serverACDS server hostname
Returns
ASCIICHAT_OK on success, error code otherwise

Definition at line 222 of file discovery_keys.c.

222 {
223 if (!acds_server) {
224 return SET_ERRNO(ERROR_INVALID_PARAM, "NULL parameter");
225 }
226
227 char cache_path[PLATFORM_MAX_PATH_LENGTH];
228 asciichat_error_t result = discovery_keys_get_cache_path(acds_server, cache_path, sizeof(cache_path));
229 if (result != ASCIICHAT_OK) {
230 return result;
231 }
232
233 if (platform_is_regular_file(cache_path)) {
234 if (remove(cache_path) != 0) {
235 return SET_ERRNO_SYS(ERROR_FILE_OPERATION, "Failed to delete cached key: %s", cache_path);
236 }
237 log_debug("Cleared cached ACDS key for server: %s", acds_server);
238 }
239
240 return ASCIICHAT_OK;
241}
#define SET_ERRNO(code,...)
#define SET_ERRNO_SYS(code,...)
asciichat_error_t discovery_keys_get_cache_path(const char *acds_server, char *path_out, size_t path_size)
Get cached key path for ACDS server.
#define PLATFORM_MAX_PATH_LENGTH
Definition common.h:95
@ ASCIICHAT_OK
Definition error_codes.h:46
@ ERROR_FILE_OPERATION
@ ERROR_INVALID_PARAM
#define log_debug(...)
Log a DEBUG message.
Definition log/log.h:595

References ASCIICHAT_OK, discovery_keys_get_cache_path(), ERROR_FILE_OPERATION, ERROR_INVALID_PARAM, log_debug, PLATFORM_MAX_PATH_LENGTH, SET_ERRNO, and SET_ERRNO_SYS.

◆ discovery_keys_download_https()

asciichat_error_t discovery_keys_download_https ( const char * url,
uint8_t pubkey_out[32] )

Download key from HTTPS URL.

Downloads a public key from an HTTPS URL using lib/crypto/http_client.h. Supports both SSH (OpenSSH format) and GPG (ASCII-armored or binary) keys.

Parameters
urlHTTPS URL to download from
pubkey_outEd25519 public key output (32 bytes)
Returns
ASCIICHAT_OK on success, error code otherwise

Definition at line 91 of file discovery_keys.c.

91 {
92 if (!url || !pubkey_out) {
93 return SET_ERRNO(ERROR_INVALID_PARAM, "NULL parameter");
94 }
95
96 log_debug("Downloading ACDS key from %s", url);
97
98 // Use existing parse_public_key infrastructure which handles HTTPS URLs
99 public_key_t key;
100 asciichat_error_t result = parse_public_key(url, &key);
101 if (result != ASCIICHAT_OK) {
102 return SET_ERRNO(ERROR_CRYPTO_KEY, "Failed to download and parse ACDS key from %s", url);
103 }
104
105 memcpy(pubkey_out, key.key, ED25519_PUBLIC_KEY_SIZE);
106 log_debug("Successfully downloaded and parsed ACDS key from %s", url);
107 return ASCIICHAT_OK;
108}
@ ERROR_CRYPTO_KEY
Definition error_codes.h:94
uint8_t key[CRYPTO_PUBLIC_KEY_SIZE]
Definition key_types.h:74
asciichat_error_t parse_public_key(const char *input, public_key_t *key_out)
Parse SSH/GPG public key from any format (returns first key only).
Definition keys.c:36
#define ED25519_PUBLIC_KEY_SIZE
Ed25519 public key size in bytes.
Definition sizes.h:33
The normalized public identity used by ascii-chat's crypto and key-management code.
Definition key_types.h:72

References ASCIICHAT_OK, ED25519_PUBLIC_KEY_SIZE, ERROR_CRYPTO_KEY, ERROR_INVALID_PARAM, public_key_t::key, log_debug, parse_public_key(), and SET_ERRNO.

◆ discovery_keys_get_cache_path()

asciichat_error_t discovery_keys_get_cache_path ( const char * acds_server,
char * path_out,
size_t path_size )

Get cached key path for ACDS server.

Returns the local cache path for a given ACDS server's key. Path: ~/.config/ascii-chat/acds_keys/<hostname>/key.pub

Parameters
acds_serverACDS server hostname
path_outOutput buffer for cache path
path_sizeSize of output buffer
Returns
ASCIICHAT_OK on success, error code otherwise

Definition at line 133 of file discovery_keys.c.

133 {
134 if (!acds_server || !path_out || path_size == 0) {
135 return SET_ERRNO(ERROR_INVALID_PARAM, "NULL parameter");
136 }
137
138 char *config_dir = get_config_dir();
139 if (!config_dir) {
140 return SET_ERRNO(ERROR_CONFIG, "Failed to get config directory");
141 }
142
143 // Path: ~/.config/ascii-chat/acds_keys/<hostname>/key.pub
144 safe_snprintf(path_out, path_size, "%s" ACDS_KEYS_CACHE_DIR PATH_SEPARATOR_STR "%s" PATH_SEPARATOR_STR "key.pub",
145 config_dir, acds_server);
146 SAFE_FREE(config_dir);
147
148 return ASCIICHAT_OK;
149}
#define ACDS_KEYS_CACHE_DIR
Key cache directory (relative to config dir).
#define SAFE_FREE(ptr)
Definition common.h:377
@ ERROR_CONFIG
Definition error_codes.h:52
int safe_snprintf(char *buffer, size_t buffer_size, const char *format,...)
Platform-safe snprintf wrapper.
char * get_config_dir(void)
Get configuration directory path with XDG_CONFIG_HOME support.
Definition path.c:281

References ACDS_KEYS_CACHE_DIR, ASCIICHAT_OK, ERROR_CONFIG, ERROR_INVALID_PARAM, get_config_dir(), SAFE_FREE, safe_snprintf(), and SET_ERRNO.

Referenced by discovery_keys_clear_cache(), discovery_keys_load_cached(), and discovery_keys_save_cached().

◆ discovery_keys_load_cached()

asciichat_error_t discovery_keys_load_cached ( const char * acds_server,
uint8_t pubkey_out[32] )

Check if cached key exists and load it.

Attempts to load a cached key for the given ACDS server.

Parameters
acds_serverACDS server hostname
pubkey_outEd25519 public key output (32 bytes)
Returns
ASCIICHAT_OK if cached key exists and loaded successfully, error otherwise

Definition at line 151 of file discovery_keys.c.

151 {
152 if (!acds_server || !pubkey_out) {
153 return SET_ERRNO(ERROR_INVALID_PARAM, "NULL parameter");
154 }
155
156 char cache_path[PLATFORM_MAX_PATH_LENGTH];
157 asciichat_error_t result = discovery_keys_get_cache_path(acds_server, cache_path, sizeof(cache_path));
158 if (result != ASCIICHAT_OK) {
159 return result;
160 }
161
162 // Check if cached key exists
163 if (!platform_is_regular_file(cache_path)) {
164 return SET_ERRNO(ERROR_FILE_NOT_FOUND, "No cached key for ACDS server: %s", acds_server);
165 }
166
167 // Load cached key using existing infrastructure
168 return discovery_keys_load_file(cache_path, pubkey_out);
169}
asciichat_error_t discovery_keys_load_file(const char *file_path, uint8_t pubkey_out[32])
Load key from local file.
@ ERROR_FILE_NOT_FOUND

References ASCIICHAT_OK, discovery_keys_get_cache_path(), discovery_keys_load_file(), ED25519_PUBLIC_KEY_SIZE, ERROR_FILE_NOT_FOUND, ERROR_INVALID_PARAM, PLATFORM_MAX_PATH_LENGTH, and SET_ERRNO.

Referenced by discovery_keys_verify().

◆ discovery_keys_load_file()

asciichat_error_t discovery_keys_load_file ( const char * file_path,
uint8_t pubkey_out[32] )

Load key from local file.

Loads a public key from a local file. Supports:

  • OpenSSH format (.pub files)
  • GPG ASCII-armored format (.asc, .gpg)
  • GPG binary format
Parameters
file_pathPath to key file
pubkey_outEd25519 public key output (32 bytes)
Returns
ASCIICHAT_OK on success, error code otherwise

Definition at line 110 of file discovery_keys.c.

110 {
111 if (!file_path || !pubkey_out) {
112 return SET_ERRNO(ERROR_INVALID_PARAM, "NULL parameter");
113 }
114
115 log_debug("Loading ACDS key from file: %s", file_path);
116
117 // Use existing parse_public_key infrastructure which handles file paths
118 public_key_t key;
120 if (result != ASCIICHAT_OK) {
121 return SET_ERRNO(ERROR_CRYPTO_KEY, "Failed to load ACDS key from file: %s", file_path);
122 }
123
124 memcpy(pubkey_out, key.key, ED25519_PUBLIC_KEY_SIZE);
125 log_debug("Successfully loaded ACDS key from file: %s", file_path);
126 return ASCIICHAT_OK;
127}
char file_path[4096]
Definition mmap.c:42

References ASCIICHAT_OK, ED25519_PUBLIC_KEY_SIZE, ERROR_CRYPTO_KEY, ERROR_INVALID_PARAM, file_path, public_key_t::key, log_debug, parse_public_key(), and SET_ERRNO.

Referenced by discovery_keys_load_cached().

◆ discovery_keys_save_cached()

asciichat_error_t discovery_keys_save_cached ( const char * acds_server,
const uint8_t pubkey[32] )

Save key to cache.

Caches a public key for the given ACDS server.

Parameters
acds_serverACDS server hostname
pubkeyPublic key to cache (32 bytes)
Returns
ASCIICHAT_OK on success, error code otherwise

Definition at line 171 of file discovery_keys.c.

171 {
172 if (!acds_server || !pubkey) {
173 return SET_ERRNO(ERROR_INVALID_PARAM, "NULL parameter");
174 }
175
176 char cache_path[PLATFORM_MAX_PATH_LENGTH];
177 asciichat_error_t result = discovery_keys_get_cache_path(acds_server, cache_path, sizeof(cache_path));
178 if (result != ASCIICHAT_OK) {
179 return result;
180 }
181
182 // Create cache directory if it doesn't exist
183 char dir_path[PLATFORM_MAX_PATH_LENGTH];
184 safe_snprintf(dir_path, sizeof(dir_path), "%s", cache_path);
185
186 // Find the last path separator (handle both / and \ for cross-platform compatibility)
187 char *last_sep = strrchr(dir_path, '\\');
188 if (!last_sep) {
189 last_sep = strrchr(dir_path, '/');
190 }
191
192 if (last_sep) {
193 *last_sep = '\0';
194 if (!platform_is_directory(dir_path)) {
195 result = platform_mkdir_recursive(dir_path, 0700);
196 if (result != ASCIICHAT_OK) {
197 return SET_ERRNO(ERROR_FILE_OPERATION, "Failed to create ACDS key cache directory: %s", dir_path);
198 }
199 }
200 }
201
202 // Save key in OpenSSH public key format
203 FILE *f = platform_fopen("file_stream", cache_path, "w");
204 if (!f) {
205 return SET_ERRNO_SYS(ERROR_FILE_OPERATION, "Failed to create cache file: %s", cache_path);
206 }
207
208 // OpenSSH encodes a length-prefixed algorithm name followed by the key string.
209 uint8_t wire_key[SSH_ED25519_WIRE_KEY_SIZE] = {0, 0, 0, 11, 's', 's', 'h', '-', 'e', 'd',
210 '2', '5', '5', '1', '9', 0, 0, 0, 32};
211 memcpy(wire_key + 19, pubkey, ED25519_PUBLIC_KEY_SIZE);
213 sodium_bin2base64(base64_key, sizeof(base64_key), wire_key, sizeof(wire_key), sodium_base64_VARIANT_ORIGINAL);
214
215 fprintf(f, "ssh-ed25519 %s acds-cached-key\n", base64_key);
216 fclose(f);
217
218 log_debug("Cached ACDS key for server: %s", acds_server);
219 return ASCIICHAT_OK;
220}
#define CRYPTO_DISCOVERY_KEYS_BASE64_KEY_BUFFER_SIZE
#define SSH_ED25519_WIRE_KEY_SIZE

References ASCIICHAT_OK, CRYPTO_DISCOVERY_KEYS_BASE64_KEY_BUFFER_SIZE, discovery_keys_get_cache_path(), ED25519_PUBLIC_KEY_SIZE, ERROR_FILE_OPERATION, ERROR_INVALID_PARAM, log_debug, PLATFORM_MAX_PATH_LENGTH, safe_snprintf(), SET_ERRNO, SET_ERRNO_SYS, and SSH_ED25519_WIRE_KEY_SIZE.

Referenced by discovery_keys_verify().

◆ discovery_keys_verify()

asciichat_error_t discovery_keys_verify ( const char * acds_server,
const char * key_spec,
uint8_t pubkey_out[32] )

Verify and load ACDS server public key.

This function handles all ACDS key verification scenarios:

Automatic Trust (discovery-service.ascii-chat.com only):

  • If acds_server == "discovery-service.ascii-chat.com" and key_spec == NULL:
    • Downloads from ACDS_OFFICIAL_KEY_SSH_URL or ACDS_OFFICIAL_KEY_GPG_URL
    • Caches key locally
    • Trusts without user verification (first time)
    • Requires user verification if key changes

Explicit Key Specification:

  • HTTPS URL: Downloads key from URL, caches it
  • Local file: Loads key from file path
  • github:user: Fetches SSH or GPG key from GitHub
  • gitlab:user.gpg: Fetches GPG key from GitLab

Caching Behavior:

  • Keys are cached in ~/.config/ascii-chat/acds_keys/<hostname>/
  • Cache invalidation requires user confirmation (prevents MITM attacks)
Parameters
acds_serverACDS server hostname (e.g., "acds.example.com")
key_specKey specification:
  • NULL: automatic trust for discovery-service.ascii-chat.com only
  • HTTPS URL: https://example.com/key.pub
  • File path: /path/to/key.pub or ~/.ssh/server.pub
  • GitHub: github:username
  • GitLab: gitlab:username.gpg
pubkey_outEd25519 public key output (32 bytes)
Returns
ASCIICHAT_OK on success, error code otherwise

Definition at line 278 of file discovery_keys.c.

279 {
280 if (!acds_server || !pubkey_out) {
281 return SET_ERRNO(ERROR_INVALID_PARAM, "NULL parameter");
282 }
283
285 asciichat_error_t result;
286 bool is_official = is_official_server(acds_server);
287
288 // ===========================================================================
289 // Step 1: Obtain the public key
290 // ===========================================================================
291
292 if (!key_spec && is_official) {
293 // Automatic trust for official server: try SSH key first, then GPG
294 log_info("Attempting automatic HTTPS key trust for official ACDS server");
295
296 public_key_t key;
298 if (result != ASCIICHAT_OK) {
299 log_debug("SSH key download failed, trying GPG key");
301 }
302
303 if (result != ASCIICHAT_OK) {
304 return SET_ERRNO(ERROR_NETWORK, "Failed to download key from official ACDS server");
305 }
306
307 memcpy(new_pubkey, key.key, ED25519_PUBLIC_KEY_SIZE);
308
309 } else if (!key_spec) {
310 // No key_spec and not official server = error
312 "Third-party ACDS servers require explicit --discovery-service-key configuration."
313 "Only %s has automatic trust.",
315
316 } else {
317 // Use parse_public_key for all other cases (handles HTTPS, files, github:, gitlab:, etc.)
318 public_key_t key;
319 result = parse_public_key(key_spec, &key);
320 if (result != ASCIICHAT_OK) {
321 return SET_ERRNO(ERROR_CRYPTO_KEY, "Failed to load/download ACDS key from: %s", key_spec);
322 }
323
324 memcpy(new_pubkey, key.key, ED25519_PUBLIC_KEY_SIZE);
325 }
326
327 // ===========================================================================
328 // Step 2: Check cache and handle key changes
329 // ===========================================================================
330
331 uint8_t cached_pubkey[ED25519_PUBLIC_KEY_SIZE];
332 result = discovery_keys_load_cached(acds_server, cached_pubkey);
333
334 if (result == ASCIICHAT_OK) {
335 // Cached key exists - compare
336 if (memcmp(cached_pubkey, new_pubkey, ED25519_PUBLIC_KEY_SIZE) != 0) {
337 // Key changed - require user verification
338 result = discovery_keys_verify_change(acds_server, cached_pubkey, new_pubkey);
339 if (result != ASCIICHAT_OK) {
340 return result; // User rejected or error
341 }
342
343 // User accepted - update cache
344 result = discovery_keys_save_cached(acds_server, new_pubkey);
345 if (result != ASCIICHAT_OK) {
346 log_warn("Failed to update cached key, continuing anyway");
347 }
348 } else {
349 log_debug("ACDS key matches cached key for: %s", acds_server);
350 }
351
352 } else {
353 // No cached key - save it for next time
354 log_info("First connection to ACDS server: %s, caching key", acds_server);
355 result = discovery_keys_save_cached(acds_server, new_pubkey);
356 if (result != ASCIICHAT_OK) {
357 log_warn("Failed to cache key, continuing anyway");
358 }
359 }
360
361 // ===========================================================================
362 // Step 3: Return verified key
363 // ===========================================================================
364
365 memcpy(pubkey_out, new_pubkey, ED25519_PUBLIC_KEY_SIZE);
366 log_debug("ACDS key verification successful for: %s", acds_server);
367 return ASCIICHAT_OK;
368}
asciichat_error_t discovery_keys_load_cached(const char *acds_server, uint8_t pubkey_out[32])
Check if cached key exists and load it.
asciichat_error_t discovery_keys_verify_change(const char *acds_server, const uint8_t old_pubkey[32], const uint8_t new_pubkey[32])
Verify key change with user.
asciichat_error_t discovery_keys_save_cached(const char *acds_server, const uint8_t pubkey[32])
Save key to cache.
#define ACDS_OFFICIAL_SERVER
Official ACDS server hostname (automatic HTTPS key trust).
#define ACDS_OFFICIAL_KEY_SSH_URL
Default HTTPS URLs for official ACDS keys.
#define ACDS_OFFICIAL_KEY_GPG_URL
@ ERROR_NETWORK
Definition error_codes.h:72
#define log_warn(...)
Log a WARN message.
Definition log/log.h:621
#define log_info(...)
Log an INFO message.
Definition log/log.h:608

References ACDS_OFFICIAL_KEY_GPG_URL, ACDS_OFFICIAL_KEY_SSH_URL, ACDS_OFFICIAL_SERVER, ASCIICHAT_OK, discovery_keys_load_cached(), discovery_keys_save_cached(), discovery_keys_verify_change(), ED25519_PUBLIC_KEY_SIZE, ERROR_CRYPTO_KEY, ERROR_INVALID_PARAM, ERROR_NETWORK, public_key_t::key, log_debug, log_info, log_warn, parse_public_key(), and SET_ERRNO.

Referenced by client_crypto_init().

◆ discovery_keys_verify_change()

asciichat_error_t discovery_keys_verify_change ( const char * acds_server,
const uint8_t old_pubkey[32],
const uint8_t new_pubkey[32] )

Verify key change with user.

When a cached key doesn't match the newly downloaded/loaded key, prompts the user to verify the change.

Displays:

  • Old key fingerprint (SHA256)
  • New key fingerprint (SHA256)
  • Warning about potential MITM attack
  • Prompt: "Accept new key? (y/N): "
Parameters
acds_serverACDS server hostname
old_pubkeyPrevious cached key (32 bytes)
new_pubkeyNew downloaded key (32 bytes)
Returns
ASCIICHAT_OK if user accepts, ERROR_USER_REJECTED if declined

Definition at line 247 of file discovery_keys.c.

249 {
250 if (!acds_server || !old_pubkey || !new_pubkey) {
251 return SET_ERRNO(ERROR_INVALID_PARAM, "NULL parameter");
252 }
253
254 char old_fingerprint[HEX_STRING_SIZE_32], new_fingerprint[CRYPTO_DISCOVERY_KEYS_NEW_FINGERPRINT_BUFFER_SIZE];
255 compute_key_fingerprint(old_pubkey, old_fingerprint);
256 compute_key_fingerprint(new_pubkey, new_fingerprint);
257
258 // Ask user to confirm
260 safe_snprintf(question, sizeof(question),
261 "ACDS SERVER KEY HAS CHANGED\nServer: %s\n\nOld SHA256: %s\nNew SHA256: %s\n\n"
262 "This may indicate key rotation or a man-in-the-middle attack.\n"
263 "Verify the new fingerprint with the operator before accepting.\n\nAccept new ACDS server key",
264 acds_server, old_fingerprint, new_fingerprint);
265 bool accepted = ui_notice_confirm_kind(UI_PROMPT_DISCOVERY_KEY_CHANGE, UI_NOTICE_DANGER, question, 120);
266 if (!accepted) {
267 return SET_ERRNO(ERROR_CRYPTO_VERIFICATION, "User rejected ACDS key change for: %s", acds_server);
268 }
269
270 log_info("User accepted ACDS key change for: %s", acds_server);
271 return ASCIICHAT_OK;
272}
#define CRYPTO_DISCOVERY_KEYS_QUESTION_BUFFER_SIZE
#define CRYPTO_DISCOVERY_KEYS_NEW_FINGERPRINT_BUFFER_SIZE
@ ERROR_CRYPTO_VERIFICATION
Definition error_codes.h:97
void compute_key_fingerprint(const uint8_t key[ED25519_PUBLIC_KEY_SIZE], char fingerprint[CRYPTO_HEX_KEY_SIZE_NULL])
bool ui_notice_confirm_kind(ui_prompt_kind_t kind, ui_notice_severity_t severity, const char *text, unsigned timeout_seconds)
Definition notice.c:498
@ UI_NOTICE_DANGER
Definition notice.h:12
#define HEX_STRING_SIZE_32
Hex string size for 32-byte values (64 hex chars + null terminator).
Definition sizes.h:154

References ASCIICHAT_OK, compute_key_fingerprint(), CRYPTO_DISCOVERY_KEYS_NEW_FINGERPRINT_BUFFER_SIZE, CRYPTO_DISCOVERY_KEYS_QUESTION_BUFFER_SIZE, ED25519_PUBLIC_KEY_SIZE, ERROR_CRYPTO_VERIFICATION, ERROR_INVALID_PARAM, HEX_STRING_SIZE_32, log_info, safe_snprintf(), SET_ERRNO, ui_notice_confirm_kind(), and UI_NOTICE_DANGER.

Referenced by discovery_keys_verify().