当API返回可变长度的项目列表时,PKCS#11 v2.40的作者使用了一种通用模式。在诸如C_GetSlotList
和C_GetMechanismList
之类的API中,应用程序需要两次调用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
,然后应用程序负责释放该内存。然而,后来的解释似乎是可疑的,因为标准中没有其他地方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
答案 0 :(得分:7)
是的,应用程序似乎负责为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,这几乎就是fread()
这样的C标准库函数的功能。使用fgetc()
一次一个字节地读取文件中的数据是非常低效的,因此fread()
函数允许您分配一个任意大的缓冲区并读取适合它的数据。