cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
jwt.h File Reference

JWT (JSON Web Token) generation and verification. More...

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <time.h>
Include dependency graph for jwt.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  cwist_jwt_chunk
 One sequenced JWT chunk produced by cwist_jwt_split_chunks(). More...
 

Typedefs

typedef struct cwist_jwt_claims cwist_jwt_claims
 Opaque JWT claims object returned after successful verification.
 
typedef struct cwist_jwt_chunk cwist_jwt_chunk_t
 One sequenced JWT chunk produced by cwist_jwt_split_chunks().
 

Functions

char * cwist_jwt_sign (const char *payload_json, const char *secret, long exp_seconds)
 Sign a JWT token with HMAC-SHA256.
 
cwist_jwt_claims * cwist_jwt_verify (const char *token, const char *secret)
 Verify a JWT token and return the decoded claims.
 
const char * cwist_jwt_claims_get (const cwist_jwt_claims *claims, const char *key)
 Retrieve a claim value by key from decoded claims.
 
void cwist_jwt_claims_destroy (cwist_jwt_claims *claims)
 Free a claims object.
 
cwist_jwt_chunk_t * cwist_jwt_split_chunks (const char *token, uint16_t chunk_payload_size, size_t *out_count)
 Split a JWT token into sequenced chunks.
 
void cwist_jwt_chunks_free (cwist_jwt_chunk_t *chunks, size_t count)
 Free chunk objects returned by cwist_jwt_split_chunks().
 
char * cwist_jwt_join_chunks (const cwist_jwt_chunk_t *chunks, size_t count)
 Reassemble a JWT token from sequenced chunks.
 
cwist_jwt_chunk_t * cwist_jwt_sign_chunks (const char *payload_json, const char *secret, long exp_seconds, uint16_t chunk_payload_size, size_t *out_count)
 Sign a JWT and immediately split it into sequenced chunks.
 
cwist_jwt_claims * cwist_jwt_verify_chunks (const cwist_jwt_chunk_t *chunks, size_t count, const char *secret)
 Reassemble sequenced JWT chunks and verify the resulting token.
 
char * cwist_jwt_sign_es256 (const char *payload_json, const char *pem_private_key, const char *kid, long exp_seconds)
 Sign a JWT token with ES256 (ECDSA over P-256 with SHA-256).
 
cwist_jwt_claims * cwist_jwt_verify_es256 (const char *token, const char *pem_key)
 Verify an ES256-signed JWT token and return the decoded claims.
 
char * cwist_jwt_sign_ed25519 (const char *payload_json, const char *pem_private_key, const char *kid, long exp_seconds)
 Sign a JWT token with EdDSA (Ed25519, RFC 8037).
 
cwist_jwt_claims * cwist_jwt_verify_ed25519 (const char *token, const char *pem_key)
 Verify an Ed25519-signed JWT token and return the decoded claims.
 

Detailed Description

JWT (JSON Web Token) generation and verification.

Supports HS256 (HMAC-SHA256), ES256 (ECDSA P-256 + SHA-256) and EdDSA (Ed25519) signed tokens. Wrapper over OpenSSL, following the cwist security module convention.

Definition in file jwt.h.

Typedef Documentation

◆ cwist_jwt_chunk_t

One sequenced JWT chunk produced by cwist_jwt_split_chunks().

The data buffer is heap-allocated and includes the 8-byte sequence header followed by a substring of the original token.

◆ cwist_jwt_claims

typedef struct cwist_jwt_claims cwist_jwt_claims

Opaque JWT claims object returned after successful verification.

Definition at line 25 of file jwt.h.

Function Documentation

◆ cwist_jwt_chunks_free()

void cwist_jwt_chunks_free ( cwist_jwt_chunk_t *  chunks,
size_t  count 
)

Free chunk objects returned by cwist_jwt_split_chunks().

Free chunk objects returned by cwist_jwt_split_chunks().

Parameters
chunksChunk array to free; NULL is accepted as a no-op.
countNumber of entries in chunks.

Definition at line 837 of file jwt.c.

References cap, count, and cwist_free().

◆ cwist_jwt_claims_destroy()

void cwist_jwt_claims_destroy ( cwist_jwt_claims *  claims)

Free a claims object.

Parameters
claimsObject to free (may be NULL).

Free a claims object.

Parameters
claimsClaims object to destroy.

Definition at line 779 of file jwt.c.

References cap, and cwist_free().

◆ cwist_jwt_claims_get()

const char * cwist_jwt_claims_get ( const cwist_jwt_claims *  claims,
const char *  key 
)

Retrieve a claim value by key from decoded claims.

Parameters
claimsClaims object returned by cwist_jwt_verify().
keyJSON key to look up (e.g. "sub").
Returns
Read-only pointer to the value string, or NULL if not found. The pointer is valid until cwist_jwt_claims_destroy() is called.

Retrieve a claim value by key from decoded claims.

Parameters
claimsVerified claims object.
keyClaim name to retrieve.
Returns
Borrowed pointer to the claim string, or NULL when absent/non-string.

Definition at line 766 of file jwt.c.

References cap.

