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

Identity key management for discovery server. More...

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])
 Generate new Ed25519 keypair.
 
asciichat_error_t acds_identity_load (const char *path, uint8_t public_key[32], uint8_t secret_key[64])
 Load identity from file.
 
asciichat_error_t acds_identity_save (const char *path, const uint8_t public_key[32], const uint8_t secret_key[64])
 Save identity to file.
 
void acds_identity_fingerprint (const uint8_t public_key[32], char fingerprint[65])
 Compute SHA256 fingerprint of public key.
 
asciichat_error_t acds_identity_default_path (char *path_out, size_t path_size)
 Get default identity file path for current platform.
 

Detailed Description

Identity key management for discovery server.

Simple Ed25519 key generation, storage, and fingerprint computation. This is a minimal inline implementation - will be refactored to lib/identity/ in the future when we add randomart and other features.

Definition in file identity.h.

Function Documentation

◆ acds_identity_default_path()

asciichat_error_t acds_identity_default_path ( char *  path_out,
size_t  path_size 
)

Get default identity file path for current platform.

Parameters
path_outOutput buffer for path (should be at least 256 bytes)
path_sizeSize of output buffer
Returns
ASCIICHAT_OK on success, error code otherwise

Returns:

  • Unix: ~/.config/ascii-chat/acds_identity
  • Windows: APPDATA%\ascii-chat\acds_identity

Definition at line 198 of file identity.c.

198 {
199 if (!path_out || path_size == 0) {
200 return SET_ERRNO(ERROR_INVALID_PARAM, "path_out cannot be NULL and path_size must be > 0");
201 }
202
203#ifdef _WIN32
204 // Windows: %APPDATA%\ascii-chat\acds_identity
205 const char *appdata = SAFE_GETENV("APPDATA");
206 if (!appdata) {
207 return SET_ERRNO(ERROR_CONFIG, "APPDATA environment variable not set");
208 }
209
210 int written = snprintf(path_out, path_size, "%s\\ascii-chat\\acds_identity", appdata);
211 if (written < 0 || (size_t)written >= path_size) {
212 return SET_ERRNO(ERROR_CONFIG, "Path buffer too small");
213 }
214#else
215 // Unix: ~/.config/ascii-chat/acds_identity
216 const char *home = SAFE_GETENV("HOME");
217 if (!home) {
218 return SET_ERRNO(ERROR_CONFIG, "HOME environment variable not set");
219 }
220
221 // Check for XDG_CONFIG_HOME
222 const char *xdg_config = SAFE_GETENV("XDG_CONFIG_HOME");
223 if (xdg_config && xdg_config[0] != '\0') {
224 int written = snprintf(path_out, path_size, "%s/ascii-chat/acds_identity", xdg_config);
225 if (written < 0 || (size_t)written >= path_size) {
226 return SET_ERRNO(ERROR_CONFIG, "Path buffer too small");
227 }
228 } else {
229 int written = snprintf(path_out, path_size, "%s/.config/ascii-chat/acds_identity", home);
230 if (written < 0 || (size_t)written >= path_size) {
231 return SET_ERRNO(ERROR_CONFIG, "Path buffer too small");
232 }
233 }
234#endif
235
236 return ASCIICHAT_OK;
237}
#define SAFE_GETENV(name)
Definition common.h:378
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it.
@ ASCIICHAT_OK
Definition error_codes.h:48
@ ERROR_CONFIG
Definition error_codes.h:54
@ ERROR_INVALID_PARAM

References ASCIICHAT_OK, ERROR_CONFIG, ERROR_INVALID_PARAM, SAFE_GETENV, and SET_ERRNO.

◆ acds_identity_fingerprint()

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

Compute SHA256 fingerprint of public key.

Parameters
public_key32-byte Ed25519 public key
fingerprintOutput buffer for 65 bytes (64 hex chars + null terminator)

Definition at line 181 of file identity.c.

181 {
182 if (!public_key || !fingerprint) {
183 log_error("acds_identity_fingerprint: NULL parameters");
184 return;
185 }
186
187 // Compute SHA256 hash of public key
188 uint8_t hash[32];
189 crypto_hash_sha256(hash, public_key, 32);
190
191 // Convert to hex string
192 for (int i = 0; i < 32; i++) {
193 sprintf(&fingerprint[i * 2], "%02x", hash[i]);
194 }
195 fingerprint[64] = '\0';
196}
unsigned char uint8_t
Definition common.h:56
#define log_error(...)
Log an ERROR message.

References log_error.

Referenced by main().

◆ acds_identity_generate()

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

Generate new Ed25519 keypair.

Parameters
public_keyOutput buffer for 32-byte public key
secret_keyOutput buffer for 64-byte secret key
Returns
ASCIICHAT_OK on success, error code otherwise

Definition at line 21 of file identity.c.

