Skip to content

Commit

Permalink
codecov: Covering more corner cases
Browse files Browse the repository at this point in the history
Signed-off-by: Ben Collins <[email protected]>
  • Loading branch information
benmcollins committed Feb 13, 2025
1 parent 4278a6e commit ec04179
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 20 deletions.
4 changes: 1 addition & 3 deletions libjwt/jwt-builder.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,11 @@ 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;
Expand Down Expand Up @@ -319,7 +317,7 @@ char *jwt_builder_generate(jwt_builder_t *__cmd)
jwt->key = config.key;

if (jwt_head_setup(jwt))
return NULL;
return NULL; // LCOV_EXCL_LINE

out = jwt_encode_str(jwt);
jwt_copy_error(__cmd, jwt);
Expand Down
10 changes: 0 additions & 10 deletions libjwt/jwt-checker.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,7 @@ 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;
Expand Down
8 changes: 5 additions & 3 deletions libjwt/jwt-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,17 +175,19 @@ static jwt_value_error_t __run_it(jwt_common_t *__cmd, _setget_type_t type,
jwt_value_t *value, __doer_t doer)
{
json_t *which = NULL;

#ifdef JWT_BUILDER
if (!__cmd || !value) {
if (value)
return value->error = JWT_VALUE_ERR_INVALID;
return JWT_VALUE_ERR_INVALID;
}

#endif
switch (type) {
#ifdef JWT_BUILDER
case __HEADER:
which = __cmd->c.headers;
break;
#endif
case __CLAIM:
which = __cmd->c.payload;
break;
Expand Down Expand Up @@ -454,7 +456,7 @@ char *FUNC(generate)(jwt_common_t *__cmd)
jwt->key = config.key;

if (jwt_head_setup(jwt))
return NULL;
return NULL; // LCOV_EXCL_LINE

out = jwt_encode_str(jwt);
jwt_copy_error(__cmd, jwt);
Expand Down
4 changes: 2 additions & 2 deletions libjwt/jwt-setget.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,12 @@ static jwt_value_error_t jwt_set_json(json_t *which, jwt_value_t *jval)
ret = json_object_update_missing(which, json_val);

if (ret)
jval->error = JWT_VALUE_ERR_INVALID;
jval->error = JWT_VALUE_ERR_INVALID; // LCOV_EXCL_LINE
} else {
/* Add object at name */
if (!jwt_obj_check(which, jval)) {
if (json_object_set_new(which, jval->name, json_val))
jval->error = JWT_VALUE_ERR_INVALID;
jval->error = JWT_VALUE_ERR_INVALID; // LCOV_EXCL_LINE
}
}

Expand Down
4 changes: 2 additions & 2 deletions libjwt/jwt-verify.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ static jwt_claims_t __verify_claims(jwt_t *jwt)
failed |= JWT_CLAIM_EXP;
}
} else if (err != JWT_VALUE_ERR_NOEXIST)
failed |= JWT_CLAIM_EXP; // LVOC_EXCL_LINE
failed |= JWT_CLAIM_EXP; // LCOV_EXCL_LINE
}

/* not valid before now */
Expand All @@ -187,7 +187,7 @@ static jwt_claims_t __verify_claims(jwt_t *jwt)
failed |= JWT_CLAIM_NBF;
}
} else if (err != JWT_VALUE_ERR_NOEXIST)
failed |= JWT_CLAIM_NBF; // LVOC_EXCL_LINE
failed |= JWT_CLAIM_NBF; // LCOV_EXCL_LINE
}

/* issuer doesn't match */
Expand Down
63 changes: 63 additions & 0 deletions tests/jwt_builder.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ START_TEST(gen_wcb)
const char exp[] = "eyJhbGciOiJub25lIn0.eyJleHAiOjE0NzU5ODEwMjV9.";
jwt_builder_auto_t *builder = NULL;
char_auto *out = NULL;
const char *ctx;
int ret;

SET_OPS();
Expand All @@ -78,7 +79,61 @@ START_TEST(gen_wcb)
ck_assert_ptr_nonnull(out);
ck_assert_str_eq(out, exp);

ctx = jwt_builder_getctx(builder);
ck_assert_str_eq(ctx, "testing");
}
END_TEST

static int __set_alg_cb(jwt_t *jwt, jwt_config_t *config)
{
jwt_value_t jval;
int ret;

ck_assert_ptr_nonnull(jwt);
ck_assert_ptr_nonnull(config);

/* Clear the whole header */
ret = jwt_header_del(jwt, NULL);
ck_assert_int_eq(ret, JWT_VALUE_ERR_NONE);

/* This will get overwritten */
jwt_set_SET_INT(&jval, "alg", JWT_ALG_HS256);
jwt_header_set(jwt, &jval);

/* This wont */
jwt_set_SET_STR(&jval, "typ", "NOTJWT");
jwt_header_set(jwt, &jval);

return 0;
}

