|
LibJWT 3.5.0
The C JSON Web Token Library +JWK +JWKS
|
Verify and validate JWT tokens. More...
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_t * | jwt_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_t * | jwt_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. | |
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.
| #define jwt_checker_auto_t |
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.
| typedef struct jwt_checker jwt_checker_t |
Opaque Checker object.
| enum 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.
| Enumerator | |
|---|---|
| JWT_VERIFY_POLICY_ANY | Accept if >=1 signature verifies |
| JWT_VERIFY_POLICY_ALL | Accept only if every signature does |
| 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.
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.
| checker | Pointer to a checker object |
| alg | The hash for the thumbprint comparison (see jwk_thumbprint_alg_t) |
| expected_jkt | The pinned base64url JWK Thumbprint the embedded key must match |
| 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.
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.
| checker | Pointer to a checker object |
| alg | The hash for the thumbprint comparison (see jwk_thumbprint_alg_t) |
| allowed | A JWKS of acceptable keys (borrowed, not freed by the checker) |
| int jwt_checker_error | ( | const jwt_checker_t * | checker | ) |
Checks error state of checker object.
| checker | Pointer to a checker object |
| void jwt_checker_error_clear | ( | jwt_checker_t * | checker | ) |
Clear error state in a checker object.
| checker | Pointer to a checker object |
| const char * jwt_checker_error_msg | ( | const jwt_checker_t * | checker | ) |
Get the error message contained in a checker object.
| checker | Pointer to a checker object |
| 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).
| checker | Pointer to a checker object |
| typ | The required media type, or NULL to clear the requirement |
| void jwt_checker_free | ( | jwt_checker_t * | checker | ) |
Frees a previously created checker object.
| checker | Pointer to a checker object |
| 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.
| checker | Pointer to a checker object |
| jwt_checker_t * jwt_checker_new | ( | void | ) |
Function to create a new checker instance.
| int jwt_checker_require | ( | jwt_checker_t * | checker, |
| const char ** | claims, | ||
| unsigned int | count ) |
Require that a set of claims is present.
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.
| checker | Pointer to a checker object |
| claims | An array of claim names that must be present (copied) |
| count | The number of names in claims |
| 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.
| checker | Pointer to a checker object |
| algs | An array of acceptable jwt_alg_t values (copied) |
| n | The number of entries in algs |
| 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.
| checker | Pointer to a checker object |
| cb | Pointer to a callback function |
| ctx | Pointer to data to pass to the callback function |
| 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.
| checker | Pointer to a checker object |
| cb | Pointer to a jti verification callback |
| ctx | Pointer to data to pass to the callback |
| 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.
| checker | Pointer to a checker object |
| alg | A valid jwt_alg_t type |
| key | A JWK key object |
| 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.
| checker | Pointer to a checker object |
| keyring | A JWKS of candidate keys (borrowed, not freed by the checker) |
| policy | A jwt_verify_policy_t value |
| 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).
| checker | Pointer to a checker object |
| 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.
| checker | Pointer to a checker object |
| index | A signature index in [0, jwt_checker_sig_count()) |
index, or NULL if it did not verify or the index is out of range. Borrowed from the keyring; do not free. | 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.
| checker | Pointer to a checker object |
| index | A signature index in [0, jwt_checker_sig_count()) |
index verified against a keyring key, 0 otherwise (including an out-of-range index) | 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.
| checker | Pointer to a checker object |
| header | Name of the critical header parameter the application understands |
| int jwt_checker_verify | ( | jwt_checker_t * | checker, |
| const char * | token ) |
Verify a token.
| checker | Pointer to a checker object |
| token | A string containing a token to be verified |
| 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).
| checker | Pointer to a checker object |
| token | A string containing the (detached) token to verify |
| payload | The out-of-band payload bytes |
| len | The payload length in bytes |