ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
identity.c File Reference

Go to the source code of this file.

Functions

asciichat_error_t acds_identity_generate (uint8_t public_key[32], uint8_t secret_key[64])
 
asciichat_error_t acds_identity_load (const char *path, uint8_t public_key[32], uint8_t secret_key[64])
 
asciichat_error_t acds_identity_save (const char *path, const uint8_t public_key[32], const uint8_t secret_key[64])
 
void acds_identity_fingerprint (const uint8_t public_key[32], char fingerprint[65])
 
asciichat_error_t acds_identity_default_path (char *path_out, size_t path_size)
 

Function Documentation

◆ acds_identity_default_path()

asciichat_error_t acds_identity_default_path ( char *  path_out,
size_t  path_size 
)

Definition at line 121 of file identity.c.

121 {
122 if (!path_out || path_size == 0) {
123 return SET_ERRNO(ERROR_INVALID_PARAM, "path_out cannot be NULL and path_size must be > 0");
124 }
125
126 // Get platform-specific config directory (~/.config/ascii-chat/ or %APPDATA%\ascii-chat\‍)
127 char *config_dir = platform_get_config_dir();
128 if (!config_dir) {
129 return SET_ERRNO(ERROR_CONFIG, "Failed to get config directory");
130 }
131
132 // Append "acds_identity" to config directory
133 int written = safe_snprintf(path_out, path_size, "%sacds_identity", config_dir);
134 SAFE_FREE(config_dir);
135
136 if (written < 0 || (size_t)written >= path_size) {
137 return SET_ERRNO(ERROR_CONFIG, "Path buffer too small");
138 }
139
140 return ASCIICHAT_OK;
141}
int safe_snprintf(char *buffer, size_t buffer_size, const char *format,...)
Safe formatted string printing to buffer.
Definition system.c:456
char * platform_get_config_dir(void)
Definition util.c:102

References platform_get_config_dir(), and safe_snprintf().

Referenced by discovery_session_create().

◆ acds_identity_fingerprint()

void acds_identity_fingerprint ( const uint8_t  public_key[32],
char  fingerprint[65] 
)

Definition at line 104 of file identity.c.

104 {
105 if (!public_key || !fingerprint) {
106 log_error("acds_identity_fingerprint: NULL parameters");
107 return;
108 }
109
110 // Compute SHA256 hash of public key
111 uint8_t hash[32];
112 crypto_hash_sha256(hash, public_key, 32);
113
114 // Convert to hex string
115 for (int i = 0; i < 32; i++) {
116 safe_snprintf(&fingerprint[i * 2], 3, "%02x", hash[i]);
117 }
118 fingerprint[64] = '\0';
119}

References safe_snprintf().

Referenced by acds_main(), and discovery_session_create().

◆ acds_identity_generate()

asciichat_error_t acds_identity_generate ( uint8_t  public_key[32],
uint8_t  secret_key[64] 
)

Definition at line 18 of file identity.c.

18 {
19 if (!public_key || !secret_key) {
20 return SET_ERRNO(ERROR_INVALID_PARAM, "public_key and secret_key cannot be NULL");
21 }
22
23 // Generate Ed25519 keypair using libsodium
24 if (crypto_sign_keypair(public_key, secret_key) != 0) {
25 return SET_ERRNO(ERROR_CRYPTO, "Failed to generate Ed25519 keypair");
26 }
27
28 log_debug("Generated new Ed25519 identity keypair");
29 return ASCIICHAT_OK;
30}

Referenced by acds_main(), and discovery_session_create().

◆ acds_identity_load()

asciichat_error_t acds_identity_load ( const char *  path,
uint8_t  public_key[32],
uint8_t  secret_key[64] 
)

Definition at line 32 of file identity.c.

32 {
33 if (!path || !public_key || !secret_key) {
34 return SET_ERRNO(ERROR_INVALID_PARAM, "path, public_key, and secret_key cannot be NULL");
35 }
36
37 // Open file for reading
38 FILE *fp = platform_fopen(path, "rb");
39 if (!fp) {
40 if (errno == ENOENT) {
41 return SET_ERRNO(ERROR_CONFIG, "Identity file does not exist: %s", path);
42 }
43 return SET_ERRNO_SYS(ERROR_CONFIG, "Failed to open identity file: %s", path);
44 }
45
46 // Read secret key (64 bytes)
47 size_t read = fread(secret_key, 1, 64, fp);
48 if (read != 64) {
49 fclose(fp);
50 return SET_ERRNO(ERROR_CONFIG, "Identity file corrupted (expected 64 bytes, got %zu): %s", read, path);
51 }
52
53 // Extract public key from secret key (last 32 bytes of Ed25519 secret key)
54 memcpy(public_key, secret_key + 32, 32);
55
56 fclose(fp);
57 log_info("Loaded identity from %s", path);
58 return ASCIICHAT_OK;
59}
FILE * platform_fopen(const char *filename, const char *mode)

References platform_fopen().

Referenced by acds_main(), and discovery_session_create().

◆ acds_identity_save()

asciichat_error_t acds_identity_save ( const char *  path,
const uint8_t  public_key[32],
const uint8_t  secret_key[64] 
)

Definition at line 61 of file identity.c.

61 {
62 if (!path || !public_key || !secret_key) {
63 return SET_ERRNO(ERROR_INVALID_PARAM, "path, public_key, and secret_key cannot be NULL");
64 }
65
66 // Extract directory path and create all parent directories
67 char dir_path[PLATFORM_MAX_PATH_LENGTH];
68 SAFE_STRNCPY(dir_path, path, sizeof(dir_path));
69
70 // Find last directory separator
71 char *last_sep = strrchr(dir_path, '/');
72 if (!last_sep) {
73 last_sep = strrchr(dir_path, '\\');
74 }
75
76 if (last_sep) {
77 *last_sep = '\0';
78
79 // Create directory recursively (mkdir -p equivalent)
80 asciichat_error_t result = platform_mkdir_recursive(dir_path, 0700);
81 if (result != ASCIICHAT_OK) {
82 return result;
83 }
84 }
85
86 // Open file for writing (mode 0600 = owner read/write only)
87 int fd = platform_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
88 if (fd < 0) {
89 return SET_ERRNO_SYS(ERROR_CONFIG, "Failed to create identity file: %s", path);
90 }
91
92 // Write secret key (64 bytes)
93 ssize_t written = write(fd, secret_key, 64);
94 close(fd);
95
96 if (written != 64) {
97 return SET_ERRNO(ERROR_CONFIG, "Failed to write identity file (wrote %zd/64 bytes): %s", written, path);
98 }
99
100 log_info("Saved identity to %s", path);
101 return ASCIICHAT_OK;
102}
#define PLATFORM_MAX_PATH_LENGTH
Definition system.c:64
asciichat_error_t platform_mkdir_recursive(const char *path, int mode)
int platform_open(const char *pathname, int flags,...)

References PLATFORM_MAX_PATH_LENGTH, platform_mkdir_recursive(), and platform_open().

Referenced by acds_main(), and discovery_session_create().