1b56b3d07SJens Wiklander // SPDX-License-Identifier: BSD-2-Clause 2b56b3d07SJens Wiklander /* 3b56b3d07SJens Wiklander * Copyright (c) 2017-2020, Linaro Limited 4b56b3d07SJens Wiklander */ 5b56b3d07SJens Wiklander 6b56b3d07SJens Wiklander #include <assert.h> 7b56b3d07SJens Wiklander #include <inttypes.h> 8b56b3d07SJens Wiklander #include <string_ext.h> 9b56b3d07SJens Wiklander #include <tee_internal_api.h> 10b56b3d07SJens Wiklander #include <tee_internal_api_extensions.h> 11b56b3d07SJens Wiklander 12b56b3d07SJens Wiklander #include "attributes.h" 13b56b3d07SJens Wiklander #include "handle.h" 14b56b3d07SJens Wiklander #include "object.h" 15b56b3d07SJens Wiklander #include "pkcs11_attributes.h" 16b56b3d07SJens Wiklander #include "pkcs11_helpers.h" 17b56b3d07SJens Wiklander #include "pkcs11_token.h" 18b56b3d07SJens Wiklander #include "sanitize_object.h" 19b56b3d07SJens Wiklander #include "serializer.h" 20b56b3d07SJens Wiklander 21b56b3d07SJens Wiklander struct pkcs11_object *pkcs11_handle2object(uint32_t handle, 22b56b3d07SJens Wiklander struct pkcs11_session *session) 23b56b3d07SJens Wiklander { 24b56b3d07SJens Wiklander return handle_lookup(&session->object_handle_db, handle); 25b56b3d07SJens Wiklander } 26b56b3d07SJens Wiklander 27b56b3d07SJens Wiklander uint32_t pkcs11_object2handle(struct pkcs11_object *obj, 28b56b3d07SJens Wiklander struct pkcs11_session *session) 29b56b3d07SJens Wiklander { 30b56b3d07SJens Wiklander return handle_lookup_handle(&session->object_handle_db, obj); 31b56b3d07SJens Wiklander } 32b56b3d07SJens Wiklander 33b56b3d07SJens Wiklander /* Currently handle pkcs11 sessions and tokens */ 34b56b3d07SJens Wiklander 35b56b3d07SJens Wiklander static struct object_list *get_session_objects(void *session) 36b56b3d07SJens Wiklander { 37b56b3d07SJens Wiklander /* Currently supporting only pkcs11 session */ 38b56b3d07SJens Wiklander struct pkcs11_session *ck_session = session; 39b56b3d07SJens Wiklander 40b56b3d07SJens Wiklander return pkcs11_get_session_objects(ck_session); 41b56b3d07SJens Wiklander } 42b56b3d07SJens Wiklander 43*334316feSJens Wiklander static struct ck_token *get_session_token(void *session) 44*334316feSJens Wiklander { 45*334316feSJens Wiklander struct pkcs11_session *ck_session = session; 46*334316feSJens Wiklander 47*334316feSJens Wiklander return pkcs11_session2token(ck_session); 48*334316feSJens Wiklander } 49*334316feSJens Wiklander 50b56b3d07SJens Wiklander /* Release resources of a non-persistent object */ 51b56b3d07SJens Wiklander static void cleanup_volatile_obj_ref(struct pkcs11_object *obj) 52b56b3d07SJens Wiklander { 53b56b3d07SJens Wiklander if (!obj) 54b56b3d07SJens Wiklander return; 55b56b3d07SJens Wiklander 56b56b3d07SJens Wiklander if (obj->key_handle != TEE_HANDLE_NULL) 57b56b3d07SJens Wiklander TEE_FreeTransientObject(obj->key_handle); 58b56b3d07SJens Wiklander 59b56b3d07SJens Wiklander if (obj->attribs_hdl != TEE_HANDLE_NULL) 60b56b3d07SJens Wiklander TEE_CloseObject(obj->attribs_hdl); 61b56b3d07SJens Wiklander 62b56b3d07SJens Wiklander TEE_Free(obj->attributes); 63b56b3d07SJens Wiklander TEE_Free(obj->uuid); 64b56b3d07SJens Wiklander TEE_Free(obj); 65b56b3d07SJens Wiklander } 66b56b3d07SJens Wiklander 67b56b3d07SJens Wiklander /* Release resources of a persistent object including volatile resources */ 68*334316feSJens Wiklander static void cleanup_persistent_object(struct pkcs11_object *obj, 69*334316feSJens Wiklander struct ck_token *token) 70b56b3d07SJens Wiklander { 71*334316feSJens Wiklander TEE_Result res = TEE_SUCCESS; 72*334316feSJens Wiklander 73*334316feSJens Wiklander if (!obj) 74*334316feSJens Wiklander return; 75*334316feSJens Wiklander 76*334316feSJens Wiklander /* Open handle with write properties to destroy the object */ 77*334316feSJens Wiklander if (obj->attribs_hdl != TEE_HANDLE_NULL) 78*334316feSJens Wiklander TEE_CloseObject(obj->attribs_hdl); 79*334316feSJens Wiklander 80*334316feSJens Wiklander res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE, 81*334316feSJens Wiklander obj->uuid, sizeof(TEE_UUID), 82*334316feSJens Wiklander TEE_DATA_FLAG_ACCESS_WRITE_META, 83*334316feSJens Wiklander &obj->attribs_hdl); 84*334316feSJens Wiklander if (!res) 85*334316feSJens Wiklander TEE_CloseAndDeletePersistentObject1(obj->attribs_hdl); 86*334316feSJens Wiklander 87*334316feSJens Wiklander obj->attribs_hdl = TEE_HANDLE_NULL; 88*334316feSJens Wiklander destroy_object_uuid(token, obj); 89*334316feSJens Wiklander 90*334316feSJens Wiklander LIST_REMOVE(obj, link); 91*334316feSJens Wiklander 92*334316feSJens Wiklander cleanup_volatile_obj_ref(obj); 93b56b3d07SJens Wiklander } 94b56b3d07SJens Wiklander 95b56b3d07SJens Wiklander /* 96b56b3d07SJens Wiklander * destroy_object - destroy an PKCS11 TA object 97b56b3d07SJens Wiklander * 98b56b3d07SJens Wiklander * @session - session requesting object destruction 99b56b3d07SJens Wiklander * @obj - reference to the PKCS11 TA object 100b56b3d07SJens Wiklander * @session_only - true if only session object shall be destroyed 101b56b3d07SJens Wiklander */ 102b56b3d07SJens Wiklander void destroy_object(struct pkcs11_session *session, struct pkcs11_object *obj, 103b56b3d07SJens Wiklander bool session_only) 104b56b3d07SJens Wiklander { 105b56b3d07SJens Wiklander #ifdef DEBUG 106b56b3d07SJens Wiklander trace_attributes("[destroy]", obj->attributes); 107b56b3d07SJens Wiklander if (obj->uuid) 108b56b3d07SJens Wiklander MSG_RAW("[destroy] obj uuid %pUl", (void *)obj->uuid); 109b56b3d07SJens Wiklander #endif 110b56b3d07SJens Wiklander 111b56b3d07SJens Wiklander /* 112b56b3d07SJens Wiklander * Remove from session list only if it was published. 113b56b3d07SJens Wiklander * 114b56b3d07SJens Wiklander * This depends on obj->link.le_prev always pointing on the 115b56b3d07SJens Wiklander * link.le_next element in the previous object in the list even if 116b56b3d07SJens Wiklander * there's only a single object in the list. In the first object in 117b56b3d07SJens Wiklander * the list obj->link.le_prev instead points to lh_first in the 118b56b3d07SJens Wiklander * list head. If list implementation is changed we need to revisit 119b56b3d07SJens Wiklander * this. 120b56b3d07SJens Wiklander */ 121b56b3d07SJens Wiklander if (obj->link.le_next || obj->link.le_prev) 122b56b3d07SJens Wiklander LIST_REMOVE(obj, link); 123b56b3d07SJens Wiklander 124b56b3d07SJens Wiklander if (session_only) { 125b56b3d07SJens Wiklander /* Destroy object due to session closure */ 126b56b3d07SJens Wiklander handle_put(&session->object_handle_db, 127b56b3d07SJens Wiklander pkcs11_object2handle(obj, session)); 128b56b3d07SJens Wiklander cleanup_volatile_obj_ref(obj); 129b56b3d07SJens Wiklander 130b56b3d07SJens Wiklander return; 131b56b3d07SJens Wiklander } 132b56b3d07SJens Wiklander 133b56b3d07SJens Wiklander /* Destroy target object (persistent or not) */ 134b56b3d07SJens Wiklander if (get_bool(obj->attributes, PKCS11_CKA_TOKEN)) { 135*334316feSJens Wiklander assert(obj->uuid); 136*334316feSJens Wiklander /* Try twice otherwise panic! */ 137*334316feSJens Wiklander if (unregister_persistent_object(session->token, obj->uuid) && 138*334316feSJens Wiklander unregister_persistent_object(session->token, obj->uuid)) 139b56b3d07SJens Wiklander TEE_Panic(0); 140*334316feSJens Wiklander 141*334316feSJens Wiklander handle_put(&session->object_handle_db, 142*334316feSJens Wiklander pkcs11_object2handle(obj, session)); 143*334316feSJens Wiklander cleanup_persistent_object(obj, session->token); 144b56b3d07SJens Wiklander } else { 145b56b3d07SJens Wiklander handle_put(&session->object_handle_db, 146b56b3d07SJens Wiklander pkcs11_object2handle(obj, session)); 147b56b3d07SJens Wiklander cleanup_volatile_obj_ref(obj); 148b56b3d07SJens Wiklander } 149b56b3d07SJens Wiklander } 150b56b3d07SJens Wiklander 151b56b3d07SJens Wiklander static struct pkcs11_object *create_obj_instance(struct obj_attrs *head) 152b56b3d07SJens Wiklander { 153b56b3d07SJens Wiklander struct pkcs11_object *obj = NULL; 154b56b3d07SJens Wiklander 155b56b3d07SJens Wiklander obj = TEE_Malloc(sizeof(struct pkcs11_object), TEE_MALLOC_FILL_ZERO); 156b56b3d07SJens Wiklander if (!obj) 157b56b3d07SJens Wiklander return NULL; 158b56b3d07SJens Wiklander 159b56b3d07SJens Wiklander obj->key_handle = TEE_HANDLE_NULL; 160b56b3d07SJens Wiklander obj->attribs_hdl = TEE_HANDLE_NULL; 161b56b3d07SJens Wiklander obj->attributes = head; 162b56b3d07SJens Wiklander 163b56b3d07SJens Wiklander return obj; 164b56b3d07SJens Wiklander } 165b56b3d07SJens Wiklander 166*334316feSJens Wiklander struct pkcs11_object *create_token_object(struct obj_attrs *head, 167*334316feSJens Wiklander TEE_UUID *uuid) 168*334316feSJens Wiklander { 169*334316feSJens Wiklander struct pkcs11_object *obj = create_obj_instance(head); 170*334316feSJens Wiklander 171*334316feSJens Wiklander if (obj) 172*334316feSJens Wiklander obj->uuid = uuid; 173*334316feSJens Wiklander 174*334316feSJens Wiklander return obj; 175*334316feSJens Wiklander } 176*334316feSJens Wiklander 177b56b3d07SJens Wiklander /* 178b56b3d07SJens Wiklander * create_object - create an PKCS11 TA object from its attributes and value 179b56b3d07SJens Wiklander * 180b56b3d07SJens Wiklander * @sess - session requesting object creation 181b56b3d07SJens Wiklander * @head - reference to serialized attributes 182b56b3d07SJens Wiklander * @out_handle - generated handle for the created object 183b56b3d07SJens Wiklander */ 184b56b3d07SJens Wiklander enum pkcs11_rc create_object(void *sess, struct obj_attrs *head, 185b56b3d07SJens Wiklander uint32_t *out_handle) 186b56b3d07SJens Wiklander { 187b56b3d07SJens Wiklander enum pkcs11_rc rc = 0; 188b56b3d07SJens Wiklander struct pkcs11_object *obj = NULL; 189b56b3d07SJens Wiklander struct pkcs11_session *session = (struct pkcs11_session *)sess; 190b56b3d07SJens Wiklander uint32_t obj_handle = 0; 191b56b3d07SJens Wiklander 192b56b3d07SJens Wiklander #ifdef DEBUG 193b56b3d07SJens Wiklander trace_attributes("[create]", head); 194b56b3d07SJens Wiklander #endif 195b56b3d07SJens Wiklander 196b56b3d07SJens Wiklander /* 197b56b3d07SJens Wiklander * We do not check the key attributes. At this point, key attributes 198b56b3d07SJens Wiklander * are expected consistent and reliable. 199b56b3d07SJens Wiklander */ 200b56b3d07SJens Wiklander 201b56b3d07SJens Wiklander obj = create_obj_instance(head); 202b56b3d07SJens Wiklander if (!obj) 203b56b3d07SJens Wiklander return PKCS11_CKR_DEVICE_MEMORY; 204b56b3d07SJens Wiklander 205b56b3d07SJens Wiklander /* Create a handle for the object in the session database */ 206b56b3d07SJens Wiklander obj_handle = handle_get(&session->object_handle_db, obj); 207b56b3d07SJens Wiklander if (!obj_handle) { 208b56b3d07SJens Wiklander rc = PKCS11_CKR_DEVICE_MEMORY; 209b56b3d07SJens Wiklander goto err; 210b56b3d07SJens Wiklander } 211b56b3d07SJens Wiklander 212b56b3d07SJens Wiklander if (get_bool(obj->attributes, PKCS11_CKA_TOKEN)) { 213*334316feSJens Wiklander TEE_Result res = TEE_SUCCESS; 214*334316feSJens Wiklander 215*334316feSJens Wiklander /* 216*334316feSJens Wiklander * Get an ID for the persistent object 217*334316feSJens Wiklander * Create the file 218*334316feSJens Wiklander * Register the object in the persistent database 219*334316feSJens Wiklander * (move the full sequence to persisent_db.c?) 220*334316feSJens Wiklander */ 221*334316feSJens Wiklander size_t size = sizeof(struct obj_attrs) + 222*334316feSJens Wiklander obj->attributes->attrs_size; 223*334316feSJens Wiklander uint32_t tee_obj_flags = TEE_DATA_FLAG_ACCESS_READ | 224*334316feSJens Wiklander TEE_DATA_FLAG_ACCESS_WRITE | 225*334316feSJens Wiklander TEE_DATA_FLAG_ACCESS_WRITE_META; 226*334316feSJens Wiklander 227*334316feSJens Wiklander rc = create_object_uuid(get_session_token(session), obj); 228*334316feSJens Wiklander if (rc) 229*334316feSJens Wiklander goto err; 230*334316feSJens Wiklander 231*334316feSJens Wiklander res = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE, 232*334316feSJens Wiklander obj->uuid, sizeof(TEE_UUID), 233*334316feSJens Wiklander tee_obj_flags, 234*334316feSJens Wiklander TEE_HANDLE_NULL, 235*334316feSJens Wiklander obj->attributes, size, 236*334316feSJens Wiklander &obj->attribs_hdl); 237*334316feSJens Wiklander if (res) { 238*334316feSJens Wiklander rc = tee2pkcs_error(res); 239*334316feSJens Wiklander goto err; 240*334316feSJens Wiklander } 241*334316feSJens Wiklander 242*334316feSJens Wiklander rc = register_persistent_object(get_session_token(session), 243*334316feSJens Wiklander obj->uuid); 244*334316feSJens Wiklander if (rc) 245*334316feSJens Wiklander goto err; 246*334316feSJens Wiklander 247*334316feSJens Wiklander LIST_INSERT_HEAD(&session->token->object_list, obj, link); 248b56b3d07SJens Wiklander } else { 249b56b3d07SJens Wiklander rc = PKCS11_CKR_OK; 250b56b3d07SJens Wiklander LIST_INSERT_HEAD(get_session_objects(session), obj, link); 251b56b3d07SJens Wiklander } 252b56b3d07SJens Wiklander 253b56b3d07SJens Wiklander *out_handle = obj_handle; 254b56b3d07SJens Wiklander 255b56b3d07SJens Wiklander return PKCS11_CKR_OK; 256b56b3d07SJens Wiklander err: 257b56b3d07SJens Wiklander /* make sure that supplied "head" isn't freed */ 258b56b3d07SJens Wiklander obj->attributes = NULL; 259b56b3d07SJens Wiklander handle_put(&session->object_handle_db, obj_handle); 260b56b3d07SJens Wiklander if (get_bool(head, PKCS11_CKA_TOKEN)) 261b56b3d07SJens Wiklander cleanup_persistent_object(obj, session->token); 262b56b3d07SJens Wiklander else 263b56b3d07SJens Wiklander cleanup_volatile_obj_ref(obj); 264b56b3d07SJens Wiklander 265b56b3d07SJens Wiklander return rc; 266b56b3d07SJens Wiklander } 267b56b3d07SJens Wiklander 268b56b3d07SJens Wiklander enum pkcs11_rc entry_create_object(struct pkcs11_client *client, 269b56b3d07SJens Wiklander uint32_t ptypes, TEE_Param *params) 270b56b3d07SJens Wiklander { 271b56b3d07SJens Wiklander const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 272b56b3d07SJens Wiklander TEE_PARAM_TYPE_NONE, 273b56b3d07SJens Wiklander TEE_PARAM_TYPE_MEMREF_OUTPUT, 274b56b3d07SJens Wiklander TEE_PARAM_TYPE_NONE); 275b56b3d07SJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 276b56b3d07SJens Wiklander TEE_Param *ctrl = params; 277b56b3d07SJens Wiklander TEE_Param *out = params + 2; 278b56b3d07SJens Wiklander struct serialargs ctrlargs = { }; 279b56b3d07SJens Wiklander struct pkcs11_session *session = NULL; 280b56b3d07SJens Wiklander struct obj_attrs *head = NULL; 281b56b3d07SJens Wiklander struct pkcs11_object_head *template = NULL; 282b56b3d07SJens Wiklander uint32_t session_handle = 0; 283b56b3d07SJens Wiklander size_t template_size = 0; 284b56b3d07SJens Wiklander uint32_t obj_handle = 0; 285b56b3d07SJens Wiklander 286b56b3d07SJens Wiklander /* 287b56b3d07SJens Wiklander * Collect the arguments of the request 288b56b3d07SJens Wiklander */ 289b56b3d07SJens Wiklander 290b56b3d07SJens Wiklander if (!client || ptypes != exp_pt || 291b56b3d07SJens Wiklander out->memref.size != sizeof(obj_handle)) 292b56b3d07SJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 293b56b3d07SJens Wiklander 294b56b3d07SJens Wiklander serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 295b56b3d07SJens Wiklander 296b56b3d07SJens Wiklander rc = serialargs_get(&ctrlargs, &session_handle, sizeof(uint32_t)); 297b56b3d07SJens Wiklander if (rc) 298b56b3d07SJens Wiklander return rc; 299b56b3d07SJens Wiklander 300b56b3d07SJens Wiklander rc = serialargs_alloc_get_attributes(&ctrlargs, &template); 301b56b3d07SJens Wiklander if (rc) 302b56b3d07SJens Wiklander return rc; 303b56b3d07SJens Wiklander 304b56b3d07SJens Wiklander if (serialargs_remaining_bytes(&ctrlargs)) { 305b56b3d07SJens Wiklander rc = PKCS11_CKR_ARGUMENTS_BAD; 306b56b3d07SJens Wiklander goto out; 307b56b3d07SJens Wiklander } 308b56b3d07SJens Wiklander 309b56b3d07SJens Wiklander session = pkcs11_handle2session(session_handle, client); 310b56b3d07SJens Wiklander if (!session) { 311b56b3d07SJens Wiklander rc = PKCS11_CKR_SESSION_HANDLE_INVALID; 312b56b3d07SJens Wiklander goto out; 313b56b3d07SJens Wiklander } 314b56b3d07SJens Wiklander 315b56b3d07SJens Wiklander template_size = sizeof(*template) + template->attrs_size; 316b56b3d07SJens Wiklander 317b56b3d07SJens Wiklander /* 318b56b3d07SJens Wiklander * Prepare a clean initial state for the requested object attributes. 319b56b3d07SJens Wiklander * Free temporary template once done. 320b56b3d07SJens Wiklander */ 321b56b3d07SJens Wiklander rc = create_attributes_from_template(&head, template, template_size, 322b56b3d07SJens Wiklander NULL, PKCS11_FUNCTION_IMPORT, 323b56b3d07SJens Wiklander PKCS11_PROCESSING_IMPORT); 324b56b3d07SJens Wiklander TEE_Free(template); 325b56b3d07SJens Wiklander template = NULL; 326b56b3d07SJens Wiklander if (rc) 327b56b3d07SJens Wiklander goto out; 328b56b3d07SJens Wiklander 329b56b3d07SJens Wiklander /* 330b56b3d07SJens Wiklander * Check target object attributes match target processing 331b56b3d07SJens Wiklander * Check target object attributes match token state 332b56b3d07SJens Wiklander */ 333b56b3d07SJens Wiklander rc = check_created_attrs_against_processing(PKCS11_PROCESSING_IMPORT, 334b56b3d07SJens Wiklander head); 335b56b3d07SJens Wiklander if (rc) 336b56b3d07SJens Wiklander goto out; 337b56b3d07SJens Wiklander 338b56b3d07SJens Wiklander rc = check_created_attrs_against_token(session, head); 339b56b3d07SJens Wiklander if (rc) 340b56b3d07SJens Wiklander goto out; 341b56b3d07SJens Wiklander 342b56b3d07SJens Wiklander /* 343b56b3d07SJens Wiklander * At this stage the object is almost created: all its attributes are 344b56b3d07SJens Wiklander * referenced in @head, including the key value and are assumed 345b56b3d07SJens Wiklander * reliable. Now need to register it and get a handle for it. 346b56b3d07SJens Wiklander */ 347b56b3d07SJens Wiklander rc = create_object(session, head, &obj_handle); 348b56b3d07SJens Wiklander if (rc) 349b56b3d07SJens Wiklander goto out; 350b56b3d07SJens Wiklander 351b56b3d07SJens Wiklander /* 352b56b3d07SJens Wiklander * Now obj_handle (through the related struct pkcs11_object 353b56b3d07SJens Wiklander * instance) owns the serialised buffer that holds the object 354b56b3d07SJens Wiklander * attributes. We clear reference in head to NULL as the serializer 355b56b3d07SJens Wiklander * object is now referred from obj_handle. This allows smooth pass 356b56b3d07SJens Wiklander * through free at function exit. 357b56b3d07SJens Wiklander */ 358b56b3d07SJens Wiklander head = NULL; 359b56b3d07SJens Wiklander 360b56b3d07SJens Wiklander TEE_MemMove(out->memref.buffer, &obj_handle, sizeof(obj_handle)); 361b56b3d07SJens Wiklander out->memref.size = sizeof(obj_handle); 362b56b3d07SJens Wiklander 363b56b3d07SJens Wiklander DMSG("PKCS11 session %"PRIu32": import object %#"PRIx32, 364b56b3d07SJens Wiklander session->handle, obj_handle); 365b56b3d07SJens Wiklander 366b56b3d07SJens Wiklander out: 367b56b3d07SJens Wiklander TEE_Free(template); 368b56b3d07SJens Wiklander TEE_Free(head); 369b56b3d07SJens Wiklander 370b56b3d07SJens Wiklander return rc; 371b56b3d07SJens Wiklander } 372b56b3d07SJens Wiklander 373b56b3d07SJens Wiklander enum pkcs11_rc entry_destroy_object(struct pkcs11_client *client, 374b56b3d07SJens Wiklander uint32_t ptypes, TEE_Param *params) 375b56b3d07SJens Wiklander { 376b56b3d07SJens Wiklander const uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, 377b56b3d07SJens Wiklander TEE_PARAM_TYPE_NONE, 378b56b3d07SJens Wiklander TEE_PARAM_TYPE_NONE, 379b56b3d07SJens Wiklander TEE_PARAM_TYPE_NONE); 380b56b3d07SJens Wiklander enum pkcs11_rc rc = PKCS11_CKR_OK; 381b56b3d07SJens Wiklander TEE_Param *ctrl = params; 382b56b3d07SJens Wiklander struct serialargs ctrlargs = { }; 383b56b3d07SJens Wiklander uint32_t object_handle = 0; 384b56b3d07SJens Wiklander struct pkcs11_session *session = NULL; 385b56b3d07SJens Wiklander struct pkcs11_object *object = NULL; 386b56b3d07SJens Wiklander uint32_t session_handle = 0; 387b56b3d07SJens Wiklander 388b56b3d07SJens Wiklander if (!client || ptypes != exp_pt) 389b56b3d07SJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 390b56b3d07SJens Wiklander 391b56b3d07SJens Wiklander serialargs_init(&ctrlargs, ctrl->memref.buffer, ctrl->memref.size); 392b56b3d07SJens Wiklander 393b56b3d07SJens Wiklander rc = serialargs_get_u32(&ctrlargs, &session_handle); 394b56b3d07SJens Wiklander if (rc) 395b56b3d07SJens Wiklander return rc; 396b56b3d07SJens Wiklander 397b56b3d07SJens Wiklander rc = serialargs_get_u32(&ctrlargs, &object_handle); 398b56b3d07SJens Wiklander if (rc) 399b56b3d07SJens Wiklander return rc; 400b56b3d07SJens Wiklander 401b56b3d07SJens Wiklander if (serialargs_remaining_bytes(&ctrlargs)) 402b56b3d07SJens Wiklander return PKCS11_CKR_ARGUMENTS_BAD; 403b56b3d07SJens Wiklander 404b56b3d07SJens Wiklander session = pkcs11_handle2session(session_handle, client); 405b56b3d07SJens Wiklander if (!session) 406b56b3d07SJens Wiklander return PKCS11_CKR_SESSION_HANDLE_INVALID; 407b56b3d07SJens Wiklander 408b56b3d07SJens Wiklander object = pkcs11_handle2object(object_handle, session); 409b56b3d07SJens Wiklander if (!object) 410b56b3d07SJens Wiklander return PKCS11_CKR_OBJECT_HANDLE_INVALID; 411b56b3d07SJens Wiklander 412b56b3d07SJens Wiklander destroy_object(session, object, false); 413b56b3d07SJens Wiklander 414b56b3d07SJens Wiklander DMSG("PKCS11 session %"PRIu32": destroy object %#"PRIx32, 415b56b3d07SJens Wiklander session->handle, object_handle); 416b56b3d07SJens Wiklander 417b56b3d07SJens Wiklander return rc; 418b56b3d07SJens Wiklander } 419