ChatSocket is a multi-room chat application written in C for macOS and Linux. It ships with:
- a TLS server
- a raw CLI client
- a modern full-screen terminal UI client
This app is designed with focus on end-to-end security, portability across Unix-like systems, and clean local bootstrapping.
- Protected rooms are end-to-end encrypted against the server.
- Room access verification and room encryption keys are derived separately.
- Direct messages use a signed ephemeral X25519 handshake and AES-256-GCM.
- The TUI is done through custom terminal renderer.
- The
run.shscripts can bootstrap build dependencies on macOS and common Linux distros. - Clients pin the server certificate fingerprint on first successful connection.
Protected rooms do not send the room secret or a directly reusable room key derivative to the server.
- The client generates a random salt.
- The server stores only a salted verifier.
- The room encryption key is derived locally from the room secret with a separate KDF context.
- Room messages are encrypted client-side with AES-256-GCM.
That means the server can decide whether a join proof is valid, but it cannot decrypt the room contents.
DM sessions use:
- Ed25519 identity keys for long-term identity
- signed ephemeral X25519 key exchange for session setup
- HKDF-SHA256 for session key derivation
- AES-256-GCM for message encryption
This is strong because session keys are not just permanent derivatives of the long-lived identity material.
The transport layer is TLS, clients pin the server certificate fingerprint on first use.
- First connection to
host:port: the fingerprint is stored locally. - Later connections: the fingerprint must match.
This is a trust-on-first-use model.
The TUI is a custom full-screen terminal interface built directly on ANSI terminal control and raw input handling.
- split conversation and sidebar layout
- room list and DM list on the right
- scrollback with arrow keys
- in-app help with
? - dark, modern terminal aesthetic instead of the old
ncurseslook
cd Server
./run.shcd Client
./run_tui.shcd Client
./run.shTo connect to another host:
cd Client
./run_tui.sh 192.168.1.100:2077For an isolated throwaway identity, append -test to either client script.
The run.sh scripts now check for:
gccpkg-config- OpenSSL development headers/libraries
If anything is missing, the scripts try to install the required packages:
- macOS: Homebrew
- Linux:
apt,dnf,yum,pacman, orzypper
If your system uses another package manager, install the dependencies manually and rerun the script.
/name <name>: set your local display name and sync it to the server/rooms: refresh the server room list/create <room>: create an open room/create <room> -p <secret>: create a protected room/enter <room>: enter a room/leave: leave the current room/dm <contact>: start a DM by number, nickname, token prefix, or full token/dmleave: close the active DM session/list: show your locally-known DM contacts in recent-first order/search <query>: search contacts the way you would in a messaging app/nick [@|contact] <name>: save a local nickname for the active DM or any contact/nick <contact> -: clear a saved nickname/token: show your identity token/help: show help/exit: disconnect
The scripts compile with pkg-config:
pkg-config --cflags --libs opensslIf you want to compile manually, use the same OpenSSL flags plus -lpthread.
On macOS, ChatSocket uses the system C toolchain plus Homebrew's pkg-config
and openssl@3. If the Apple command line tools are missing, install them
with:
xcode-select --installThere is a basic end-to-end CLI smoke test for local regression checking:
./tests/smoke_cli.shIt recompiles the server and CLI client, starts a local relay, connects two
test users, exercises room chat, DM handshakes, /nick, /list, /search,
and reopening a DM by contact number.
Client state is stored under ~/.socketchat/ by default.
identity.key: persistent Ed25519 identity seedusername: saved display namedm_*.log: DM history filesdm_nicks.tsv: token-to-nickname mappingsserver.crt/server.key: server TLS materialknown_servers.tsv: pinned TLS fingerprints byhost:port
- This targets macOS and Linux. Windows support was intentionally deferred.
- The room protection model is still password-based, so weak shared secrets remain guessable offline if the verifier is stolen.
- The TUI is intentionally lightweight and terminal-native; it is not using an external widget toolkit.
MIT