From d108e2008ec7205ef3907296fd3e5a810e45919b Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Tue, 9 Dec 2008 20:09:51 +0000 Subject: First shot at renaming the project. --- p11-capi-builtin.c | 245 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 p11-capi-builtin.c (limited to 'p11-capi-builtin.c') diff --git a/p11-capi-builtin.c b/p11-capi-builtin.c new file mode 100644 index 0000000..2757cb3 --- /dev/null +++ b/p11-capi-builtin.c @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2007 Stef Walter + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "p11-capi.h" +#include "p11-capi-object.h" +#include "p11-capi-session.h" +#include "p11-capi-token.h" + +#include "pkcs11/pkcs11n.h" + +/* -------------------------------------------------------------------------- + * BUILT IN VALUES + */ + +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"; + +/* -------------------------------------------------------------------------- + * BUILT IN OBJECTS + */ + +#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 } +}; + +typedef struct _BuiltinMatch +{ + CK_ATTRIBUTE_PTR attr; + CK_ULONG slot_flags; +} +BuiltinMatch; + +static const BuiltinMatch all_builtins[] = { + { (CK_ATTRIBUTE_PTR)&builtin_root, P11c_SLOT_TRUSTED | P11c_SLOT_CA | P11c_SLOT_CERTS }, + { NULL, 0 } +}; + +/* This is filled in later */ +static CK_ULONG num_builtins = 0; + +/* -------------------------------------------------------------------------- + * IMPLEMENTATION + */ + +/* Represents a loaded builtin object */ +typedef struct _BuiltinObject +{ + P11cObject obj; + CK_ATTRIBUTE_PTR attr; +} +BuiltinObject; + +typedef struct _BuiltinObjectData +{ + P11cObjectData base; + CK_ATTRIBUTE_PTR attr; +} +BuiltinObjectData; + +static CK_RV +builtin_attribute(P11cObjectData* objdata, CK_ATTRIBUTE_PTR attr) +{ + BuiltinObjectData* bdata = (BuiltinObjectData*)objdata; + CK_ATTRIBUTE_PTR builtin = bdata->attr; + + ASSERT(attr); + ASSERT(bdata); + + while(builtin->type != CK_END_LIST) + { + if(builtin->type == attr->type) + { + if(builtin->ulValueLen == 0) + return CKR_ATTRIBUTE_TYPE_INVALID; + return p11c_return_data(attr, builtin->pValue, builtin->ulValueLen); + } + + builtin++; + } + + return CKR_ATTRIBUTE_TYPE_INVALID; +} + +static void +builtin_data_release(void* data) +{ + BuiltinObjectData* bdata = (BuiltinObjectData*)data; + ASSERT(bdata); + free(bdata); +} + +static const P11cObjectDataVtable builtin_objdata_vtable = { + builtin_attribute, + builtin_attribute, + builtin_attribute, + builtin_data_release, +}; + +static CK_RV +builtin_load_data(P11cSession* sess, P11cObject* obj, P11cObjectData** objdata) +{ + BuiltinObject* bobj = (BuiltinObject*)obj; + BuiltinObjectData* bdata; + + ASSERT(bobj); + ASSERT(objdata); + ASSERT(num_builtins > 0); + + bdata = (BuiltinObjectData*)calloc(1, sizeof(BuiltinObjectData)); + if(!bdata) + return CKR_HOST_MEMORY; + + /* Simple, just use same data */ + bdata->attr = bobj->attr; + + bdata->base.object = obj->id; + bdata->base.data_funcs = &builtin_objdata_vtable; + + *objdata = &(bdata->base); + return CKR_OK; +} + +static unsigned int +builtin_hash_func(P11cObject* obj) +{ + return p11c_hash_pointer(((BuiltinObject*)obj)->attr); +} + +static int +builtin_equal_func(P11cObject* one, P11cObject* two) +{ + return ((BuiltinObject*)one)->attr == ((BuiltinObject*)two)->attr; +} + +static void +builtin_object_release(void* data) +{ + BuiltinObject* bobj = (BuiltinObject*)data; + ASSERT(bobj); + free(bobj); +} + +static const P11cObjectVtable builtin_object_vtable = { + builtin_load_data, + builtin_hash_func, + builtin_equal_func, + builtin_object_release, +}; + +static CK_RV +register_builtin_object(P11cSession* sess, CK_ATTRIBUTE_PTR attr, P11cObject** obj) +{ + BuiltinObject* bobj; + CK_RV ret; + + bobj = calloc(1, sizeof(BuiltinObject)); + if(!bobj) + return CKR_HOST_MEMORY; + + bobj->attr = attr; + + bobj->obj.id = 0; + bobj->obj.obj_funcs = &builtin_object_vtable; + + ret = p11c_token_register_object(sess->slot, &(bobj->obj)); + if(ret != CKR_OK) + { + free(bobj); + return ret; + } + + ASSERT(bobj->obj.id != 0); + *obj = &(bobj->obj); + return CKR_OK; +} + +CK_RV +p11c_builtin_find(P11cSession* sess, CK_OBJECT_CLASS cls, CK_ATTRIBUTE_PTR match, + CK_ULONG count, P11cArray* arr) +{ + P11cObject* obj; + BuiltinObjectData bdata; + CK_RV ret = CKR_OK; + CK_ULONG i, fl; + + /* First time around count total number */ + if(!num_builtins) + { + while(all_builtins[num_builtins].attr) + ++num_builtins; + ASSERT(num_builtins > 0); + } + + /* Match each certificate */ + for(i = 0; i < num_builtins; ++i) + { + /* Only apply built in objects to appropriate slots */ + fl = p11c_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(p11c_object_data_match(&bdata.base, match, count)) + { + ret = register_builtin_object(sess, all_builtins[i].attr, &obj); + if(ret != CKR_OK) + break; + + p11c_array_append(arr, obj->id); + } + } + + return ret; +} + -- cgit v1.2.3