LibJWT 3.5.0
The C JSON Web Token Library +JWK +JWKS

Verify and validate JWT tokens. More...

Collaboration diagram for Checker:

Macros

#define jwt_checker_auto_t
 A jwt_checker_t pointer that is freed automatically at scope exit.

Typedefs

typedef struct jwt_checker jwt_checker_t
 Opaque Checker object.

Enumerations

enum  jwt_verify_policy_t { JWT_VERIFY_POLICY_ANY = 0 , JWT_VERIFY_POLICY_ALL }
 Multi-signature verification policy. More...

Functions

jwt_checker_tjwt_checker_new (void)
 Function to create a new checker instance.
void jwt_checker_free (jwt_checker_t *checker)
 Frees a previously created checker object.
int jwt_checker_error (const jwt_checker_t *checker)
 Checks error state of checker object.
const char * jwt_checker_error_msg (const jwt_checker_t *checker)
 Get the error message contained in a checker object.
void jwt_checker_error_clear (jwt_checker_t *checker)
 Clear error state in a checker object.
int jwt_checker_setkey (jwt_checker_t *checker, const jwt_alg_t alg, const jwk_item_t *key)
 Sets a key and algorithm for a checker.
int jwt_checker_setkeyring (jwt_checker_t *checker, const jwk_set_t *keyring, jwt_verify_policy_t policy)
 Set a keyring and policy for multi-signature verification.
int jwt_checker_expect_typ (jwt_checker_t *checker, const char *typ)
 Require a specific token media type ("typ" header).
int jwt_checker_setalgs (jwt_checker_t *checker, const jwt_alg_t *algs, size_t n)
 Set an allowlist of acceptable algorithms.
int jwt_checker_require (jwt_checker_t *checker, const char **claims, unsigned int count)
 Require that a set of claims is present.
int jwt_checker_enable_embedded_jwk (jwt_checker_t *checker, jwk_thumbprint_alg_t alg, const char *expected_jkt)
 Verify using the key embedded in the header, pinned by thumbprint.
int jwt_checker_enable_embedded_jwk_keyring (jwt_checker_t *checker, jwk_thumbprint_alg_t alg, const jwk_set_t *allowed)
 Verify using the key embedded in the header, allowed by a keyring.
int jwt_checker_setcb (jwt_checker_t *checker, jwt_callback_t cb, void *ctx)
 Set a callback for generating tokens.
int jwt_checker_setjti (jwt_checker_t *checker, jwt_jti_check_cb_t cb, void *ctx)
 Set a callback to verify the jti (JWT ID) claim (RFC-7519 Sec 4.1.7).
void * jwt_checker_getctx (jwt_checker_t *checker)
 Retrieve the callback context that was previously set.
int jwt_checker_understands (jwt_checker_t *checker, const char *header)
 Declare a critical header parameter as understood (RFC-7515 Sec 4.1.11).
int jwt_checker_verify (jwt_checker_t *checker, const char *token)
 Verify a token.
unsigned int jwt_checker_sig_count (const jwt_checker_t *checker)
 Number of signatures in the last verified token.
int jwt_checker_sig_verified (const jwt_checker_t *checker, unsigned int index)
 Whether a given signature of the last token verified.
const jwk_item_tjwt_checker_sig_key (const jwt_checker_t *checker, unsigned int index)
 The key a given signature of the last token verified against.
int jwt_checker_verify_detached (jwt_checker_t *checker, const char *token, const unsigned char *payload, size_t len)
 Verify a token whose payload was detached.

Detailed Description

Verify and validate JWT tokens.

Validating a JWT involves decoding the Base64url parts of the JWT then verifying claims and the signature hash. The checker object allows you to configure how you want to perform these steps so you can easily process tokens with one simple call.

Macro Definition Documentation

◆ jwt_checker_auto_t

#define jwt_checker_auto_t
Value:
jwt_checker_t \
__attribute__((cleanup(jwt_checker_freep)))

A jwt_checker_t pointer that is freed automatically at scope exit.

Declares a jwt_checker_t pointer carrying the GCC/Clang cleanup attribute so jwt_checker_free() is invoked on it automatically when the variable goes out of scope. Initialize it where you declare it.

Since
3.0.0

Typedef Documentation

◆ jwt_checker_t

typedef struct jwt_checker jwt_checker_t

Opaque Checker object.

Since
3.0.0

Enumeration Type Documentation

◆ jwt_verify_policy_t

Multi-signature verification policy.

