Server/Client Example
Overview
This page walks through the SST C server/client example, which demonstrates basic secure communication between two entities using Auth-distributed session keys.
Source: examples/server_client_example/ in iotauth/sst-c-api.
What this demonstrates
- A client requests session keys from Auth, connects to the server, and performs the three-way SST handshake.
- The server accepts client connections, validates the handshake, and exchanges encrypted messages.
- Session keys from a first connection are cached in the server's key list and reused for subsequent connections without another Auth round-trip.
- Both sides use
send_secure_message/read_secure_messagefor all communication.
Prerequisites
- Auth is running (see Quick Start).
- The sst-c-api library is built (see C Guide).
Build
cd sst-c-api/examples/server_client_example
mkdir -p build && cd build
cmake ../
make
For verbose debug output:
cmake -DCMAKE_BUILD_TYPE=DEBUG ../
make
This produces two binaries in build/:
entity_server— the server entityentity_client— the client entity
Run
1. Start Auth
cd auth/auth-server # inside iotauth/iotauth
java -jar target/auth-server-jar-with-dependencies.jar -p ../properties/exampleAuth101.properties
2. Start the server
cd sst-c-api/examples/server_client_example/build
./entity_server ../c_server.config
The server binds to its configured port and waits for a client.
3. Start the client
cd sst-c-api/examples/server_client_example/build
./entity_client ../c_client.config
The client contacts Auth for session keys, connects to the server, completes the handshake, and sends encrypted messages.
What should happen
You should see:
- Auth logs showing session key requests from both entities.
- The server logging a successful handshake and received decrypted message.
- The client logging the server's encrypted acknowledgment after decryption.
Implementation walkthrough
Client (entity_client.c)
// Load config and credentials
SST_ctx_t* ctx = init_SST(config_path);
// Request session keys from Auth
session_key_list_t* s_key_list = get_session_key(ctx, NULL);
// Connect to server and perform SST handshake
SST_session_ctx_t* session = secure_connect_to_server(&s_key_list->s_key[0], ctx);
// Start a background receive thread
pthread_t thread;
pthread_create(&thread, NULL, receive_thread_read_one_each, (void*)session);
// Send encrypted messages
send_secure_message("hello from client", 17, session);
// Cleanup
pthread_cancel(thread);
pthread_join(thread, NULL);
free_session_ctx(session);
free_session_key_list_t(s_key_list);
free_SST_ctx_t(ctx);
Server (entity_server.c)
SST_ctx_t* ctx = init_SST(config_path);
session_key_list_t* key_list = init_empty_session_key_list();
// Create TCP socket and listen
int server_sock = /* create, bind, listen */;
// Accept first client
int clnt_sock = accept(server_sock, ...);
SST_session_ctx_t* session = server_secure_comm_setup(ctx, clnt_sock, key_list);
// Communicate
pthread_t thread;
pthread_create(&thread, NULL, receive_thread_read_one_each, (void*)session);
send_secure_message("hello from server", 17, session);
// For subsequent clients, key_list already has cached keys from the first handshake
int clnt_sock2 = accept(server_sock, ...);
SST_session_ctx_t* session2 = server_secure_comm_setup(ctx, clnt_sock2, key_list);
Message framing
Each send_secure_message call writes a framed message of the form:
[1 byte : message type (SECURE_COMM_MSG = 33)]
[2 bytes: payload length]
[16 bytes: AES IV]
[8 bytes: sequence number + payload + padding]
[32 bytes: HMAC tag]
Total maximum message size: 1091 bytes. The sequence number prevents replay attacks; read_secure_message verifies it automatically.
Config files
| File | Purpose |
|---|---|
c_client.config | Client entity config: Auth coordinates, server IP/port, session key purpose. |
c_server.config | Server entity config: Auth coordinates, listening port, entity credentials. |
The configs are generated by generateAll.sh and placed in the example directory. Key fields:
| Field | Example value |
|---|---|
auth_ip_addr | 127.0.0.1 |
auth_port_num | 21900 |
entity_server_ip_addr | 127.0.0.1 |
entity_server_port_num | 21100 |
numkey | 1 |
Next steps
- See C API Reference for full function documentation.
- See File Block Encryption for per-block encryption without sockets.
- See IPFS File Sharing for Auth-managed file encryption and distribution.