jwks_find_bykid: New function to find keys by "kid"
Signed-off-by: Ben Collins <bcollins@libjwt.io>
This commit is contained in:
parent
99cd27d258
commit
62a6f564eb
7 changed files with 102 additions and 8 deletions
|
@ -1381,6 +1381,19 @@ static inline void jwks_freep(jwk_set_t **jwks) {
|
|||
JWT_EXPORT
|
||||
const jwk_item_t *jwks_item_get(const jwk_set_t *jwk_set, size_t index);
|
||||
|
||||
/**
|
||||
* @brief Find a jwk_item_t with a specific kid (Key ID)
|
||||
*
|
||||
* LibJWT does not ensure that kid's are unique in a given keyring, so care
|
||||
* must be taken. This will return the first match.
|
||||
*
|
||||
* @param jwk_set An existing jwk_set_t
|
||||
* @param kid String representing a ``kid`` to find
|
||||
* @return A jwk_item_t object or NULL if none found
|
||||
*/
|
||||
JWT_EXPORT
|
||||
jwk_item_t *jwks_find_bykid(jwk_set_t *jwk_set, const char *kid);
|
||||
|
||||
/**
|
||||
* @brief Whether this key is private (or public)
|
||||
*
|
||||
|
|
|
@ -310,6 +310,19 @@ static int jwks_item_add(jwk_set_t *jwk_set, jwk_item_t *item)
|
|||
return 0;
|
||||
}
|
||||
|
||||
jwk_item_t *jwks_find_bykid(jwk_set_t *jwk_set, const char *kid)
|
||||
{
|
||||
jwk_item_t *item = NULL;
|
||||
|
||||
list_for_each_entry(item, &jwk_set->head, node) {
|
||||
if (item->kid == NULL || strcmp(item->kid, kid))
|
||||
continue;
|
||||
return item;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void __item_free(jwk_item_t *todel)
|
||||
{
|
||||
if (todel->provider == JWT_CRYPTO_OPS_ANY)
|
||||
|
|
|
@ -471,8 +471,7 @@ jwt_t *jwt_verify_sig(jwt_t *jwt, const char *head, unsigned int head_len,
|
|||
// LCOV_EXCL_START
|
||||
default:
|
||||
jwt_write_error(jwt, "Unknown algorigthm");
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
return jwt;
|
||||
}
|
||||
|
|
|
@ -329,7 +329,7 @@ static int mbedtls_verify_sha_pem(jwt_t *jwt, const char *head,
|
|||
/* Verify ECDSA signature */
|
||||
if (mbedtls_ecdsa_verify(&ecdsa.private_grp, hash,
|
||||
mbedtls_md_get_size(md_info), &ecdsa.private_Q, &r, &s))
|
||||
VERIFY_ERROR("ECDSA signature verification failed"); // LCOV_EXCL_LINE
|
||||
VERIFY_ERROR("Failed to verify signature"); // LCOV_EXCL_LINE
|
||||
|
||||
/* Free ECDSA resources */
|
||||
mbedtls_mpi_free(&r);
|
||||
|
@ -343,13 +343,13 @@ static int mbedtls_verify_sha_pem(jwt_t *jwt, const char *head,
|
|||
mbedtls_md_get_type(md_info),
|
||||
mbedtls_md_get_size(md_info),
|
||||
hash, sig))
|
||||
VERIFY_ERROR("RSASSA-PSS verify failed"); // LCOV_EXCL_LINE
|
||||
VERIFY_ERROR("Failed to verify signature"); // LCOV_EXCL_LINE
|
||||
} else {
|
||||
if (mbedtls_rsa_pkcs1_verify(mbedtls_pk_rsa(pk),
|
||||
mbedtls_md_get_type(md_info),
|
||||
mbedtls_md_get_size(md_info),
|
||||
hash, sig))
|
||||
VERIFY_ERROR("RSA verify failed"); // LCOV_EXCL_LINE
|
||||
VERIFY_ERROR("Failed to verify signature"); // LCOV_EXCL_LINE
|
||||
}
|
||||
} else {
|
||||
VERIFY_ERROR("Unexpected key typ"); // LCOV_EXCL_LINE
|
||||
|
|
|
@ -411,7 +411,7 @@ static int openssl_verify_sha_pem(jwt_t *jwt, const char *head,
|
|||
/* One-shot update and verify */
|
||||
if (EVP_DigestVerify(mdctx, sig, slen, (const unsigned char *)head,
|
||||
head_len) != 1)
|
||||
VERIFY_ERROR("Signature failed validation");
|
||||
VERIFY_ERROR("Failed to verify signature");
|
||||
|
||||
jwt_verify_sha_pem_done:
|
||||
BIO_free(bufkey);
|
||||
|
|
|
@ -774,8 +774,8 @@ START_TEST(verify_ps256_nosig)
|
|||
|
||||
read_json("rsa_pss_key_2048.json");
|
||||
|
||||
ret = jwt_checker_setkey(NULL, JWT_ALG_PS256, g_item);
|
||||
ck_assert_int_ne(ret, 0);
|
||||
ret = jwt_checker_setkey(checker, JWT_ALG_PS256, g_item);
|
||||
ck_assert_int_eq(ret, 0);
|
||||
|
||||
ret = jwt_checker_verify(checker, token);
|
||||
ck_assert_int_ne(ret, 0);
|
||||
|
@ -786,6 +786,67 @@ START_TEST(verify_ps256_nosig)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(verify_ps256_bad_b64_sig)
|
||||
{
|
||||
jwt_checker_auto_t *checker = NULL;
|
||||
const char token[] = "eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI"
|
||||
"6ZmFsc2UsImlhdCI6MTczNjY5NDU5NCwiaXNzIjoiaHR0cHM6Ly9zd2lzc2Rp"
|
||||
"c2suY29tIiwidXNlciI6ImJlbmNvbGxpbnMifQ.eyJhbGciOiJQUzI1N*IsIn"
|
||||
"R5cCI6I!pXVCJ9";
|
||||
int ret;
|
||||
|
||||
SET_OPS();
|
||||
|
||||
checker = jwt_checker_new();
|
||||
ck_assert_ptr_nonnull(checker);
|
||||
ck_assert_int_eq(jwt_checker_error(checker), 0);
|
||||
|
||||
read_json("rsa_pss_key_2048.json");
|
||||
|
||||
ret = jwt_checker_setkey(checker, JWT_ALG_PS256, 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),
|
||||
"Error decoding signature");
|
||||
|
||||
free_key();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(verify_ps256_bad_sig)
|
||||
{
|
||||
jwt_checker_auto_t *checker = NULL;
|
||||
const char token[] = "eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI"
|
||||
"6ZmFsc2UsImlhdCI6MTczNjY5NDU5NCwiaXNzIjoiaHR0cHM6Ly9zd2lzc2Rp"
|
||||
"c2suY29tIiwidXNlciI6ImJlbmNvbGxpbnMifQ.eyJhbGciOiJQUzI1NiIsIn"
|
||||
"R5cCI6IkpXVCJ9";
|
||||
const char *err;
|
||||
int ret;
|
||||
|
||||
SET_OPS();
|
||||
|
||||
checker = jwt_checker_new();
|
||||
ck_assert_ptr_nonnull(checker);
|
||||
ck_assert_int_eq(jwt_checker_error(checker), 0);
|
||||
|
||||
read_json("rsa_pss_key_2048.json");
|
||||
|
||||
ret = jwt_checker_setkey(checker, JWT_ALG_PS256, g_item);
|
||||
ck_assert_int_eq(ret, 0);
|
||||
|
||||
ret = jwt_checker_verify(checker, token);
|
||||
ck_assert_int_ne(ret, 0);
|
||||
|
||||
err = jwt_checker_error_msg(checker);
|
||||
ck_assert_ptr_nonnull(err);
|
||||
ck_assert_ptr_nonnull(strstr(err, "Failed to verify signature"));
|
||||
|
||||
free_key();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static Suite *libjwt_suite(const char *title)
|
||||
{
|
||||
Suite *s;
|
||||
|
@ -836,6 +897,8 @@ static Suite *libjwt_suite(const char *title)
|
|||
|
||||
tc_core = tcase_create("Corner cases");
|
||||
tcase_add_loop_test(tc_core, verify_ps256_nosig, 0, i);
|
||||
tcase_add_loop_test(tc_core, verify_ps256_bad_b64_sig, 0, i);
|
||||
tcase_add_loop_test(tc_core, verify_ps256_bad_sig, 0, i);
|
||||
suite_add_tcase(s, tc_core);
|
||||
|
||||
return s;
|
||||
|
|
|
@ -53,6 +53,12 @@ START_TEST(test_jwks_keyring_load)
|
|||
}
|
||||
ck_assert_int_eq(fails, 0);
|
||||
|
||||
item = jwks_find_bykid(g_jwk_set, "SDSDS");
|
||||
ck_assert_ptr_null(item);
|
||||
|
||||
item = jwks_find_bykid(g_jwk_set, "354912a0-b90a-435e-886a-1629f7b2665e");
|
||||
ck_assert_ptr_nonnull(item);
|
||||
|
||||
ck_assert_int_eq(i, 27);
|
||||
i = jwks_item_count(g_jwk_set);
|
||||
ck_assert_int_eq(i, 27);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue