jwt-common: Generate jwt-builder and jwt-checker
The way I was build this was causing some off issues, especially for windows builds. The dll* attributes don't like playing these games. In retrospect, autoconf/make would have handled this nicely. I could have done a %.c:%.i make rule and built off of there, but cmake does not appear to have anything that easy. Oh well, builder and checker have way too much code in commong to split them, so for now this is still the easier option. Signed-off-by: Ben Collins <bcollins@libjwt.io>
This commit is contained in:
parent
444ea08d0e
commit
734c0c5840
7 changed files with 680 additions and 40 deletions
|
@ -66,20 +66,9 @@ set(JWT_SOURCES libjwt/base64.c
|
|||
libjwt/jwt-setget.c
|
||||
libjwt/jwt-crypto-ops.c
|
||||
libjwt/jwt-encode.c
|
||||
libjwt/jwt-verify.c)
|
||||
|
||||
add_library(builder OBJECT)
|
||||
target_sources(builder PRIVATE libjwt/jwt-common.c)
|
||||
target_compile_definitions(builder PRIVATE JWT_BUILDER)
|
||||
set_property(TARGET builder PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_library(checker OBJECT)
|
||||
target_sources(checker PRIVATE libjwt/jwt-common.c)
|
||||
target_compile_definitions(checker PRIVATE JWT_CHECKER)
|
||||
set_property(TARGET checker PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
target_link_libraries(jwt PRIVATE builder checker)
|
||||
target_link_libraries(jwt_static PRIVATE builder checker)
|
||||
libjwt/jwt-verify.c
|
||||
libjwt/jwt-builder.c
|
||||
libjwt/jwt-checker.c)
|
||||
|
||||
# Allow building without deprecated functions (suggested)
|
||||
option(EXCLUDE_DEPRECATED
|
||||
|
@ -95,8 +84,6 @@ include_directories(${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}
|
|||
|
||||
target_link_libraries(jwt PUBLIC PkgConfig::JANSSON)
|
||||
target_link_libraries(jwt_static PUBLIC PkgConfig::JANSSON)
|
||||
target_link_libraries(builder PUBLIC PkgConfig::JANSSON)
|
||||
target_link_libraries(checker PUBLIC PkgConfig::JANSSON)
|
||||
|
||||
# Process the detected packages
|
||||
set(HAVE_CRYPTO FALSE)
|
||||
|
@ -294,7 +281,7 @@ if (CHECK_FOUND)
|
|||
include(CodeCoverage)
|
||||
append_coverage_compiler_flags()
|
||||
|
||||
set(COVERAGE_LCOV_INCLUDES "${CMAKE_SOURCE_DIR}/libjwt/*.c")
|
||||
set(COVERAGE_LCOV_INCLUDES "${CMAKE_SOURCE_DIR}/libjwt/")
|
||||
setup_target_for_coverage_lcov(
|
||||
NAME check-code-coverage
|
||||
OUTPUT "${PROJECT_NAME}-${PROJECT_VERSION}-coverage"
|
||||
|
|
6
libjwt/Makefile
Normal file
6
libjwt/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
|||
FILES = jwt-builder.c jwt-checker.c
|
||||
|
||||
all: $(FILES)
|
||||
|
||||
jwt-%.c: %.sed jwt-common.c
|
||||
sed -f $< jwt-common.c > $@
|
8
libjwt/builder.sed
Normal file
8
libjwt/builder.sed
Normal file
|
@ -0,0 +1,8 @@
|
|||
s/FUNC(\([^)]*\))/jwt_builder_\1/
|
||||
s/jwt_common_t/jwt_builder_t/g
|
||||
s/CLAIMS_DEF/JWT_CLAIM_IAT/g
|
||||
s/.*XXX.*/\/\* XXX This file is generated, do not edit! \*\//
|
||||
s/__DISABLE/0/
|
||||
/#ifdef JWT_CHECKER/,/#endif/d
|
||||
/#ifdef/d
|
||||
/#endif/d
|
8
libjwt/checker.sed
Normal file
8
libjwt/checker.sed
Normal file
|
@ -0,0 +1,8 @@
|
|||
s/FUNC(\([^)]*\))/jwt_checker_\1/
|
||||
s/jwt_common_t/jwt_checker_t/g
|
||||
s/CLAIMS_DEF/(JWT_CLAIM_EXP\|JWT_CLAIM_NBF)/g
|
||||
s/.*XXX.*/\/\* XXX This file is generated, do not edit! \*\//
|
||||
s/__DISABLE/-1/
|
||||
/#ifdef JWT_BUILDER/,/#endif/d
|
||||
/#ifdef/d
|
||||
/#endif/d
|
328
libjwt/jwt-builder.c
Normal file
328
libjwt/jwt-builder.c
Normal file
|
@ -0,0 +1,328 @@
|
|||
/* Copyright (C) 2015-2025 maClara, LLC <info@maclara-llc.com>
|
||||
This file is part of the JWT C Library
|
||||
|
||||
SPDX-License-Identifier: MPL-2.0
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <jwt.h>
|
||||
|
||||
#include "jwt-private.h"
|
||||
|
||||
/* XXX This file is generated, do not edit! */
|
||||
|
||||
void jwt_builder_free(jwt_builder_t *__cmd)
|
||||
{
|
||||
if (__cmd == NULL)
|
||||
return;
|
||||
|
||||
json_decref(__cmd->c.payload);
|
||||
json_decref(__cmd->c.headers);
|
||||
|
||||
memset(__cmd, 0, sizeof(*__cmd));
|
||||
|
||||
jwt_freemem(__cmd);
|
||||
}
|
||||
|
||||
jwt_builder_t *jwt_builder_new(void)
|
||||
{
|
||||
jwt_builder_t *__cmd = jwt_malloc(sizeof(*__cmd));
|
||||
|
||||
if (__cmd == NULL)
|
||||
return NULL; // LCOV_EXCL_LINE
|
||||
|
||||
memset(__cmd, 0, sizeof(*__cmd));
|
||||
|
||||
__cmd->c.payload = json_object();
|
||||
__cmd->c.headers = json_object();
|
||||
__cmd->c.claims = JWT_CLAIM_IAT;
|
||||
|
||||
if (!__cmd->c.payload || !__cmd->c.headers)
|
||||
jwt_freemem(__cmd); // LCOV_EXCL_LINE
|
||||
|
||||
return __cmd;
|
||||
}
|
||||
|
||||
static int __setkey_check(jwt_builder_t *__cmd, const jwt_alg_t alg,
|
||||
const jwk_item_t *key)
|
||||
{
|
||||
if (__cmd == NULL)
|
||||
return 1;
|
||||
|
||||
if (key && !key->is_private_key) {
|
||||
jwt_write_error(__cmd, "Signing requires a private key");
|
||||
return 1;
|
||||
}
|
||||
/* TODO: Check key_ops and use */
|
||||
|
||||
if (key == NULL) {
|
||||
if (alg == JWT_ALG_NONE)
|
||||
return 0;
|
||||
|
||||
jwt_write_error(__cmd, "Cannot set alg without a key");
|
||||
} else if (key->alg == JWT_ALG_NONE) {
|
||||
if (alg != JWT_ALG_NONE)
|
||||
return 0;
|
||||
|
||||
jwt_write_error(__cmd, "Key provided, but could not find alg");
|
||||
} else {
|
||||
if (alg == JWT_ALG_NONE)
|
||||
return 0;
|
||||
|
||||
if (alg == key->alg)
|
||||
return 0;
|
||||
|
||||
jwt_write_error(__cmd, "Alg mismatch");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int jwt_builder_setkey(jwt_builder_t *__cmd, const jwt_alg_t alg,
|
||||
const jwk_item_t *key)
|
||||
{
|
||||
if (__setkey_check(__cmd, alg, key))
|
||||
return 1;
|
||||
|
||||
__cmd->c.alg = alg;
|
||||
__cmd->c.key = key;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jwt_builder_error(const jwt_builder_t *__cmd)
|
||||
{
|
||||
if (__cmd == NULL)
|
||||
return 1;
|
||||
|
||||
return __cmd->error ? 1 : 0;
|
||||
}
|
||||
|
||||
const char *jwt_builder_error_msg(const jwt_builder_t *__cmd)
|
||||
{
|
||||
if (__cmd == NULL)
|
||||
return NULL;
|
||||
|
||||
return __cmd->error_msg;
|
||||
}
|
||||
|
||||
void jwt_builder_error_clear(jwt_builder_t *__cmd)
|
||||
{
|
||||
if (__cmd == NULL)
|
||||
return;
|
||||
|
||||
__cmd->error = 0;
|
||||
__cmd->error_msg[0] = '\0';
|
||||
}
|
||||
|
||||
int jwt_builder_enable_iat(jwt_builder_t *__cmd, int enable)
|
||||
{
|
||||
int orig;
|
||||
|
||||
if (!__cmd)
|
||||
return -1;
|
||||
|
||||
orig = __cmd->c.claims & JWT_CLAIM_IAT ? 1 : 0;
|
||||
|
||||
if (enable)
|
||||
__cmd->c.claims |= JWT_CLAIM_IAT;
|
||||
else
|
||||
__cmd->c.claims &= ~JWT_CLAIM_IAT;
|
||||
|
||||
return orig;
|
||||
}
|
||||
|
||||
int jwt_builder_setcb(jwt_builder_t *__cmd, jwt_callback_t cb, void *ctx)
|
||||
{
|
||||
if (__cmd == NULL)
|
||||
return 1;
|
||||
|
||||
if (cb == NULL && ctx != NULL) {
|
||||
jwt_write_error(__cmd, "Setting ctx without a cb won't work");
|
||||
return 1;
|
||||
}
|
||||
|
||||
__cmd->c.cb = cb;
|
||||
__cmd->c.cb_ctx = ctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *jwt_builder_getctx(jwt_builder_t *__cmd)
|
||||
{
|
||||
if (__cmd == NULL)
|
||||
return NULL;
|
||||
|
||||
return __cmd->c.cb_ctx;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
__HEADER,
|
||||
__CLAIM,
|
||||
} _setget_type_t;
|
||||
|
||||
typedef jwt_value_error_t (*__doer_t)(json_t *, jwt_value_t *);
|
||||
|
||||
static jwt_value_error_t __run_it(jwt_builder_t *__cmd, _setget_type_t type,
|
||||
jwt_value_t *value, __doer_t doer)
|
||||
{
|
||||
json_t *which = NULL;
|
||||
|
||||
if (!__cmd || !value) {
|
||||
if (value)
|
||||
return value->error = JWT_VALUE_ERR_INVALID;
|
||||
return JWT_VALUE_ERR_INVALID;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case __HEADER:
|
||||
which = __cmd->c.headers;
|
||||
break;
|
||||
case __CLAIM:
|
||||
which = __cmd->c.payload;
|
||||
break;
|
||||
default:
|
||||
return value->error = JWT_VALUE_ERR_INVALID; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
return doer(which, value);
|
||||
}
|
||||
|
||||
/* Claims */
|
||||
jwt_value_error_t jwt_builder_claim_get(jwt_builder_t *__cmd, jwt_value_t *value)
|
||||
{
|
||||
return __run_it(__cmd, __CLAIM, value, __getter);
|
||||
}
|
||||
|
||||
jwt_value_error_t jwt_builder_claim_set(jwt_builder_t *__cmd, jwt_value_t *value)
|
||||
{
|
||||
return __run_it(__cmd, __CLAIM, value, __setter);
|
||||
}
|
||||
|
||||
jwt_value_error_t jwt_builder_claim_del(jwt_builder_t *__cmd, const char *claim)
|
||||
{
|
||||
if (!__cmd)
|
||||
return JWT_VALUE_ERR_INVALID;
|
||||
return __deleter(__cmd->c.payload, claim);
|
||||
}
|
||||
|
||||
/* Headers */
|
||||
jwt_value_error_t jwt_builder_header_get(jwt_builder_t *__cmd, jwt_value_t *value)
|
||||
{
|
||||
return __run_it(__cmd, __HEADER, value, __getter);
|
||||
}
|
||||
|
||||
jwt_value_error_t jwt_builder_header_set(jwt_builder_t *__cmd, jwt_value_t *value)
|
||||
{
|
||||
return __run_it(__cmd, __HEADER, value, __setter);
|
||||
}
|
||||
|
||||
jwt_value_error_t jwt_builder_header_del(jwt_builder_t *__cmd, const char *header)
|
||||
{
|
||||
if (!__cmd)
|
||||
return JWT_VALUE_ERR_INVALID;
|
||||
return __deleter(__cmd->c.headers, header);
|
||||
}
|
||||
|
||||
|
||||
/* Time offsets */
|
||||
int jwt_builder_time_offset(jwt_builder_t *__cmd, jwt_claims_t claim, time_t secs)
|
||||
{
|
||||
if (!__cmd)
|
||||
return 1;
|
||||
|
||||
switch (claim) {
|
||||
case JWT_CLAIM_EXP:
|
||||
__cmd->c.exp = secs;
|
||||
break;
|
||||
|
||||
case JWT_CLAIM_NBF:
|
||||
__cmd->c.nbf = secs;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (secs <= 0)
|
||||
__cmd->c.claims &= ~claim;
|
||||
else
|
||||
__cmd->c.claims |= claim;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char *jwt_builder_generate(jwt_builder_t *__cmd)
|
||||
{
|
||||
JWT_CONFIG_DECLARE(config);
|
||||
jwt_auto_t *jwt = NULL;
|
||||
char *out = NULL;
|
||||
jwt_value_t jval;
|
||||
time_t tm = time(NULL);
|
||||
|
||||
if (__cmd == NULL)
|
||||
return NULL;
|
||||
|
||||
jwt = jwt_malloc(sizeof(*jwt));
|
||||
if (jwt == NULL)
|
||||
return NULL; // LCOV_EXCL_LINE
|
||||
|
||||
memset(jwt, 0, sizeof(*jwt));
|
||||
|
||||
jwt->headers = json_deep_copy(__cmd->c.headers);
|
||||
jwt->claims = json_deep_copy(__cmd->c.payload);
|
||||
|
||||
/* Our internal work first */
|
||||
if (__cmd->c.claims & JWT_CLAIM_IAT) {
|
||||
jwt_set_SET_INT(&jval, "iat", (long)tm);
|
||||
jval.replace = 1;
|
||||
jwt_claim_set(jwt, &jval);
|
||||
}
|
||||
|
||||
if (__cmd->c.claims & JWT_CLAIM_NBF) {
|
||||
jwt_set_SET_INT(&jval, "nbf", (long)(tm + __cmd->c.nbf));
|
||||
jval.replace = 1;
|
||||
jwt_claim_set(jwt, &jval);
|
||||
}
|
||||
|
||||
if (__cmd->c.claims & JWT_CLAIM_EXP) {
|
||||
jwt_set_SET_INT(&jval, "exp", (long)(tm + __cmd->c.exp));
|
||||
jval.replace = 1;
|
||||
jwt_claim_set(jwt, &jval);
|
||||
}
|
||||
|
||||
/* Alg and key checks */
|
||||
config.alg = __cmd->c.alg;
|
||||
if (config.alg == JWT_ALG_NONE && __cmd->c.key)
|
||||
config.alg = __cmd->c.key->alg;
|
||||
config.key = __cmd->c.key;
|
||||
config.ctx = __cmd->c.cb_ctx;
|
||||
|
||||
/* Let the callback do it's thing */
|
||||
if (__cmd->c.cb && __cmd->c.cb(jwt, &config)) {
|
||||
jwt_write_error(__cmd, "User callback returned error");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Callback may have changed this */
|
||||
if (__setkey_check(__cmd, config.alg, config.key)) {
|
||||
jwt_write_error(__cmd, "Algorithm and key returned by callback invalid");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jwt->alg = config.alg;
|
||||
jwt->key = config.key;
|
||||
|
||||
if (jwt_head_setup(jwt))
|
||||
return NULL;
|
||||
|
||||
out = jwt_encode_str(jwt);
|
||||
jwt_copy_error(__cmd, jwt);
|
||||
|
||||
return out;
|
||||
}
|
323
libjwt/jwt-checker.c
Normal file
323
libjwt/jwt-checker.c
Normal file
|
@ -0,0 +1,323 @@
|
|||
/* Copyright (C) 2015-2025 maClara, LLC <info@maclara-llc.com>
|
||||
This file is part of the JWT C Library
|
||||
|
||||
SPDX-License-Identifier: MPL-2.0
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <jwt.h>
|
||||
|
||||
#include "jwt-private.h"
|
||||
|
||||
/* XXX This file is generated, do not edit! */
|
||||
|
||||
void jwt_checker_free(jwt_checker_t *__cmd)
|
||||
{
|
||||
if (__cmd == NULL)
|
||||
return;
|
||||
|
||||
json_decref(__cmd->c.payload);
|
||||
json_decref(__cmd->c.headers);
|
||||
|
||||
memset(__cmd, 0, sizeof(*__cmd));
|
||||
|
||||
jwt_freemem(__cmd);
|
||||
}
|
||||
|
||||
jwt_checker_t *jwt_checker_new(void)
|
||||
{
|
||||
jwt_checker_t *__cmd = jwt_malloc(sizeof(*__cmd));
|
||||
|
||||
if (__cmd == NULL)
|
||||
return NULL; // LCOV_EXCL_LINE
|
||||
|
||||
memset(__cmd, 0, sizeof(*__cmd));
|
||||
|
||||
__cmd->c.payload = json_object();
|
||||
__cmd->c.headers = json_object();
|
||||
__cmd->c.claims = (JWT_CLAIM_EXP|JWT_CLAIM_NBF);
|
||||
|
||||
if (!__cmd->c.payload || !__cmd->c.headers)
|
||||
jwt_freemem(__cmd); // LCOV_EXCL_LINE
|
||||
|
||||
return __cmd;
|
||||
}
|
||||
|
||||
static int __setkey_check(jwt_checker_t *__cmd, const jwt_alg_t alg,
|
||||
const jwk_item_t *key)
|
||||
{
|
||||
if (__cmd == NULL)
|
||||
return 1;
|
||||
|
||||
/* TODO: Check key_ops and use */
|
||||
|
||||
if (key == NULL) {
|
||||
if (alg == JWT_ALG_NONE)
|
||||
return 0;
|
||||
|
||||
jwt_write_error(__cmd, "Cannot set alg without a key");
|
||||
} else if (key->alg == JWT_ALG_NONE) {
|
||||
if (alg != JWT_ALG_NONE)
|
||||
return 0;
|
||||
|
||||
jwt_write_error(__cmd, "Key provided, but could not find alg");
|
||||
} else {
|
||||
if (alg == JWT_ALG_NONE)
|
||||
return 0;
|
||||
|
||||
if (alg == key->alg)
|
||||
return 0;
|
||||
|
||||
jwt_write_error(__cmd, "Alg mismatch");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int jwt_checker_setkey(jwt_checker_t *__cmd, const jwt_alg_t alg,
|
||||
const jwk_item_t *key)
|
||||
{
|
||||
if (__setkey_check(__cmd, alg, key))
|
||||
return 1;
|
||||
|
||||
__cmd->c.alg = alg;
|
||||
__cmd->c.key = key;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jwt_checker_error(const jwt_checker_t *__cmd)
|
||||
{
|
||||
if (__cmd == NULL)
|
||||
return 1;
|
||||
|
||||
return __cmd->error ? 1 : 0;
|
||||
}
|
||||
|
||||
const char *jwt_checker_error_msg(const jwt_checker_t *__cmd)
|
||||
{
|
||||
if (__cmd == NULL)
|
||||
return NULL;
|
||||
|
||||
return __cmd->error_msg;
|
||||
}
|
||||
|
||||
void jwt_checker_error_clear(jwt_checker_t *__cmd)
|
||||
{
|
||||
if (__cmd == NULL)
|
||||
return;
|
||||
|
||||
__cmd->error = 0;
|
||||
__cmd->error_msg[0] = '\0';
|
||||
}
|
||||
|
||||
|
||||
int jwt_checker_setcb(jwt_checker_t *__cmd, jwt_callback_t cb, void *ctx)
|
||||
{
|
||||
if (__cmd == NULL)
|
||||
return 1;
|
||||
|
||||
if (cb == NULL && ctx != NULL) {
|
||||
jwt_write_error(__cmd, "Setting ctx without a cb won't work");
|
||||
return 1;
|
||||
}
|
||||
|
||||
__cmd->c.cb = cb;
|
||||
__cmd->c.cb_ctx = ctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *jwt_checker_getctx(jwt_checker_t *__cmd)
|
||||
{
|
||||
if (__cmd == NULL)
|
||||
return NULL;
|
||||
|
||||
return __cmd->c.cb_ctx;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
__HEADER,
|
||||
__CLAIM,
|
||||
} _setget_type_t;
|
||||
|
||||
typedef jwt_value_error_t (*__doer_t)(json_t *, jwt_value_t *);
|
||||
|
||||
static jwt_value_error_t __run_it(jwt_checker_t *__cmd, _setget_type_t type,
|
||||
jwt_value_t *value, __doer_t doer)
|
||||
{
|
||||
json_t *which = NULL;
|
||||
|
||||
if (!__cmd || !value) {
|
||||
if (value)
|
||||
return value->error = JWT_VALUE_ERR_INVALID;
|
||||
return JWT_VALUE_ERR_INVALID;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case __HEADER:
|
||||
which = __cmd->c.headers;
|
||||
break;
|
||||
case __CLAIM:
|
||||
which = __cmd->c.payload;
|
||||
break;
|
||||
default:
|
||||
return value->error = JWT_VALUE_ERR_INVALID; // LCOV_EXCL_LINE
|
||||
}
|
||||
|
||||
return doer(which, value);
|
||||
}
|
||||
|
||||
|
||||
/* Just a few types of claims */
|
||||
static const char *__get_name(jwt_claims_t type)
|
||||
{
|
||||
if (type == JWT_CLAIM_ISS)
|
||||
return "iss";
|
||||
else if (type == JWT_CLAIM_AUD)
|
||||
return "aud";
|
||||
else if (type == JWT_CLAIM_SUB)
|
||||
return "sub";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *jwt_checker_claim_get(jwt_checker_t *__cmd, jwt_claims_t type)
|
||||
{
|
||||
const char *name = NULL;
|
||||
jwt_value_t jval;
|
||||
|
||||
if (!__cmd)
|
||||
return NULL;
|
||||
|
||||
name = __get_name(type);
|
||||
if (name == NULL)
|
||||
return NULL;
|
||||
|
||||
jwt_set_GET_STR(&jval, name);
|
||||
__run_it(__cmd, __CLAIM, &jval, __getter);
|
||||
|
||||
/* Ignore errors, just return a string or NULL */
|
||||
return jval.str_val;
|
||||
}
|
||||
|
||||
int jwt_checker_claim_set(jwt_checker_t *__cmd, jwt_claims_t type, const char *value)
|
||||
{
|
||||
const char *name = NULL;
|
||||
jwt_value_t jval;
|
||||
|
||||
if (!__cmd || !value)
|
||||
return 1;
|
||||
|
||||
name = __get_name(type);
|
||||
if (name == NULL)
|
||||
return 1;
|
||||
|
||||
__cmd->c.claims |= type;
|
||||
|
||||
jwt_set_SET_STR(&jval, name, value);
|
||||
jval.replace = 1;
|
||||
|
||||
return __run_it(__cmd, __CLAIM, &jval, __setter) ? 1 : 0;
|
||||
}
|
||||
|
||||
int jwt_checker_claim_del(jwt_checker_t *__cmd, jwt_claims_t type)
|
||||
{
|
||||
const char *name = NULL;
|
||||
|
||||
if (!__cmd)
|
||||
return 1;
|
||||
|
||||
name = __get_name(type);
|
||||
if (name == NULL)
|
||||
return 1;
|
||||
|
||||
__cmd->c.claims &= ~type;
|
||||
|
||||
return __deleter(__cmd->c.payload, name);
|
||||
}
|
||||
|
||||
/* Time offsets */
|
||||
int jwt_checker_time_leeway(jwt_checker_t *__cmd, jwt_claims_t claim, time_t secs)
|
||||
{
|
||||
if (!__cmd)
|
||||
return 1;
|
||||
|
||||
switch (claim) {
|
||||
case JWT_CLAIM_EXP:
|
||||
__cmd->c.exp = secs;
|
||||
break;
|
||||
|
||||
case JWT_CLAIM_NBF:
|
||||
__cmd->c.nbf = secs;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (secs <= -1)
|
||||
__cmd->c.claims &= ~claim;
|
||||
else
|
||||
__cmd->c.claims |= claim;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int jwt_checker_verify(jwt_checker_t *__cmd, const char *token)
|
||||
{
|
||||
JWT_CONFIG_DECLARE(config);
|
||||
unsigned int payload_len;
|
||||
jwt_auto_t *jwt = NULL;
|
||||
|
||||
if (__cmd == NULL)
|
||||
return 1;
|
||||
|
||||
if (token == NULL || !strlen(token)) {
|
||||
jwt_write_error(__cmd, "Must pass a token");
|
||||
return 1;
|
||||
}
|
||||
|
||||
jwt = jwt_new();
|
||||
if (jwt == NULL) {
|
||||
// LCOV_EXCL_START
|
||||
jwt_write_error(__cmd, "Could not allocate JWT object");
|
||||
return 1;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
/* First parsing pass, error will be set for us */
|
||||
if (jwt_parse(jwt, token, &payload_len)) {
|
||||
jwt_copy_error(__cmd, jwt);
|
||||
return 1;
|
||||
};
|
||||
|
||||
config.key = __cmd->c.key;
|
||||
config.alg = __cmd->c.alg;
|
||||
config.ctx = __cmd->c.cb_ctx;
|
||||
|
||||
/* Let the user handle this and update config */
|
||||
if (__cmd->c.cb && __cmd->c.cb(jwt, &config)) {
|
||||
jwt_write_error(__cmd, "User callback returned error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Callback may have changed this */
|
||||
if (__setkey_check(__cmd, config.alg, config.key))
|
||||
return 1;
|
||||
|
||||
jwt->key = config.key;
|
||||
jwt->checker = __cmd;
|
||||
|
||||
/* Finish it up */
|
||||
jwt = jwt_verify_complete(jwt, &config, token, payload_len);
|
||||
|
||||
/* Copy any errors back */
|
||||
jwt_copy_error(__cmd, jwt);
|
||||
|
||||
return __cmd->error;
|
||||
}
|
||||
|
|
@ -8,28 +8,12 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <jwt.h>
|
||||
|
||||
#include "base64.h"
|
||||
|
||||
#include "jwt-private.h"
|
||||
|
||||
#ifdef JWT_BUILDER
|
||||
#define jwt_common_t jwt_builder_t
|
||||
#define FUNC(__x) jwt_builder_##__x
|
||||
#define CLAIMS_DEF JWT_CLAIM_IAT
|
||||
#endif
|
||||
#ifdef JWT_CHECKER
|
||||
#define jwt_common_t jwt_checker_t
|
||||
#define FUNC(__x) jwt_checker_##__x
|
||||
#define CLAIMS_DEF (JWT_CLAIM_EXP | JWT_CLAIM_NBF)
|
||||
#endif
|
||||
|
||||
#ifndef jwt_common_t
|
||||
#error Must have target defined
|
||||
#endif
|
||||
/* XXX This file is used to generate jwt-builder.c and jwt-checker.c */
|
||||
|
||||
void FUNC(free)(jwt_common_t *__cmd)
|
||||
{
|
||||
|
@ -321,13 +305,9 @@ int FUNC(claim_del)(jwt_common_t *__cmd, jwt_claims_t type)
|
|||
|
||||
/* Time offsets */
|
||||
#ifdef JWT_BUILDER
|
||||
#define __DISABLE 0
|
||||
#else
|
||||
#define __DISABLE -1
|
||||
#endif
|
||||
#ifdef JWT_BUILDER
|
||||
int FUNC(time_offset)(jwt_common_t *__cmd, jwt_claims_t claim, time_t secs)
|
||||
#else
|
||||
#endif
|
||||
#ifdef JWT_CHECKER
|
||||
int FUNC(time_leeway)(jwt_common_t *__cmd, jwt_claims_t claim, time_t secs)
|
||||
#endif
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue