opensc/src/pkcs11/object.c

239 lines
7.8 KiB
C

#include <stdio.h>
#include "sc-pkcs11.h"
#define min(a,b) (((a)<(b))?(a):(b))
static void dump_template(char *info, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
{
int i, j;
for (i = 0; i < ulCount; i++) {
char foo[1024] = "";
unsigned char *value = (unsigned char*) pTemplate[i].pValue;
if (pTemplate[i].pValue) {
if (pTemplate[i].ulValueLen < 16) {
for (j = 0; j < pTemplate[i].ulValueLen; j++)
sprintf(&foo[j*2], "%02X", value[j]);
LOG("%s: Attribute 0x%x = %s (length=%d)\n",
info, pTemplate[i].type, foo, pTemplate[i].ulValueLen);
} else {
LOG("%s: Attribute 0x%x = ... (length=%d)\n",
info, pTemplate[i].type, pTemplate[i].ulValueLen);
}
} else {
LOG("%s: Attribute 0x%x, length inquiry\n",
info, pTemplate[i].type);
}
}
}
CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, /* the session's handle */
CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
CK_ULONG ulCount, /* attributes in template */
CK_OBJECT_HANDLE_PTR phObject) /* receives new object's handle. */
{
LOG("C_CreateObject(%d, 0x%x, %d, 0x%d)\n", hSession, pTemplate, ulCount, phObject);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_RV C_CopyObject(CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
CK_ULONG ulCount, /* attributes in template */
CK_OBJECT_HANDLE_PTR phNewObject) /* receives handle of copy */
{
LOG("C_CopyObject(%d, %d, 0x%d, %d, 0x%x)\n",
hSession, hObject, pTemplate, ulCount, phNewObject);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject) /* the object's handle */
{
LOG("C_DestroyObject(%d, %d)\n", hSession, hObject);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_RV C_GetObjectSize(CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ULONG_PTR pulSize) /* receives size of object */
{
LOG("C_GetObjectSize(%d, %d, 0x%x)\n", hSession, hObject, pulSize);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_RV C_GetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* specifies attributes, gets values */
CK_ULONG ulCount) /* attributes in template */
{
struct pkcs11_slot *slt;
struct pkcs11_object *object;
int i, j;
LOG("C_GetAttributeValue(%d, %d, 0x%x, %d)\n", hSession, hObject, pTemplate, ulCount);
dump_template("C_GetAttributeValue", pTemplate, ulCount);
if (hSession < 1 || hSession > PKCS11_MAX_SESSIONS || session[hSession] == NULL)
return CKR_SESSION_HANDLE_INVALID;
slt = &slot[session[hSession]->slot];
if (hObject < 1 || hObject > slt->num_objects)
return CKR_OBJECT_HANDLE_INVALID;
object = slt->object[hObject];
LOG("C_GetAttributeValue: Slot %d, Object: 0x%x, Attributes: %d\n",
session[hSession]->slot, object, object->num_attributes);
for (i = 0; i < ulCount; i++) {
// For each request attribute
// 1. Find matching attribute
for (j = 0; j < object->num_attributes; j++) {
if (pTemplate[i].type == object->attribute[j].type)
break;
}
// 2. If object doesn't posses attribute
if (j >= object->num_attributes) {
LOG("C_GetAttributeValue: Attribute 0x%x not present\n", pTemplate[i].type);
pTemplate[i].ulValueLen = -1;
continue;
}
// 3. If pValue is NULL_PTR then it's a size inquiry
if (pTemplate[i].pValue == NULL_PTR) {
pTemplate[i].ulValueLen = object->attribute[j].ulValueLen;
LOG("C_GetAttributeValue: Attribute 0x%x length %d\n",
pTemplate[i].type, object->attribute[j].ulValueLen);
continue;
}
// 4. If value fits then copy it and update true length
if (pTemplate[i].ulValueLen >= object->attribute[j].ulValueLen) {
LOG("C_GetAttributeValue: Copying attribute 0x%x length %d\n",
pTemplate[i].type, object->attribute[j].ulValueLen);
pTemplate[i].ulValueLen = object->attribute[j].ulValueLen;
memcpy(pTemplate[i].pValue,
object->attribute[j].pValue,
object->attribute[j].ulValueLen);
continue;
}
// 5. Otherwise set length to minus one
pTemplate[i].ulValueLen = -1;
}
return CKR_OK;
}
CK_RV C_SetAttributeValue(CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject, /* the object's handle */
CK_ATTRIBUTE_PTR pTemplate, /* specifies attributes and values */
CK_ULONG ulCount) /* attributes in template */
{
LOG("C_SetAttributeValue(%d, %d, 0x%x, %d)\n", hSession, hObject, pTemplate, ulCount);
dump_template("C_SetAttributeValue", pTemplate, ulCount);
return CKR_FUNCTION_NOT_SUPPORTED;
}
CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession, /* the session's handle */
CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
CK_ULONG ulCount) /* attributes in search template */
{
struct pkcs11_session *ses;
struct pkcs11_slot *slt;
int i, j, k;
LOG("C_FindObjectsInit(%d, %d, 0x%x, %d)\n", hSession, pTemplate, ulCount);
dump_template("C_FindObjectsInit", pTemplate, ulCount);
if (hSession < 1 || hSession > PKCS11_MAX_SESSIONS || session[hSession] == NULL)
return CKR_SESSION_HANDLE_INVALID;
ses = session[hSession];
slt = &slot[ses->slot];
ses->search.position = 0;
ses->search.num_matches = 0;
// For each object in token do
for (i = 1; i <= slt->num_objects; i++) {
int matched = 1;
// Try to match every attribute
for (j = 0; j < ulCount; j++) {
struct pkcs11_object *object = slt->object[i];
// Find the matching attribute in object
for (k = 0; k < object->num_attributes; k++) {
if (pTemplate[j].type == object->attribute[k].type)
break;
}
// Is the attribute matching?
if (k >= object->num_attributes ||
pTemplate[j].ulValueLen != object->attribute[k].ulValueLen ||
memcmp(pTemplate[j].pValue, object->attribute[k].pValue, pTemplate[j].ulValueLen)) {
matched = 0;
break;
}
}
if (matched) {
LOG("C_FindObjectsInit(): Object %d matches search criteria\n", i);
ses->search.handles[ses->search.num_matches++] = i;
}
}
return CKR_OK;
}
CK_RV C_FindObjects(CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE_PTR phObject, /* receives object handle array */
CK_ULONG ulMaxObjectCount, /* max handles to be returned */
CK_ULONG_PTR pulObjectCount) /* actual number returned */
{
struct pkcs11_session *ses;
int to_return;
LOG("C_FindObjects(%d, 0x%x, %d, 0x%x)\n", hSession, phObject, ulMaxObjectCount, pulObjectCount);
if (hSession < 1 || hSession > PKCS11_MAX_SESSIONS || session[hSession] == NULL)
return CKR_SESSION_HANDLE_INVALID;
ses = session[hSession];
to_return = min(ulMaxObjectCount, ses->search.num_matches - ses->search.position);
*pulObjectCount = to_return;
memcpy(phObject,
&ses->search.handles[ses->search.position],
to_return * sizeof(CK_OBJECT_HANDLE));
ses->search.position += to_return;
return CKR_OK;
}
CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession) /* the session's handle */
{
struct pkcs11_session *ses;
LOG("C_FindObjectsFinal(%d)\n", hSession);
if (hSession < 1 || hSession > PKCS11_MAX_SESSIONS || session[hSession] == NULL)
return CKR_SESSION_HANDLE_INVALID;
ses = session[hSession];
ses->search.num_matches = 0;
ses->search.position = 0;
return CKR_OK;
}