A multi-user chat server in C where users have to authenticate before they can talk, and group conversations are end-to-end keyed between their members. I built it to implement a classic key-distribution protocol from the paper down to the sockets, rather than only reading the message diagrams.
The server runs two listeners on separate ports: a key distribution centre (KDC) and the chat server itself. Each accepts connections concurrently so several clients can be served at once. Every user has a long-term symmetric key derived ahead of time with a password-based key derivation function, and that long-term key is what the authentication protocol bootstraps from.
Logging in follows the Needham-Schroeder scheme. A client first talks to the KDC, sending a fresh nonce along with its identity and the name of the chat server it wants to reach. The KDC mints a session key and a ticket, encrypts the reply under the user's long-term key, and sends it back. The client then presents the ticket to the chat server, which is what finally lets it in.
The nonce is the anti-replay anchor: the client checks that the value echoed back matches the one it sent, so a recorded KDC reply cannot be replayed at it later. After that handshake the client and the chat server share a session key and all further traffic rides on it.
Broadcasting to everyone is easy; the interesting case is a private group. When a user
creates a group and invites others, the members run a multi-party Diffie-Hellman
exchange so the group ends up with a shared secret that the server itself never holds.
The initiator establishes a key with the first member, then folds in each additional
member by passing the current shared secret encrypted under the new member's public
key and mixing in their contribution. Group messages are encrypted under that derived
key with AES-256, so users outside the group cannot read them.
/who: list logged-in users./write all: broadcast to everyone./create group and /group invite: build a private group./init group dhxchg: run the group key exchange./write group: send an encrypted message to a group./request file: pull a file from another user over a TLS connection
with a self-signed certificate.Implementing Needham-Schroeder by hand is the clearest way to see why the nonce exchange matters, and why the protocol was later patched against replay. It is a study build, the long-term keys and the textbook handshake are not how I would ship a real chat system, but wiring up a KDC, ticket validation, and a group key agreement on top of raw sockets made the whole family of authentication protocols click.