START_TEST(set_alg)
{
jwt_builder_auto_t *builder = NULL;
const char *exp = "eyJhbGciOiJIUzI1NiIsInR5cCI6Ik5PVEpXVCJ9.e30.GsBNaD"
"rcrck5dXU9za1MrrOxpz8KQXjq-JHmeCyFhAA";
char *out = NULL;
int ret;

SET_OPS();

builder = jwt_builder_new();
ck_assert_ptr_nonnull(builder);
ck_assert_int_eq(jwt_builder_error(builder), 0);

ret = jwt_builder_enable_iat(builder, 0);
ck_assert_int_eq(ret, 1);

ret = jwt_builder_setcb(builder, __set_alg_cb, NULL);
ck_assert_int_eq(ret, 0);

read_json("oct_key_256.json");
ret = jwt_builder_setkey(builder, JWT_ALG_HS256, g_item);
ck_assert_int_eq(ret, 0);

out = jwt_builder_generate(builder);
ck_assert_ptr_nonnull(out);
ck_assert_str_eq(out, exp);
}
END_TEST

Expand Down Expand Up @@ -274,6 +329,13 @@ START_TEST(null_handling)
ck_assert_ptr_null(jwt_builder_getctx(NULL));

ck_assert_int_eq(jwt_builder_claim_del(NULL, NULL), JWT_VALUE_ERR_INVALID);

ck_assert_int_eq(jwt_builder_claim_get(NULL, &jval), JWT_VALUE_ERR_INVALID);
ck_assert_int_eq(jwt_builder_claim_get(builder, NULL), JWT_VALUE_ERR_INVALID);

ck_assert_int_eq(jwt_builder_time_offset(NULL, JWT_CLAIM_NBF, 0), 1);
ck_assert_int_eq(jwt_builder_time_offset(builder, JWT_CLAIM_SUB, 0), 1);
ck_assert_int_eq(jwt_builder_time_offset(builder, JWT_CLAIM_NBF, 0), 0);
}
END_TEST

Expand Down Expand Up @@ -772,6 +834,7 @@ static Suite *libjwt_suite(const char *title)
tcase_add_loop_test(tc_core, gen_stress, 0, i);
tcase_add_loop_test(tc_core, gen_wcb, 0, i);
tcase_add_loop_test(tc_core, gen_es384_pub, 0, i);
tcase_add_loop_test(tc_core, set_alg, 0, i);
suite_add_tcase(s, tc_core);

tc_core = tcase_create("Error Handling");
Expand Down
143 changes: 143 additions & 0 deletions tests/jwt_checker.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,26 @@ START_TEST(verify)
}
END_TEST

START_TEST(alg_none_with_sig)
{
const char token[] = "eyJhbGciOiJub25lIn0.eyJpc3MiOiJka"
"XNrLnN3aXNzZGlzay5jb20ifQ.XNrLnN3aXNzZGlzay5jb20ifQ";
jwt_checker_auto_t *checker = NULL;
int ret;

SET_OPS();

checker = jwt_checker_new();
ck_assert_ptr_nonnull(checker);
ck_assert_int_eq(jwt_checker_error(checker), 0);

ret = jwt_checker_verify(checker, token);
ck_assert_int_ne(ret, 0);
ck_assert_str_eq(jwt_checker_error_msg(checker),
"JWT has signature block, but no alg set");
}
END_TEST

START_TEST(bad_alg)
{
const char token[] = "eyJhbGciOiJmb28ifQo.e30K.";
Expand Down Expand Up @@ -306,6 +326,26 @@ START_TEST(null_handling)
ret = jwt_checker_time_leeway(NULL, JWT_CLAIM_IAT, 0);
ck_assert_int_ne(ret, 0);
ret = jwt_checker_time_leeway(checker, JWT_CLAIM_IAT, 0);

/* Some alg mismatches */
read_json("eddsa_key_ed25519_pub.json");
ret = jwt_checker_setkey(checker, JWT_ALG_NONE, g_item);
ck_assert_int_ne(ret, 0);

jwt_checker_error_clear(checker);

read_json("oct_key_256.json");
ret = jwt_checker_setkey(checker, JWT_ALG_ES256, g_item);
ck_assert_int_ne(ret, 0);

/* Callbacks */
ck_assert_int_ne(jwt_checker_setcb(NULL, NULL, NULL), 0);
ck_assert_int_ne(jwt_checker_setcb(checker, NULL, "foo"), 0);
ck_assert_ptr_null(jwt_checker_getctx(NULL));

/* Some claims stuff */
ck_assert_ptr_null(jwt_checker_claim_get(NULL, JWT_CLAIM_SUB));
ck_assert_ptr_null(jwt_checker_claim_get(checker, JWT_CLAIM_IAT));
}
END_TEST

