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

Identity key management implementation. 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 implementation.

Definition in file identity.c.

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().