summaryrefslogtreecommitdiff
path: root/ckcapi-builtin.c
diff options
context:
space:
mode:
Diffstat (limited to 'ckcapi-builtin.c')
-rw-r--r--ckcapi-builtin.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/ckcapi-builtin.c b/ckcapi-builtin.c
new file mode 100644
index 0000000..94d170e
--- /dev/null
+++ b/ckcapi-builtin.c
@@ -0,0 +1,190 @@
+
+#include "ckcapi.h"
+#include "pkcs11/pkcs11n.h"
+
+static const CK_BBOOL ck_true = CK_TRUE;
+static const CK_BBOOL ck_false = CK_FALSE;
+
+static const CK_OBJECT_CLASS cko_netscape_builtin_root_list = CKO_NETSCAPE_BUILTIN_ROOT_LIST;
+
+static const char ck_root_label[] = "Windows Certificate Roots";
+
+#define CK_END_LIST (CK_ULONG)-1
+
+static const CK_ATTRIBUTE builtin_root[] = {
+ { CKA_TOKEN, (void*)&ck_true, sizeof(CK_BBOOL) },
+ { CKA_CLASS, (void*)&cko_netscape_builtin_root_list, sizeof(CK_OBJECT_CLASS) },
+ { CKA_PRIVATE, (void*)&ck_false, sizeof(CK_BBOOL) },
+ { CKA_MODIFIABLE, (void*)&ck_false, sizeof(CK_BBOOL) },
+ { CKA_LABEL, (void*)ck_root_label, sizeof(ck_root_label) },
+ { CK_END_LIST, NULL, 0 }
+};
+
+static const CK_ATTRIBUTE_PTR all_builtins[] = {
+ (CK_ATTRIBUTE_PTR)&builtin_root,
+ NULL,
+};
+
+static CK_ULONG num_builtins = 0;
+
+typedef struct _BuiltinObject
+{
+ CkCapiObject obj;
+
+ /* Together these form the unique key. Must be contiguous */
+ unsigned int otype;
+ CK_ULONG builtin_index;
+}
+BuiltinObject;
+
+static CK_RV
+builtin_attribute(void* obj, CK_ATTRIBUTE_TYPE type,
+ CK_VOID_PTR data, CK_ULONG_PTR len)
+{
+ CK_ATTRIBUTE_PTR builtin = (CK_ATTRIBUTE_PTR)obj;
+
+ ASSERT(len);
+ ASSERT(obj);
+
+ while(builtin->type != CK_END_LIST)
+ {
+ if(builtin->type == type)
+ {
+ if(builtin->ulValueLen == 0)
+ return CKR_ATTRIBUTE_TYPE_INVALID;
+
+ if(!data)
+ {
+ *len = builtin->ulValueLen;
+ return CKR_OK;
+ }
+
+ if(builtin->ulValueLen > *len)
+ {
+ *len = builtin->ulValueLen;
+ return CKR_BUFFER_TOO_SMALL;
+ }
+
+ *len = builtin->ulValueLen;
+ memcpy(data, builtin->pValue, builtin->ulValueLen);
+ return CKR_OK;
+ }
+
+ builtin++;
+ }
+
+ return CKR_ATTRIBUTE_TYPE_INVALID;
+}
+
+static void
+builtin_release(void* data)
+{
+ /* Nothing to do to free builtin data */
+}
+
+static const CkCapiObjectDataVtable builtin_objdata_vtable = {
+ builtin_attribute,
+ builtin_attribute,
+ builtin_attribute,
+ builtin_attribute,
+ builtin_release,
+};
+
+static CK_RV
+builtin_load(CkCapiObject* obj, CkCapiObjectData* objdata)
+{
+ BuiltinObject* bobj = (BuiltinObject*)obj;
+
+ ASSERT(bobj);
+ ASSERT(objdata);
+ ASSERT(num_builtins > 0);
+
+ if(bobj->builtin_index > num_builtins)
+ return CKR_OBJECT_HANDLE_INVALID;
+
+ objdata->data = (void*)all_builtins[bobj->builtin_index];
+ objdata->data_funcs = builtin_objdata_vtable;
+
+ return CKR_OK;
+}
+
+
+static void
+builtin_object_release(void* data)
+{
+ BuiltinObject* bobj = (BuiltinObject*)data;
+ ASSERT(bobj);
+ free(bobj);
+}
+
+static const CkCapiObjectVtable builtin_object_vtable = {
+ builtin_load,
+ builtin_object_release,
+};
+
+static CK_RV
+register_builtin_object(CkCapiSession* sess, CK_ULONG index, CK_OBJECT_HANDLE_PTR id)
+{
+ BuiltinObject* bobj;
+ CK_RV ret;
+
+ bobj = calloc(sizeof(BuiltinObject), 1);
+ if(!bobj)
+ return CKR_HOST_MEMORY;
+
+ bobj->otype = OBJECT_BUILTIN;
+ bobj->builtin_index = index;
+
+ 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);
+
+ ret = ckcapi_object_register(sess, &(bobj->obj));
+ if(ret != CKR_OK)
+ {
+ free(bobj);
+ return ret;
+ }
+
+ ASSERT(bobj->obj.id != 0);
+ *id = bobj->obj.id;
+ return CKR_OK;
+}
+
+CK_RV
+ckcapi_builtin_find_all(CkCapiSession* sess, CK_ATTRIBUTE_PTR match,
+ CK_ULONG count, CkCapiArray* arr)
+{
+ CK_OBJECT_HANDLE obj;
+ CkCapiObjectData objdata;
+ CK_RV ret = CKR_OK;
+ CK_ULONG i;
+
+ /* First time around count total number */
+ if(!num_builtins)
+ {
+ while(all_builtins[num_builtins])
+ ++num_builtins;
+ ASSERT(num_builtins > 0);
+ }
+
+ /* Match each certificate */
+ for(i = 0; i < num_builtins; ++i)
+ {
+ objdata.data = (void*)all_builtins[i];
+ objdata.data_funcs = builtin_objdata_vtable;
+
+ if(ckcapi_object_data_match(&objdata, match, count))
+ {
+ ret = register_builtin_object(sess, i, &obj);
+ if(ret != CKR_OK)
+ break;
+
+ ckcapi_array_append(arr, obj);
+ }
+ }
+
+ return ret;
+}
+