◆ cwist_jwt_join_chunks()

char * cwist_jwt_join_chunks ( const cwist_jwt_chunk_t *  chunks,
size_t  count 
)

Reassemble a JWT token from sequenced chunks.

Duplicate chunks are discarded. The chunks may be supplied in any order, but all chunks for one token must be present.

Parameters
chunksArray of chunk objects.
countNumber of chunks.
Returns
Heap-allocated token string, or NULL on error. Caller must free with cwist_free().

Reassemble a JWT token from sequenced chunks.

Parameters
chunksArray of sequenced chunks, in any order accepted by the assembler.
countNumber of entries in chunks.
Returns
Heap-allocated null-terminated JWT string, or NULL when the chunk set is invalid/incomplete or assembly/allocation fails.

The caller owns the returned string and must free it with cwist_free().

Definition at line 852 of file jwt.c.

References cap, count, cwist_alloc(), cwist_seq_assembler_create(), cwist_seq_assembler_destroy(), cwist_seq_assembler_feed(), cwist_seq_assembler_get_data(), and cwist_seq_chunk_parse().

Referenced by cwist_jwt_verify_chunks().

◆ cwist_jwt_sign()

char * cwist_jwt_sign ( const char *  payload_json,
const char *  secret,
long  exp_seconds 
)

Sign a JWT token with HMAC-SHA256.

Parameters
payload_jsonJSON string for the payload (e.g. "{\"sub\":\"1\"}"). Standard claims like "exp" and "iat" are added automatically when exp_seconds is > 0. Supply them yourself if you need fine-grained control (pass exp_seconds = 0 in that case).
secretHMAC secret key (null-terminated).
exp_secondsSeconds until expiry from now. Pass 0 to skip automatic "exp" injection (you must include it in payload_json).
Returns
Heap-allocated null-terminated JWT string, or NULL on error. Caller must free with cwist_free().

Definition at line 620 of file jwt.c.

References cap, and JWT_ALG_HS256.

Referenced by cwist_jwt_sign_chunks().

◆ cwist_jwt_sign_chunks()

cwist_jwt_chunk_t * cwist_jwt_sign_chunks ( const char *  payload_json,
const char *  secret,
long  exp_seconds,
uint16_t  chunk_payload_size,
size_t *  out_count 
)

Sign a JWT and immediately split it into sequenced chunks.

This is a convenience helper for the login/authentication path: the caller receives chunks that can be transmitted out of order and later verified with cwist_jwt_verify_chunks().

Parameters
payload_jsonJSON payload for the new token.
secretHMAC secret key.
exp_secondsLifetime in seconds (see cwist_jwt_sign()).
chunk_payload_sizeMaximum token bytes per chunk (must be > 0).
out_countReceives the number of chunks.
Returns
Array of chunk objects, or NULL on error. Caller must free with cwist_jwt_chunks_free().

Sign a JWT and immediately split it into sequenced chunks.

Parameters
payload_jsonRaw payload JSON string to sign.
secretShared HS256 signing secret.
exp_secondsLifetime in seconds to add when the payload lacks exp/iat.
chunk_payload_sizeMaximum payload bytes per chunk; must be non-zero.
out_countSet to the number of chunks produced.
Returns
Heap-allocated chunk array, or NULL when signing or chunking fails.

Free the result with cwist_jwt_chunks_free().

Definition at line 897 of file jwt.c.

References cap, cwist_free(), cwist_jwt_sign(), and cwist_jwt_split_chunks().

◆ cwist_jwt_sign_ed25519()

char * cwist_jwt_sign_ed25519 ( const char *  payload_json,
const char *  pem_private_key,
const char *  kid,
long  exp_seconds 
)

Sign a JWT token with EdDSA (Ed25519, RFC 8037).

Like cwist_jwt_sign_es256() but with an Ed25519 PEM private key; the header declares "alg":"EdDSA".

Parameters
payload_jsonJSON string for the payload (see cwist_jwt_sign()).
pem_private_keyPEM-encoded Ed25519 private key, null-terminated.
kidOptional key id written into the JWT header, or NULL.
exp_secondsSeconds until expiry (see cwist_jwt_sign()).
Returns
Heap-allocated null-terminated JWT string, or NULL on error. Caller must free with cwist_free().

Definition at line 629 of file jwt.c.

References cap, and JWT_ALG_ED25519.

◆ cwist_jwt_sign_es256()

char * cwist_jwt_sign_es256 ( const char *  payload_json,
const char *  pem_private_key,
const char *  kid,
long  exp_seconds 
)

Sign a JWT token with ES256 (ECDSA over P-256 with SHA-256).

Behaves like cwist_jwt_sign() except the signature is asymmetric: the header declares "alg":"ES256" and the signature is the 64-byte raw R||S form required by JOSE (RFC 7518 section 3.4).