Governs how jwt_checker_verify() decides on a JWS JSON Serialization that carries more than one signature (RFC-7515 Sec 7.2 leaves this to the application). It has no effect on a Compact or single-signature token.

Since
3.6.0
Enumerator
JWT_VERIFY_POLICY_ANY 

Accept if >=1 signature verifies

JWT_VERIFY_POLICY_ALL 

Accept only if every signature does

Function Documentation

◆ jwt_checker_enable_embedded_jwk()

int jwt_checker_enable_embedded_jwk ( jwt_checker_t * checker,
jwk_thumbprint_alg_t alg,
const char * expected_jkt )

Verify using the key embedded in the header, pinned by thumbprint.

RFC-7515 Sec 4.1.3 📄 RFC-9449

Enables taking the verification key from the token's protected-header "jwk" (a self-contained token, as used by DPoP and OpenID4VCI key proofs). Because that key is supplied by whoever made the token, it is never trusted on its own: it is accepted only if its JWK Thumbprint (alg) equals expected_jkt – the value you obtained out of band and are pinning to, such as the cnf.jkt of a presented access token (read with jwt_get_cnf()). The confirmed key is still held to the usual key-type/algorithm binding. Combine with jwt_checker_setalgs() to bound the acceptable algorithms.

Passing a NULL or empty expected_jkt fails: there is no "trust whatever is embedded" mode. Applies to the Compact Serialization (what DPoP/OpenID4VCI use). Mutually exclusive with the keyring form; the last call wins.

Parameters
checkerPointer to a checker object
algThe hash for the thumbprint comparison (see jwk_thumbprint_alg_t)
expected_jktThe pinned base64url JWK Thumbprint the embedded key must match
Returns
0 on success, non-zero otherwise with error set in the checker
Since
3.6.0

◆ jwt_checker_enable_embedded_jwk_keyring()

int jwt_checker_enable_embedded_jwk_keyring ( jwt_checker_t * checker,
jwk_thumbprint_alg_t alg,
const jwk_set_t * allowed )

Verify using the key embedded in the header, allowed by a keyring.

RFC-7515 Sec 4.1.3

As jwt_checker_enable_embedded_jwk(), but the protected-header "jwk" is accepted only if its JWK Thumbprint (alg) matches that of some key in allowed (via jwks_find_bythumbprint()). Use this when the set of acceptable holder keys is known in advance rather than pinned per token. The keyring is borrowed: the caller retains ownership and must keep it valid for the lifetime of the checker.

Passing a NULL allowed fails. Mutually exclusive with the pinned form; the last call wins.

Parameters
checkerPointer to a checker object
algThe hash for the thumbprint comparison (see jwk_thumbprint_alg_t)
allowedA JWKS of acceptable keys (borrowed, not freed by the checker)
Returns
0 on success, non-zero otherwise with error set in the checker
Since
3.6.0

◆ jwt_checker_error()

int jwt_checker_error ( const jwt_checker_t * checker)

Checks error state of checker object.

Parameters
checkerPointer to a checker object
Returns
0 if no errors exist, non-zero otherwise
Since
3.0.0

◆ jwt_checker_error_clear()

void jwt_checker_error_clear ( jwt_checker_t * checker)

Clear error state in a checker object.

Parameters
checkerPointer to a checker object
Since
3.0.0

◆ jwt_checker_error_msg()

const char * jwt_checker_error_msg ( const jwt_checker_t * checker)

Get the error message contained in a checker object.

Parameters
checkerPointer to a checker object
Returns
Pointer to a string with the error message. Can be an empty string if there is no error. Never returns NULL.
Since
3.0.0

◆ jwt_checker_expect_typ()

int jwt_checker_expect_typ ( jwt_checker_t * checker,
const char * typ )

Require a specific token media type ("typ" header).

When set, jwt_checker_verify() rejects a token whose "typ" header does not match typ. The comparison is case-insensitive and tolerates the optional application/ prefix (RFC 6838), so expect_typ(c, "at+jwt") accepts both "at+jwt" and "application/at+jwt". This is the standardized cross-JWT-confusion defense (📄 RFC-8725 §3.11).

Parameters
checkerPointer to a checker object
typThe required media type, or NULL to clear the requirement
Returns
0 on success, non-zero otherwise with error set in the checker
Since
3.6.0

◆ jwt_checker_free()

void jwt_checker_free ( jwt_checker_t * checker)

Frees a previously created checker object.

Parameters
checkerPointer to a checker object
Since
3.0.0

◆ jwt_checker_getctx()

