From 626776eb571be729867fa80965620b0a6efdb28c Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Wed, 8 Jan 2025 09:55:22 -0500 Subject: [PATCH] jwt_grant: Convert to same functions as header - Consolidated adder, getter and deleter functions - Remove use of get_*_js and similar functions - Reworked tests Signed-off-by: Ben Collins --- examples/main-gen.c | 2 +- include/jwt.h | 389 ++++++++++++++++++++-------------------- libjwt/jwt-encode.c | 19 +- libjwt/jwt-memory.c | 5 - libjwt/jwt-private.h | 3 - libjwt/jwt-setget.c | 417 +++++++++++++++++++------------------------ tests/jwt_dump.c | 84 +++++---- tests/jwt_encode.c | 120 +++++++++---- tests/jwt_grant.c | 169 +++++++++++------- tests/jwt_header.c | 20 +-- tests/jwt_jwks.c | 15 +- tests/jwt_new.c | 23 ++- tests/jwt_rsa.c | 4 +- tests/jwt_rsa_pss.c | 15 +- tests/jwt_tests.h | 30 ++-- tests/jwt_validate.c | 49 +++-- 16 files changed, 729 insertions(+), 635 deletions(-) diff --git a/examples/main-gen.c b/examples/main-gen.c index c4f7392f..bf699c33 100644 --- a/examples/main-gen.c +++ b/examples/main-gen.c @@ -171,7 +171,7 @@ int main(int argc, char *argv[]) char *out = jwt_encode_str(jwt); printf("%s\n", out); - jwt_free_str(out); + free(out); finish: return 0; diff --git a/include/jwt.h b/include/jwt.h index 65d8688c..1aa4ce08 100644 --- a/include/jwt.h +++ b/include/jwt.h @@ -511,21 +511,47 @@ jwt_t *jwt_verify_wcb(const char *token, jwt_config_t *config, */ /** - * @defgroup jwt_header_grp Header Hanagement - * These functions allow you to add, remove and retrieve headers from a JWT - * object. + * @defgroup jwt_head_grant_grp Grants and Headers + * + * These functions allow you to add, get, and delete items in the headers and + * grants of a JWT that is being prepared for encoding. * @{ */ +/** + * @brief Value types for grants and headers + */ typedef enum { - JWT_VALUE_NONE = 0, - JWT_VALUE_INT, - JWT_VALUE_STR, - JWT_VALUE_BOOL, - JWT_VALUE_JSON, - JWT_VALUE_INVALID, + JWT_VALUE_NONE = 0, /**< No type (do not use this) */ + JWT_VALUE_INT, /**< Integer */ + JWT_VALUE_STR, /**< String */ + JWT_VALUE_BOOL, /**< Boolean */ + JWT_VALUE_JSON, /**< JSON String */ + JWT_VALUE_INVALID, /**< Invalid (used internally) */ } jwt_value_type_t; +/** + * @brief Error values for header and grant requests + */ +typedef enum { + JWT_VALUE_ERR_NONE = 0, /**< No error, success */ + JWT_VALUE_ERR_EXIST, /**< Item exists (when adding) */ + JWT_VALUE_ERR_NOEXIST, /**< Item doesn't exist (when getting) */ + JWT_VALUE_ERR_TYPE, /**< Item is not of the type requested */ + JWT_VALUE_ERR_INVALID, /**< Invalid request (general error) */ + JWT_VALUE_ERR_NOMEM, /**< Memory allocation error */ +} jwt_value_error_t; + +/** + * @brief Data type for get and add actions for JWT headers and grants + * + * This is used for both add and get requests. Specific rules for each type is + * described in more detail for the add and get requests. + * + * @note There are helper macros to simplify settng this structure properly and + * reducing common mistakes. See the jwt_set_{ADD,GET}_{INT,STR,BOOL,JSON} + * definitions. + */ typedef struct { jwt_value_type_t type; char *name; @@ -536,240 +562,224 @@ typedef struct { char *json_val; }; int replace; + jwt_value_error_t error; } jwt_value_t; -#define jwt_set_GET_INT(__v, __n) ({ \ - (__v)->type=JWT_VALUE_INT;(__v)->replace=0; \ - (__v)->name=(__n); (__v)->int_val=0; }) - -#define jwt_set_GET_STR(__v, __n) ({ \ - (__v)->type=JWT_VALUE_STR;(__v)->replace=0; \ - (__v)->name=(__n); (__v)->str_val=NULL; }) - -#define jwt_set_GET_BOOL(__v, __n) ({ \ - (__v)->type=JWT_VALUE_BOOL;(__v)->replace=0; \ - (__v)->name=(__n); (__v)->bool_val=0; }) - -#define jwt_set_GET_JSON(__v, __n) ({ \ - (__v)->type=JWT_VALUE_JSON;(__v)->replace=0; \ - (__v)->name=(__n); (__v)->json_val=NULL; }) - -#define jwt_set_ADD_INT(__v, __n, __x) ({ \ - (__v)->type=JWT_VALUE_INT;(__v)->replace=0; \ - (__v)->name=(__n); (__v)->int_val=(__x); }) - -#define jwt_set_ADD_STR(__v, __n, __x) ({ \ - (__v)->type=JWT_VALUE_STR;(__v)->replace=0; \ - (__v)->name=(__n); (__v)->str_val=(__x); }) - -#define jwt_set_ADD_BOOL(__v, __n, __x) ({ \ - (__v)->type=JWT_VALUE_BOOL;(__v)->replace=0; \ - (__v)->name=(__n); (__v)->bool_val=(__x); }) - -#define jwt_set_ADD_JSON(__v, __x) ({ \ - (__v)->type=JWT_VALUE_JSON;(__v)->replace=0; \ - (__v)->name=NULL; (__v)->json_val=(__x); }) - /** - * @brief Delete a header from a JWT object. + * @brief Add a value to the header of a JWT * - * Deletes the named header from this object. It is not an error if there - * is no header matching the passed name. If header is NULL, then all headers - * are deleted from this JWT. + * When adding a value, you must set the type, name, and the specific val for + * the type. If the value already exists, then the function will return + * JWT_VALUE_ERR_EXISTS and value.error will be set the same. If value.replace + * is non-zero, then the exist value will be overwritten if it exists. * - * @param jwt Pointer to a JWT object. - * @param header String containing the name of the header to delete. If this - * is NULL, then all headers are deleted. - * @return Returns 0 on success, valid errno otherwise. + * @remarks When adding a JSON value, you can set value.name = NULL, in which case + * the entire header will be set to the JSON string pointed to by + * value.json_val. If value.replace is not set, only values that do not already + * exist will be added. If replace is set, then existing values will also be + * updated. There is no indication of which values are or aren't updated in + * either case. + * + * @code + * jwt_value_error_t ret; + * jwt_value_t jval; + * + * jwt_set_ADD_STR(&jval, "iss", "foo.example.com"); + * ret = jwt_header_add(jwt, &jval); + * + * if (ret == JWT_VALUE_ERR_NONE) + * printf("iss: %s\n", jval.str_val); + * @endcode + * + * @param jwt Pointer to a jwt_t token, previously created with jwt_create() + * @param value A jwt_value_t structure with relevant actions filled in + * @return A jwt_value_error_t value, JWT_VALUE_ERR_NONE being success. The + * value.error field will match this return value. */ JWT_EXPORT -int jwt_header_del(jwt_t *jwt, const char *header); - -JWT_EXPORT -int jwt_header_add(jwt_t *jwt, jwt_value_t *value); - -JWT_EXPORT -int jwt_header_get(jwt_t *jwt, jwt_value_t *value); +jwt_value_error_t jwt_header_add(jwt_t *jwt, jwt_value_t *value); /** - * @} - * @noop jwt_header_grp - */ - -/** - * @defgroup jwt_grant_grp Grant Management - * These functions allow you to add, remove and retrieve grants from a JWT - * object. - * @{ - */ - -/** - * Return the value of a string grant. + * @brief Get a value from the header of a JWT * - * Returns the string value for a grant (e.g. "iss"). If it does not exist, - * NULL will be returned. + * When getting a value, you must set type and name. On a successful return, the + * val in value specific to the type will be filled in. Common errors responses + * for this function are JWT_VALUE_ERR_NOEXIST when the name does not exist, and + * JWT_VALUE_ERR_TYPE, when the named object is not of the type you requested + * (e.g. you requested a string, but it's an integer value). * - * @param jwt Pointer to a JWT object. - * @param grant String containing the name of the grant to return a value - * for. - * @return Returns a string for the value, or NULL when not found. + * @remarks When getting a JSON value, you can set value.name = NULL, in which + * case the entire header is returned. Also, the resulting value.json_val + * will be using allocated memory and must be freed by the caller. + * + * @code + * jwt_value_error_t ret; + * jwt_value_t jval; * - * @remark This will only return grants with JSON string values. Use - * jwt_get_grants_json() to get the JSON representation of more complex - * values (e.g. arrays) or use jwt_get_grant_int() to get simple integer - * values. + * jwt_set_GET_INT(&jval, "h1"); + * ret = jwt_header_get(jwt, &jval); + * if (ret == JWT_VALUE_ERR_NONE) + * printf("h1 = %d\n", jval.int_val); + * @endcode + * + * @param jwt Pointer to a jwt_t token, previously created with jwt_create() + * @param value A jwt_value_t structure with relevant actions filled in + * @return A jwt_value_error_t value, JWT_VALUE_ERR_NONE being success. The + * value.error field will match this return value. */ JWT_EXPORT -const char *jwt_get_grant(const jwt_t *jwt, const char *grant); +jwt_value_error_t jwt_header_get(jwt_t *jwt, jwt_value_t *value); /** - * Return the value of an integer grant. + * @brief Delete a value from the header of a JWT * - * Returns the int value for a grant (e.g. "exp"). If it does not exist, - * 0 will be returned. + * Deletes the value referenced by value.name from the header. If you set + * value.name = NULL, then the entire header will be cleared of all values. This + * function will generally return without error. * - * @param jwt Pointer to a JWT object. - * @param grant String containing the name of the grant to return a value - * for. - * @return Returns an int for the value. Sets errno to ENOENT when not - * found. - * - * @remark This will only return grants with JSON integer values. Use - * jwt_get_grants_json() to get the JSON representation of more complex - * values (e.g. arrays) or use jwt_get_grant() to get string values. + * @param jwt Pointer to a jwt_t token, previously created with jwt_create() + * @param header The name of the header to delete, or NULL to clear the entire + * header + * @return A jwt_value_error_t value, JWT_VALUE_ERR_NONE being success. The + * value.error field will match this return value. */ JWT_EXPORT -long jwt_get_grant_int(const jwt_t *jwt, const char *grant); +jwt_value_error_t jwt_header_del(jwt_t *jwt, const char *header); /** - * Return the value of an boolean grant. + * @brief Add a value to the grants of a JWT * - * Returns the int value for a grant (e.g. "exp"). If it does not exist, - * 0 will be returned. - * - * @param jwt Pointer to a JWT object. - * @param grant String containing the name of the grant to return a value - * for. - * @return Returns a boolean for the value. Sets errno to ENOENT when not - * found. + * See jwt_header_add() for detailed description. * - * @remark This will only return grants with JSON boolean values. Use - * jwt_get_grants_json() to get the JSON representation of more complex - * values (e.g. arrays) or use jwt_get_grant() to get string values. + * @param jwt Pointer to a jwt_t token, previously created with jwt_create() + * @param value A jwt_value_t structure with relevant actions filled in + * @return A jwt_value_error_t value, JWT_VALUE_ERR_NONE being success. The + * value.error field will match this return value. */ JWT_EXPORT -int jwt_get_grant_bool(const jwt_t *jwt, const char *grant); +jwt_value_error_t jwt_grant_add(jwt_t *jwt, jwt_value_t *value); /** - * Return the value of a grant as JSON encoded object string. + * @brief Get a value from the grants of a JWT * - * Returns the JSON encoded string value for a grant (e.g. "iss"). If it - * does not exist, NULL will be returned. + * See jwt_header_get() for detailed description. * - * @param jwt Pointer to a JWT object. - * @param grant String containing the name of the grant to return a value - * for. If this is NULL, all grants will be returned as a JSON encoded - * hash. - * @return Returns a string for the value, or NULL when not found. The - * returned string must be freed by the caller. + * @param jwt Pointer to a jwt_t token, previously created with jwt_create() + * @param value A jwt_value_t structure with relevant actions filled in + * @return A jwt_value_error_t value, JWT_VALUE_ERR_NONE being success. The + * value.error field will match this return value. */ JWT_EXPORT -char *jwt_get_grants_json(const jwt_t *jwt, const char *grant); +jwt_value_error_t jwt_grant_get(jwt_t *jwt, jwt_value_t *value); /** - * Add a new string grant to this JWT object. + * @brief Delete a value from the grants of a JWT * - * Creates a new grant for this object. The string for grant and val - * are copied internally, so do not require that the pointer or string - * remain valid for the lifetime of this object. It is an error if you - * try to add a grant that already exists. + * See jwt_grant_get() for detailed description. * - * @param jwt Pointer to a JWT object. - * @param grant String containing the name of the grant to add. - * @param val String containing the value to be saved for grant. Can be - * an empty string, but cannot be NULL. - * @return Returns 0 on success, valid errno otherwise. - * - * @remark This only allows for string based grants. If you wish to add - * integer grants, then use jwt_add_grant_int(). If you wish to add more - * complex grants (e.g. an array), then use jwt_add_grants_json(). + * @param jwt Pointer to a jwt_t token, previously created with jwt_create() + * @param header The name of the grant to delete, or NULL to clear all grants + * @return A jwt_value_error_t value, JWT_VALUE_ERR_NONE being success. The + * value.error field will match this return value. */ JWT_EXPORT -int jwt_add_grant(jwt_t *jwt, const char *grant, const char *val); +jwt_value_error_t jwt_grant_del(jwt_t *jwt, const char *header); /** - * Add a new integer grant to this JWT object. - * - * Creates a new grant for this object. The string for grant - * is copied internally, so do not require that the pointer or string - * remain valid for the lifetime of this object. It is an error if you - * try to add a grant that already exists. - * - * @param jwt Pointer to a JWT object. - * @param grant String containing the name of the grant to add. - * @param val int containing the value to be saved for grant. - * @return Returns 0 on success, valid errno otherwise. + * @brief Setup a jwt_value_t to get an integer value * - * @remark This only allows for integer based grants. If you wish to add - * string grants, then use jwt_add_grant(). If you wish to add more - * complex grants (e.g. an array), then use jwt_add_grants_json(). + * @param __v Pointer to a jwt_value_t object + * @param __n Name of the value + * @return No return value */ -JWT_EXPORT -int jwt_add_grant_int(jwt_t *jwt, const char *grant, long val); +#define jwt_set_GET_INT(__v, __n) ({ \ + (__v)->type=JWT_VALUE_INT;(__v)->replace=0; \ + (__v)->name=(__n);(__v)->int_val=0;(__v)->error=0;}) /** - * Add a new boolean grant to this JWT object. + * @brief Setup a jwt_value_t to get a string value * - * Creates a new grant for this object. The string for grant - * is copied internally, so do not require that the pointer or string - * remain valid for the lifetime of this object. It is an error if you - * try to add a grant that already exists. + * @param __v Pointer to a jwt_value_t object + * @param __n Name of the value + * @return No return value + */ +#define jwt_set_GET_STR(__v, __n) ({ \ + (__v)->type=JWT_VALUE_STR;(__v)->replace=0; \ + (__v)->name=(__n);(__v)->str_val=NULL;(__v)->error=0;}) + +/** + * @brief Setup a jwt_value_t to get a boolean value * - * @param jwt Pointer to a JWT object. - * @param grant String containing the name of the grant to add. - * @param val boolean containing the value to be saved for grant. - * @return Returns 0 on success, valid errno otherwise. + * @param __v Pointer to a jwt_value_t object + * @param __n Name of the value + * @return No return value + */ +#define jwt_set_GET_BOOL(__v, __n) ({ \ + (__v)->type=JWT_VALUE_BOOL;(__v)->replace=0; \ + (__v)->name=(__n);(__v)->bool_val=0;(__v)->error=0;}) + +/** + * @brief Setup a jwt_value_t to get an JSON string * - * @remark This only allows for boolean based grants. If you wish to add - * string grants, then use jwt_add_grant(). If you wish to add more - * complex grants (e.g. an array), then use jwt_add_grants_json(). + * @param __v Pointer to a jwt_value_t object + * @param __n Name of the value + * @return No return value */ -JWT_EXPORT -int jwt_add_grant_bool(jwt_t *jwt, const char *grant, int val); +#define jwt_set_GET_JSON(__v, __n) ({ \ + (__v)->type=JWT_VALUE_JSON;(__v)->replace=0; \ + (__v)->name=(__n);(__v)->json_val=NULL;(__v)->error=0;}) /** - * Add grants from a JSON encoded object string. + * @brief Setup a jwt_value_t to add an integer value * - * Loads a grant from an existing JSON encoded object string. Overwrites - * existing grant. If grant is NULL, then the JSON encoded string is - * assumed to be a JSON hash of all grants being added and will be merged - * into the grant listing. + * @param __v Pointer to a jwt_value_t object + * @param __n Name of the value + * @param __x Value to add + * @return No return value + */ +#define jwt_set_ADD_INT(__v, __n, __x) ({ \ + (__v)->type=JWT_VALUE_INT;(__v)->replace=0; \ + (__v)->name=(__n);(__v)->int_val=(__x);(__v)->error=0;}) + +/** + * @brief Setup a jwt_value_t to add a string value * - * @param jwt Pointer to a JWT object. - * @param json String containing a JSON encoded object of grants. - * @return Returns 0 on success, valid errno otherwise. + * @param __v Pointer to a jwt_value_t object + * @param __n Name of the value + * @param __x Value to add + * @return No return value */ -JWT_EXPORT -int jwt_add_grants_json(jwt_t *jwt, const char *json); +#define jwt_set_ADD_STR(__v, __n, __x) ({ \ + (__v)->type=JWT_VALUE_STR;(__v)->replace=0; \ + (__v)->name=(__n);(__v)->str_val=(__x);(__v)->error=0;}) /** - * Delete a grant from this JWT object. + * @brief Setup a jwt_value_t to add a boolean value * - * Deletes the named grant from this object. It is not an error if there - * is no grant matching the passed name. If grant is NULL, then all grants - * are deleted from this JWT. + * @param __v Pointer to a jwt_value_t object + * @param __n Name of the value + * @param __x Value to add + * @return No return value + */ +#define jwt_set_ADD_BOOL(__v, __n, __x) ({ \ + (__v)->type=JWT_VALUE_BOOL;(__v)->replace=0; \ + (__v)->name=(__n);(__v)->bool_val=(__x);(__v)->error=0;}) + +/** + * @brief Setup a jwt_value_t to add a JSON string * - * @param jwt Pointer to a JWT object. - * @param grant String containing the name of the grant to delete. If this - * is NULL, then all grants are deleted. - * @return Returns 0 on success, valid errno otherwise. + * @param __v Pointer to a jwt_value_t object + * @param __n Name of the value + * @param __x Value to add + * @return No return value */ -JWT_EXPORT -int jwt_del_grants(jwt_t *jwt, const char *grant); +#define jwt_set_ADD_JSON(__v, __n, __x) ({ \ + (__v)->type=JWT_VALUE_JSON;(__v)->replace=0; \ + (__v)->name=(__n);(__v)->json_val=(__x);(__v)->error=0;}) /** * @} - * @noop jwt_grant_grp + * @noop jwt_head_grant_grp */ /** @@ -853,8 +863,7 @@ int jwt_encode_fp(jwt_t *jwt, FILE *fp); * Fully encode a JWT object and return as a string. * * Similar to jwt_encode_fp() except that a string is returned. The string - * must be freed by the caller. If you changed the allocation method using - * jwt_set_alloc, then you must use jwt_free_str() to free the memory. + * must be freed by the caller. * * @param jwt Pointer to a JWT object. * @return A null terminated string on success, NULL on error with errno @@ -863,15 +872,6 @@ int jwt_encode_fp(jwt_t *jwt, FILE *fp); JWT_EXPORT char *jwt_encode_str(jwt_t *jwt); -/** - * Free a string returned from the library. - * - * @param str Pointer to a string previously created with - * jwt_encode_str(). - */ -JWT_EXPORT -void jwt_free_str(char *str); - /** * @} * @noop jwt_encode_grp @@ -1583,8 +1583,7 @@ int jwt_valid_set_headers(jwt_valid_t *jwt_valid, int hdr); /** * Parses exceptions and returns a comma delimited and human-readable string. * - * The returned string must be freed by the caller. If you changed the allocation - * method using jwt_set_alloc, then you must use jwt_free_str() to free the memory. + * The returned string must be freed by the caller. * * @remark This string is currently en-US ASCII only. Language support will come in the * future. diff --git a/libjwt/jwt-encode.c b/libjwt/jwt-encode.c index 23dfc945..993d93e1 100644 --- a/libjwt/jwt-encode.c +++ b/libjwt/jwt-encode.c @@ -48,24 +48,25 @@ static int write_js(const json_t *js, char **buf, int pretty) static int jwt_write_head(jwt_t *jwt, char **buf, int pretty) { - int ret = 0; + jwt_value_t jval; if (jwt->alg != JWT_ALG_NONE) { + /* Only add default 'typ' header if it has not been defined, * allowing for any value of it. This allows for signaling * of application specific extensions to JWT, such as PASSporT, * RFC 8225. */ - if ((ret = jwt_add_header(jwt, "typ", "JWT"))) { - if (ret != EEXIST) - return ret; + jwt_set_ADD_STR(&jval, "typ", "JWT"); + if (jwt_header_add(jwt, &jval)) { + if (jval.error != JWT_VALUE_ERR_EXIST) + return jval.error; } } - if ((ret = jwt_header_del(jwt, "alg"))) - return ret; - - if ((ret = jwt_add_header(jwt, "alg", jwt_alg_str(jwt->alg)))) - return ret; + jwt_set_ADD_STR(&jval, "alg", jwt_alg_str(jwt->alg)); + jval.replace = 1; + if (jwt_header_add(jwt, &jval)) + return jval.error; return write_js(jwt->headers, buf, pretty); } diff --git a/libjwt/jwt-memory.c b/libjwt/jwt-memory.c index 657477c1..2d046619 100644 --- a/libjwt/jwt-memory.c +++ b/libjwt/jwt-memory.c @@ -35,11 +35,6 @@ void *jwt_realloc(void *ptr, size_t size) return realloc(ptr, size); } -void jwt_free_str(char *str) -{ - jwt_freemem(str); -} - int jwt_set_alloc(jwt_malloc_t pmalloc, jwt_realloc_t prealloc, jwt_free_t pfree) { /* Set allocator functions for LibJWT. */ diff --git a/libjwt/jwt-private.h b/libjwt/jwt-private.h index 418ed9c0..cfeca9f2 100644 --- a/libjwt/jwt-private.h +++ b/libjwt/jwt-private.h @@ -201,9 +201,6 @@ int jwt_sign(jwt_t *jwt, char **out, unsigned int *len, const char *str, JWT_NO_EXPORT int __append_str(char **buf, const char *str); -JWT_NO_EXPORT -int jwt_add_header(jwt_t *jwt, const char *header, const char *val); - #define __trace() fprintf(stderr, "%s:%d\n", __func__, __LINE__) #endif /* JWT_PRIVATE_H */ diff --git a/libjwt/jwt-setget.c b/libjwt/jwt-setget.c index 4d84a538..f184d023 100644 --- a/libjwt/jwt-setget.c +++ b/libjwt/jwt-setget.c @@ -8,337 +8,280 @@ #include #include -#include #include #include "jwt-private.h" -const char *jwt_get_grant(const jwt_t *jwt, const char *grant) +static jwt_value_error_t jwt_get_str(const jwt_t *jwt, json_t *which, + jwt_value_t *jval) { - if (!jwt || !grant || !strlen(grant)) { - errno = EINVAL; - return NULL; - } - - errno = 0; - - return get_js_string(jwt->grants, grant); -} - -long jwt_get_grant_int(const jwt_t *jwt, const char *grant) -{ - if (!jwt || !grant || !strlen(grant)) { - errno = EINVAL; - return 0; - } - - errno = 0; - - return get_js_int(jwt->grants, grant); -} - -int jwt_get_grant_bool(const jwt_t *jwt, const char *grant) -{ - if (!jwt || !grant || !strlen(grant)) { - errno = EINVAL; - return 0; - } - - errno = 0; - - return get_js_bool(jwt->grants, grant); -} - -char *jwt_get_grants_json(const jwt_t *jwt, const char *grant) -{ - json_t *js_val = NULL; - - if (!jwt) { - errno = EINVAL; - return NULL; - } - - if (grant && strlen(grant)) - js_val = json_object_get(jwt->grants, grant); - else - js_val = jwt->grants; - - if (js_val == NULL) { - errno = ENOENT; - return NULL; - } + json_t *val; - errno = 0; + if (!jval->name || !strlen(jval->name)) + return jval->error = JWT_VALUE_ERR_INVALID; - return json_dumps(js_val, JSON_SORT_KEYS | JSON_COMPACT | - JSON_ENCODE_ANY); -} - -int jwt_add_grant(jwt_t *jwt, const char *grant, const char *val) -{ - if (!jwt || !grant || !strlen(grant) || !val) - return EINVAL; + val = json_object_get(which, jval->name); + if (val == NULL) + return jval->error = JWT_VALUE_ERR_NOEXIST; + else if (!json_is_string(val)) + return jval->error = JWT_VALUE_ERR_TYPE; - if (get_js_string(jwt->grants, grant) != NULL) - return EEXIST; + jval->str_val = json_string_value(val); + if (jval->str_val == NULL) + jval->error = JWT_VALUE_ERR_INVALID; - if (json_object_set_new(jwt->grants, grant, json_string(val))) - return EINVAL; - - return 0; + return jval->error; } -int jwt_add_grant_int(jwt_t *jwt, const char *grant, long val) +static jwt_value_error_t jwt_get_int(const jwt_t *jwt, json_t *which, + jwt_value_t *jval) { - if (!jwt || !grant || !strlen(grant)) - return EINVAL; - - if (get_js_int(jwt->grants, grant) != -1) - return EEXIST; + json_t *val; - if (json_object_set_new(jwt->grants, grant, json_integer((json_int_t)val))) - return EINVAL; + if (!jval->name || !strlen(jval->name)) + return jval->error = JWT_VALUE_ERR_INVALID; - return 0; -} - -int jwt_add_grant_bool(jwt_t *jwt, const char *grant, int val) -{ - if (!jwt || !grant || !strlen(grant)) - return EINVAL; + val = json_object_get(which, jval->name); + if (val == NULL) + return jval->error = JWT_VALUE_ERR_NOEXIST; + else if (!json_is_integer(val)) + return jval->error = JWT_VALUE_ERR_TYPE; - if (get_js_int(jwt->grants, grant) != -1) - return EEXIST; + jval->int_val = (long)json_integer_value(val); - if (json_object_set_new(jwt->grants, grant, json_boolean(val))) - return EINVAL; - - return 0; + return jval->error; } -int jwt_add_grants_json(jwt_t *jwt, const char *json) +static jwt_value_error_t jwt_get_bool(const jwt_t *jwt, json_t *which, + jwt_value_t *jval) { - json_auto_t *js_val = NULL; - int ret = -1; + json_t *val; - if (!jwt) - return EINVAL; + if (!jval->name || !strlen(jval->name)) + return jval->error = JWT_VALUE_ERR_INVALID; - js_val = json_loads(json, JSON_REJECT_DUPLICATES, NULL); + val = json_object_get(which, jval->name); + if (val == NULL) + return jval->error = JWT_VALUE_ERR_NOEXIST; + else if (!json_is_boolean(val)) + return jval->error = JWT_VALUE_ERR_TYPE; - if (json_is_object(js_val)) - ret = json_object_update(jwt->grants, js_val); + jval->bool_val = json_is_true(val) ? 1 : 0; - return ret ? EINVAL : 0; + return jval->error; } -int jwt_del_grants(jwt_t *jwt, const char *grant) +static jwt_value_error_t jwt_get_json(const jwt_t *jwt, json_t *which, + jwt_value_t *jval) { - if (!jwt) - return EINVAL; + json_t *json_val = NULL; - if (grant == NULL || !strlen(grant)) - json_object_clear(jwt->grants); + if (jval->name && strlen(jval->name)) + json_val = json_object_get(which, jval->name); else - json_object_del(jwt->grants, grant); - - return 0; -} - -static const char *jwt_get_header(const jwt_t *jwt, const char *header) -{ - if (!jwt || !header || !strlen(header)) { - errno = EINVAL; - return NULL; - } - - errno = 0; - - return get_js_string(jwt->headers, header); -} + json_val = which; -static long jwt_get_header_int(const jwt_t *jwt, const char *header) -{ - if (!jwt || !header || !strlen(header)) { - errno = EINVAL; - return 0; - } + if (json_val == NULL) + return jval->error = JWT_VALUE_ERR_NOEXIST; - errno = 0; + jval->json_val = json_dumps(json_val, JSON_SORT_KEYS | + JSON_COMPACT | JSON_ENCODE_ANY); + if (jval->json_val == NULL) + jval->error = JWT_VALUE_ERR_NOMEM; - return get_js_int(jwt->headers, header); + return jval->error; } -static int jwt_get_header_bool(const jwt_t *jwt, const char *header) +static jwt_value_error_t jwt_obj_check(json_t *which, jwt_value_t *jval) { - if (!jwt || !header || !strlen(header)) { - errno = EINVAL; - return 0; + if (json_object_get(which, jval->name)) { + if (jval->replace) + json_object_del(which, jval->name); + else + return jval->error = JWT_VALUE_ERR_EXIST; } - errno = 0; - - return get_js_bool(jwt->headers, header); + return JWT_VALUE_ERR_NONE; } -static char *jwt_get_headers_json(const jwt_t *jwt, const char *header) +static jwt_value_error_t jwt_add_str(jwt_t *jwt, json_t *which, + jwt_value_t *jval) { - json_t *js_val = NULL; + if (!jval->name || !strlen(jval->name) || !jval->str_val) + return jval->error = JWT_VALUE_ERR_INVALID; - errno = EINVAL; + if (jwt_obj_check(which, jval)) + return jval->error; - if (!jwt) - return NULL; + if (json_object_set_new(which, jval->name, json_string(jval->str_val))) + jval->error = JWT_VALUE_ERR_INVALID; - if (header && strlen(header)) - js_val = json_object_get(jwt->headers, header); - else - js_val = jwt->headers; - - if (js_val == NULL) - return NULL; - - errno = 0; - - return json_dumps(js_val, JSON_SORT_KEYS | JSON_COMPACT | JSON_ENCODE_ANY); + return jval->error; } -int jwt_add_header(jwt_t *jwt, const char *header, const char *val) +static jwt_value_error_t jwt_add_int(jwt_t *jwt, json_t *which, + jwt_value_t *jval) { - if (!jwt || !header || !strlen(header) || !val) - return EINVAL; + if (!jval->name || !strlen(jval->name)) + return jval->error = JWT_VALUE_ERR_INVALID; - if (get_js_string(jwt->headers, header) != NULL) - return EEXIST; + if (jwt_obj_check(which, jval)) + return jval->error; - if (json_object_set_new(jwt->headers, header, json_string(val))) - return EINVAL; + if (json_object_set_new(which, jval->name, + json_integer((json_int_t)jval->int_val))) + jval->error = JWT_VALUE_ERR_INVALID; - return 0; + return jval->error; } -static int jwt_add_header_int(jwt_t *jwt, const char *header, long val) +static jwt_value_error_t jwt_add_bool(jwt_t *jwt, json_t *which, + jwt_value_t *jval) { - if (!jwt || !header || !strlen(header)) - return EINVAL; + if (!jval->name || !strlen(jval->name)) + return jval->error = JWT_VALUE_ERR_INVALID; - if (get_js_int(jwt->headers, header) != -1) - return EEXIST; + if (jwt_obj_check(which, jval)) + return jval->error; - if (json_object_set_new(jwt->headers, header, json_integer((json_int_t)val))) - return EINVAL; + if (json_object_set_new(which, jval->name, json_boolean(jval->bool_val))) + jval->error = JWT_VALUE_ERR_INVALID; - return 0; + return jval->error; } -static int jwt_add_header_bool(jwt_t *jwt, const char *header, int val) +static jwt_value_error_t jwt_add_json(jwt_t *jwt, json_t *which, + jwt_value_t *jval) { - if (!jwt || !header || !strlen(header)) - return EINVAL; - - if (get_js_int(jwt->headers, header) != -1) - return EEXIST; - - if (json_object_set_new(jwt->headers, header, json_boolean(val))) - return EINVAL; + json_auto_t *json_val; + int ret; + + json_val = json_loads(jval->json_val, JSON_REJECT_DUPLICATES, NULL); + + if (!json_is_object(json_val)) + return jval->error = JWT_VALUE_ERR_INVALID; + + if (jval->name == NULL) { + /* Update the whole thing */ + if (jval->replace) + ret = json_object_update(which, json_val); + else + ret = json_object_update_missing(which, json_val); + + if (ret) + return jval->error = JWT_VALUE_ERR_INVALID; + } else { + /* Add object at name */ + if (jwt_obj_check(which, jval)) + return jval->error; + + if (json_object_set_new(which, jval->name, json_val)) + return jval->error = JWT_VALUE_ERR_INVALID; + } - return 0; + return jval->error; } -static int jwt_add_headers_json(jwt_t *jwt, char *json) +static jwt_value_error_t __deleter(jwt_t *jwt, json_t *which, const char *field) { - json_auto_t *js_val = NULL; - int ret = -1; - if (!jwt) - return EINVAL; - - js_val = json_loads(json, JSON_REJECT_DUPLICATES, NULL); + return JWT_VALUE_ERR_INVALID; - if (json_is_object(js_val)) - ret = json_object_update(jwt->headers, js_val); + if (field == NULL || !strlen(field)) + json_object_clear(which); + else + json_object_del(which, field); - return ret ? EINVAL : 0; + return JWT_VALUE_ERR_NONE; } -int jwt_header_del(jwt_t *jwt, const char *header) +static jwt_value_error_t __adder(jwt_t *jwt, json_t *which, jwt_value_t *value) { - if (!jwt) - return EINVAL; + if (!jwt || !value || !which) { + if (value) + return value->error = JWT_VALUE_ERR_INVALID; + else + return JWT_VALUE_ERR_INVALID; + } - if (header == NULL || !strlen(header)) - json_object_clear(jwt->headers); - else - json_object_del(jwt->headers, header); + value->error = JWT_VALUE_ERR_NONE; - return 0; -} - -int jwt_header_add(jwt_t *jwt, jwt_value_t *value) -{ switch (value->type) { case JWT_VALUE_INT: - if (jwt_add_header_int(jwt, value->name, value->int_val)) - return 1; - break; + return jwt_add_int(jwt, which, value); case JWT_VALUE_STR: - if (jwt_add_header(jwt, value->name, value->str_val)) - return 1; - break; + return jwt_add_str(jwt, which, value); case JWT_VALUE_BOOL: - if (jwt_add_header_bool(jwt, value->name, value->bool_val)) - return 1; - break; + return jwt_add_bool(jwt, which, value); case JWT_VALUE_JSON: - if (jwt_add_headers_json(jwt, value->json_val)) - return 1; - break; + return jwt_add_json(jwt, which, value); default: - return 1; + return value->error = JWT_VALUE_ERR_INVALID; } - - return 0; } -int jwt_header_get(jwt_t *jwt, jwt_value_t *value) +static jwt_value_error_t __getter(jwt_t *jwt, json_t *which, jwt_value_t *value) { + if (!jwt || !value || !which) { + if (value) + return value->error = JWT_VALUE_ERR_INVALID; + else + return JWT_VALUE_ERR_INVALID; + } + + value->error = JWT_VALUE_ERR_NONE; + switch (value->type) { case JWT_VALUE_INT: - value->int_val = jwt_get_header_int(jwt, value->name); - if (errno) { - errno = 0; - return 1; - } - break; + return jwt_get_int(jwt, which, value); case JWT_VALUE_STR: - value->str_val = jwt_get_header(jwt, value->name); - if (value->str_val == NULL) - return 1; - break; + return jwt_get_str(jwt, which, value); case JWT_VALUE_BOOL: - value->bool_val = jwt_get_header_bool(jwt, value->name); - if (errno) { - errno = 0; - return 1; - } - break; + return jwt_get_bool(jwt, which, value); case JWT_VALUE_JSON: - value->json_val = jwt_get_headers_json(jwt, value->name); - if (value->json_val == NULL) - return 1; - break; + return jwt_get_json(jwt, which, value); default: - return 1; + return value->error = JWT_VALUE_ERR_INVALID; } +} + +/* Headers */ +jwt_value_error_t jwt_header_get(jwt_t *jwt, jwt_value_t *value) +{ + return __getter(jwt, jwt ? jwt->headers : NULL, value); +} + +jwt_value_error_t jwt_header_add(jwt_t *jwt, jwt_value_t *value) +{ + return __adder(jwt, jwt ? jwt->headers : NULL, value); +} - return 0; +jwt_value_error_t jwt_header_del(jwt_t *jwt, const char *header) +{ + return __deleter(jwt, jwt ? jwt->headers : NULL, header); +} + +/* Grants */ +jwt_value_error_t jwt_grant_get(jwt_t *jwt, jwt_value_t *value) +{ + return __getter(jwt, jwt ? jwt->grants : NULL, value); +} + +jwt_value_error_t jwt_grant_add(jwt_t *jwt, jwt_value_t *value) +{ + return __adder(jwt, jwt ? jwt->grants : NULL, value); +} + +jwt_value_error_t jwt_grant_del(jwt_t *jwt, const char *grant) +{ + return __deleter(jwt, jwt ? jwt->grants : NULL, grant); } diff --git a/tests/jwt_dump.c b/tests/jwt_dump.c index ea4dfbfe..599e4c24 100644 --- a/tests/jwt_dump.c +++ b/tests/jwt_dump.c @@ -79,6 +79,7 @@ const char dump_exp[] = "\n\ START_TEST(test_jwt_dump_fp) { + jwt_value_t jval; char read_back[BUFSIZ]; FILE *out; jwt_t *jwt = NULL; @@ -92,16 +93,20 @@ START_TEST(test_jwt_dump_fp) jwt = jwt_create(NULL); ck_assert_ptr_nonnull(jwt); - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", TS_CONST); + jwt_set_ADD_INT(&jval, "iat", TS_CONST); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); out = fopen("dump_fp_out.txt", "w"); @@ -144,22 +149,26 @@ START_TEST(test_jwt_dump_str) jwt = jwt_create(NULL); ck_assert_ptr_nonnull(jwt); - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", (long)time(NULL)); + jwt_set_ADD_INT(&jval, "iat", (long)time(NULL)); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); /* Test 'typ' header: should not be present, cause 'alg' is JWT_ALG_NONE. */ jwt_set_GET_STR(&jval, "typ"); ret = jwt_header_get(jwt, &jval); - ck_assert_int_eq(ret, 1); + ck_assert_int_eq(ret, JWT_VALUE_ERR_NOEXIST); ck_assert_ptr_null(jval.str_val); out = jwt_dump_str(jwt, 1); @@ -168,10 +177,10 @@ START_TEST(test_jwt_dump_str) /* Test 'typ' header: should not be present, cause 'alg' is JWT_ALG_NONE. */ jwt_set_GET_STR(&jval, "typ"); ret = jwt_header_get(jwt, &jval); - ck_assert_int_eq(ret, 1); + ck_assert_int_eq(ret, JWT_VALUE_ERR_NOEXIST); ck_assert_ptr_null(jval.str_val); - jwt_free_str(out); + free(out); out = jwt_dump_str(jwt, 0); ck_assert_ptr_nonnull(out); @@ -179,10 +188,10 @@ START_TEST(test_jwt_dump_str) /* Test 'typ' header: should not be present, cause 'alg' is JWT_ALG_NONE. */ jwt_set_GET_STR(&jval, "typ"); ret = jwt_header_get(jwt, &jval); - ck_assert_int_ne(ret, 0); + ck_assert_int_eq(ret, JWT_VALUE_ERR_NOEXIST); ck_assert_ptr_null(jval.str_val); - jwt_free_str(out); + free(out); jwt_free(jwt); } @@ -201,6 +210,7 @@ END_TEST START_TEST(test_jwt_dump_grants_str) { + jwt_value_t jval; jwt_t *jwt = NULL; int ret = 0; char *out; @@ -215,16 +225,20 @@ START_TEST(test_jwt_dump_grants_str) jwt = jwt_create(NULL); ck_assert_ptr_nonnull(jwt); - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", timestamp); + jwt_set_ADD_INT(&jval, "iat", timestamp); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); out = jwt_dump_grants_str(jwt, 1); @@ -238,7 +252,7 @@ START_TEST(test_jwt_dump_grants_str) "sub", "user0"); ck_assert_str_eq(out, buf); - jwt_free_str(out); + free(out); out = jwt_dump_grants_str(jwt, 0); ck_assert_ptr_nonnull(out); @@ -251,7 +265,7 @@ START_TEST(test_jwt_dump_grants_str) "sub", "user0"); ck_assert_str_eq(out, buf); - jwt_free_str(out); + free(out); jwt_free(jwt); } @@ -271,16 +285,20 @@ START_TEST(test_jwt_dump_str_alg_default_typ_header) CREATE_JWT(jwt, "oct_key_256.json", JWT_ALG_HS256); - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", (long)time(NULL)); + jwt_set_ADD_INT(&jval, "iat", (long)time(NULL)); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); /* @@ -307,7 +325,7 @@ START_TEST(test_jwt_dump_str_alg_default_typ_header) ck_assert_ptr_nonnull(jval.str_val); ck_assert_str_eq(jval.str_val, "JWT"); - jwt_free_str(out); + free(out); out = jwt_dump_str(jwt, 0); ck_assert_ptr_nonnull(out); @@ -323,7 +341,7 @@ START_TEST(test_jwt_dump_str_alg_default_typ_header) ck_assert_ptr_nonnull(jval.str_val); ck_assert_str_eq(jval.str_val, "JWT"); - jwt_free_str(out); + free(out); } END_TEST @@ -341,16 +359,20 @@ START_TEST(test_jwt_dump_str_alg_custom_typ_header) CREATE_JWT(jwt, "oct_key_256.json", JWT_ALG_HS256); - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", (long)time(NULL)); + jwt_set_ADD_INT(&jval, "iat", (long)time(NULL)); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); jwt_set_ADD_STR(&jval, "typ", "favourite"); @@ -381,7 +403,7 @@ START_TEST(test_jwt_dump_str_alg_custom_typ_header) ck_assert_ptr_nonnull(jval.str_val); ck_assert_str_eq(jval.str_val, "favourite"); - jwt_free_str(out); + free(out); out = jwt_dump_str(jwt, 0); ck_assert_ptr_nonnull(out); @@ -393,7 +415,7 @@ START_TEST(test_jwt_dump_str_alg_custom_typ_header) ck_assert_ptr_nonnull(jval.str_val); ck_assert_str_eq(jval.str_val, "favourite"); - jwt_free_str(out); + free(out); } END_TEST diff --git a/tests/jwt_encode.c b/tests/jwt_encode.c index 3546b37a..03599a5b 100644 --- a/tests/jwt_encode.c +++ b/tests/jwt_encode.c @@ -14,6 +14,7 @@ START_TEST(test_jwt_encode_fp) "zcyI6ImZpbGVzLm1hY2xhcmEtbGxjLmNvbSIsInJlZiI6IlhYWFgtWVlZW" "S1aWlpaLUFBQUEtQ0NDQyIsInN1YiI6InVzZXIwIn0."; char read_back[BUFSIZ]; + jwt_value_t jval; FILE *out; jwt_t *jwt = NULL; int ret = 0; @@ -22,16 +23,20 @@ START_TEST(test_jwt_encode_fp) EMPTY_JWT(jwt); - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", TS_CONST); + jwt_set_ADD_INT(&jval, "iat", TS_CONST); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); out = fopen("test_outfile.txt", "w"); @@ -60,6 +65,7 @@ START_TEST(test_jwt_encode_str) const char res[] = "eyJhbGciOiJub25lIn0.eyJpYXQiOjE0NzU5ODA1NDUsIml" "zcyI6ImZpbGVzLm1hY2xhcmEtbGxjLmNvbSIsInJlZiI6IlhYWFgtWVlZW" "S1aWlpaLUFBQUEtQ0NDQyIsInN1YiI6InVzZXIwIn0."; + jwt_value_t jval; jwt_t *jwt = NULL; int ret = 0; char *out; @@ -68,16 +74,20 @@ START_TEST(test_jwt_encode_str) EMPTY_JWT(jwt); - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", TS_CONST); + jwt_set_ADD_INT(&jval, "iat", TS_CONST); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); out = jwt_encode_str(jwt); @@ -85,7 +95,7 @@ START_TEST(test_jwt_encode_str) ck_assert_str_eq(out, res); - jwt_free_str(out); + free(out); jwt_free(jwt); } @@ -97,6 +107,7 @@ START_TEST(test_jwt_encode_alg_none) "ubmwiLCJleHAiOjE0Nzc1MTQ4MTIsInN1YiI6IlBsdWdnZXJzIFNvZnR3Y" "XJlIn0."; jwt_t *jwt = NULL; + jwt_value_t jval; int ret = 0; char *out; @@ -104,13 +115,16 @@ START_TEST(test_jwt_encode_alg_none) EMPTY_JWT(jwt); - ret = jwt_add_grant(jwt, "aud", "www.pluggers.nl"); + jwt_set_ADD_STR(&jval, "aud", "www.pluggers.nl"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "exp", 1477514812); + jwt_set_ADD_INT(&jval, "exp", 1477514812); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "Pluggers Software"); + jwt_set_ADD_STR(&jval, "sub", "Pluggers Software"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); out = jwt_encode_str(jwt); @@ -118,7 +132,7 @@ START_TEST(test_jwt_encode_alg_none) ck_assert_str_eq(out, res); - jwt_free_str(out); + free(out); jwt_free(jwt); } @@ -131,6 +145,7 @@ START_TEST(test_jwt_encode_hs256) "ZiI6IlhYWFgtWVlZWS1aWlpaLUFBQUEtQ0NDQyIsInN1YiI6InVzZXIwIn" "0.JgSDx8Xwc6tjMDglRndhLeAbjPPrTNoK6uc_E_TDu_o"; jwt_test_auto_t *jwt = NULL; + jwt_value_t jval; int ret = 0; char *out; @@ -138,16 +153,20 @@ START_TEST(test_jwt_encode_hs256) CREATE_JWT(jwt, "oct_key_256.json", JWT_ALG_HS256); - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", TS_CONST); + jwt_set_ADD_INT(&jval, "iat", TS_CONST); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); out = jwt_encode_str(jwt); @@ -155,7 +174,7 @@ START_TEST(test_jwt_encode_hs256) ck_assert_str_eq(out, res); - jwt_free_str(out); + free(out); } END_TEST @@ -167,6 +186,7 @@ START_TEST(test_jwt_encode_hs384) "0.sI0hzVmaMsnfKjEGsANdMNPUfe_Pk1JPY_aixKCxVvCy25B0ADUBQdKz" "6VIUPmG_"; jwt_test_auto_t *jwt = NULL; + jwt_value_t jval; int ret = 0; char *out; @@ -174,16 +194,20 @@ START_TEST(test_jwt_encode_hs384) CREATE_JWT(jwt, "oct_key_384.json", JWT_ALG_HS384); - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", TS_CONST); + jwt_set_ADD_INT(&jval, "iat", TS_CONST); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); out = jwt_encode_str(jwt); @@ -191,7 +215,7 @@ START_TEST(test_jwt_encode_hs384) ck_assert_str_eq(out, res); - jwt_free_str(out); + free(out); } END_TEST @@ -203,6 +227,7 @@ START_TEST(test_jwt_encode_hs512) "0.qQ1ghQaPvzIRnzGgUPmvqEk0NlcMYjeZuna8xQLfKtZ52VHCaT-FS8T0" "O2O_O9NQyqnA3sNnDaSsTxq1fEuDLA"; jwt_test_auto_t *jwt = NULL; + jwt_value_t jval; int ret = 0; char *out; @@ -210,16 +235,20 @@ START_TEST(test_jwt_encode_hs512) CREATE_JWT(jwt, "oct_key_512.json", JWT_ALG_HS512); - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", TS_CONST); + jwt_set_ADD_INT(&jval, "iat", TS_CONST); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); out = jwt_encode_str(jwt); @@ -227,7 +256,7 @@ START_TEST(test_jwt_encode_hs512) ck_assert_str_eq(out, res); - jwt_free_str(out); + free(out); } END_TEST @@ -239,6 +268,7 @@ START_TEST(test_jwt_encode_change_alg) "0.qQ1ghQaPvzIRnzGgUPmvqEk0NlcMYjeZuna8xQLfKtZ52VHCaT-FS8T0" "O2O_O9NQyqnA3sNnDaSsTxq1fEuDLA"; jwt_test_auto_t *jwt = NULL; + jwt_value_t jval; int ret = 0; char *out; @@ -246,16 +276,20 @@ START_TEST(test_jwt_encode_change_alg) CREATE_JWT(jwt, "oct_key_512.json", JWT_ALG_HS512); - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", TS_CONST); + jwt_set_ADD_INT(&jval, "iat", TS_CONST); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); out = jwt_encode_str(jwt); @@ -263,7 +297,7 @@ START_TEST(test_jwt_encode_change_alg) ck_assert_str_eq(out, res); - jwt_free_str(out); + free(out); } END_TEST @@ -271,14 +305,18 @@ START_TEST(test_jwt_encode_decode) { jwt_test_auto_t *mytoken = NULL; jwt_auto_t *ymtoken = NULL; + jwt_value_t jval; char *encoded; SET_OPS(); CREATE_JWT(mytoken, "oct_key_256.json", JWT_ALG_HS256); - jwt_add_grant(mytoken, "sub", "user0"); - jwt_add_grant_int(mytoken, "iat", 1619130517); - jwt_add_grant_int(mytoken, "exp", 1619216917); + jwt_set_ADD_STR(&jval, "sub", "user0"); + jwt_grant_add(mytoken, &jval); + jwt_set_ADD_INT(&jval, "iat", 1619130517); + jwt_grant_add(mytoken, &jval); + jwt_set_ADD_INT(&jval, "exp", 1619216917); + jwt_grant_add(mytoken, &jval); encoded = jwt_encode_str(mytoken); @@ -294,14 +332,18 @@ END_TEST START_TEST(test_jwt_encode_too_short) { jwt_test_auto_t *mytoken; + jwt_value_t jval; char *encoded; SET_OPS(); CREATE_JWT(mytoken, "oct_key_512_bad.json", JWT_ALG_HS512); - jwt_add_grant(mytoken, "sub", "user0"); - jwt_add_grant_int(mytoken, "iat", 1619130517); - jwt_add_grant_int(mytoken, "exp", 1619216917); + jwt_set_ADD_STR(&jval, "sub", "user0"); + jwt_grant_add(mytoken, &jval); + jwt_set_ADD_INT(&jval, "iat", 1619130517); + jwt_grant_add(mytoken, &jval); + jwt_set_ADD_INT(&jval, "exp", 1619216917); + jwt_grant_add(mytoken, &jval); encoded = jwt_encode_str(mytoken); ck_assert_ptr_null(encoded); diff --git a/tests/jwt_grant.c b/tests/jwt_grant.c index 0f59ff0f..102d1a38 100644 --- a/tests/jwt_grant.c +++ b/tests/jwt_grant.c @@ -3,39 +3,44 @@ #include #include #include -#include #include #include "jwt_tests.h" -START_TEST(test_jwt_add_grant) +START_TEST(test_jwt_grant_add) { jwt_auto_t *jwt = NULL; + jwt_value_t jval; int ret = 0; SET_OPS(); EMPTY_JWT(jwt); - ret = jwt_add_grant(jwt, "iss", "test"); + jwt_set_ADD_STR(&jval, "iss", "test"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); /* No duplicates */ - ret = jwt_add_grant(jwt, "iss", "other"); - ck_assert_int_eq(ret, EEXIST); + jwt_set_ADD_STR(&jval, "iss", "other"); + ret = jwt_grant_add(jwt, &jval); + ck_assert_int_eq(ret, JWT_VALUE_ERR_EXIST); /* No duplicates for int */ - ret = jwt_add_grant_int(jwt, "iat", (long)time(NULL)); + jwt_set_ADD_INT(&jval, "iat", (long)time(NULL)); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", (long)time(NULL)); - ck_assert_int_eq(ret, EEXIST); + jwt_set_ADD_INT(&jval, "iat", (long)time(NULL)); + ret = jwt_grant_add(jwt, &jval); + ck_assert_int_eq(ret, JWT_VALUE_ERR_EXIST); } END_TEST -START_TEST(test_jwt_get_grant) +START_TEST(test_jwt_grant_get) { jwt_auto_t *jwt = NULL; + jwt_value_t jval; const char *val; const char testval[] = "testing"; int ret = 0; @@ -44,39 +49,47 @@ START_TEST(test_jwt_get_grant) EMPTY_JWT(jwt); - ret = jwt_add_grant(jwt, "iss", testval); + jwt_set_ADD_STR(&jval, "iss", testval); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - val = jwt_get_grant(jwt, "iss"); + jwt_set_GET_STR(&jval, "iss"); + ret = jwt_grant_get(jwt, &jval); + val = jval.str_val; ck_assert_ptr_nonnull(val); ck_assert_str_eq(val, testval); } END_TEST -START_TEST(test_jwt_add_grant_int) +START_TEST(test_jwt_grant_add_int) { jwt_auto_t *jwt = NULL; - long val; + jwt_value_t jval; int ret = 0; SET_OPS(); EMPTY_JWT(jwt); - ret = jwt_add_grant_int(jwt, "int", 1); + jwt_set_ADD_INT(&jval, "int", 1); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - val = jwt_get_grant_int(jwt, "int"); - ck_assert(val); + jwt_set_GET_INT(&jval, "int"); + ret = jwt_grant_get(jwt, &jval); + ck_assert_int_eq(ret, 0); + ck_assert_int_eq(jval.int_val, 1); - val = jwt_get_grant_int(jwt, "not found"); - ck_assert_int_eq(errno, ENOENT); + jwt_set_GET_INT(&jval, "not found"); + ret = jwt_grant_get(jwt, &jval); + ck_assert_int_eq(ret, JWT_VALUE_ERR_NOEXIST); } END_TEST -START_TEST(test_jwt_add_grant_bool) +START_TEST(test_jwt_grant_add_bool) { jwt_auto_t *jwt = NULL; + jwt_value_t jval; int val; int ret = 0; @@ -84,26 +97,35 @@ START_TEST(test_jwt_add_grant_bool) EMPTY_JWT(jwt); - ret = jwt_add_grant_bool(jwt, "admin", 1); + jwt_set_ADD_BOOL(&jval, "admin", 1); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - val = jwt_get_grant_bool(jwt, "admin"); + jwt_set_GET_BOOL(&jval, "admin"); + ret = jwt_grant_get(jwt, &jval); + val = jval.bool_val; ck_assert(val); - ret = jwt_add_grant_bool(jwt, "test", 0); + jwt_set_ADD_BOOL(&jval, "test", 0); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - val = jwt_get_grant_bool(jwt, "test"); + jwt_set_GET_BOOL(&jval, "test"); + ret = jwt_grant_get(jwt, &jval); + val = jval.bool_val; ck_assert(!val); - val = jwt_get_grant_bool(jwt, "not found"); - ck_assert_int_eq(errno, ENOENT); + jwt_set_GET_BOOL(&jval, "not found"); + ret = jwt_grant_get(jwt, &jval); + val = jval.bool_val; + ck_assert_int_eq(ret, JWT_VALUE_ERR_NOEXIST); } END_TEST -START_TEST(test_jwt_del_grants) +START_TEST(test_jwt_grant_del) { jwt_auto_t *jwt = NULL; + jwt_value_t jval; const char *val; const char testval[] = "testing"; int ret = 0; @@ -112,27 +134,33 @@ START_TEST(test_jwt_del_grants) EMPTY_JWT(jwt); - ret = jwt_add_grant(jwt, "iss", testval); + jwt_set_ADD_STR(&jval, "iss", testval); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "other", testval); + jwt_set_ADD_STR(&jval, "other", testval); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_del_grants(jwt, "iss"); + ret = jwt_grant_del(jwt, "iss"); ck_assert_int_eq(ret, 0); - val = jwt_get_grant(jwt, "iss"); + jwt_set_GET_STR(&jval, "iss"); + ret = jwt_grant_get(jwt, &jval); + val = jval.str_val; ck_assert_ptr_null(val); /* Delete non existent. */ - ret = jwt_del_grants(jwt, "iss"); + ret = jwt_grant_del(jwt, "iss"); ck_assert_int_eq(ret, 0); /* Delete all grants. */ - ret = jwt_del_grants(jwt, NULL); + ret = jwt_grant_del(jwt, NULL); ck_assert_int_eq(ret, 0); - val = jwt_get_grant(jwt, "other"); + jwt_set_GET_STR(&jval, "other"); + ret = jwt_grant_get(jwt, &jval); + val = jval.str_val; ck_assert_ptr_null(val); } END_TEST @@ -140,6 +168,7 @@ END_TEST START_TEST(test_jwt_grant_invalid) { jwt_auto_t *jwt = NULL; + jwt_value_t jval; const char *val; long valint = 0; int valbool = 0; @@ -149,63 +178,77 @@ START_TEST(test_jwt_grant_invalid) EMPTY_JWT(jwt); - ret = jwt_add_grant(jwt, "iss", NULL); - ck_assert_int_eq(ret, EINVAL); + jwt_set_ADD_STR(&jval, "iss", NULL); + ret = jwt_grant_add(jwt, &jval); + ck_assert_int_eq(ret, JWT_VALUE_ERR_INVALID); - ret = jwt_add_grant_int(jwt, "", (long)time(NULL)); - ck_assert_int_eq(ret, EINVAL); + jwt_set_ADD_INT(&jval, "", (long)time(NULL)); + ret = jwt_grant_add(jwt, &jval); + ck_assert_int_eq(ret, JWT_VALUE_ERR_INVALID); - val = jwt_get_grant(jwt, NULL); - ck_assert_int_eq(errno, EINVAL); + jwt_set_GET_STR(&jval, NULL); + ret = jwt_grant_get(jwt, &jval); + val = jval.str_val; + ck_assert_int_eq(ret, JWT_VALUE_ERR_INVALID); ck_assert_ptr_null(val); - valint = jwt_get_grant_int(jwt, NULL); - ck_assert_int_eq(errno, EINVAL); + jwt_set_GET_INT(&jval, NULL); + ret = jwt_grant_get(jwt, &jval); + valint = jval.int_val; + ck_assert_int_eq(ret, JWT_VALUE_ERR_INVALID); ck_assert(valint == 0); - valbool = jwt_get_grant_bool(jwt, NULL); - ck_assert_int_eq(errno, EINVAL); + jwt_set_GET_BOOL(&jval, NULL); + ret = jwt_grant_get(jwt, &jval); + valbool = jval.bool_val; + ck_assert_int_eq(ret, JWT_VALUE_ERR_INVALID); ck_assert(valbool == 0); } END_TEST START_TEST(test_jwt_grants_json) { - const char *json = "{\"id\":\"FVvGYTr3FhiURCFebsBOpBqTbzHdX/DvImiA2yheXr8=\"," + char *json = "{\"id\":\"FVvGYTr3FhiURCFebsBOpBqTbzHdX/DvImiA2yheXr8=\"," "\"iss\":\"localhost\",\"other\":[\"foo\",\"bar\"]," "\"ref\":\"385d6518-fb73-45fc-b649-0527d8576130\"," "\"scopes\":\"storage\",\"sub\":\"user0\"}"; jwt_auto_t *jwt = NULL; + jwt_value_t jval; const char *val; - char *json_val; int ret = 0; SET_OPS(); EMPTY_JWT(jwt); - ret = jwt_add_grants_json(jwt, json); + jwt_set_ADD_JSON(&jval, NULL, json); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - val = jwt_get_grant(jwt, "ref"); + jwt_set_GET_STR(&jval, "ref"); + ret = jwt_grant_get(jwt, &jval); + val = jval.str_val; ck_assert_ptr_nonnull(val); ck_assert_str_eq(val, "385d6518-fb73-45fc-b649-0527d8576130"); - json_val = jwt_get_grants_json(NULL, "other"); - ck_assert_ptr_null(json_val); - ck_assert_int_eq(errno, EINVAL); + jwt_set_GET_JSON(&jval, "other"); + ret = jwt_grant_get(NULL, &jval); + ck_assert_ptr_null(jval.json_val); + ck_assert_int_eq(ret, JWT_VALUE_ERR_INVALID); - json_val = jwt_get_grants_json(jwt, "other"); - ck_assert_ptr_nonnull(json_val); - ck_assert_str_eq(json_val, "[\"foo\",\"bar\"]"); + jwt_set_GET_JSON(&jval, "other"); + ret = jwt_grant_get(jwt, &jval); + ck_assert_int_eq(ret, 0); + ck_assert_ptr_nonnull(jval.json_val); + ck_assert_str_eq(jval.json_val, "[\"foo\",\"bar\"]"); - jwt_free_str(json_val); + free(jval.json_val); - json_val = jwt_get_grants_json(jwt, NULL); - ck_assert_ptr_nonnull(json_val); - ck_assert_str_eq(json_val, json); + jwt_set_GET_JSON(&jval, "other"); + ret = jwt_grant_get(jwt, NULL); + ck_assert_int_eq(ret, JWT_VALUE_ERR_INVALID); - jwt_free_str(json_val); + free(jval.json_val); } END_TEST @@ -219,11 +262,11 @@ static Suite *libjwt_suite(const char *title) tc_core = tcase_create("jwt_grant"); - tcase_add_loop_test(tc_core, test_jwt_add_grant, 0, i); - tcase_add_loop_test(tc_core, test_jwt_add_grant_int, 0, i); - tcase_add_loop_test(tc_core, test_jwt_add_grant_bool, 0, i); - tcase_add_loop_test(tc_core, test_jwt_get_grant, 0, i); - tcase_add_loop_test(tc_core, test_jwt_del_grants, 0, i); + tcase_add_loop_test(tc_core, test_jwt_grant_add, 0, i); + tcase_add_loop_test(tc_core, test_jwt_grant_add_int, 0, i); + tcase_add_loop_test(tc_core, test_jwt_grant_add_bool, 0, i); + tcase_add_loop_test(tc_core, test_jwt_grant_get, 0, i); + tcase_add_loop_test(tc_core, test_jwt_grant_del, 0, i); tcase_add_loop_test(tc_core, test_jwt_grant_invalid, 0, i); tcase_add_loop_test(tc_core, test_jwt_grants_json, 0, i); diff --git a/tests/jwt_header.c b/tests/jwt_header.c index 623d1def..26c04b61 100644 --- a/tests/jwt_header.c +++ b/tests/jwt_header.c @@ -81,7 +81,7 @@ START_TEST(test_jwt_header_add_int) jwt_set_GET_STR(&jval, "not found"); ret = jwt_header_get(jwt, &jval); - ck_assert_int_eq(ret, 1); + ck_assert_int_eq(ret, JWT_VALUE_ERR_NOEXIST); } END_TEST @@ -115,7 +115,7 @@ START_TEST(test_jwt_header_add_bool) jwt_set_GET_BOOL(&jval, "not found"); ret = jwt_header_get(jwt, &jval); - ck_assert_int_eq(ret, 1); + ck_assert_int_eq(ret, JWT_VALUE_ERR_NOEXIST); } END_TEST @@ -143,7 +143,7 @@ START_TEST(test_jwt_header_del) jwt_set_GET_STR(&jval, "iss"); ret = jwt_header_get(jwt, &jval); - ck_assert_int_eq(ret, 1); + ck_assert_int_eq(ret, JWT_VALUE_ERR_NOEXIST); ck_assert_ptr_null(jval.str_val); /* Delete non existent. */ @@ -181,16 +181,16 @@ START_TEST(test_jwt_header_invalid) jwt_set_GET_STR(&jval, NULL); ret = jwt_header_get(jwt, &jval); - ck_assert_int_eq(ret, 1); + ck_assert_int_eq(ret, JWT_VALUE_ERR_INVALID); ck_assert_ptr_null(jval.str_val); jwt_set_GET_INT(&jval, NULL); ret = jwt_header_get(jwt, &jval); - ck_assert_int_eq(ret, 1); + ck_assert_int_eq(ret, JWT_VALUE_ERR_INVALID); jwt_set_GET_BOOL(&jval, NULL); ret = jwt_header_get(jwt, &jval); - ck_assert_int_eq(ret, 1); + ck_assert_int_eq(ret, JWT_VALUE_ERR_INVALID); } END_TEST @@ -208,7 +208,7 @@ START_TEST(test_jwt_headers_json) EMPTY_JWT(jwt); - jwt_set_ADD_JSON(&jval, json); + jwt_set_ADD_JSON(&jval, NULL, json); ret = jwt_header_add(jwt, &jval); ck_assert_int_eq(ret, 0); @@ -220,7 +220,7 @@ START_TEST(test_jwt_headers_json) jwt_set_GET_STR(&jval, "other"); ret = jwt_header_get(NULL, &jval); - ck_assert_int_eq(ret, 1); + ck_assert_int_eq(ret, JWT_VALUE_ERR_INVALID); jwt_set_GET_JSON(&jval, "other"); ret = jwt_header_get(jwt, &jval); @@ -228,7 +228,7 @@ START_TEST(test_jwt_headers_json) ck_assert_ptr_nonnull(jval.json_val); ck_assert_str_eq(jval.json_val, "[\"foo\",\"bar\"]"); - jwt_free_str(jval.json_val); + free(jval.json_val); jwt_set_GET_JSON(&jval, NULL); ret = jwt_header_get(jwt, &jval); @@ -236,7 +236,7 @@ START_TEST(test_jwt_headers_json) ck_assert_ptr_nonnull(jval.json_val); ck_assert_str_eq(jval.json_val, json); - jwt_free_str(jval.json_val); + free(jval.json_val); } END_TEST diff --git a/tests/jwt_jwks.c b/tests/jwt_jwks.c index bb94f1dc..192af7c4 100644 --- a/tests/jwt_jwks.c +++ b/tests/jwt_jwks.c @@ -23,6 +23,7 @@ static void __jwks_check(const char *json, const char *pem) jwk_set_auto_t *jwk_set = NULL; const jwk_item_t *item = NULL; jwt_auto_t *jwt = NULL; + jwt_value_t jval; char *out = NULL; int ret; @@ -70,16 +71,20 @@ static void __jwks_check(const char *json, const char *pem) ck_assert_ptr_nonnull(jwt); /* Add some grants */ - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", TS_CONST); + jwt_set_ADD_INT(&jval, "iat", TS_CONST); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); /* Encode it */ @@ -96,7 +101,7 @@ static void __jwks_check(const char *json, const char *pem) /* Verify it using our JWK */ __verify_jwk(out, item); - jwt_free_str(out); + free(out); } JWKS_KEY_TEST(ec_key_prime256v1); diff --git a/tests/jwt_new.c b/tests/jwt_new.c index 67f654c3..802e4308 100644 --- a/tests/jwt_new.c +++ b/tests/jwt_new.c @@ -32,6 +32,7 @@ END_TEST START_TEST(test_jwt_dup) { jwt_auto_t *jwt = NULL, *new = NULL; + jwt_value_t jval; int ret = 0; const char *val = NULL; time_t now; @@ -44,23 +45,29 @@ START_TEST(test_jwt_dup) EMPTY_JWT(jwt); - ret = jwt_add_grant(jwt, "iss", "test"); + jwt_set_ADD_STR(&jval, "iss", "test"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); new = jwt_dup(jwt); ck_assert_ptr_nonnull(new); - val = jwt_get_grant(new, "iss"); + jwt_set_GET_STR(&jval, "iss"); + ret = jwt_grant_get(new, &jval); + val = jval.str_val; ck_assert_ptr_nonnull(val); ck_assert_str_eq(val, "test"); ck_assert_int_eq(jwt_get_alg(new), JWT_ALG_NONE); now = time(NULL); - ret = jwt_add_grant_int(jwt, "iat", (long)now); + jwt_set_ADD_INT(&jval, "iat", (long)now); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - valint = jwt_get_grant_int(jwt, "iat"); + jwt_set_GET_INT(&jval, "iat"); + ret = jwt_grant_get(jwt, &jval); + valint = jval.int_val; ck_assert(((long)now) == valint); } END_TEST @@ -69,6 +76,7 @@ START_TEST(test_jwt_dup_signed) { jwt_test_auto_t *jwt = NULL; jwt_auto_t *new = NULL; + jwt_value_t jval; int ret = 0; const char *val = NULL; @@ -76,13 +84,16 @@ START_TEST(test_jwt_dup_signed) CREATE_JWT(jwt, "oct_key_256.json", JWT_ALG_HS256); - ret = jwt_add_grant(jwt, "iss", "test"); + jwt_set_ADD_STR(&jval, "iss", "test"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); new = jwt_dup(jwt); ck_assert_ptr_nonnull(new); - val = jwt_get_grant(new, "iss"); + jwt_set_GET_STR(&jval, "iss"); + ret = jwt_grant_get(new, &jval); + val = jval.str_val; ck_assert_ptr_nonnull(val); ck_assert_str_eq(val, "test"); diff --git a/tests/jwt_rsa.c b/tests/jwt_rsa.c index 696cb236..c7c3fb57 100644 --- a/tests/jwt_rsa.c +++ b/tests/jwt_rsa.c @@ -176,6 +176,7 @@ END_TEST START_TEST(test_jwt_encode_rsa_1024) { jwt_test_auto_t *jwt = NULL; + jwt_value_t jval; char *out; int ret = 0; @@ -183,7 +184,8 @@ START_TEST(test_jwt_encode_rsa_1024) CREATE_JWT(jwt, "rsa_key_1024.json", JWT_ALG_RS256); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); /* Should fail from too few bits in key */ diff --git a/tests/jwt_rsa_pss.c b/tests/jwt_rsa_pss.c index 504630f9..d179e720 100644 --- a/tests/jwt_rsa_pss.c +++ b/tests/jwt_rsa_pss.c @@ -60,21 +60,26 @@ static void __test_rsa_pss_encode(const char *priv_key_file, const jwt_alg_t alg) { jwt_auto_t *jwt = NULL; + jwt_value_t jval; int ret; char *out; CREATE_JWT(jwt, priv_key_file, alg); - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", TS_CONST); + jwt_set_ADD_INT(&jval, "iat", TS_CONST); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); out = jwt_encode_str(jwt); @@ -84,7 +89,7 @@ static void __test_rsa_pss_encode(const char *priv_key_file, __verify_alg_key(pub_key_file, out, alg); - jwt_free_str(out); + free(out); } START_TEST(test_jwt_encode_ps256) diff --git a/tests/jwt_tests.h b/tests/jwt_tests.h index 5b9ecb64..9570b50c 100644 --- a/tests/jwt_tests.h +++ b/tests/jwt_tests.h @@ -242,22 +242,27 @@ static void __verify_jwk(const char *jwt_str, const jwk_item_t *item) __attribute__((unused)) static void __test_alg_key(const jwt_alg_t alg, const char *file, const char *pub) { + jwt_value_t jval; jwt_auto_t *jwt = NULL; int ret = 0; char *out; CREATE_JWT(jwt, file, alg); - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", TS_CONST); + jwt_set_ADD_INT(&jval, "iat", TS_CONST); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); out = jwt_encode_str(jwt); @@ -267,7 +272,7 @@ static void __test_alg_key(const jwt_alg_t alg, const char *file, const char *pu __verify_jwt(out, alg, pub); - jwt_free_str(out); + free(out); /* auto free */ } @@ -305,21 +310,26 @@ static void __compare_alg_key(const char *key_file, const char *jwt_str, const jwt_alg_t alg) { jwt_test_auto_t *jwt = NULL; + jwt_value_t jval; int ret = 0; char *out; CREATE_JWT(jwt, key_file, alg); - ret = jwt_add_grant(jwt, "iss", "files.maclara-llc.com"); + jwt_set_ADD_STR(&jval, "iss", "files.maclara-llc.com"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "sub", "user0"); + jwt_set_ADD_STR(&jval, "sub", "user0"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant(jwt, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + jwt_set_ADD_STR(&jval, "ref", "XXXX-YYYY-ZZZZ-AAAA-CCCC"); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); - ret = jwt_add_grant_int(jwt, "iat", TS_CONST); + jwt_set_ADD_INT(&jval, "iat", TS_CONST); + ret = jwt_grant_add(jwt, &jval); ck_assert_int_eq(ret, 0); out = jwt_encode_str(jwt); @@ -327,7 +337,7 @@ static void __compare_alg_key(const char *key_file, const char *jwt_str, ck_assert_str_eq(out, jwt_str); - jwt_free_str(out); + free(out); } #endif /* JWT_TESTS_H */ diff --git a/tests/jwt_validate.c b/tests/jwt_validate.c index 082b9307..b5feb010 100644 --- a/tests/jwt_validate.c +++ b/tests/jwt_validate.c @@ -16,12 +16,23 @@ static const time_t expires = TS_CONST + 600L; static void __setup_jwt() { + jwt_value_t jval; + EMPTY_JWT(jwt); - jwt_add_grant(jwt, "iss", "test"); - jwt_add_grant(jwt, "sub", "user0"); - jwt_add_grants_json(jwt, "{\"aud\": [\"svc1\",\"svc2\"]}"); - jwt_add_grant_int(jwt, "iat", iat); - jwt_add_grant_bool(jwt, "admin", 1); + jwt_set_ADD_STR(&jval, "iss", "test"); + jwt_grant_add(jwt, &jval); + + jwt_set_ADD_STR(&jval, "sub", "user0"); + jwt_grant_add(jwt, &jval); + + jwt_set_ADD_JSON(&jval, NULL, "{\"aud\": [\"svc1\",\"svc2\"]}"); + jwt_grant_add(jwt, &jval); + + jwt_set_ADD_INT(&jval, "iat", iat); + jwt_grant_add(jwt, &jval); + + jwt_set_ADD_BOOL(&jval, "admin", 1); + jwt_grant_add(jwt, &jval); } static void __teardown_jwt() @@ -38,7 +49,7 @@ static void __teardown_jwt() ck_assert_int_eq(__e, __r); \ __s = jwt_exception_str(__r); \ ck_assert_str_eq(__str, __s); \ - jwt_free_str(__s); \ + free(__s); \ } while(0); START_TEST(test_jwt_validate_errno) @@ -62,7 +73,7 @@ START_TEST(test_jwt_validate_errno) ck_assert_int_eq(ret, JWT_VALIDATION_ERROR); exc = jwt_exception_str(ret); ck_assert_str_eq(exc, "general failures"); - jwt_free_str(exc); + free(exc); /* Validate fails with NULL jwt_valid */ @@ -360,10 +371,12 @@ START_TEST(test_jwt_valid_not_before) { jwt_valid_t *jwt_valid = NULL; unsigned int ret = 0; + jwt_value_t jval; SET_OPS(); - jwt_add_grant_int(jwt, "nbf", not_before); + jwt_set_ADD_INT(&jval, "nbf", not_before); + jwt_grant_add(jwt, &jval); ret = jwt_valid_new(&jwt_valid, JWT_ALG_NONE); ck_assert_int_eq(ret, 0); @@ -415,10 +428,12 @@ START_TEST(test_jwt_valid_not_before_leeway) { jwt_valid_t *jwt_valid = NULL; unsigned int ret = 0; + jwt_value_t jval; SET_OPS(); - jwt_add_grant_int(jwt, "nbf", not_before); + jwt_set_ADD_INT(&jval, "nbf", not_before); + jwt_grant_add(jwt, &jval); ret = jwt_valid_new(&jwt_valid, JWT_ALG_NONE); ck_assert_int_eq(ret, 0); @@ -448,10 +463,12 @@ START_TEST(test_jwt_valid_expires) { jwt_valid_t *jwt_valid = NULL; unsigned int ret = 0; + jwt_value_t jval; SET_OPS(); - jwt_add_grant_int(jwt, "exp", expires); + jwt_set_ADD_INT(&jval, "exp", expires); + jwt_grant_add(jwt, &jval); ret = jwt_valid_new(&jwt_valid, JWT_ALG_NONE); ck_assert_int_eq(ret, 0); @@ -503,10 +520,12 @@ START_TEST(test_jwt_valid_expires_leeway) { jwt_valid_t *jwt_valid = NULL; unsigned int ret = 0; + jwt_value_t jval; SET_OPS(); - jwt_add_grant_int(jwt, "exp", expires); + jwt_set_ADD_INT(&jval, "exp", expires); + jwt_grant_add(jwt, &jval); ret = jwt_valid_new(&jwt_valid, JWT_ALG_NONE); ck_assert_int_eq(ret, 0); @@ -578,13 +597,13 @@ START_TEST(test_jwt_valid_headers) __VAL_EQ(jwt_valid, JWT_VALIDATION_SUCCESS, "success"); /* JWT is valid when checking hdr and aud matches */ - jwt_set_ADD_JSON(&jval, "{\"aud\": [\"svc1\",\"svc2\"]}"); + jwt_set_ADD_JSON(&jval, NULL, "{\"aud\": [\"svc1\",\"svc2\"]}"); jwt_header_add(jwt, &jval); __VAL_EQ(jwt_valid, JWT_VALIDATION_SUCCESS, "success"); /* JWT is invalid when checking hdr and aud does not match */ jwt_header_del(jwt, "aud"); - jwt_set_ADD_JSON(&jval, "{\"aud\": [\"svc1\",\"svc2\",\"svc3\"]}"); + jwt_set_ADD_JSON(&jval, NULL, "{\"aud\": [\"svc1\",\"svc2\",\"svc3\"]}"); jwt_header_add(jwt, &jval); __VAL_EQ(jwt_valid, JWT_VALIDATION_AUD_MISMATCH, "audience mismatch"); @@ -628,13 +647,13 @@ START_TEST(test_jwt_valid_grants_json) ck_assert_ptr_nonnull(json_val); ck_assert_str_eq(json_val, "[\"foo\",\"bar\"]"); - jwt_free_str(json_val); + free(json_val); json_val = jwt_valid_get_grants_json(jwt_valid, NULL); ck_assert_ptr_nonnull(json_val); ck_assert_str_eq(json_val, json); - jwt_free_str(json_val); + free(json_val); jwt_valid_free(jwt_valid); }