Skip to main content

Server/Client Example

Overview​

This page demonstrates secure communication between two entities using Auth-distributed session keys. Choose a technology to see the matching setup, run commands, and client/server implementation.

The examples share the same flow:

  1. The client requests session keys from Auth.
  2. The client connects to the server and completes the SST handshake.
  3. Both entities exchange encrypted messages over the secure channel.
  4. Session keys are cached and reused when the implementation supports it.

Prerequisites​

  • Clone the iotauth/iotauth repository.
  • Run ./generateAll.sh from examples/ to generate the shared credentials and the entity configs supported by the generator.
  • Start Auth 101 before starting either entity:
cd auth/auth-server
mvn clean install
java -jar target/auth-server-jar-with-dependencies.jar \
-p ../properties/exampleAuth101.properties

Technology example​

Choose one of the following technologies:

C example​

The C example uses the native SST API and demonstrates the protocol lifecycle directly.

Source: examples/server_client_example/ in iotauth/sst-c-api.

Build the C example​

cd entity/c/examples/server_client_example
mkdir -p build
cd build
cmake ../
make

For verbose debug output:

cmake -DCMAKE_BUILD_TYPE=DEBUG ../
make

This produces entity_server and entity_client in build/.

Run the C server​

cd entity/c/examples/server_client_example/build
./entity_server ../c_server.config

The server binds to its configured port and waits for the client.

Run the C client​

cd entity/c/examples/server_client_example/build
./entity_client ../c_client.config

The client requests session keys from Auth, completes the handshake, and sends encrypted messages.

C client implementation​

These C excerpts assume successful API calls; check pointer and status results in application code. Stop and join receiver threads before closing sockets and freeing sessions.

SST_ctx_t* ctx = init_SST(config_path);
session_key_list_t* keys = get_session_key(ctx, NULL);

SST_session_ctx_t* session =
secure_connect_to_server(&keys->s_key[0], ctx);

pthread_t receive_thread;
pthread_create(
&receive_thread,
NULL,
receive_thread_read_one_each,
(void*)session
);

send_secure_message(
"Hello server",
strlen("Hello server"),
session
);

shutdown(session->sock, SHUT_RDWR);
pthread_join(receive_thread, NULL);
close(session->sock);
free_session_ctx(session);
free_session_key_list_t(keys);
free_SST_ctx_t(ctx);

C server implementation​

SST_ctx_t* ctx = init_SST(config_path);
session_key_list_t* keys = init_empty_session_key_list();

int client_socket = accept(server_socket, NULL, NULL);
SST_session_ctx_t* session =
server_secure_comm_setup(ctx, client_socket, keys);

pthread_t receive_thread;
pthread_create(
&receive_thread,
NULL,
receive_thread_read_one_each,
(void*)session
);

send_secure_message(
"Hello client",
strlen("Hello client"),
session
);

The server keeps keys available for later accepted connections so cached session keys can be reused without another Auth round trip.

C configuration​

FilePurpose
c_client.configAuth coordinates, server address, session key purpose, and client credentials.
c_server.configAuth coordinates, listening port, and server credentials.

What should happen​

You should see:

  1. Auth logs showing session key requests from the entities.
  2. The server logging a successful handshake and the decrypted client message.
  3. The client logging the decrypted server response.

All four implementations use the same SST message framing, authenticated encryption, and sequence-number validation.

Next steps​