void * jwt_checker_getctx ( jwt_checker_t * checker)

Retrieve the callback context that was previously set.

This is useful for accessing the context that was previously passed in the setcb function.

Parameters
checkerPointer to a checker object
Returns
Pointer to the context or NULL
Since
3.0.0

◆ jwt_checker_new()

jwt_checker_t * jwt_checker_new ( void )

Function to create a new checker instance.

Returns
Pointer to a checker object on success, NULL on failure
Since
3.0.0

◆ jwt_checker_require()

int jwt_checker_require ( jwt_checker_t * checker,
const char ** claims,
unsigned int count )

Require that a set of claims is present.

RFC-9068 Sec 4

When set, jwt_checker_verify() rejects a token that is missing any of the named claims, independent of any value match (a value check is a separate concern – see jwt_checker_claim_set()). LibJWT otherwise validates only the claims it is told to compare, and silently tolerates an absent one; this asserts the mandatory-claims discipline that profiles such as RFC 9068 (at+jwt) require – e.g. {"iss","exp","aud","sub","client_id","jti"}. The names are copied. Passing count as 0 (or claims as NULL) clears the requirement.

Parameters
checkerPointer to a checker object
claimsAn array of claim names that must be present (copied)
countThe number of names in claims
Returns
0 on success, non-zero otherwise with error set in the checker
Since
3.6.0

◆ jwt_checker_setalgs()

int jwt_checker_setalgs ( jwt_checker_t * checker,
const jwt_alg_t * algs,
size_t n )

Set an allowlist of acceptable algorithms.

Restricts the algorithms jwt_checker_verify() will accept to the given set, checked before any signature work (📄 RFC-8725). Useful when verifying against a keyring (jwt_checker_setkeyring()) where several algorithms are acceptable, e.g. {JWT_ALG_RS256, JWT_ALG_ES256}. A token whose "alg" is not in the set is rejected, which also blocks an alg:none downgrade. Passing n as 0 (or algs as NULL) clears the allowlist.

Parameters
checkerPointer to a checker object
algsAn array of acceptable jwt_alg_t values (copied)
nThe number of entries in algs
Returns
0 on success, non-zero otherwise with error set in the checker
Since
3.6.0

◆ jwt_checker_setcb()

int jwt_checker_setcb ( jwt_checker_t * checker,
jwt_callback_t cb,
void * ctx )

Set a callback for generating tokens.

When verifying a token, this callback will be run after jwt_t has been parsed, but before the token is verified (including signature verification). During this, the callback should only inspect the header or claims in the JWT. Any attempts to make changes to the jwt_t object will not change the rest of the process.

The callback can also set the key and algorithm used to verify the signature. If the callback returns non-zero, then processing will stop and return an error.

The ctx value is also passed to the callback as part of the jwt_value_t struct.

Note
Calling this with a NULL cb param and a new ctx param after already setting the callback will allow updating the ctx passed to the callback. Calling with both values as NULL will disable the callback completely.
Parameters
checkerPointer to a checker object
cbPointer to a callback function
ctxPointer to data to pass to the callback function
Returns
0 on success, non-zero otherwise with error set in the checker
Since
3.0.0

◆ jwt_checker_setjti()

int jwt_checker_setjti ( jwt_checker_t * checker,
jwt_jti_check_cb_t cb,
void * ctx )

Set a callback to verify the jti (JWT ID) claim (RFC-7519 Sec 4.1.7).

When set, verification reads the token's "jti" claim and passes it to the callback, which returns 0 to accept or non-zero to reject the token. This is where an application implements replay protection against its own id pool (look the id up and consume it). When this callback is set, a token that has no "jti" claim is rejected.

The ctx is passed to the callback via the jwt_config_t structure.

Note
Calling this with a NULL cb and a new ctx updates the ctx. Calling with both NULL disables the callback.
Parameters
checkerPointer to a checker object
cbPointer to a jti verification callback
ctxPointer to data to pass to the callback
Returns
0 on success, non-zero otherwise with error set in the checker
Since
3.4.0

◆ jwt_checker_setkey()

int jwt_checker_setkey ( jwt_checker_t * checker,
const jwt_alg_t alg,
const jwk_item_t * key )

Sets a key and algorithm for a checker.

See jwt_builder_setkey for detailed information.

Parameters
checkerPointer to a checker object
algA valid jwt_alg_t type
keyA JWK key object
Returns
0 on success, non-zero otherwise with error set in the checker
Since
3.0.0

