Skip to content
ClientsIn development

Native

Link a static library into your binary. It holds no key, opens no socket to Root Herald, and writes into buffers you own.

respond.cc
#include <rootherald.h>

/* challenge: the "rhc1.…" string your backend relayed, verbatim. Returns malloc'd JSON or NULL. */
char* answer_challenge(const char* challenge) {
    RH_HANDLE h = NULL;
    if (RootHeraldOpen(&h) != RH_OK) return NULL;            /* no TPM reachable */

    size_t cap = 64 * 1024, len = 0;                          /* generous first size; grow once if told to */
    char* evidence = malloc(cap);
    RH_STATUS st = RootHeraldRespond(h, challenge, NULL, evidence, cap, &len, NULL, 0, NULL);
    if (st == RH_ERR_BUFFER_TOO_SMALL) {
        evidence = realloc(evidence, len); cap = len;
        st = RootHeraldRespond(h, challenge, NULL, evidence, cap, &len, NULL, 0, NULL);
    }
    if (st == RH_ERR_NOT_ENROLLED) { /* first run: EnrollBegin + EnrollComplete, elevated on Windows, then retry */ }

    RootHeraldClose(h);
    if (st != RH_OK) { free(evidence); return NULL; }
    return evidence;                                          /* POST { challengeId, evidence } to your backend */
}

Install

One archive per platform from the sdk-windows, sdk-linux and sdk-macos releases: lib/, include/rootherald.h, SHA256SUMS.

linkbash
link.exe app.obj RootHerald.lib ncrypt.lib tbs.lib winhttp.lib bcrypt.lib crypt32.lib     # Windows
gcc app.o -lrootherald -ltss2-esys -ltss2-tctildr -ltss2-mu -lcurl -lpthread              # Linux
clang app.o -lrootherald -framework Security -framework Foundation                       # macOS

First contact

RH_ERR_NOT_ENROLLED means run the two enroll legs once on one session — RootHeraldEnrollBegin, relay through your backend, RootHeraldEnrollComplete, relay again. On Windows that session must be elevated; the SDK returns RH_ERR_ELEVATION_REQUIRED and never elevates for you. Code and patterns on the Enrollment and Windows elevation pages.

The server half

Identical for every client and written out once in the quickstart: send { challengeId, evidence } over whatever channel your app already has to your backend, which calls rh.verify().

Platforms

Windows is the complete desktop path today. The Linux (tpm2-tss) and macOS (Secure Enclave) collectors share the byte-identical header; check RootHeraldPreCheck for what the machine can serve before minting an ask it cannot answer.