ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
lib/crypto/key_identity/display.c
Go to the documentation of this file.
2#include <ascii-chat/common.h>
8#include <string.h>
10
11asciichat_error_t key_identity_format(const public_key_t *key, bool art, bool unicode, int cols, char *out,
12 size_t size) {
13 if (!out || !size)
14 return SET_ERRNO(ERROR_INVALID_PARAM, "Missing identity output buffer");
15 out[0] = '\0';
16 if (!key)
17 return SET_ERRNO(ERROR_INVALID_PARAM, "Missing public identity");
18 const char *type;
19 switch (key->type) {
21 type = "Ed25519";
22 break;
23 case KEY_TYPE_GPG:
24 type = "Ed25519 (GPG)";
25 break;
26 case KEY_TYPE_X25519:
27 type = "X25519";
28 break;
29 default:
30 return SET_ERRNO(ERROR_INVALID_PARAM, "Unsupported public identity type");
31 }
33 asciichat_error_t result = key_fingerprint_digest(key->key, digest);
34 if (result != ASCIICHAT_OK)
35 return result;
36 char hex[HEX_STRING_SIZE_32];
37 for (size_t i = 0; i < sizeof(digest); ++i) {
38 hex[i * 2] = "0123456789abcdef"[digest[i] >> 4];
39 hex[i * 2 + 1] = "0123456789abcdef"[digest[i] & 15];
40 }
41 hex[64] = '\0';
42 char mask[KEYMASK_BUFFER_SIZE] = "";
43 bool show = art && cols >= KEYMASK_WIDTH;
44 if (show && (result = keymask_render(digest, unicode, mask, sizeof(mask))) != ASCIICHAT_OK)
45 return result;
46 const char *heading = show ? "Keymask v2 / SHA-256\n" : "";
47 size_t needed = strlen(type) + strlen(" public key\n") + strlen(heading) + strlen(mask) + strlen("SHA256:") + 64 + 2;
48 if (size < needed)
49 return SET_ERRNO(ERROR_INVALID_PARAM, "Identity output needs %zu bytes", needed);
50 safe_snprintf(out, size, "%s public key\n%s%sSHA256:%s\n", type, heading, mask, hex);
51 return ASCIICHAT_OK;
52}
53
55 bool tty = platform_isatty(STDERR_FILENO);
56 bool art = tty && !GET_OPTION(snapshot_mode);
57 int cols = tty ? ui_controller_size().cols : 80;
58 // Notices reserve borders, padding, and the terminal's final column.
59 cols = (cols > 81 ? 80 : cols - 1) - 4;
60 bool unicode = terminal_should_use_utf8(GET_OPTION(force_utf8));
61 return key_identity_format(key, art, unicode, cols, out, size);
62}
63
64const char *key_identity_art_end(const char *text) {
65 static const char heading[] = "Keymask v2 / SHA-256\n";
66 static const char border[] = "+--------------------------------+\n";
67 if (!text || strncmp(text, heading, sizeof(heading) - 1) != 0)
68 return NULL;
69 const char *row = text + sizeof(heading) - 1;
70 if (strncmp(row, border, sizeof(border) - 1) != 0)
71 return NULL;
72 row += sizeof(border) - 1;
73 for (unsigned i = 0; i < KEYMASK_ROWS - 2; ++i) {
74 const char *end = strchr(row, '\n');
75 if (!end || end - row < 2 || row[0] != '|' || end[-1] != '|' ||
76 utf8_display_width_n(row, (size_t)(end - row)) != KEYMASK_WIDTH)
77 return NULL;
78 row = end + 1;
79 }
80 return strncmp(row, border, sizeof(border) - 1) == 0 ? row + sizeof(border) - 1 : NULL;
81}
82
83void key_identity_announce(const char *label, const public_key_t *key) {
84 char identity[KEY_IDENTITY_BUFFER_SIZE];
85 if (key_identity_format_terminal(key, identity, sizeof(identity)) == ASCIICHAT_OK)
86 NOTICE_ANNOUNCE(label, "%s", identity);
87}
#define SET_ERRNO(code,...)
⚙️ Common definitions, error codes, macros, and types shared throughout the application
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
@ ASCIICHAT_OK
Definition error_codes.h:46
@ ERROR_INVALID_PARAM
uint8_t key[CRYPTO_PUBLIC_KEY_SIZE]
Definition key_types.h:74
key_type_t type
Definition key_types.h:73
@ KEY_TYPE_ED25519
Definition key_types.h:54
@ KEY_TYPE_GPG
Definition key_types.h:56
@ KEY_TYPE_X25519
Definition key_types.h:55
#define GET_OPTION(field)
Safely get a specific option field (lock-free read).
Definition options.h:1336
int safe_snprintf(char *buffer, size_t buffer_size, const char *format,...)
Platform-safe snprintf wrapper.
int utf8_display_width_n(const char *str, size_t max_bytes)
Calculate terminal display width of a UTF-8 string up to byte limit.
Definition utf8.c:102
asciichat_error_t key_fingerprint_digest(const uint8_t public_key[ED25519_PUBLIC_KEY_SIZE], uint8_t digest[KEYMASK_DIGEST_SIZE])
Definition keymask.c:11
asciichat_error_t keymask_render(const uint8_t digest[KEYMASK_DIGEST_SIZE], bool unicode, char *out, size_t size)
Definition keymask.c:42
#define KEYMASK_WIDTH
Definition keymask.h:10
#define KEYMASK_BUFFER_SIZE
Definition keymask.h:13
#define KEYMASK_ROWS
Definition keymask.h:11
#define KEYMASK_DIGEST_SIZE
Definition keymask.h:9
asciichat_error_t key_identity_format_terminal(const public_key_t *key, char *out, size_t size)
asciichat_error_t key_identity_format(const public_key_t *key, bool art, bool unicode, int cols, char *out, size_t size)
void key_identity_announce(const char *label, const public_key_t *key)
const char * key_identity_art_end(const char *text)
#define NOTICE_ANNOUNCE(title,...)
Definition notice.h:74
⚙️ Unified options parsing system for ascii-chat with builder pattern and lock-free access
static bool size_t gotel_query_t * out
Definition queries.h:8
#define HEX_STRING_SIZE_32
Hex string size for 32-byte values (64 hex chars + null terminator).
Definition sizes.h:154
🔤 String Manipulation and Shell Escaping Utilities
The normalized public identity used by ascii-chat's crypto and key-management code.
Definition key_types.h:72
terminal_size_t ui_controller_size(void)
🔤 UTF-8 Encoding and Decoding Utilities