|
cwist
Modern C web framework with libttak runtime
|
HS256/ES256/EdDSA JWT signing, verification, and decoded-claims access helpers. More...
#include <cwist/security/jwt/jwt.h>#include <cwist/core/mem/alloc.h>#include <cwist/core/sstring/sstring.h>#include <cwist/core/seq/seq.h>#include <cjson/cJSON.h>#include <openssl/hmac.h>#include <openssl/sha.h>#include <openssl/evp.h>#include <openssl/pem.h>#include <openssl/bio.h>#include <openssl/ec.h>#include <openssl/ecdsa.h>#include <openssl/bn.h>#include <openssl/obj.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>
Go to the source code of this file.
Macros | |
| #define | CWIST_JWT_TIME_LEEWAY 300 |
Enumerations | |
| enum | jwt_alg_t { JWT_ALG_HS256 , JWT_ALG_ES256 , JWT_ALG_ED25519 } |
Functions | |
| char * | cwist_jwt_sign (const char *payload_json, const char *secret, long exp_seconds) |
| Sign a JWT token with HMAC-SHA256. | |
| 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). | |
| 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 (const char *token, const char *secret) |
| Verify a JWT token and return the decoded claims. | |
| 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. | |
| 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. | |
| const char * | cwist_jwt_claims_get (const cwist_jwt_claims *claims, const char *key) |
| Retrieve one string-valued claim from a verified JWT payload. | |
| void | cwist_jwt_claims_destroy (cwist_jwt_claims *claims) |
| Destroy a verified claims object and its parsed JSON payload. | |
| 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 transport chunks. | |
| void | cwist_jwt_chunks_free (cwist_jwt_chunk_t *chunks, size_t count) |
| Free a chunk array produced by cwist_jwt_split_chunks() or cwist_jwt_sign_chunks(). | |
| char * | cwist_jwt_join_chunks (const cwist_jwt_chunk_t *chunks, size_t count) |
| Reassemble a JWT token from sequenced transport 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 payload as an HS256 JWT and split it into sequenced transport chunks. | |
| cwist_jwt_claims * | cwist_jwt_verify_chunks (const cwist_jwt_chunk_t *chunks, size_t count, const char *secret) |
| Reassemble sequenced chunks into a token, verify it, and return its claims. | |
HS256/ES256/EdDSA JWT signing, verification, and decoded-claims access helpers.
Definition in file jwt.c.
| #define CWIST_JWT_TIME_LEEWAY 300 |
| void cwist_jwt_chunks_free | ( | cwist_jwt_chunk_t * | chunks, |
| size_t | count | ||
| ) |
Free a chunk array produced by cwist_jwt_split_chunks() or cwist_jwt_sign_chunks().
Free chunk objects returned by cwist_jwt_split_chunks().
| chunks | Chunk array to free; NULL is accepted as a no-op. |
| count | Number of entries in chunks. |
Definition at line 837 of file jwt.c.
References cap, count, and cwist_free().
| void cwist_jwt_claims_destroy | ( | cwist_jwt_claims * | claims | ) |
Destroy a verified claims object and its parsed JSON payload.
Free a claims object.
| claims | Claims object to destroy. |
Definition at line 779 of file jwt.c.
References cap, and cwist_free().
Retrieve one string-valued claim from a verified JWT payload.
Retrieve a claim value by key from decoded claims.
| claims | Verified claims object. |
| key | Claim name to retrieve. |
Definition at line 766 of file jwt.c.
References cap.
| char * cwist_jwt_join_chunks | ( | const cwist_jwt_chunk_t * | chunks, |
| size_t | count | ||
| ) |
Reassemble a JWT token from sequenced transport chunks.
Reassemble a JWT token from sequenced chunks.
| chunks | Array of sequenced chunks, in any order accepted by the assembler. |
| count | Number of entries in chunks. |
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().
Sign a JWT token with HMAC-SHA256.
| payload_json | JSON 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). |
| secret | HMAC secret key (null-terminated). |
| exp_seconds | Seconds until expiry from now. Pass 0 to skip automatic "exp" injection (you must include it in payload_json). |
Definition at line 620 of file jwt.c.
References cap, and JWT_ALG_HS256.
Referenced by 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 payload as an HS256 JWT and split it into sequenced transport chunks.
Sign a JWT and immediately split it into sequenced chunks.
| payload_json | Raw payload JSON string to sign. |
| secret | Shared HS256 signing secret. |
| exp_seconds | Lifetime in seconds to add when the payload lacks exp/iat. |
| chunk_payload_size | Maximum payload bytes per chunk; must be non-zero. |
| out_count | Set to the number of chunks produced. |
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().
| 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".
| payload_json | JSON string for the payload (see cwist_jwt_sign()). |
| pem_private_key | PEM-encoded Ed25519 private key, null-terminated. |
| kid | Optional key id written into the JWT header, or NULL. |
| exp_seconds | Seconds until expiry (see cwist_jwt_sign()). |
Definition at line 629 of file jwt.c.
References cap, and JWT_ALG_ED25519.
| 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).
| payload_json | JSON string for the payload (see cwist_jwt_sign()). |
| pem_private_key | PEM-encoded EC private key (SEC 1 or PKCS#8), null-terminated. The key's curve must be P-256. |
| kid | Optional key id written into the JWT header, or NULL. |
| exp_seconds | Seconds until expiry (see cwist_jwt_sign()). |
Definition at line 624 of file jwt.c.
References cap, and JWT_ALG_ES256.
| 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 transport chunks.
Split a JWT token into sequenced chunks.
| token | Null-terminated JWT string to split. |
| chunk_payload_size | Maximum payload bytes per chunk; must be non-zero. |
| out_count | Set to the number of chunks produced. |
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().
Verify a JWT token and return the decoded claims.
Validates:
| token | Null-terminated JWT string ("header.payload.sig"). |
| secret | HMAC secret key (null-terminated). |
Definition at line 748 of file jwt.c.
References cap, and JWT_ALG_HS256.
Referenced by 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 chunks into a token, verify it, and return its claims.
Reassemble sequenced JWT chunks and verify the resulting token.
| chunks | Array of sequenced chunks carrying the JWT token. |
| count | Number of entries in chunks. |
| secret | Shared HS256 signing secret. |
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().
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.
| token | Null-terminated JWT string ("header.payload.sig"). |
| pem_key | PEM-encoded Ed25519 public key (or private key), null-terminated. |
Definition at line 756 of file jwt.c.
References cap, and JWT_ALG_ED25519.
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().
| token | Null-terminated JWT string ("header.payload.sig"). |
| pem_key | PEM-encoded EC P-256 public key (or private key; the public half is used), null-terminated. |
Definition at line 752 of file jwt.c.
References cap, and JWT_ALG_ES256.