Skip to content

Commit 0d15d75

Browse files
committed
jwks: Implement jwks_error_any(), jwks_item_free_bad(), and jwks_item_count()
Closes #209 Signed-off-by: Ben Collins <bcollins@libjwt.io>
1 parent b494699 commit 0d15d75

File tree

3 files changed

+102
-17
lines changed

3 files changed

+102
-17
lines changed

include/jwt.h

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,10 +1296,10 @@ int jwks_error(const jwk_set_t *jwk_set);
12961296
* the jwk_item_t in the set.
12971297
*
12981298
* @param jwk_set An existing jwk_set_t
1299-
* @return 0 if no error exists, 1 if any exists.
1299+
* @return 0 if no error exists, or the number of errors in the set
13001300
*/
13011301
JWT_EXPORT
1302-
int jwks_error_any(jwk_set_t *jwk_set);
1302+
int jwks_error_any(const jwk_set_t *jwk_set);
13031303

13041304
/**
13051305
* @brief Retrieve an error message from a jwk_set
@@ -1504,25 +1504,46 @@ JWT_EXPORT
15041504
int jwks_item_key_bits(const jwk_item_t *item);
15051505

15061506
/**
1507-
* Free all memory associated with the nth jwk_item_t in a jwk_set
1507+
* @brief Free remove and free the nth jwk_item_t in a jwk_set
15081508
*
1509-
* @param jwk_set A JWKS object
1509+
* @param jwk_set Pointer to a JWKS object
15101510
* @param index the position of the item in the index
15111511
* @return 0 if no item was was deleted (found), 1 if it was
15121512
*/
15131513
JWT_EXPORT
15141514
int jwks_item_free(jwk_set_t *jwk_set, size_t index);
15151515

15161516
/**
1517-
* Free all memory associated with all @ref jwk_item_t in a @ref jwk_set_t.
1517+
* @brief Remove and free all jwk_item_t in a jwk_set_t
1518+
*
15181519
* The jwk_set_t becomes an empty set.
15191520
*
1520-
* @param jwk_set A JWKS object
1521+
* @param jwk_set Pointer to a JWKS object
15211522
* @return The number of items deleted
15221523
*/
15231524
JWT_EXPORT
15241525
int jwks_item_free_all(jwk_set_t *jwk_set);
15251526

1527+
/**
1528+
* @brief Free all keys marked with an error in a jwk_set_t
1529+
*
1530+
* The jwk_set_t becomes an empty set.
1531+
*
1532+
* @param jwk_set Pointer to a JWKS object
1533+
* @return The number of items with an error that were deleted
1534+
*/
1535+
JWT_EXPORT
1536+
int jwks_item_free_bad(jwk_set_t *jwk_set);
1537+
1538+
/**
1539+
* @brief Return the number of keys in a jwk_set_t
1540+
*
1541+
* @param jwk_set Pointer to a JWKS object
1542+
* @return The number of items in the set
1543+
*/
1544+
JWT_EXPORT
1545+
size_t jwks_item_count(const jwk_set_t *jwk_set);
1546+
15261547
/**
15271548
* @}
15281549
* @noop jwks_item_grp

libjwt/jwks.c

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,19 @@ const jwk_item_t *jwks_item_get(const jwk_set_t *jwk_set, size_t index)
207207
return NULL;
208208
}
209209

210+
int jwks_error_any(const jwk_set_t *jwk_set)
211+
{
212+
jwk_item_t *item = NULL;
213+
int count = jwk_set->error;
214+
215+
list_for_each_entry(item, &jwk_set->head, node) {
216+
if (item->error)
217+
count++;
218+
}
219+
220+
return count;
221+
}
222+
210223
int jwks_item_is_private(const jwk_item_t *item)
211224
{
212225
return item->is_private_key ? 1 : 0;
@@ -297,6 +310,22 @@ static int jwks_item_add(jwk_set_t *jwk_set, jwk_item_t *item)
297310
return 0;
298311
}
299312

313+
static void __item_free(jwk_item_t *todel)
314+
{
315+
if (todel->provider == JWT_CRYPTO_OPS_ANY)
316+
jwt_freemem(todel->oct.key);
317+
else
318+
jwt_ops->process_item_free(todel);
319+
320+
/* A few non-crypto specific things. */
321+
jwt_freemem(todel->kid);
322+
json_decrefp(&todel->json);
323+
list_del(&todel->node);
324+
325+
/* Free the container and the item itself. */
326+
jwt_freemem(todel);
327+
}
328+
300329
int jwks_item_free(jwk_set_t *jwk_set, const size_t index)
301330
{
302331
jwk_item_t *item = NULL, *todel = NULL;
@@ -316,20 +345,35 @@ int jwks_item_free(jwk_set_t *jwk_set, const size_t index)
316345
if (todel == NULL)
317346
return 0;
318347

319-
if (todel->provider == JWT_CRYPTO_OPS_ANY)
320-
jwt_freemem(todel->oct.key);
321-
else
322-
jwt_ops->process_item_free(todel);
348+
__item_free(todel);
323349

324-
/* A few non-crypto specific things. */
325-
jwt_freemem(todel->kid);
326-
json_decrefp(&todel->json);
327-
list_del(&todel->node);
350+
return 1;
351+
}
328352

