Владение памятью в PKCS #11 C FindObjects где ulMaxObjectCount!= 1

авторы PKCS #11 v2.40 используйте общий шаблон, когда API возвращает список элементов переменной длины. В APIs, таких как C_GetSlotList и C_GetMechanismList, ожидается, что приложение дважды вызовет API. В первом вызове указатель на CK_ULONG устанавливается на количество элементов, которые будут возвращены при следующем вызове. Это позволяет приложению выделить достаточно памяти и снова вызвать API для получения результатов.

на C_FindObjects вызов также возвращает переменное количество элементов, но он использует другую парадигму. Параметр CK_OBJECT_HANDLE_PTR phObject устанавливается в начало списка результатов. Параметр CK_ULONG_PTR pulObjectCount устанавливается на количество возвращаемых элементов, которое должно быть меньше CK_ULONG ulMaxObjectCount.

стандарт явно не говорит, что phObject должен быть допустимым указателем на блок памяти, достаточно большой для хранения ulMaxObjectCount CK_OBJECT_HANDLEs.

можно интерпретировать стандарт таким образом, что приложение должно пессимистически выделите достаточно памяти для ulMaxObjectCount объекты. В качестве альтернативы можно интерпретировать стандарт как означающий, что реализация PKCS #11 выделит pulObjectCount CK_OBJECT_HANDLEs, и тогда ответственность приложения за освобождение этой памяти. Однако эта более поздняя интерпретация кажется подозрительной, поскольку нигде в стандарте реализация PKCS #11 никогда не выделяет память.

проезд:

C_FindObjects continues a search for token and session objects that 
match a template, obtaining additional object handles. hSession is 
the session’s handle; phObject points to the location that receives 
the list (array) of additional object handles; ulMaxObjectCount is 
the maximum number of object handles to be returned; pulObjectCount 
points to the location that receives the actual number of object 
handles returned.

If there are no more objects matching the template, then the location 
that pulObjectCount points to receives the value 0.

The search MUST have been initialized with C_FindObjectsInit.

ненормативный пример не очень полезен, так как он наборы ulMaxObjectCount для 1. Тем не менее, он выделяет память для этой одной записи. Что, похоже, указывает на то, что приложение должно пессимистически предварительно выделить память.

CK_SESSION_HANDLE hSession;
CK_OBJECT_HANDLE hObject;
CK_ULONG ulObjectCount;
CK_RV rv;
.
.
rv = C_FindObjectsInit(hSession, NULL_PTR, 0);
assert(rv == CKR_OK);
while (1) {
 rv = C_FindObjects(hSession, &hObject, 1, &ulObjectCount);
 if (rv != CKR_OK || ulObjectCount == 0)
 break;
 .
 .
}
rv = C_FindObjectsFinal(hSession);
assert(rv == CKR_OK);

Ссылка Спецификации:http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.pdf

1 ответов


да, похоже, что приложение отвечает за выделение пространства для объекта обработки, возвращенные C_FindObjects(). Пример кода делает это, даже если он запрашивает только один дескриптор объекта за раз, и вы должны это сделать.

вы можете просто переписать пример кода, чтобы запросить несколько дескрипторов объектов, например, так:

#define MAX_OBJECT_COUNT 100  /* arbitrary value */

K_SESSION_HANDLE hSession;
CK_OBJECT_HANDLE hObjects[MAX_OBJECT_COUNT];
CK_ULONG ulObjectCount, i;
CK_RV rv;

rv = C_FindObjectsInit(hSession, NULL_PTR, 0);
assert(rv == CKR_OK);
while (1) {
  rv = C_FindObjects(hSession, hObjects, MAX_OBJECT_COUNT, &ulObjectCount);
  if (rv != CKR_OK || ulObjectCount == 0) break;
  for (i = 0; i < ulObjectCount; i++) {
    /* do something with hObjects[i] here */
  }
}
rv = C_FindObjectsFinal(hSession);
assert(rv == CKR_OK);

предположительно, возможность запрашивать несколько дескрипторов объектов в одном C_FindObjects() вызов предназначен как оптимизация производительности.

FWIW, это почти точно, сколько стандартных функций библиотеки C, таких как fread() работа. Было бы крайне неэффективно считывать данные из файла по одному байту за раз с помощью fgetc(), так что fread() функция позволяет выделить произвольно большой буфер и прочитать столько данных, сколько поместится в него.