21 {
22 if (!public_key || !secret_key) {
23 return SET_ERRNO(ERROR_INVALID_PARAM, "public_key and secret_key cannot be NULL");
24 }
25
26 // Generate Ed25519 keypair using libsodium
27 if (crypto_sign_keypair(public_key, secret_key) != 0) {
28 return SET_ERRNO(ERROR_CRYPTO, "Failed to generate Ed25519 keypair");
29 }
30
31 log_debug("Generated new Ed25519 identity keypair");
32 return ASCIICHAT_OK;
33}
@ ERROR_CRYPTO
Definition error_codes.h:88
#define log_debug(...)
Log a DEBUG message.

References ASCIICHAT_OK, ERROR_CRYPTO, ERROR_INVALID_PARAM, log_debug, and SET_ERRNO.

Referenced by main().

◆ acds_identity_load()

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

Load identity from file.

Parameters
pathPath to identity file (e.g., ~/.config/ascii-chat/acds_identity)
public_keyOutput buffer for 32-byte public key
secret_keyOutput buffer for 64-byte secret key
Returns
ASCIICHAT_OK on success, ERROR_CONFIG if file doesn't exist

Definition at line 35 of file identity.c.

35 {
36 if (!path || !public_key || !secret_key) {
37 return SET_ERRNO(ERROR_INVALID_PARAM, "path, public_key, and secret_key cannot be NULL");
38 }
39
40 // Open file for reading
41 FILE *fp = fopen(path, "rb");
42 if (!fp) {
43 if (errno == ENOENT) {
44 return SET_ERRNO(ERROR_CONFIG, "Identity file does not exist: %s", path);
45 }
46 return SET_ERRNO_SYS(ERROR_CONFIG, "Failed to open identity file: %s", path);
47 }
48
49 // Read secret key (64 bytes)
50 size_t read = fread(secret_key, 1, 64, fp);
51 if (read != 64) {
52 fclose(fp);
53 return SET_ERRNO(ERROR_CONFIG, "Identity file corrupted (expected 64 bytes, got %zu): %s", read, path);
54 }
55
56 // Extract public key from secret key (last 32 bytes of Ed25519 secret key)
57 memcpy(public_key, secret_key + 32, 32);
58
59 fclose(fp);
60 log_info("Loaded identity from %s", path);
61 return ASCIICHAT_OK;
62}
#define SET_ERRNO_SYS(code, context_msg,...)
Set error code with custom message and system error context.
#define log_info(...)
Log an INFO message.
int errno

References ASCIICHAT_OK, errno, ERROR_CONFIG, ERROR_INVALID_PARAM, log_info, SET_ERRNO, and SET_ERRNO_SYS.

Referenced by main().

◆ acds_identity_save()

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

Save identity to file.

Parameters
pathPath to identity file
public_key32-byte public key
secret_key64-byte secret key
Returns
ASCIICHAT_OK on success, error code otherwise

Definition at line 138 of file identity.c.

138 {
139 if (!path || !public_key || !secret_key) {
140 return SET_ERRNO(ERROR_INVALID_PARAM, "path, public_key, and secret_key cannot be NULL");
141 }
142
143 // Extract directory path and create all parent directories
144 char dir_path[512];
145 SAFE_STRNCPY(dir_path, path, sizeof(dir_path));
146
147 // Find last directory separator
148 char *last_sep = strrchr(dir_path, '/');
149 if (!last_sep) {
150 last_sep = strrchr(dir_path, '\\');
151 }
152
153 if (last_sep) {
154 *last_sep = '\0';
155
156 // Create directory recursively (mkdir -p equivalent)
157 asciichat_error_t result = ensure_directory_exists(dir_path);
158 if (result != ASCIICHAT_OK) {
159 return result;
160 }
161 }
162
163 // Open file for writing (mode 0600 = owner read/write only)
164 int fd = platform_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
165 if (fd < 0) {
166 return SET_ERRNO_SYS(ERROR_CONFIG, "Failed to create identity file: %s", path);
167 }
168
169 // Write secret key (64 bytes)
170 ssize_t written = write(fd, secret_key, 64);
171 close(fd);
172
173 if (written != 64) {
174 return SET_ERRNO(ERROR_CONFIG, "Failed to write identity file (wrote %zd/64 bytes): %s", written, path);
175 }
176
177 log_info("Saved identity to %s", path);
178 return ASCIICHAT_OK;
179}
#define SAFE_STRNCPY(dst, src, size)
Definition common.h:358
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:46
int platform_open(const char *pathname, int flags,...)
Safe file open (open replacement)

References ASCIICHAT_OK, ERROR_CONFIG, ERROR_INVALID_PARAM, log_info, platform_open(), SAFE_STRNCPY, SET_ERRNO, and SET_ERRNO_SYS.

Referenced by main().