Подпись (9 функций)
xjwtSign config-стиль
Подпись с полным контролем: инъекция iss/aud/sub/jti/exp/iat и kid в заголовок (iat всегда). Заголовок строится JSON-сериализацией (kid экранируется автоматически, без ограничения длины); ёмкость выходного буфера подписи проверяется (покрывает RSA-8192). Внимание: объект claims изменяется на месте.
xjwtconfig cfg;
xjwtConfigInit(&cfg);
cfg.Alg = XJWT_ALG_RS256;
cfg.KeyPem = sPrivateKeyPem; /* загружен при старте */
cfg.KeyId = "web-2026-09";
cfg.Issuer = "https://myapp.example.com";
cfg.Audience = "myapp-web";
cfg.ExpireSeconds = 900;
xvalue* claims = xrtValueObject();
xrtValueObjectSetNew(claims, xrtStrView("scope"),
xrtValueString(xrtStrView("profile orders")));
char* sToken = xjwtSign(&cfg, claims); /* освободить xrtFree */
xrtValueRelease(claims);
xjwtHs256 / Hs384 / Hs512 / Rs256 / Rs384 / Rs512 / Es256 одношаговые
Семь одношаговых подписей (claims + ключ + срок в секундах). Это семейство не инъектирует iss/aud — если проверяющая сторона в xjwtcheck указала Issuer/Audience, используйте xjwtSign. HS принимает ключ как C-строку (встроенный '\0' обрезает; бинарные ключи не поддерживаются); RS — PEM закрытого ключа PKCS#8/PKCS#1; ES256 — PEM закрытого ключа SEC1/PKCS#8.
xjwtConfigInit инициализация
Обнуляет конфигурацию, по умолчанию HS256. KeyId длиной ≥ 256 символов отклоняется при подписи (симметрично лимиту проверяющей стороны).
Проверка (4 функции)
xjwtVerify путь PEM
Проверка за один шаг: декодирование alg из заголовка → проверка claims (нецелые exp/nbf отклоняются; iss/aud за константное время; aud принимает строки и массивы) → проверка подписи. HS принимает строку-ключ, RS/ES — PEM открытого ключа; тип ключа сверяется с семейством алгоритмов (защита от подмены). Успех — claims (освободить xrtValueRelease), неудача — NULL с кодом ошибки.
xjwtcheck check;
xjwtCheckInit(&check);
check.Issuer = "https://myapp.example.com";
check.Audience = "myapp-web";
check.ClockLeeway = 30;
xvalue* claims = xjwtVerify(sBearerToken, sPublicKeyPem, &check);
if ( claims == NULL ) {
if ( xjwtLastError() == XJWT_ERROR_EXPIRED )
return 401; /* истёк */
return 401; /* подделка / подмена / неверная подпись */
}
char aUser[64];
xjwtClaimString(claims, "sub", aUser, sizeof(aUser));
xrtValueRelease(claims);
xjwtKeyParse / xjwtKeyFree / xjwtVerifyKey кэш ключа
Высокочастотная проверка: открытый ключ разбирается один раз (RSA SPKI/PKCS#1 или EC P-256 SPKI; закрытые ключи и сертификаты отклоняются); объект кэша только для чтения и разделяем между потоками. VerifyKey отклоняет семейство HS и сверяет семейство алгоритмов с типом ключа. Кучный указатель — естественный путь для уровня скриптов.
JWKS (3 функции)
xjwtJwksParse / xjwtJwksFree набор ключей
Разбор JWKS (RFC 7517) JSON: RSA n/e и EC x/y (только P-256; прочие кривые пропускаются; координаты строго 32 байта). Не более 16 ключей — при превышении весь набор отклоняется; повреждённые записи (например, n без e) немедленно освобождаются.
xjwtVerifyJwks проверка с выбором ключа
Выбор ключа по строгому совпадению kid из заголовка токена (без kid — первый ключ; kid ≥ 260 отклоняется везде). Явно отклоняет семейство HS; перекрёстные проверки RS* ↔ RSA и ES256 ↔ EC. Повтор при ротации: при xjwtLastError() == XJWT_ERROR_KEY_NOT_FOUND перезагрузите JWKS и проверьте ещё раз.
Claims и ошибки (3 функции)
xjwtClaimsValid ручной поток
Автономная проверка claims (exp/nbf/iss/aud): требуется JSON-объект; exp/nbf нецелого типа всегда отклоняются; aud принимает строки и массивы (любое совпадение).
xjwtClaimString извлечение
Безопасное извлечение строкового claim: усечение до cap-1 с завершающим нулём; false, если claim отсутствует или не строка.
xjwtLastError чтение ошибки
Возвращает код ошибки домена xjwt (XJWT_ERROR_*) текущего контекста выполнения, 0 — если текущая ошибка из другого домена. Читайте сразу после сбоя.
Декодирование и утилиты (5 функций)
xjwtDecode / xjwtDecodeHeader декодирование
Декодирование без проверки подписи (доверенные источники / отладка): первый возвращает claims и может отдать alg заголовка; второй возвращает объект заголовка с alg + kid (kid — кучная копия, освободить xrtFree). Claims/заголовок обязаны быть JSON-объектами; при переданном pKid kid ≥ 260 отклоняет вызов целиком.
xjwtCheckInit / xjwtAlgName / xjwtAlgParse утилиты
Обнуляет структуру проверки (NowOverride внедряет тестовые часы, ClockLeeway — допуск в секундах); преобразует enum алгоритма в имя и обратно.