Expand Down Expand Up @@ -333,6 +373,104 @@ START_TEST(verify_hs256)
}
END_TEST

START_TEST(hs256_no_key)
{
jwt_checker_auto_t *checker = NULL;
const char token[] = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.CM4dD95Nj"
"0vSfMGtDas432AUW1HAo7feCiAbt5Yjuds";
int ret;

SET_OPS();

checker = jwt_checker_new();
ck_assert_ptr_nonnull(checker);
ck_assert_int_eq(jwt_checker_error(checker), 0);

ret = jwt_checker_verify(checker, token);
ck_assert_int_ne(ret, 0);
ck_assert_str_eq(jwt_checker_error_msg(checker),
"JWT has signature, but no key was given");
}
END_TEST

START_TEST(hs256_wrong_key)
{
jwt_checker_auto_t *checker = NULL;
const char token[] = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.CM4dD95Nj"
"0vSfMGtDas432AUW1HAo7feCiAbt5Yjuds";
int ret;

SET_OPS();

checker = jwt_checker_new();
ck_assert_ptr_nonnull(checker);
ck_assert_int_eq(jwt_checker_error(checker), 0);

read_json("ec_key_secp384r1_pub.json");
ret = jwt_checker_setkey(checker, JWT_ALG_NONE, g_item);
ck_assert_int_eq(ret, 0);

ret = jwt_checker_verify(checker, token);
ck_assert_int_ne(ret, 0);
ck_assert_str_eq(jwt_checker_error_msg(checker),
"Key alg does not match JWT");

free_key();
}
END_TEST

START_TEST(hs256_token_failed)
{
jwt_checker_auto_t *checker = NULL;
const char token[] = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.CM4dD95Nj"
"0vSfMGtDas432AUW1HAo7feCiAbt5Yjuds";
int ret;

SET_OPS();

checker = jwt_checker_new();
ck_assert_ptr_nonnull(checker);
ck_assert_int_eq(jwt_checker_error(checker), 0);

read_json("eddsa_key_ed25519_pub.json");
ret = jwt_checker_setkey(checker, JWT_ALG_HS256, g_item);
ck_assert_int_eq(ret, 0);

ret = jwt_checker_verify(checker, token);
ck_assert_int_ne(ret, 0);
ck_assert_str_eq(jwt_checker_error_msg(checker),
"Token failed verification");

free_key();
}
END_TEST

START_TEST(hs256_wrong_key_alg)
{
jwt_checker_auto_t *checker = NULL;
const char token[] = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.CM4dD95Nj"
"0vSfMGtDas432AUW1HAo7feCiAbt5Yjuds";
int ret;

SET_OPS();

checker = jwt_checker_new();
ck_assert_ptr_nonnull(checker);
ck_assert_int_eq(jwt_checker_error(checker), 0);

read_json("eddsa_key_ed25519_pub.json");
ret = jwt_checker_setkey(checker, JWT_ALG_EDDSA, g_item);
ck_assert_int_eq(ret, 0);

ret = jwt_checker_verify(checker, token);
ck_assert_int_ne(ret, 0);
ck_assert_str_eq(jwt_checker_error_msg(checker),
"Config alg does not match JWT");

free_key();
}
END_TEST

START_TEST(verify_rsapss384)
{
jwt_checker_auto_t *checker = NULL;
Expand Down Expand Up @@ -665,6 +803,11 @@ static Suite *libjwt_suite(const char *title)
tcase_add_loop_test(tc_core, no_alg, 0, i);
tcase_add_loop_test(tc_core, no_first_dot, 0, i);
tcase_add_loop_test(tc_core, no_second_dot, 0, i);
tcase_add_loop_test(tc_core, alg_none_with_sig, 0, i);
tcase_add_loop_test(tc_core, hs256_no_key, 0, i);
tcase_add_loop_test(tc_core, hs256_wrong_key, 0, i);
tcase_add_loop_test(tc_core, hs256_wrong_key_alg, 0, i);
tcase_add_loop_test(tc_core, hs256_token_failed, 0, i);
suite_add_tcase(s, tc_core);

tc_core = tcase_create("HS256 Key Verify");
Expand Down

0 comments on commit ec04179

Please sign in to comment.