Parameters
payload_jsonJSON string for the payload (see cwist_jwt_sign()).
pem_private_keyPEM-encoded EC private key (SEC 1 or PKCS#8), null-terminated. The key's curve must be P-256.
kidOptional key id written into the JWT header, or NULL.
exp_secondsSeconds until expiry (see cwist_jwt_sign()).
Returns
Heap-allocated null-terminated JWT string, or NULL on error. Caller must free with cwist_free().

Definition at line 624 of file jwt.c.

References cap, and JWT_ALG_ES256.

◆ cwist_jwt_split_chunks()

cwist_jwt_chunk_t * cwist_jwt_split_chunks ( const char *  token,
uint16_t  chunk_payload_size,
size_t *  out_count 
)

Split a JWT token into sequenced chunks.

The returned chunks can be transmitted out of order and reassembled with cwist_jwt_join_chunks(). This is useful when the token is too large for a single UDP datagram, WebSocket frame, or HTTP/2 DATA frame.

Parameters
tokenJWT string to split.
chunk_payload_sizeMaximum token bytes per chunk (must be > 0).
out_countReceives the number of chunks.
Returns
Array of chunk objects, or NULL on error. Caller must free with cwist_jwt_chunks_free().

Split a JWT token into sequenced chunks.

Parameters
tokenNull-terminated JWT string to split.
chunk_payload_sizeMaximum payload bytes per chunk; must be non-zero.
out_countSet to the number of chunks produced.
Returns
Heap-allocated array of out_count chunks, or NULL on invalid input, split failure, or allocation failure.

Each chunk's data buffer is owned by the caller and must be released with cwist_jwt_chunks_free().

Definition at line 800 of file jwt.c.

References cap, count, cwist_alloc_array(), cwist_seq_message_free(), cwist_seq_split(), cwist_jwt_chunk::data, and cwist_jwt_chunk::len.

Referenced by cwist_jwt_sign_chunks().

◆ cwist_jwt_verify()

cwist_jwt_claims * cwist_jwt_verify ( const char *  token,
const char *  secret 
)

Verify a JWT token and return the decoded claims.

Validates:

  • Structural integrity (three Base64URL-encoded parts).
  • HMAC-SHA256 signature.
  • "exp" claim (token must not be expired) if present.
Parameters
tokenNull-terminated JWT string ("header.payload.sig").
secretHMAC secret key (null-terminated).
Returns
Pointer to a cwist_jwt_claims object on success, NULL on failure. Caller must free with cwist_jwt_claims_destroy().

Definition at line 748 of file jwt.c.

References cap, and JWT_ALG_HS256.

Referenced by cwist_jwt_verify_chunks().

◆ cwist_jwt_verify_chunks()

cwist_jwt_claims * cwist_jwt_verify_chunks ( const cwist_jwt_chunk_t *  chunks,
size_t  count,
const char *  secret 
)

Reassemble sequenced JWT chunks and verify the resulting token.

Chunks may arrive in any order; duplicates are discarded. The function performs the same validation as cwist_jwt_verify() on the reassembled token.

Parameters
chunksArray of chunk objects received from the peer.
countNumber of chunks.
secretHMAC secret key.
Returns
Claims object on success, NULL when reassembly or verification fails. Caller must free with cwist_jwt_claims_destroy().

Reassemble sequenced JWT chunks and verify the resulting token.

Parameters
chunksArray of sequenced chunks carrying the JWT token.
countNumber of entries in chunks.
secretShared HS256 signing secret.
Returns
Heap-allocated verified claims object, or NULL when assembly, parsing, signature verification, or claim validation fails.

The caller owns the result and must release it with cwist_jwt_claims_destroy().

Definition at line 921 of file jwt.c.

References cap, count, cwist_free(), cwist_jwt_join_chunks(), and cwist_jwt_verify().

◆ cwist_jwt_verify_ed25519()

cwist_jwt_claims * cwist_jwt_verify_ed25519 ( const char *  token,
const char *  pem_key 
)

Verify an Ed25519-signed JWT token and return the decoded claims.

The header must declare exactly "alg":"EdDSA". See cwist_jwt_verify_es256() for the verification contract.

Parameters
tokenNull-terminated JWT string ("header.payload.sig").
pem_keyPEM-encoded Ed25519 public key (or private key), null-terminated.
Returns
Pointer to a cwist_jwt_claims object on success, NULL on failure. Caller must free with cwist_jwt_claims_destroy().

Definition at line 756 of file jwt.c.

References cap, and JWT_ALG_ED25519.

◆ cwist_jwt_verify_es256()

cwist_jwt_claims * cwist_jwt_verify_es256 ( const char *  token,
const char *  pem_key 
)

Verify an ES256-signed JWT token and return the decoded claims.

The header must declare exactly "alg":"ES256" (a token signed with any other algorithm is rejected, which also closes the HS256/ES256 confusion class of RFC 8725 section 2.1) and the signature must verify against the public half of pem_key. The "exp"/"nbf" checks match cwist_jwt_verify().

Parameters
tokenNull-terminated JWT string ("header.payload.sig").
pem_keyPEM-encoded EC P-256 public key (or private key; the public half is used), null-terminated.
Returns
Pointer to a cwist_jwt_claims object on success, NULL on failure. Caller must free with cwist_jwt_claims_destroy().

Definition at line 752 of file jwt.c.

References cap, and JWT_ALG_ES256.