summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2007-05-11 17:07:19 +0000
committerStef Walter <stef@memberwebs.com>2007-05-11 17:07:19 +0000
commitc6d18eea781bc98a362595e2334223b48f41b522 (patch)
treefe4c326602a5c1ae3d3b92d85c3a4368f7427390
parente7b1e2fecde1053e661984f2dcb33f7e1cdd6dda (diff)
Add different tokens for different certificate stores.
-rw-r--r--ckcapi-builtin.c42
-rw-r--r--ckcapi-cert.c127
-rw-r--r--ckcapi-object.c168
-rw-r--r--ckcapi-session.c204
-rw-r--r--ckcapi-token.c230
-rw-r--r--ckcapi-trust.c4
-rw-r--r--ckcapi.c81
-rw-r--r--ckcapi.dsp4
-rw-r--r--ckcapi.h113
9 files changed, 533 insertions, 440 deletions
diff --git a/ckcapi-builtin.c b/ckcapi-builtin.c
index 6788701..26e9cd9 100644
--- a/ckcapi-builtin.c
+++ b/ckcapi-builtin.c
@@ -46,9 +46,16 @@ static const CK_ATTRIBUTE builtin_root[] = {
{ CK_END_LIST, NULL, 0 }
};
-static const CK_ATTRIBUTE_PTR all_builtins[] = {
- (CK_ATTRIBUTE_PTR)&builtin_root,
- NULL,
+typedef struct _BuiltinMatch
+{
+ CK_ATTRIBUTE_PTR attr;
+ CK_ULONG slot_flags;
+}
+BuiltinMatch;
+
+static const BuiltinMatch all_builtins[] = {
+ { (CK_ATTRIBUTE_PTR)&builtin_root, CKCAPI_SLOT_TRUSTED | CKCAPI_SLOT_CA },
+ { NULL, 0 }
};
/* This is filled in later */
@@ -68,7 +75,7 @@ typedef struct _BuiltinObject
* laid out together in memory.
*/
unsigned int otype;
- CK_ULONG builtin_index;
+ CK_ATTRIBUTE_PTR attr;
}
BuiltinObject;
@@ -144,14 +151,12 @@ builtin_load_data(CkCapiSession* sess, CkCapiObject* obj, CkCapiObjectData** obj
ASSERT(objdata);
ASSERT(num_builtins > 0);
- if(bobj->builtin_index > num_builtins)
- return CKR_OBJECT_HANDLE_INVALID;
-
bdata = (BuiltinObjectData*)calloc(sizeof(BuiltinObjectData), 1);
if(!bdata)
return CKR_HOST_MEMORY;
- bdata->attr = all_builtins[bobj->builtin_index];
+ /* Simple, just use same data */
+ bdata->attr = bobj->attr;
bdata->base.object = obj->id;
bdata->base.data_funcs = &builtin_objdata_vtable;
@@ -174,7 +179,7 @@ static const CkCapiObjectVtable builtin_object_vtable = {
};
static CK_RV
-register_builtin_object(CkCapiSession* sess, CK_ULONG index, CkCapiObject** obj)
+register_builtin_object(CkCapiSession* sess, CK_ATTRIBUTE_PTR attr, CkCapiObject** obj)
{
BuiltinObject* bobj;
CK_RV ret;
@@ -184,14 +189,14 @@ register_builtin_object(CkCapiSession* sess, CK_ULONG index, CkCapiObject** obj)
return CKR_HOST_MEMORY;
bobj->otype = OBJECT_BUILTIN;
- bobj->builtin_index = index;
+ bobj->attr = attr;
bobj->obj.id = 0;
bobj->obj.obj_funcs = &builtin_object_vtable;
bobj->obj.unique_key = UNIQUE_KEY_AT(bobj, otype);
- bobj->obj.unique_len = UNIQUE_KEY_LEN(bobj, otype, builtin_index);
+ bobj->obj.unique_len = UNIQUE_KEY_LEN(bobj, otype, attr);
- ret = ckcapi_object_register(sess, &(bobj->obj));
+ ret = ckcapi_token_register_object(sess->slot, &(bobj->obj));
if(ret != CKR_OK)
{
free(bobj);
@@ -210,12 +215,12 @@ ckcapi_builtin_find(CkCapiSession* sess, CK_OBJECT_CLASS cls, CK_ATTRIBUTE_PTR m
CkCapiObject* obj;
BuiltinObjectData bdata;
CK_RV ret = CKR_OK;
- CK_ULONG i;
+ CK_ULONG i, fl;
/* First time around count total number */
if(!num_builtins)
{
- while(all_builtins[num_builtins])
+ while(all_builtins[num_builtins].attr)
++num_builtins;
ASSERT(num_builtins > 0);
}
@@ -223,13 +228,18 @@ ckcapi_builtin_find(CkCapiSession* sess, CK_OBJECT_CLASS cls, CK_ATTRIBUTE_PTR m
/* Match each certificate */
for(i = 0; i < num_builtins; ++i)
{
- bdata.attr = all_builtins[i];
+ /* Only apply built in objects to appropriate slots */
+ fl = ckcapi_token_get_flags(sess->slot) & all_builtins[i].slot_flags;
+ if(fl != all_builtins[i].slot_flags)
+ continue;
+
+ bdata.attr = all_builtins[i].attr;
bdata.base.object = 0;
bdata.base.data_funcs = &builtin_objdata_vtable;
if(ckcapi_object_data_match(&bdata.base, match, count))
{
- ret = register_builtin_object(sess, i, &obj);
+ ret = register_builtin_object(sess, all_builtins[i].attr, &obj);
if(ret != CKR_OK)
break;
diff --git a/ckcapi-cert.c b/ckcapi-cert.c
index 0e40905..15ab880 100644
--- a/ckcapi-cert.c
+++ b/ckcapi-cert.c
@@ -31,22 +31,9 @@
#define USE_ENCODINGS (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
-/* All the stores we look in for certificates, in this order */
-static const char* CERT_STORES[] = {
- "My",
- "AddressBook",
- "CA",
- "Root",
- "Trust",
- "TrustedPeople",
- "AuthRoot",
- NULL
-};
-
typedef struct _CertObject
{
CkCapiObject obj;
- const char* store;
/* Together these can uniquely identify a certificate */
CRYPT_INTEGER_BLOB serial;
@@ -238,31 +225,26 @@ static CK_RV
cert_load_data(CkCapiSession* sess, CkCapiObject* obj, CkCapiObjectData** objdata)
{
CertObject* cobj = (CertObject*)obj;
- HCERTSTORE store;
CERT_INFO info;
PCCERT_CONTEXT cert;
ASSERT(cobj);
ASSERT(objdata);
- ASSERT(cobj->store);
- store = CertOpenSystemStore((HCRYPTPROV)NULL, cobj->store);
- if(!store)
- return ckcapi_winerr_to_ckr(GetLastError());
-
ASSERT(cobj->issuer.pbData);
ASSERT(cobj->issuer.cbData);
ASSERT(cobj->serial.pbData);
ASSERT(cobj->serial.cbData);
+ /* No store should mean no objects were loaded */
+ ASSERT(sess->store);
+
/* Setup our search */
memset(&info, 0, sizeof(info));
memcpy(&info.SerialNumber, &cobj->serial, sizeof(info.SerialNumber));
memcpy(&info.Issuer, &cobj->issuer, sizeof(info.Issuer));
- cert = CertGetSubjectCertificateFromStore(store, USE_ENCODINGS, &info);
-
- CertCloseStore(store, 0);
+ cert = CertGetSubjectCertificateFromStore(sess->store, USE_ENCODINGS, &info);
if(!cert)
{
@@ -481,8 +463,7 @@ ckcapi_cert_object_data_get_certificate(CkCapiObjectData* objdata)
}
static CK_RV
-register_cert_object(CkCapiSession* sess, const char* store, PCCERT_CONTEXT cert,
- CkCapiObject** obj)
+register_cert_object(CkCapiSession* sess, PCCERT_CONTEXT cert, CkCapiObject** obj)
{
CertObject* cobj;
CK_RV ret;
@@ -500,7 +481,6 @@ register_cert_object(CkCapiSession* sess, const char* store, PCCERT_CONTEXT cert
return CKR_HOST_MEMORY;
cobj->otype = OBJECT_CERT;
- cobj->store = store;
cobj->obj.id = 0;
cobj->obj.unique_key = UNIQUE_KEY_AT(cobj, otype);
@@ -519,7 +499,7 @@ register_cert_object(CkCapiSession* sess, const char* store, PCCERT_CONTEXT cert
memcpy(cobj->serial.pbData, cert->pCertInfo->SerialNumber.pbData,
cobj->serial.cbData);
- ret = ckcapi_object_register(sess, &(cobj->obj));
+ ret = ckcapi_token_register_object(sess->slot, &(cobj->obj));
if(ret != CKR_OK)
{
free(cobj);
@@ -531,52 +511,22 @@ register_cert_object(CkCapiSession* sess, const char* store, PCCERT_CONTEXT cert
return CKR_OK;
}
-static void
-clear_object_data_for_store(CkCapiSession* sess, CkCapiObject* obj,
- CkCapiObjectData* data, void* arg)
-{
- const char* store = (const char*) arg;
- CertObject *cobj = (CertObject*)obj;
-
- // Is it one of ours?
- if(obj->obj_funcs != &cert_object_vtable)
- return;
-
- if(strcmp(cobj->store, store) == 0)
- ckcapi_session_clear_object_data(sess, obj);
-}
-
static CK_RV
-find_in_store(CkCapiSession* sess, const char* store_name,
- CK_ATTRIBUTE_PTR match, CK_ULONG count, CkCapiArray* arr)
+find_in_store(CkCapiSession* sess, CK_ATTRIBUTE_PTR match,
+ CK_ULONG count, CkCapiArray* arr)
{
PCCERT_CONTEXT cert = NULL;
CkCapiObject* obj;
- HCERTSTORE store;
CertObjectData cdata;
CkCapiObjectData* objdata;
- DWORD err;
CK_RV ret = CKR_OK;
-
- /* Clear any loaded data for objects in this store */
- ckcapi_session_enum_object_data(sess, clear_object_data_for_store, (void*)store_name);
-
- store = CertOpenSystemStore((HCRYPTPROV)NULL, store_name);
- if(store == NULL)
- {
- err = GetLastError();
-
- /* Store not found, we don't care */
- if(err == ERROR_FILE_NOT_FOUND)
- return CKR_OK;
-
- else
- return ckcapi_winerr_to_ckr(err);
- }
+ /* No store, no objects */
+ if(!sess->store)
+ return CKR_OK;
/* Match each certificate */
- while((cert = CertEnumCertificatesInStore(store, cert)) != NULL)
+ while((cert = CertEnumCertificatesInStore(sess->store, cert)) != NULL)
{
cdata.cert = cert;
cdata.base.object = 0;
@@ -584,7 +534,7 @@ find_in_store(CkCapiSession* sess, const char* store_name,
if(ckcapi_object_data_match(&cdata.base, match, count))
{
- ret = register_cert_object(sess, store_name, cert, &obj);
+ ret = register_cert_object(sess, cert, &obj);
if(ret != CKR_OK)
break;
@@ -604,37 +554,25 @@ find_in_store(CkCapiSession* sess, const char* store_name,
}
}
- ASSERT(store);
- CertCloseStore(store, 0);
-
return ret;
}
static CK_RV
-match_in_store(CkCapiSession* sess, const char* store_name, PCERT_INFO info,
- CK_ATTRIBUTE_PTR match, CK_ULONG count, CkCapiArray* arr)
+match_in_store(CkCapiSession* sess, PCERT_INFO info, CK_ATTRIBUTE_PTR match,
+ CK_ULONG count, CkCapiArray* arr)
{
PCCERT_CONTEXT cert = NULL;
CkCapiObject* obj;
CkCapiObjectData* objdata;
- HCERTSTORE store;
CertObjectData cdata;
DWORD err;
CK_RV ret = CKR_OK;
- store = CertOpenSystemStore((HCRYPTPROV)NULL, store_name);
- if(store == NULL)
- {
- err = GetLastError();
-
- /* Store not found, we don't care */
- if(err == ERROR_FILE_NOT_FOUND)
- return CKR_OK;
- else
- return ckcapi_winerr_to_ckr(err);
- }
+ /* No store, no objects */
+ if(!sess->store)
+ return CKR_OK;
- cert = CertGetSubjectCertificateFromStore(store, USE_ENCODINGS, info);
+ cert = CertGetSubjectCertificateFromStore(sess->store, USE_ENCODINGS, info);
if(cert == NULL)
{
err = GetLastError();
@@ -653,7 +591,7 @@ match_in_store(CkCapiSession* sess, const char* store_name, PCERT_INFO info,
if(ckcapi_object_data_match(&cdata.base, match, count))
{
- ret = register_cert_object(sess, store_name, cert, &obj);
+ ret = register_cert_object(sess, cert, &obj);
if(ret == CKR_OK)
{
ASSERT(obj);
@@ -669,10 +607,6 @@ match_in_store(CkCapiSession* sess, const char* store_name, PCERT_INFO info,
if(ret != CKR_OK && cert)
CertFreeCertificateContext(cert);
-
- ASSERT(store);
- CertCloseStore(store, 0);
-
return ret;
}
@@ -683,7 +617,6 @@ ckcapi_cert_find(CkCapiSession* sess, CK_OBJECT_CLASS cls, CK_ATTRIBUTE_PTR matc
CRYPT_INTEGER_BLOB* serial = NULL;
CERT_INFO info;
CK_RV ret;
- BOOL specific;
CK_ULONG i;
DWORD size;
@@ -728,21 +661,13 @@ ckcapi_cert_find(CkCapiSession* sess, CK_OBJECT_CLASS cls, CK_ATTRIBUTE_PTR matc
}
}
- specific = info.SerialNumber.cbData && info.Issuer.cbData;
+ /* Match a specific certificate */
+ if(info.SerialNumber.cbData && info.Issuer.cbData)
+ ret = match_in_store(sess, &info, match, count, arr);
- for(i = 0; CERT_STORES[i]; ++i)
- {
- /* Match a specific certificate */
- if(specific)
- ret = match_in_store(sess, CERT_STORES[i], &info, match, count, arr);
-
- /* Match any ol certificate */
- else
- ret = find_in_store(sess, CERT_STORES[i], match, count, arr);
-
- if(ret != CKR_OK)
- break;
- }
+ /* Match any ol certificate */
+ else
+ ret = find_in_store(sess, match, count, arr);
if(serial)
free(serial);
diff --git a/ckcapi-object.c b/ckcapi-object.c
index 6d8bb86..051baf4 100644
--- a/ckcapi-object.c
+++ b/ckcapi-object.c
@@ -23,174 +23,6 @@
#include <memory.h>
-static CkCapiArray* object_array = NULL;
-static CkCapiHash* object_hash = NULL;
-
-static void
-object_free(CkCapiObject* obj)
-{
- ASSERT(obj);
- ASSERT(obj->obj_funcs);
- ASSERT(obj->obj_funcs->release);
- (obj->obj_funcs->release)(obj);
-}
-
-void
-ckcapi_object_clear_all(void)
-{
- size_t i;
-
- ckcapi_lock_global();
-
- if(object_hash)
- {
- ckcapi_hash_free(object_hash, NULL);
- object_hash = NULL;
- }
-
- if(object_array)
- {
- for(i = 1; i < object_array->len; ++i)
- {
- ASSERT(ckcapi_array_index(object_array, CkCapiObject*, i));
- object_free(ckcapi_array_index(object_array, CkCapiObject*, i));
- }
-
- ckcapi_array_free(object_array, TRUE);
- object_array = NULL;
- }
-
- ckcapi_unlock_global();
-}
-
-CK_OBJECT_HANDLE
-ckcapi_object_get_max_handle(void)
-{
- if(!object_array)
- return 0;
- return object_array->len;
-}
-
-CkCapiObject*
-ckcapi_object_lookup(CkCapiSession* sess, CK_OBJECT_HANDLE obj)
-{
- /* This must be called without any locks held */
-
- CkCapiObject* ret = NULL;
-
- ASSERT(sess);
- ASSERT(obj > 0);
-
- ckcapi_lock_global();
-
- if(object_array && obj < object_array->len)
- ret = ckcapi_array_index(object_array, CkCapiObject*, obj);
-
- ckcapi_unlock_global();
-
- return ret;
-}
-
-CK_RV
-ckcapi_object_register(CkCapiSession* sess, CkCapiObject* obj)
-{
- CkCapiObject* prev;
- CK_RV ret = CKR_OK;
- void* key;
- size_t klen;
-
- ASSERT(sess);
- ASSERT(obj->id == 0);
- ASSERT(obj->unique_key);
- ASSERT(obj->unique_len > 0);
-
- DBG(("registering object"));
-
- ckcapi_lock_global();
-
- if(!object_array)
- {
- object_array = ckcapi_array_sized_new(0, 1, sizeof(CkCapiObject*), 16);
- if(object_array)
- {
- /* A blank entry for '0' */
- CkCapiObject* blank = NULL;
- ckcapi_array_append(object_array, blank);
- }
-
- object_hash = ckcapi_hash_new();
-
-
- if(!object_array || !object_hash)
- {
- /* Allocation failed above */
- ret = CKR_HOST_MEMORY;
- }
- }
-
- if(ret == CKR_OK)
- {
- ASSERT(object_array);
- ASSERT(object_hash);
-
- /* The type of object is part of the hash */
- key = obj->unique_key;
- klen = obj->unique_len;
-
- /* Sanity check, in case calcs went wrong somewhere */
- ASSERT(klen < 0xFFFFFF);
-
- /* Look in the hash and find a previous object */
- prev = ckcapi_hash_get(object_hash, key, klen);
- if(prev)
- {
- /* Register it in the previous object's place */
- obj->id = prev->id;
- ASSERT(prev->id < object_array->len);
- if(ckcapi_hash_set(object_hash, key, klen, obj))
- {
- ckcapi_array_index(object_array, CkCapiObject*, obj->id) = obj;
- object_free(prev);
- DBGO(obj, "found old object id");
- }
- else
- {
- ret = CKR_HOST_MEMORY;
- }
-
- }
- else
- {
- /* Register it at the end of the array */
- obj->id = object_array->len;
- ASSERT(obj->id > 0);
- if(ckcapi_hash_set(object_hash, key, klen, obj))
- {
- if(ckcapi_array_append(object_array, obj))
- {
- DBGO(obj, "registered new object id");
- }
- else
- {
- ret = CKR_HOST_MEMORY;
-
- /* Roll back our addition */
- ckcapi_hash_rem(object_hash, key, klen);
- }
- }
- else
- {
- ret = CKR_HOST_MEMORY;
- }
- }
- }
-
- ckcapi_unlock_global();
-
- return ret;
-
-}
-
enum
{
DATA_UNKNOWN = 0,
diff --git a/ckcapi-session.c b/ckcapi-session.c
index 0e9316f..0d71fe2 100644
--- a/ckcapi-session.c
+++ b/ckcapi-session.c
@@ -21,13 +21,7 @@
#include "ckcapi.h"
-typedef struct _SessionList {
- CkCapiSession **list;
- size_t lmax;
-} SessionList;
-
-/* These are protected by global_mutex */
-static SessionList the_sessions = { NULL, 0 };
+static CkCapiArray* all_sessions = NULL;
static void
object_data_release(CkCapiObjectData* objdata)
@@ -37,34 +31,58 @@ object_data_release(CkCapiObjectData* objdata)
(objdata->data_funcs->release)(objdata);
}
-CkCapiSession*
-ckcapi_session_create(void)
+CK_RV
+ckcapi_session_create(CK_SLOT_ID slot, CkCapiSession** ret)
{
- CkCapiSession* sess = calloc(1, sizeof(CkCapiSession));
+ CkCapiSession* sess;
+ DWORD err;
+
+ sess = calloc(1, sizeof(CkCapiSession));
if(!sess)
- return NULL;
+ return CKR_HOST_MEMORY;
sess->object_data = ckcapi_hash_new();
if(!sess->object_data) {
free(sess);
- return NULL;
+ return CKR_HOST_MEMORY;
}
sess->mutex = CreateMutex(NULL, FALSE, NULL);
if(!sess->mutex) {
ckcapi_hash_free(sess->object_data, NULL);
free(sess);
- return NULL;
+ return CKR_HOST_MEMORY;
+ }
+
+ sess->store = CertOpenSystemStore((HCRYPTPROV)NULL,
+ ckcapi_token_get_store_name(slot));
+ if(sess->store == NULL)
+ {
+ err = GetLastError();
+
+ /* Store not found, we don't care */
+ if(err != ERROR_FILE_NOT_FOUND)
+ {
+ ckcapi_hash_free(sess->object_data, NULL);
+ CloseHandle(sess->mutex);
+ free(sess);
+ return ckcapi_winerr_to_ckr(err);
+ }
}
+ sess->slot = slot;
+
DBGS(sess, "created");
- return sess;
+
+ *ret = sess;
+ return CKR_OK;
}
CK_RV
ckcapi_session_register(CkCapiSession* sess)
{
- CK_ULONG id = 0;
+ CkCapiSession* blank = NULL;
+ CK_SESSION_HANDLE id = 0;
CK_RV ret = CKR_OK;
size_t i;
@@ -78,6 +96,22 @@ ckcapi_session_register(CkCapiSession* sess)
/* Find a nice session identifier */
while(id == 0) {
+ /* Allocate sessions properly */
+ if(!all_sessions)
+ {
+ all_sessions = ckcapi_array_new(0, 1, sizeof(CkCapiSession*));
+ if(!all_sessions)
+ {
+ ret = CKR_HOST_MEMORY;
+ break;
+ }
+
+ /* A blank entry for '0' */
+ ckcapi_array_append(all_sessions, blank);
+
+ DBG(("allocated new session list"));
+ }
+
/*
* PKCS#11 GRAY AREA: We're assuming we can reuse session
* handles. PKCS#11 spec says they're like file handles,
@@ -85,53 +119,32 @@ ckcapi_session_register(CkCapiSession* sess)
*/
/* Note we never put anything in array position '0' */
- for(i = 1; i < the_sessions.lmax; ++i)
+ for(i = 1; i < all_sessions->len; ++i)
{
/* Any empty position will do */
- if(!the_sessions.list[i])
+ if(!ckcapi_array_index(all_sessions, CkCapiSession*, i))
{
id = i;
break;
}
}
- /* Couldn't find a handle, reallocate */
- if(id == 0)
+ /* Couldn't find a handle, append a handle */
+ if(id == 0)
{
- CkCapiSession** buf;
- size_t oldmax, newmax;
-
- oldmax = the_sessions.lmax;
- newmax = oldmax + 16;
-
- buf = realloc(the_sessions.list, newmax * sizeof(CkCapiSession*));
- if(!buf)
- {
- DBGS(sess, ("couldn't allocate session list, out of memory"));
- ret = CKR_HOST_MEMORY;
- break;
- }
-
- /* Choose the first of the new block as the id */
- id = oldmax;
-
- /* Clear new memory */
- the_sessions.list = buf;
- for( ; oldmax < newmax; ++oldmax)
- buf[oldmax] = NULL;
- the_sessions.lmax = newmax;
-
- DBG(("allocated new session list: %d max", newmax));
+ id = all_sessions->len;
+ ckcapi_array_append(all_sessions, blank);
}
}
if(ret == CKR_OK)
{
- ASSERT(id > 0 && id < the_sessions.lmax);
- ASSERT(the_sessions.list[id] == NULL);
+ ASSERT(id > 0 && id < all_sessions->len);
+ ASSERT(!ckcapi_array_index(all_sessions, CkCapiSession*, id));
+
/* And assign it to the session handle */
- the_sessions.list[id] = sess;
+ ckcapi_array_index(all_sessions, CkCapiSession*, i) = sess;
sess->id = id;
/* The session list reference */
@@ -163,6 +176,9 @@ ckcapi_session_destroy(CkCapiSession* sess)
ASSERT(sess->operation_data == NULL);
ASSERT(sess->operation_cancel == NULL);
+ if(sess->store)
+ CertCloseStore(sess->store, 0);
+
/* Make all the object adat go away */
ASSERT(sess->object_data != NULL);
ckcapi_hash_free(sess->object_data, object_data_release);
@@ -176,7 +192,7 @@ ckcapi_session_destroy(CkCapiSession* sess)
}
static CK_RV
-lock_ref_internal(SessionList* sessions, CK_SESSION_HANDLE id,
+lock_ref_internal(CkCapiArray* sessions, CK_SESSION_HANDLE id,
int remove, CkCapiSession** sess_ret)
{
CkCapiSession *sess;
@@ -185,15 +201,15 @@ lock_ref_internal(SessionList* sessions, CK_SESSION_HANDLE id,
ASSERT(sessions);
ASSERT(sess_ret);
- if(id >= sessions->lmax)
+ if(id >= sessions->len)
{
DBG(("invalid session id: %d", id));
return CKR_SESSION_HANDLE_INVALID;
}
/* A seemingly valid id */
- ASSERT(sessions->list);
- sess = sessions->list[id];
+ ASSERT(sessions);
+ sess = ckcapi_array_index(sessions, CkCapiSession*, id);
if(!sess)
{
@@ -241,7 +257,7 @@ lock_ref_internal(SessionList* sessions, CK_SESSION_HANDLE id,
/* And remove it if necessary */
if(remove)
{
- sessions->list[id] = NULL;
+ ckcapi_array_index(sessions, CkCapiSession*, id) = NULL;
/* The session list reference */
sess->refs--;
@@ -276,7 +292,7 @@ ckcapi_session_get_lock_ref(CK_ULONG id, int remove, CkCapiSession **sess)
ckcapi_lock_global();
- ret = lock_ref_internal (&the_sessions, id, remove, sess);
+ ret = lock_ref_internal (all_sessions, id, remove, sess);
ckcapi_unlock_global();
@@ -313,15 +329,15 @@ ckcapi_session_unref_unlock(CkCapiSession* sess)
ckcapi_session_destroy(sess);
}
-void
-ckcapi_session_close_all()
+CK_RV
+ckcapi_session_close_all(CK_SLOT_ID slot)
{
/* This must be called without any locks held */
- SessionList sessions;
+ CkCapiArray* sessions;
CkCapiSession *sess;
size_t i;
- CK_RV ret;
+ CK_RV ret = CKR_OK;
/*
* PKCS#11 GRAY AREA: What happens when this gets called
@@ -329,37 +345,71 @@ ckcapi_session_close_all()
* because by the time it returns, all sessions should be closed.
*/
+ DBG(("closing all sessions for: %d", slot));
+
ckcapi_lock_global();
+ sessions = ckcapi_array_sized_new(0, 1, sizeof(CkCapiSession*),
+ all_sessions->len);
+ if(!sessions)
+ ret = CKR_HOST_MEMORY;
+
/* Steal all the session data */
- sessions.list = the_sessions.list;
- the_sessions.list = NULL;
- sessions.lmax = the_sessions.lmax;
- the_sessions.lmax = 0;
-
- if(sessions.list || sessions.lmax)
- DBG(("closing all sessions"));
+ if(ret == CKR_OK)
+ {
+ for(i = 0; i < all_sessions->len; ++i)
+ {
+ sess = ckcapi_array_index(all_sessions, CkCapiSession*, i);
+ if(sess && (slot == ((CK_SLOT_ID)-1) || sess->slot == slot))
+ {
+ /* Steal this session */
+ ckcapi_array_index(all_sessions, CkCapiSession*, i) = NULL;
+ }
+ else
+ {
+ /* Not a session we're interested in */
+ sess = NULL;
+ }
+
+ /* Both null and normal sessions are set to preserve indexes */
+ ckcapi_array_append(sessions, sess);
+ }
+
+ ASSERT(sessions->len == all_sessions->len);
+ }
ckcapi_unlock_global();
+ if(ret != CKR_OK)
+ return ret;
+
/* Close each session in turn */
- for(i = 1; i < sessions.lmax; ++i)
+ for(i = 0; i < sessions->len; ++i)
{
- if(!sessions.list[i])
+ if(!ckcapi_array_index(sessions, CkCapiSession*, i))
continue;
-
- ret = lock_ref_internal (&sessions, i, 1, &sess);
- ASSERT(ret == CKR_OK);
- ckcapi_session_unref_unlock(sess);
+ /* We need any calls in other threads to finish, so wait here */
+ if(lock_ref_internal(sessions, i, 1, &sess) == CKR_OK)
+ ckcapi_session_unref_unlock(sess);
}
/* We stole the memory above, free it now */
- if(sessions.list)
- {
- free(sessions.list);
- DBG(("freed session list"));
- }
+ ckcapi_array_free(sessions, 1);
+ return CKR_OK;
+}
+
+void
+ckcapi_session_cleanup_all()
+{
+ ckcapi_session_close_all((CK_SLOT_ID)-1);
+
+ ckcapi_lock_global();
+
+ ckcapi_array_free(all_sessions, 1);
+ all_sessions = NULL;
+
+ ckcapi_unlock_global();
}
/* ----------------------------------------------------------------------------
@@ -430,14 +480,14 @@ ckcapi_session_enum_object_data(CkCapiSession* sess,
ASSERT(sess->object_data);
ASSERT(enum_func);
- max = ckcapi_object_get_max_handle();
+ max = ckcapi_token_get_max_handle();
for(i = 0; i < max; ++i)
{
objdata = (CkCapiObjectData*)ckcapi_hash_get(sess->object_data, &i, sizeof(i));
if(!objdata)
continue;
- obj = ckcapi_object_lookup (sess, i);
+ obj = ckcapi_token_lookup_object(sess->slot, i);
if(!obj)
continue;
@@ -451,7 +501,7 @@ ckcapi_session_get_object_data_for(CkCapiSession* sess, CK_OBJECT_HANDLE hand,
{
CkCapiObject* obj;
- obj = ckcapi_object_lookup(sess, hand);
+ obj = ckcapi_token_lookup_object(sess->slot, hand);
if(!obj)
return CKR_OBJECT_HANDLE_INVALID;
diff --git a/ckcapi-token.c b/ckcapi-token.c
new file mode 100644
index 0000000..d7ef75a
--- /dev/null
+++ b/ckcapi-token.c
@@ -0,0 +1,230 @@
+
+#include "ckcapi.h"
+
+static CkCapiArray* object_array = NULL;
+static CkCapiHash* object_hash = NULL;
+
+typedef struct _SlotInfo
+{
+ const char* capi_store;
+ const char* display_name;
+ CK_ULONG slot_flags;
+}
+SlotInfo;
+
+static const SlotInfo slot_info[] = {
+ { "My", "Personal Certificates", CKCAPI_SLOT_TRUSTED },
+ { "AddressBook", "Address Book Certificates", 0 },
+ { "CA", "Certificate Authorities", CKCAPI_SLOT_CA },
+ { "Root", "Root Authorities", CKCAPI_SLOT_TRUSTED | CKCAPI_SLOT_CA },
+ { "Trust", "Trust", 0 },
+ { "TrustedPeople", "Trusted People", CKCAPI_SLOT_TRUSTED },
+ { "AuthRoot", "Auth Root", 0 },
+};
+
+unsigned int
+ckcapi_token_get_count(void)
+{
+ return sizeof(slot_info) / sizeof(slot_info[0]);
+}
+
+CK_BBOOL
+ckcapi_token_is_valid(CK_SLOT_ID slot)
+{
+ return slot >= 0 && slot < ckcapi_token_get_count();
+}
+
+const char*
+ckcapi_token_get_display_name(CK_SLOT_ID slot)
+{
+ ASSERT(ckcapi_token_is_valid(slot));
+ ASSERT(slot_info[slot].display_name);
+ return slot_info[slot].display_name;
+}
+
+const char*
+ckcapi_token_get_store_name(CK_SLOT_ID slot)
+{
+ ASSERT(ckcapi_token_is_valid(slot));
+ ASSERT(slot_info[slot].capi_store);
+ return slot_info[slot].capi_store;
+}
+
+CK_ULONG
+ckcapi_token_get_flags(CK_SLOT_ID slot)
+{
+ ASSERT(ckcapi_token_is_valid(slot));
+ return slot_info[slot].slot_flags;
+}
+
+static void
+object_free(CkCapiObject* obj)
+{
+ ASSERT(obj);
+ ASSERT(obj->obj_funcs);
+ ASSERT(obj->obj_funcs->release);
+ (obj->obj_funcs->release)(obj);
+}
+
+void
+ckcapi_token_cleanup_all(void)
+{
+ size_t i;
+
+ ckcapi_lock_global();
+
+ if(object_hash)
+ {
+ ckcapi_hash_free(object_hash, NULL);
+ object_hash = NULL;
+ }
+
+ if(object_array)
+ {
+ for(i = 1; i < object_array->len; ++i)
+ {
+ ASSERT(ckcapi_array_index(object_array, CkCapiObject*, i));
+ object_free(ckcapi_array_index(object_array, CkCapiObject*, i));
+ }
+
+ ckcapi_array_free(object_array, TRUE);
+ object_array = NULL;
+ }
+
+ ckcapi_unlock_global();
+}
+
+CK_OBJECT_HANDLE
+ckcapi_token_get_max_handle(void)
+{
+ if(!object_array)
+ return 0;
+ return object_array->len;
+}
+
+CkCapiObject*
+ckcapi_token_lookup_object(CK_SLOT_ID slot, CK_OBJECT_HANDLE obj)
+{
+ /* This must be called without any locks held */
+
+ CkCapiObject* ret = NULL;
+
+ ASSERT(slot);
+ ASSERT(obj > 0);
+
+ ckcapi_lock_global();
+
+ if(object_array && obj < object_array->len)
+ ret = ckcapi_array_index(object_array, CkCapiObject*, obj);
+
+ ckcapi_unlock_global();
+
+ /* Must belong to the right slot */
+ if(ret && ret->slot != slot)
+ ret = NULL;
+
+ return ret;
+}
+
+CK_RV
+ckcapi_token_register_object(CK_SLOT_ID slot, CkCapiObject* obj)
+{
+ CkCapiObject* prev;
+ CK_RV ret = CKR_OK;
+ void* key;
+ size_t klen;
+
+ ASSERT(slot);
+ ASSERT(obj->id == 0);
+ ASSERT(obj->unique_key);
+ ASSERT(obj->unique_len > 0);
+
+ DBG(("registering object"));
+
+ ckcapi_lock_global();
+
+ if(!object_array)
+ {
+ object_array = ckcapi_array_sized_new(0, 1, sizeof(CkCapiObject*), 16);
+ if(object_array)
+ {
+ /* A blank entry for '0' */
+ CkCapiObject* blank = NULL;
+ ckcapi_array_append(object_array, blank);
+ }
+
+ object_hash = ckcapi_hash_new();
+
+
+ if(!object_array || !object_hash)
+ {
+ /* Allocation failed above */
+ ret = CKR_HOST_MEMORY;
+ }
+ }
+
+ if(ret == CKR_OK)
+ {
+ ASSERT(object_array);
+ ASSERT(object_hash);
+
+ /* The type of object is part of the hash */
+ key = obj->unique_key;
+ klen = obj->unique_len;
+
+ /* Sanity check, in case calcs went wrong somewhere */
+ ASSERT(klen < 0xFFFFFF);
+/* xxxxx hash function xxxxx */
+ /* Look in the hash and find a previous object */
+ prev = ckcapi_hash_get(object_hash, key, klen);
+ if(prev)
+ {
+ /* Register it in the previous object's place */
+ obj->id = prev->id;
+ ASSERT(prev->id < object_array->len);
+ if(ckcapi_hash_set(object_hash, key, klen, obj))
+ {
+ ckcapi_array_index(object_array, CkCapiObject*, obj->id) = obj;
+ object_free(prev);
+ DBGO(obj, "found old object id");
+ }
+ else
+ {
+ ret = CKR_HOST_MEMORY;
+ }
+
+ }
+ else
+ {
+ /* Register it at the end of the array */
+ obj->id = object_array->len;
+ ASSERT(obj->id > 0);
+ if(ckcapi_hash_set(object_hash, key, klen, obj))
+ {
+ if(ckcapi_array_append(object_array, obj))
+ {
+ DBGO(obj, "registered new object id");
+ }
+ else
+ {
+ ret = CKR_HOST_MEMORY;
+
+ /* Roll back our addition */
+ ckcapi_hash_rem(object_hash, key, klen);
+ }
+ }
+ else
+ {
+ ret = CKR_HOST_MEMORY;
+ }
+ }
+ }
+
+ if(ret == CKR_OK)
+ obj->slot = slot;
+
+ ckcapi_unlock_global();
+
+ return ret;
+
+}
diff --git a/ckcapi-trust.c b/ckcapi-trust.c
index 9ab0412..30e1200 100644
--- a/ckcapi-trust.c
+++ b/ckcapi-trust.c
@@ -372,7 +372,7 @@ register_trust_object(CkCapiSession* sess, CkCapiObject* cert, CkCapiObject** ob
tobj->obj.unique_key = UNIQUE_KEY_AT(tobj, otype);
tobj->obj.unique_len = UNIQUE_KEY_LEN(tobj, otype, cert_obj);
- ret = ckcapi_object_register(sess, &(tobj->obj));
+ ret = ckcapi_token_register_object(sess->slot, &(tobj->obj));
if(ret != CKR_OK)
{
free(tobj);
@@ -449,7 +449,7 @@ ckcapi_trust_find(CkCapiSession* sess, CK_OBJECT_CLASS cls,
id = ckcapi_array_index(certarr, CK_OBJECT_HANDLE, i);
ASSERT(id);
- certobj = ckcapi_object_lookup (sess, id);
+ certobj = ckcapi_token_lookup_object(sess->slot, id);
ASSERT(certobj);
/* We'll register a trust object for any loaded certificate */
diff --git a/ckcapi.c b/ckcapi.c
index 4635a3f..1a398b3 100644
--- a/ckcapi.c
+++ b/ckcapi.c
@@ -27,7 +27,6 @@
* GLOBALS / DEFINES
*/
-static CK_ULONG slot_id = 33; /* arbitrary */
static int cryptoki_initialized = 0;
static HANDLE global_mutex = NULL;
@@ -35,7 +34,6 @@ static HANDLE global_mutex = NULL;
#define LIBRARY_DESCRIPTION "Cryptoki CAPI Provider "
#define LIBRARY_VERSION_MAJOR 1
#define LIBRARY_VERSION_MINOR 1
-#define SLOT_DESCRIPTION "Windows Certificates and Keys "
#define HARDWARE_VERSION_MAJOR 0
#define HARDWARE_VERSION_MINOR 0
#define FIRMWARE_VERSION_MAJOR 0
@@ -202,8 +200,8 @@ CC_C_Finalize(CK_VOID_PTR pReserved)
cryptoki_initialized = 0;
- ckcapi_session_close_all();
- ckcapi_object_clear_all();
+ ckcapi_session_cleanup_all();
+ ckcapi_token_cleanup_all();
RETURN(CKR_OK);
}
@@ -239,46 +237,51 @@ CC_C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR list)
static CK_RV
CC_C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR slot_list, CK_ULONG_PTR count)
{
+ unsigned int n_tokens, i;
+
ENTER(C_GetSlotList);
PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
PREREQ(count, CKR_ARGUMENTS_BAD);
- /* Token is always present */
+ /* All tokens are always present */
+
+ n_tokens = ckcapi_token_get_count();
/* Application only wants to know the number of slots. */
if(slot_list == NULL)
{
- *count = 1;
+ *count = n_tokens;
RETURN(CKR_OK);
}
- if((*count < 1) && (slot_list != NULL))
+ if(*count < n_tokens)
{
- *count = 1;
+ *count = n_tokens;
RETURN(CKR_BUFFER_TOO_SMALL);
}
- *count = 1;
- slot_list[0] = slot_id;
+ *count = n_tokens;
+ for(i = 0; i < n_tokens; ++i)
+ slot_list[i] = i;
RETURN(CKR_OK);
}
static CK_RV
CC_C_GetSlotInfo(CK_SLOT_ID id, CK_SLOT_INFO_PTR info)
{
+ const char* name;
+
ENTER(C_GetSlotInfo);
PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
PREREQ(info, CKR_ARGUMENTS_BAD);
/* Make sure the slot ID is valid */
- if(id != slot_id)
+ if(!ckcapi_token_is_valid(id))
RETURN(CKR_SLOT_ID_INVALID);
- ASSERT(strlen(SLOT_DESCRIPTION) == 64);
ASSERT(strlen(MANUFACTURER_ID) == 32);
/* Provide information about the slot in the provided buffer */
- strncpy((char*)info->slotDescription, SLOT_DESCRIPTION, 64);
strncpy((char*)info->manufacturerID, MANUFACTURER_ID, 32);
info->hardwareVersion.major = HARDWARE_VERSION_MAJOR;
info->hardwareVersion.minor = HARDWARE_VERSION_MINOR;
@@ -288,27 +291,34 @@ CC_C_GetSlotInfo(CK_SLOT_ID id, CK_SLOT_INFO_PTR info)
/* Token is always present */
info->flags = CKF_TOKEN_PRESENT;
+ /* Slot name is blank padded, odd */
+ name = ckcapi_token_get_display_name(id);
+ memset((char*)info->slotDescription, ' ',
+ sizeof(info->slotDescription));
+ memcpy((char*)info->slotDescription, name,
+ min(strlen(name), sizeof(info->slotDescription)));
+
RETURN(CKR_OK);
}
static CK_RV
CC_C_GetTokenInfo(CK_SLOT_ID id, CK_TOKEN_INFO_PTR info)
{
+ const char* name;
+
ENTER(C_GetTokenInfo);
PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
PREREQ(info, CKR_ARGUMENTS_BAD);
/* Make sure the slot ID is valid */
- if(id != slot_id)
+ if(!ckcapi_token_is_valid(id))
RETURN(CKR_SLOT_ID_INVALID);
-
- ASSERT(strlen(SLOT_DESCRIPTION) == 64);
+
ASSERT(strlen(MANUFACTURER_ID) == 32);
ASSERT(strlen(SLOT_TOKEN_MODEL) == 16);
ASSERT(strlen(SLOT_TOKEN_SERIAL) == 16);
/* Provide information about a token in the provided buffer */
- strncpy((char*)info->label, SLOT_DESCRIPTION, 32);
strncpy((char*)info->manufacturerID, MANUFACTURER_ID, 32);
strncpy((char*)info->model, SLOT_TOKEN_MODEL, 16);
strncpy((char*)info->serialNumber, SLOT_TOKEN_SERIAL, 16);
@@ -331,6 +341,12 @@ CC_C_GetTokenInfo(CK_SLOT_ID id, CK_TOKEN_INFO_PTR info)
info->firmwareVersion.minor = FIRMWARE_VERSION_MINOR;
memset(info->utcTime, ' ', 16);
+ /* Slot name is blank padded, odd */
+ name = ckcapi_token_get_display_name(id);
+ memset((char*)info->label, ' ', sizeof(info->label));
+ memcpy((char*)info->label, name,
+ min(strlen(name), sizeof(info->label)));
+
RETURN(CKR_OK);
}
@@ -342,9 +358,12 @@ CC_C_GetMechanismList(CK_SLOT_ID id, CK_MECHANISM_TYPE_PTR mechanism_list,
PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
PREREQ(count, CKR_ARGUMENTS_BAD);
- if(id != slot_id)
+ if(!ckcapi_token_is_valid(id))
RETURN(CKR_SLOT_ID_INVALID);
+ /* TODO: Eventually we'll return stuff here */
+ /* mechanism_list[0] = CKM_RSA_PKCS; */
+
if(mechanism_list == NULL)
{
*count = 0;
@@ -357,7 +376,6 @@ CC_C_GetMechanismList(CK_SLOT_ID id, CK_MECHANISM_TYPE_PTR mechanism_list,
RETURN(CKR_BUFFER_TOO_SMALL);
}
- /* mechanism_list[0] = CKM_RSA_PKCS; */
*count = 0;
RETURN(CKR_OK);
}
@@ -370,17 +388,16 @@ CC_C_GetMechanismInfo(CK_SLOT_ID id, CK_MECHANISM_TYPE type,
PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
PREREQ(info, CKR_ARGUMENTS_BAD);
- if(id != slot_id)
+ if(!ckcapi_token_is_valid(id))
RETURN(CKR_SLOT_ID_INVALID);
- /* unsupported mechanism */
- if(type != CKM_RSA_PKCS)
- RETURN(CKR_MECHANISM_INVALID);
+ /* TODO: Eventually we'll return stuff here */
+ RETURN(CKR_MECHANISM_INVALID);
- info->ulMinKeySize = 384;
+ /* info->ulMinKeySize = 384;
info->ulMaxKeySize = 16384;
- info->flags = 0; /* TODO: Choose which we'll implement */
- RETURN(CKR_OK);
+ info->flags = 0;
+ RETURN(CKR_OK);*/
}
static CK_RV
@@ -421,12 +438,12 @@ CC_C_OpenSession(CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR application,
ENTER(C_OpenSession);
PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
- if(id != slot_id)
+ if(!ckcapi_token_is_valid(id))
RETURN(CKR_SLOT_ID_INVALID);
- sess = ckcapi_session_create();
- if(sess == NULL)
- RETURN(CKR_HOST_MEMORY);
+ ret = ckcapi_session_create(id, &sess);
+ if(ret != CKR_OK)
+ RETURN(ret);
sess->notify_callback = notify;
sess->user_data = application;
@@ -472,10 +489,10 @@ CC_C_CloseAllSessions(CK_SLOT_ID id)
ENTER(C_CloseAllSession);
PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
- if(id != slot_id)
+ if(!ckcapi_token_is_valid(id))
RETURN(CKR_SLOT_ID_INVALID);
- ckcapi_session_close_all();
+ ckcapi_session_close_all(id);
RETURN(CKR_OK);
}
diff --git a/ckcapi.dsp b/ckcapi.dsp
index e417998..4394881 100644
--- a/ckcapi.dsp
+++ b/ckcapi.dsp
@@ -108,6 +108,10 @@ SOURCE=".\ckcapi-session.c"
# End Source File
# Begin Source File
+SOURCE=".\ckcapi-token.c"
+# End Source File
+# Begin Source File
+
SOURCE=".\ckcapi-trust.c"
# End Source File
# Begin Source File
diff --git a/ckcapi.h b/ckcapi.h
index b6b8daf..4ccd1cb 100644
--- a/ckcapi.h
+++ b/ckcapi.h
@@ -48,14 +48,74 @@
#include "ckcapi-util.h"
+struct _CkCapiSlot;
struct _CkCapiObject;
struct _CkCapiObjectData;
struct _CkCapiSession;
+typedef struct _CkCapiSlot CkCapiSlot;
typedef struct _CkCapiObject CkCapiObject;
typedef struct _CkCapiObjectData CkCapiObjectData;
typedef struct _CkCapiSession CkCapiSession;
+/* ------------------------------------------------------------------
+ * ckcapi-token.c
+ */
+
+/* Debug print something about an object */
+#define DBGO(obj, msg) \
+ ckcapi_debug("O%d: %s", (obj) ? (obj)->id : 0, (msg))
+
+/* A function to load data for an object */
+typedef CK_RV (*CkCapiLoadData)(CkCapiSession* sess, struct _CkCapiObject* obj,
+ CkCapiObjectData** objdata);
+
+/* A function to free some data */
+typedef void (*CkCapiRelease)(void* data);
+
+/* Object functions */
+typedef struct _CkCapiObjectVtable
+{
+ CkCapiLoadData load_data;
+ CkCapiRelease release;
+}
+CkCapiObjectVtable;
+
+/* Represents a object we've seen */
+struct _CkCapiObject
+{
+ CK_OBJECT_HANDLE id;
+ CK_SLOT_ID slot;
+ CK_SESSION_HANDLE session;
+ const CkCapiObjectVtable* obj_funcs;
+ void* unique_key;
+ size_t unique_len;
+};
+
+/* Register a new object, a handle will be assigned to obj->id */
+CK_RV ckcapi_token_register_object (CK_SLOT_ID slot, CkCapiObject* obj);
+
+/* Lookup an object for a given object handle */
+CkCapiObject* ckcapi_token_lookup_object (CK_SLOT_ID slot, CK_OBJECT_HANDLE obj);
+
+/* Clear all objects for all tokens. Only done when finalizing */
+void ckcapi_token_cleanup_all (void);
+
+/* Get the number of the maximum object handle currently in memory */
+CK_OBJECT_HANDLE ckcapi_token_get_max_handle (void);
+
+unsigned int ckcapi_token_get_count (void);
+
+CK_BBOOL ckcapi_token_is_valid (CK_SLOT_ID slot);
+
+const char* ckcapi_token_get_display_name (CK_SLOT_ID slot);
+
+const char* ckcapi_token_get_store_name (CK_SLOT_ID slot);
+
+#define CKCAPI_SLOT_CA 0x00000001
+#define CKCAPI_SLOT_TRUSTED 0x00000002
+
+CK_ULONG ckcapi_token_get_flags (CK_SLOT_ID slot);
/* ------------------------------------------------------------------
* ckcapi-object.c
@@ -64,9 +124,6 @@ typedef struct _CkCapiSession CkCapiSession;
/* A function to get an attribute from ObjectData */
typedef CK_RV (*CkCapiGetAttribute)(CkCapiObjectData* objdata, CK_ATTRIBUTE_PTR attr);
-/* A function to free some data */
-typedef void (*CkCapiRelease)(void* data);
-
/* Object data functions */
typedef struct _CkCapiObjectDataVtable
{
@@ -100,45 +157,10 @@ CK_BBOOL ckcapi_object_data_match_attr (CkCapiObjectData* objdata,
CK_RV ckcapi_object_data_get_attrs (CkCapiObjectData* objdata, CK_ATTRIBUTE_PTR attrs,
CK_ULONG count);
-/* A function to load data for an object */
-typedef CK_RV (*CkCapiLoadData)(CkCapiSession* sess, struct _CkCapiObject* obj,
- CkCapiObjectData** objdata);
-
-/* Object functions */
-typedef struct _CkCapiObjectVtable
-{
- CkCapiLoadData load_data;
- CkCapiRelease release;
-}
-CkCapiObjectVtable;
-
-/* Represents a object we've seen */
-struct _CkCapiObject
-{
- CK_OBJECT_HANDLE id;
- const CkCapiObjectVtable* obj_funcs;
- void* unique_key;
- size_t unique_len;
-};
-
-/* Debug print something about an object */
-#define DBGO(obj, msg) \
- ckcapi_debug("O%d: %s", (obj) ? (obj)->id : 0, (msg))
+/* Debug print something about an object data */
#define DBGOD(objdata, msg) \
ckcapi_debug("O%d: %s", (objdata) ? (objdata)->obj : 0, (msg))
-/* Get the number of the maximum object handle currently in memory */
-CK_OBJECT_HANDLE ckcapi_object_get_max_handle (void);
-
-/* Lookup an object for a given object handle */
-CkCapiObject* ckcapi_object_lookup (CkCapiSession* sess, CK_OBJECT_HANDLE obj);
-
-/* Register a new object, a handle will be assigned to obj->id */
-CK_RV ckcapi_object_register (CkCapiSession* sess, CkCapiObject* obj);
-
-/* Clear all objects. Only done when finalizing */
-void ckcapi_object_clear_all (void);
-
/*
* Each object has a unique key which guarantees that we're
* not loading the same objects over and over again.
@@ -184,9 +206,12 @@ typedef void (*CkCapiSessionCancel) (struct _CkCapiSession* sess);
/* Represents an open session */
typedef struct _CkCapiSession
{
- CK_ULONG id; /* Unique ID for this session */
+ CK_SESSION_HANDLE id; /* Unique ID for this session */
+ CK_SLOT_ID slot;
int in_call; /* Whether this session is use in PKCS#11 function */
+ HCERTSTORE store; /* Handle to an open certificate store */
+
int operation_type; /* Whether an operation is happening or not */
void* operation_data; /* Data for this operation */
CkCapiSessionCancel operation_cancel; /* Callback to cancel operation when necessary */
@@ -206,7 +231,7 @@ CkCapiSession;
ckcapi_debug("S%d: %s", (sess) ? (sess)->id : 0, (msg))
/* Create a session */
-CkCapiSession* ckcapi_session_create (void);
+CK_RV ckcapi_session_create (CK_SLOT_ID slot, CkCapiSession** ret);
/* Destroy a session */
void ckcapi_session_destroy (CkCapiSession* sess);
@@ -221,8 +246,8 @@ CK_RV ckcapi_session_get_lock_ref (CK_ULONG id, int remove,
/* Unlock and unreference a session */
void ckcapi_session_unref_unlock (CkCapiSession* sess);
-/* Close all sessions */
-void ckcapi_session_close_all (void);
+/* Close all sessions on a certain slot/token */
+CK_RV ckcapi_session_close_all (CK_SLOT_ID slot);
@@ -271,7 +296,7 @@ void ckcapi_session_enum_object_data (CkCapiSession* sess,
CkCapiEnumObjectData enum_func,
void* arg);
-
+void ckcapi_session_cleanup_all (void);
/* -------------------------------------------------------------------
* ckcapi-cert.c