Hi all, This is the patch about creation and destruction data objects with OpenSC PKCS#11 library. I test it with Alladin eToken PRO 32K. I hopes that it's correct ;-) --
Vincent
WYON
Dhimyotis 5 allée des écuries 59650 Villeneuve d'ascq tél. : 03 20 79 24 09
============================================= Ce mail est signé électroniquement grâce au système Certigna. Il a valeur légale. Pour plus d'informations, connectez-vous à : ============================================= |
Index: E:/Sources/opensc/svn_trunk/src/pkcs11/framework-pkcs15.c =================================================================== --- E:/Sources/opensc/svn_trunk/src/pkcs11/framework-pkcs15.c (rvision 3114) +++ E:/Sources/opensc/svn_trunk/src/pkcs11/framework-pkcs15.c (copie de travail) @@ -1260,6 +1260,72 @@ out: return rv; } +/* This function create a data object in the inserted card and create a new */ +/* PKCS#11 object too (like pkcs15_create_certificate, pkcs15_create_public_key) */ +static CK_RV pkcs15_create_data_object(struct sc_pkcs11_card *p11card, + struct sc_pkcs11_slot *slot, + struct sc_profile *profile, + CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phObject) +{ + struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data; + struct sc_pkcs15init_dataargs args; + struct pkcs15_any_object *data_any_obj; + struct sc_pkcs15_object *data_obj; + CK_BBOOL bPrivateData; + int rc, rv; + size_t i; + + memset(&args, 0, sizeof(args)); + + while (ulCount--) { + CK_ATTRIBUTE_PTR attr = pTemplate++; + + switch (attr->type) { + /* Skip attrs we already know or don't care for */ + case CKA_CLASS: + break; + case CKA_PRIVATE: + rv = attr_extract(attr, &bPrivateData, NULL); + /* If we want a private data object, then we must indicate it to the + * sc_pkcs15init_store_data_object function by using args.flags */ + if( bPrivateData ) + args.flags = SC_PKCS15_CO_FLAG_PRIVATE; + break; + case CKA_LABEL: + args.label = (char *) attr->pValue; + break; + case CKA_APPLICATION: + args.app_label = (char *) attr->pValue; + break; + case CKA_VALUE: + args.der_encoded.len = attr->ulValueLen; + args.der_encoded.value = (u8 *) attr->pValue; + break; + default: + /* ignore unknown attrs, or flag error? */ + continue; + } + } + + /* From PKCS#11 library, it's not possible to pass an OID attribute. + * So args.app_oid must be equal to -1 ! */ + args.app_oid.value[0] = -1; + + rc = sc_pkcs15init_store_data_object(fw_data->p15_card, profile, &args, &data_obj); + if (rc < 0) { + rv = sc_to_cryptoki_error(rc, p11card->reader); + goto out; + } + /* Create a new pkcs11 object for it */ + __pkcs15_create_data_object(fw_data, data_obj, &data_any_obj); + pkcs15_add_object(slot, data_any_obj, phObject); + + rv = CKR_OK; + +out: return rv; +} + static CK_RV pkcs15_create_object(struct sc_pkcs11_card *p11card, struct sc_pkcs11_slot *slot, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, @@ -1300,6 +1366,10 @@ rv = pkcs15_create_certificate(p11card, slot, profile, pTemplate, ulCount, phObject); break; + case CKO_DATA: + rv = pkcs15_create_data_object(p11card, slot, profile, + pTemplate, ulCount, phObject); + break; default: rv = CKR_FUNCTION_NOT_SUPPORTED; } @@ -2397,16 +2467,47 @@ return CKR_OK; } +/* This function allows the destruction of a data object */ +/* This function is stored in the structure sc_pkcs11_object_ops and used */ +/* with C_DestroyObject */ +static CK_RV pkcs15_dobj_destroy(struct sc_pkcs11_session *session, void *object) +{ + struct pkcs15_data_object *p15Obj = (struct pkcs15_data_object*) object; + struct sc_pkcs11_card *card = session->slot->card; + struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) card->fw_data; + struct sc_profile *profile = NULL; + int rv; + + rv = sc_lock(card->card); + if (rv < 0) + return sc_to_cryptoki_error(rv, card->reader); + + /* Bind the profile */ + rv = sc_pkcs15init_bind(card->card, "pkcs15", NULL, &profile); + if (rv < 0) { + sc_unlock(card->card); + return sc_to_cryptoki_error(rv, card->reader); + } + + rv = sc_pkcs15init_delete_object(fw_data->p15_card, profile, p15Obj->base.p15_object); + + sc_pkcs15init_unbind(profile); + sc_unlock(card->card); + + return rv; +} + + struct sc_pkcs11_object_ops pkcs15_dobj_ops = { pkcs15_dobj_release, pkcs15_dobj_set_attribute, pkcs15_dobj_get_attribute, sc_pkcs11_any_cmp_attribute, + pkcs15_dobj_destroy, NULL, NULL, NULL, NULL, - NULL, }; Index: E:/Sources/opensc/svn_trunk/src/pkcs11/pkcs11-object.c =================================================================== --- E:/Sources/opensc/svn_trunk/src/pkcs11/pkcs11-object.c (rvision 3114) +++ E:/Sources/opensc/svn_trunk/src/pkcs11/pkcs11-object.c (copie de travail) @@ -69,7 +69,34 @@ CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession, /* the session's handle */ CK_OBJECT_HANDLE hObject) /* the object's handle */ { - return CKR_FUNCTION_NOT_SUPPORTED; + struct sc_pkcs11_session *session; + struct sc_pkcs11_object *object; + char object_name[64]; + int rv; + + rv = sc_pkcs11_lock(); + if (rv != CKR_OK) + return rv; + + snprintf(object_name, sizeof(object_name), "C_DestroyObject : Object %lu", + (unsigned long) hObject); + sc_debug( context, object_name ); + + rv = pool_find(&session_pool, hSession, (void**) &session); + if (rv != CKR_OK) + goto out; + + rv = pool_find(&session->slot->object_pool, hObject, (void**) &object); + if (rv != CKR_OK) + goto out; + + if( object->ops->destroy_object == NULL ) + rv = CKR_FUNCTION_NOT_SUPPORTED; + else + rv = object->ops->destroy_object(session, object); + +out: sc_pkcs11_unlock(); + return rv; } CK_RV C_GetObjectSize(CK_SESSION_HANDLE hSession, /* the session's handle */ Index: E:/Sources/opensc/svn_trunk/src/pkcs15init/pkcs15-lib.c =================================================================== --- E:/Sources/opensc/svn_trunk/src/pkcs15init/pkcs15-lib.c (rvision 3114) +++ E:/Sources/opensc/svn_trunk/src/pkcs15init/pkcs15-lib.c (copie de travail) @@ -1827,12 +1827,23 @@ if (object == NULL) return SC_ERROR_OUT_OF_MEMORY; data_object_info = (sc_pkcs15_data_info_t *) object->data; - if (label != NULL) { + + /* The data_object_info->app_label must stores the object's application label if it's present. + * If not, it stores the object's label. */ + if( args->app_label != NULL ) { + strlcpy(data_object_info->app_label, args->app_label, + sizeof(data_object_info->app_label)); + } else { strlcpy(data_object_info->app_label, label, sizeof(data_object_info->app_label)); - } - data_object_info->app_oid = args->app_oid; + } + /* The object's flag have DEFAULT_DATA_FLAGS + flags of sc_pkcs15init_dataargs (if object + * is private) */ + object->flags |= args->flags; + + data_object_info->app_oid = args->app_oid; + r = sc_pkcs15init_store_data(p15card, profile, object, &args->id, &args->der_encoded, &data_object_info->path); Index: E:/Sources/opensc/svn_trunk/src/pkcs15init/pkcs15-init.h =================================================================== --- E:/Sources/opensc/svn_trunk/src/pkcs15init/pkcs15-init.h (rvision 3114) +++ E:/Sources/opensc/svn_trunk/src/pkcs15init/pkcs15-init.h (copie de travail) @@ -259,6 +259,11 @@ const char * app_label; struct sc_object_id app_oid; + /* This flag receives SC_PKCS15_CO_FLAG_PRIVATE (if data object is created with + * CKA_PRIVATE to TRUE). Because data object can be private or not. + * This flag is passed then to the object's flags.*/ + int flags; + sc_pkcs15_der_t der_encoded; /* Wrong name: is not DER encoded */ }; Index: E:/Sources/opensc/svn_trunk/src/pkcs15init/pkcs15-cardos.c =================================================================== --- E:/Sources/opensc/svn_trunk/src/pkcs15init/pkcs15-cardos.c (rvision 3114) +++ E:/Sources/opensc/svn_trunk/src/pkcs15init/pkcs15-cardos.c (copie de travail) @@ -754,6 +754,16 @@ return r; } +/* + * Try to delete a cardos file from his path + */ +static int cardos_delete_object(struct sc_profile *profile, struct sc_card *card, + unsigned int type, const void *data, const sc_path_t *path) +{ + /* For Cardos, all objects are files that can be deleted in any order */ + return sc_pkcs15init_delete_by_path(profile, card, path); +} + static struct sc_pkcs15init_operations sc_pkcs15init_cardos_operations = { cardos_erase, NULL, /* init_card */ @@ -768,7 +778,7 @@ NULL, NULL, /* encode private/public key */ NULL, /* finalize_card */ NULL, NULL, NULL, NULL, NULL, /* old style api */ - NULL /* delete_object */ + cardos_delete_object /* delete_object */ }; struct sc_pkcs15init_operations *
_______________________________________________ opensc-devel mailing list opensc-devel@lists.opensc-project.org http://www.opensc-project.org/mailman/listinfo/opensc-devel