🔐 Client cryptography: handshake integration, X25519 key exchange, and per-session encryption
More...
|
| int | client_crypto_init (void) |
| | Initialize client crypto handshake.
|
| |
| int | client_crypto_handshake (socket_t socket) |
| | Perform crypto handshake with server.
|
| |
| bool | crypto_client_is_ready (void) |
| | Check if crypto handshake is ready.
|
| |
| const crypto_context_t * | crypto_client_get_context (void) |
| | Get crypto context for encryption/decryption.
|
| |
| int | crypto_client_encrypt_packet (const uint8_t *plaintext, size_t plaintext_len, uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_len) |
| | Encrypt a packet for transmission.
|
| |
| int | crypto_client_decrypt_packet (const uint8_t *ciphertext, size_t ciphertext_len, uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_len) |
| | Decrypt a received packet.
|
| |
| void | crypto_client_cleanup (void) |
| | Cleanup crypto client resources.
|
| |
| bool | crypto_client_should_rekey (void) |
| | Check if session rekeying should be triggered.
|
| |
| int | crypto_client_initiate_rekey (void) |
| | Initiate session rekeying (client-initiated)
|
| |
| int | crypto_client_process_rekey_request (const uint8_t *packet, size_t packet_len) |
| | Process received REKEY_REQUEST packet from server.
|
| |
| int | crypto_client_send_rekey_response (void) |
| | Send REKEY_RESPONSE packet to server.
|
| |
| int | crypto_client_process_rekey_response (const uint8_t *packet, size_t packet_len) |
| | Process received REKEY_RESPONSE packet from server.
|
| |
| int | crypto_client_send_rekey_complete (void) |
| | Send REKEY_COMPLETE packet to server and commit to new key.
|
| |
🔐 Client cryptography: handshake integration, X25519 key exchange, and per-session encryption
CORE RESPONSIBILITIES:
- Initialize client crypto context with authentication credentials
- Perform cryptographic handshake with server during connection
- Manage global crypto context for client connection
- Provide encryption/decryption functions for secure packet transmission
- Support multiple authentication modes (password, SSH key, passwordless)
- Handle session rekeying for long-lived connections
CRYPTOGRAPHIC HANDSHAKE ARCHITECTURE:
The handshake follows a multi-phase protocol:
PHASE 0: PROTOCOL NEGOTIATION:
- Step 0a: Send client protocol version
- Step 0b: Receive server protocol version
- Step 0c: Send client crypto capabilities
- Step 0d: Receive server crypto parameters
PHASE 1: KEY EXCHANGE:
- Step 1: Receive server's ephemeral public key and send our public key
- Client generates ephemeral key pair for this session
- Both sides derive shared secret using X25519 key exchange
PHASE 2: AUTHENTICATION:
- Step 2: Receive auth challenge and send response
- Client signs challenge with identity key (if client has identity key)
- Server verifies client identity (if whitelist enabled)
- Step 3: Receive handshake complete message
CRYPTO INITIALIZATION:
The client supports three initialization modes:
- SSH KEY MODE (–key specified):
- Parses Ed25519 private key from file or gpg:keyid format
- Extracts public key for authentication
- Supports password-protected keys (SSH agent or prompt)
- Optional password for dual authentication (key + password)
- PASSWORD MODE (–password specified):
- Uses Argon2id key derivation from shared password
- Both client and server derive same key from password
- No identity keys required
- PASSWORDLESS MODE (no credentials):
- Generates random ephemeral keys
- No long-term identity (no authentication)
- Suitable for trusted networks or testing
GLOBAL CRYPTO CONTEXT:
The client uses a single global crypto context (g_crypto_ctx):
- Shared across all connection attempts (reused on reconnection)
- Initialized once per program execution
- Cleaned up on program shutdown
- Stores server connection info for known_hosts verification
SERVER IDENTITY VERIFICATION:
Client verifies server identity using known_hosts:
- Checks server's identity key against ~/.ascii-chat/known_hosts
- First connection: Prompts user to accept server key
- Subsequent connections: Verifies key matches stored value
- Key mismatch: Warns user about potential MITM attack
- Optional –server-key for explicit server key verification
CLIENT AUTHENTICATION REQUIREMENTS:
When server requires client authentication (whitelist enabled):
- Client must provide identity key with –key option
- Client's public key must be in server's –client-keys list
- Authentication failure results in connection rejection
- Interactive prompt warns user if no identity key provided
SESSION REKEYING:
Long-lived connections support periodic rekeying:
ENCRYPTION/DECRYPTION OPERATIONS:
After handshake completion:
ALGORITHM SUPPORT:
The client currently supports:
- Key Exchange: X25519 (Elliptic Curve Diffie-Hellman)
- Cipher: XSalsa20-Poly1305 (Authenticated Encryption)
- Authentication: Ed25519 (when client has identity key)
- Key Derivation: Argon2id (for password-based authentication)
- HMAC: HMAC-SHA256 (for additional integrity protection)
ERROR HANDLING:
Handshake errors are handled appropriately:
- Server disconnection during handshake: Log and return error
- Protocol mismatch: Log detailed error and abort connection
- Authentication failure: Log and return CONNECTION_ERROR_AUTH_FAILED
- Network errors: Detect and handle gracefully (reconnection)
- Invalid packets: Validate size and format before processing
THREAD SAFETY:
Crypto operations are thread-safe:
- Global crypto context protected by initialization flag
- Single crypto context per client process (no concurrent handshakes)
- Encryption/decryption operations are safe for concurrent use
- Rekeying operations coordinate with connection thread
INTEGRATION WITH OTHER MODULES:
- main.c: Calls client_crypto_init() during client startup
- server.c: Calls client_crypto_handshake() during connection
- protocol.c: Uses encryption functions for secure packet transmission
- crypto/handshake.h: Core handshake protocol implementation
- crypto/keys/keys.h: Key parsing and management functions
- crypto/known_hosts.h: Server identity verification
WHY THIS MODULAR DESIGN:
Separating cryptographic operations from connection management provides:
- Clear cryptographic interface for application code
- Easier handshake protocol evolution
- Better error isolation and debugging
- Improved security auditing capabilities
- Independent testing of crypto functionality
- Author
- Zachary Fogg me@zf.nosp@m.o.gg
- Date
- October 2025
- Version
- 2.0
- See also
- server.c For connection establishment and Crypto Module Handshake Module timing
-
crypto/handshake.h For Handshake Module protocol implementation
-
crypto/keys/keys.h For key parsing and management
-
crypto/known_hosts.h For server identity verification
Definition in file src/client/crypto.c.