329-
/* Free the container and the item itself. */
330-
jwt_freemem(todel);
353+
size_t jwks_item_count(const jwk_set_t *jwk_set)
354+
{
355+
size_t count = 0;
356+
jwk_item_t *item = NULL;
331357

332-
return 1;
358+
list_for_each_entry(item, &jwk_set->head, node)
359+
count++;
360+
361+
return count;
362+
}
363+
364+
int jwks_item_free_bad(jwk_set_t *jwk_set)
365+
{
366+
jwk_item_t *item, *pos;
367+
int count = 0;
368+
369+
list_for_each_entry_safe(item, pos, &jwk_set->head, node) {
370+
if (!item->error)
371+
continue;
372+
__item_free(item);
373+
count++;
374+
}
375+
376+
return count;
333377
}
334378

335379
int jwks_item_free_all(jwk_set_t *jwk_set)

tests/jwt_jwks.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,21 @@ START_TEST(test_jwks_keyring_load)
5353
}
5454
ck_assert_int_eq(fails, 0);
5555

56+
ck_assert_int_eq(i, 27);
57+
i = jwks_item_count(g_jwk_set);
5658
ck_assert_int_eq(i, 27);
5759

5860
ck_assert(jwks_item_free(g_jwk_set, 3));
5961

62+
i = jwks_item_count(g_jwk_set);
63+
ck_assert_int_eq(i, 26);
64+
65+
i = jwks_item_free_bad(g_jwk_set);
66+
ck_assert_int_eq(i, 0);
67+
68+
i = jwks_item_count(g_jwk_set);
69+
ck_assert_int_eq(i, 26);
70+
6071
free_key();
6172
}
6273
END_TEST
@@ -72,6 +83,9 @@ START_TEST(test_jwks_keyring_all_bad)
7283
jwk_set = jwks_create_fromfile(KEYDIR "/bad_keys.json");
7384
ck_assert_ptr_nonnull(jwk_set);
7485

86+
i = jwks_error_any(jwk_set);
87+
ck_assert_int_eq(i, 14);
88+
7589
for (i = 0; (item = jwks_item_get(jwk_set, i)); i++) {
7690
if (!jwks_item_error(item)) {
7791
fprintf(stderr, "KID: %s\n",
@@ -81,6 +95,12 @@ START_TEST(test_jwks_keyring_all_bad)
8195
}
8296

8397
ck_assert_int_eq(i, 14);
98+
99+
i = jwks_item_free_bad(jwk_set);
100+
ck_assert_int_eq(i, 14);
101+
102+
i = jwks_item_count(jwk_set);
103+
ck_assert_int_eq(i, 0);
84104
}
85105
END_TEST
86106

0 commit comments

Comments
 (0)