Владение памятью в 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_HANDLE
s.
можно интерпретировать стандарт таким образом, что приложение должно пессимистически выделите достаточно памяти для ulMaxObjectCount
объекты. В качестве альтернативы можно интерпретировать стандарт как означающий, что реализация PKCS #11 выделит pulObjectCount
CK_OBJECT_HANDLE
s, и тогда ответственность приложения за освобождение этой памяти. Однако эта более поздняя интерпретация кажется подозрительной, поскольку нигде в стандарте реализация 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()
функция позволяет выделить произвольно большой буфер и прочитать столько данных, сколько поместится в него.