◆ jwt_checker_setkeyring()

int jwt_checker_setkeyring ( jwt_checker_t * checker,
const jwk_set_t * keyring,
jwt_verify_policy_t policy )

Set a keyring and policy for multi-signature verification.

Supplies a set of candidate keys (a JWKS) instead of the single key set by jwt_checker_setkey(), so a JWS JSON Serialization with multiple signatures can be verified. A signature naming a kid is matched to that key in the ring; a keyless signature is tried against every compatible key. Each candidate is held to the usual algorithm/key-type binding.

Under JWT_VERIFY_POLICY_ANY (the default and the generalization of the single-key behavior) the token is accepted if at least one signature verifies; under JWT_VERIFY_POLICY_ALL every signature in the token must verify. The keyring is borrowed: the caller retains ownership and must keep it valid for the lifetime of the checker. Setting a keyring and setting a single key are mutually exclusive; the last call wins.

Parameters
checkerPointer to a checker object
keyringA JWKS of candidate keys (borrowed, not freed by the checker)
policyA jwt_verify_policy_t value
Returns
0 on success, non-zero otherwise with error set in the checker
Since
3.6.0

◆ jwt_checker_sig_count()

unsigned int jwt_checker_sig_count ( const jwt_checker_t * checker)

Number of signatures in the last verified token.

After jwt_checker_verify(), returns how many signatures the token carried (1 for a Compact or Flattened token, N for a General one, 0 if verification failed before the signatures were parsed).

Parameters
checkerPointer to a checker object
Returns
The signature count of the last token
Since
3.6.0

◆ jwt_checker_sig_key()

const jwk_item_t * jwt_checker_sig_key ( const jwt_checker_t * checker,
unsigned int index )

The key a given signature of the last token verified against.

Parameters
checkerPointer to a checker object
indexA signature index in [0, jwt_checker_sig_count())
Returns
The keyring key that verified signature index, or NULL if it did not verify or the index is out of range. Borrowed from the keyring; do not free.
Since
3.6.0

◆ jwt_checker_sig_verified()

int jwt_checker_sig_verified ( const jwt_checker_t * checker,
unsigned int index )

Whether a given signature of the last token verified.

After jwt_checker_verify(), reports per-signature results. Useful under JWT_VERIFY_POLICY_ANY to learn which signature(s) passed.

Parameters
checkerPointer to a checker object
indexA signature index in [0, jwt_checker_sig_count())
Returns
1 if signature index verified against a keyring key, 0 otherwise (including an out-of-range index)
Since
3.6.0

◆ jwt_checker_understands()

int jwt_checker_understands ( jwt_checker_t * checker,
const char * header )

Declare a critical header parameter as understood (RFC-7515 Sec 4.1.11).

Per RFC 7515, if a token's crit (Critical) header parameter lists a header name, the recipient MUST understand and process that header or else reject the token. LibJWT understands no extension header parameters on its own, so by default any token carrying a crit header will fail verification.

Use this function to declare each extension header parameter that your application is prepared to handle (typically inspected in your verify callback). During verification, every name listed in crit must both be present in the header and have been declared here; otherwise the token is rejected.

Parameters
checkerPointer to a checker object
headerName of the critical header parameter the application understands
Returns
0 on success, non-zero otherwise with error set in the checker
Since
3.4.0

◆ jwt_checker_verify()

int jwt_checker_verify ( jwt_checker_t * checker,
const char * token )

Verify a token.

Note
If you set a callback for this checker, this is when it will be called.
Parameters
checkerPointer to a checker object
tokenA string containing a token to be verified
Returns
0 on success, non-zero otherwise with error set in the checker
Since
3.0.0

◆ jwt_checker_verify_detached()

int jwt_checker_verify_detached ( jwt_checker_t * checker,
const char * token,
const unsigned char * payload,
size_t len )

Verify a token whose payload was detached.

Verifies a token produced with jwt_builder_set_detached() (or any JWS with a detached payload), supplying the payload out-of-band. Works for both base64url and 📄 RFC-7797 unencoded ("b64":false) payloads; the signing input is reconstructed from payload according to the token's "b64" header. As with jwt_checker_verify(), an unencoded payload is accepted only if "b64" is present in the token's "crit" header (RFC 7797 §6).

Parameters
checkerPointer to a checker object
tokenA string containing the (detached) token to verify
payloadThe out-of-band payload bytes
lenThe payload length in bytes
Returns
0 on success, non-zero otherwise with error set in the checker
Since
3.6.0