]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Fix matching of last key of a pkcs#11 token
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Mon, 21 Mar 2022 02:45:11 +0000 (13:45 +1100)
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 30 Mar 2022 22:13:47 +0000 (09:13 +1100)
Retrieving the cert for the last key of a token fails due to an
off-by-one bug in find_privkeys():

In the loop that iterates the keys, "current" contains the index
of the "next" key slot, which is also the active "count" of populated
slots in the output struct find_pkey_list_st.

The current statement:

list->key_ids_size = current - 1;

Means we return a "key_ids_size" of the current count minus one, ie 0
for 1 key etc... However, this isn't what the callers expect, for example:

find_multi_objs_cb() does:

ret = find_privkeys(sinfo, tinfo, &plist);
if (ret < 0) {
gnutls_assert();
return ret;
}

if (plist.key_ids_size == 0) {
gnutls_assert();
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
}

So a slot with a single key will fail when trying to find a certificate

Subsequent uses of "plist" in that function also show that it's expected
to contain the real slot count:

for (i = 0; i < plist.key_ids_size; i++) {

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
lib/pkcs11.c

index ba8ac0c37527489868cc1a32ed934407a37e13ec..a822b1b497c15f502f2ce4e36c9c66455fc2c8ab 100644 (file)
@@ -3105,7 +3105,7 @@ find_privkeys(struct pkcs11_session_info *sinfo,
 
        pkcs11_find_objects_final(sinfo);
 
-       list->key_ids_size = current - 1;
+       list->key_ids_size = current;
 
        return 0;
 }