C SDK

The C account client is in c/auth.h, c/auth.c, and c/auth_curl.c in mesgd-sdk. Use it to enroll an account, obtain a session, and manage public keys independently of the PKI layer. The examples use an existing account named alice; passwords and authenticator codes come from the application rather than literals in source.

Support status

CapabilityCurrent support
Account operationsAvailable: signup, confirmation, login, reset, keys, key updates, and logout
HTTPSAvailable: built-in verified HTTPS transport, covered by the live auth runner
WSSPending supported SDK message client; experimental samples are not current-server integration

Completeness position: 3 of 18. Verified HTTPS through libcurl and tested peer-key cryptography; public PKI header and WSS wrapper remain missing. The language matrix explains the ranking criteria and comparable tiers. WSS readiness is listed separately; no SDK currently provides a complete, validated encrypted messaging workflow against this server.

Setup and transport

Compile auth.c, auth_curl.c, and the bundled 3rd-party/cJSON/cJSON.c, linking libcurl. Include the C and cJSON directories. The account API accepts a transport callback; auth_curl.c is the provided HTTPS implementation.

Call curl_global_init once before concurrent use and curl_global_cleanup when all clients are finished. mesgd_auth_curl_config contains the HTTPS origin and an optional CA filename; NULL selects system trust. The example assumes global initialization has already succeeded.

A custom transport must serialize JSON, attach Authorization: Bearer TOKEN only when a token is supplied, verify the certificate and hostname, reject redirects, and use a finite timeout. Its origin is an HTTPS URL, such as https://mesgd.example.com, rather than a WebSocket URL.

Log in, read keys, and log out

Pass the current authenticator code as a six-digit string, preserving leading zeroes. This example reads the account's published keys and ends the session on its successful path. Applications that retain a session can keep the bearer until logout or expiry instead.

#include "auth.h"
#include "auth_curl.h"
#include <stdlib.h>
#include <string.h>

int read_keys(const char *password, const char *otp, cJSON **keys) {
    mesgd_auth_curl_config config = {"https://mesgd.example.com", NULL};
    mesgd_auth client = {mesgd_auth_curl_transport, &config};
    cJSON *session = NULL, *reply = NULL;
    *keys = NULL;
    int status = mesgd_auth_login(&client, "alice", password, otp, &session);
    if (status < 200 || status >= 300) return status;
    const cJSON *item = cJSON_GetObjectItemCaseSensitive(session, "access_token");
    if (!cJSON_IsString(item)) { cJSON_Delete(session); return -3; }
    char *token = malloc(strlen(item->valuestring) + 1);
    if (!token) { cJSON_Delete(session); return -2; }
    strcpy(token, item->valuestring);
    cJSON_Delete(session);
    status = mesgd_auth_keys(&client, token, keys);
    int logout_status = mesgd_auth_logout(&client, token, &reply);
    cJSON_Delete(reply);
    free(token);
    if (status >= 200 && status < 300 &&
        (logout_status < 200 || logout_status >= 300)) {
        cJSON_Delete(*keys); *keys = NULL;
        return logout_status;
    }
    return status;
}

Functions return the HTTP status, or a negative local error. The caller owns successful cJSON * results and frees them with cJSON_Delete; *out is null on failure. Input strings and JSON are borrowed for the call only. The PKI implementation currently lives in c/pki.c without a public pki.h, so account code should not assume a packaged C PKI header exists.

Enroll a new account

The following fragment uses an existing client or transport from the example above. Signup returns a pending enrollment. Display qr_png_base64 or otpauth_uri, let the person configure the authenticator, then collect a code to confirm it. These calls are separate application steps, with user interaction between them.

cJSON *enrollment = NULL;
int status = mesgd_auth_signup(&client, "alice", "alice@example.com",
                               password, NULL, &enrollment);
/* On 201, display the enrollment. Copy enrollment_token before deleting
   enrollment, then call mesgd_auth_confirm with a fresh six-digit string. */
cJSON_Delete(enrollment);

Confirmation returns the first session and eight recovery codes. Display the recovery codes for separate safekeeping. A code accepted for confirmation cannot be reused for login or a key update; wait for a new authenticator step before another operation that consumes a code.

Account operations

OperationFunction or methodHTTP endpoint
Create a pending accountmesgd_auth_signupPOST /auth/signup
Confirm authenticator enrollmentmesgd_auth_confirmPOST /auth/signup/confirm
Log inmesgd_auth_loginPOST /auth/login
Reset a forgotten passwordmesgd_auth_reset_passwordPOST /auth/password/reset
Read account public keysmesgd_auth_keysGET /auth/keys
Replace account public keysmesgd_auth_set_keysPUT /auth/keys
End the current sessionmesgd_auth_logoutPOST /auth/logout

A key update takes the session token, current password, a fresh authenticator code, and an array containing only public JWKs. An empty array clears the linked keys. A password reset takes the username, a saved recovery code, a new password, and a fresh authenticator code; success replaces the recovery codes and revokes existing sessions without returning a new session.

The shared authentication reference documents argument order, response fields, and transport behavior. Session refresh is available through the HTTP API but is not wrapped by these seven SDK operations.

Message connections

The C ping/pong sample includes root-level pki.h and mesgd.h, neither of which exists in this checkout. The libcurl account client is available independently of those missing message-client headers.

Account login does not establish a message connection. The current server accepts JSON WebSocket frames and can authenticate an upgrade with a login session or an issued grant token. Login sessions carry identity without path restrictions; grants limit routing to assigned patterns. See WebSocket and Routing.

The encrypted registration handshake in the ping/pong samples is not implemented by the current mesgd listener. Treat those samples as experimental cryptographic examples, with compatibility limits described in Samples.

Validation

From the mesgd-sdk repository root, run the account contract suite for this language:

python3 tests/test_auth.py --language c

This is an offline request-contract check. Missing toolchains are reported as skips. See Languages for live HTTPS and PKI test coverage.