17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 590e0e8c4Sizick * Common Development and Distribution License (the "License"). 690e0e8c4Sizick * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21*726fad2aSDina K Nimeh 227c478bd9Sstevel@tonic-gate /* 23*726fad2aSDina K Nimeh * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <pthread.h> 277c478bd9Sstevel@tonic-gate #include <stdio.h> 287c478bd9Sstevel@tonic-gate #include <stdlib.h> 297c478bd9Sstevel@tonic-gate #include <string.h> 307c478bd9Sstevel@tonic-gate #include <security/cryptoki.h> 317c478bd9Sstevel@tonic-gate #include "softGlobal.h" 327c478bd9Sstevel@tonic-gate #include "softObject.h" 337c478bd9Sstevel@tonic-gate #include "softSession.h" 347c478bd9Sstevel@tonic-gate #include "softKeystore.h" 357c478bd9Sstevel@tonic-gate #include "softKeystoreUtil.h" 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate /* 387c478bd9Sstevel@tonic-gate * Add an object to the session's object list. 397c478bd9Sstevel@tonic-gate * 407c478bd9Sstevel@tonic-gate * This function will acquire the lock on the session, and release 417c478bd9Sstevel@tonic-gate * that lock after adding the object to the session's object list. 427c478bd9Sstevel@tonic-gate */ 437c478bd9Sstevel@tonic-gate void 447c478bd9Sstevel@tonic-gate soft_add_object_to_session(soft_object_t *objp, soft_session_t *sp) 457c478bd9Sstevel@tonic-gate { 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate /* Acquire the session lock. */ 487c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&sp->session_mutex); 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate /* Insert the new object in front of session's object list. */ 517c478bd9Sstevel@tonic-gate if (sp->object_list == NULL) { 527c478bd9Sstevel@tonic-gate sp->object_list = objp; 537c478bd9Sstevel@tonic-gate objp->next = NULL; 547c478bd9Sstevel@tonic-gate objp->prev = NULL; 557c478bd9Sstevel@tonic-gate } else { 567c478bd9Sstevel@tonic-gate sp->object_list->prev = objp; 577c478bd9Sstevel@tonic-gate objp->next = sp->object_list; 587c478bd9Sstevel@tonic-gate objp->prev = NULL; 597c478bd9Sstevel@tonic-gate sp->object_list = objp; 607c478bd9Sstevel@tonic-gate } 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate /* Release the session lock. */ 637c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&sp->session_mutex); 647c478bd9Sstevel@tonic-gate } 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate /* 687c478bd9Sstevel@tonic-gate * Clean up and release the storage allocated to the object. 697c478bd9Sstevel@tonic-gate * 707c478bd9Sstevel@tonic-gate * The function is called either with the object lock being held 717c478bd9Sstevel@tonic-gate * (by caller soft_delete_object()), or there is no object lock 727c478bd9Sstevel@tonic-gate * yet (by soft_build_XXX_object() during creating an object). 737c478bd9Sstevel@tonic-gate */ 747c478bd9Sstevel@tonic-gate void 757c478bd9Sstevel@tonic-gate soft_cleanup_object(soft_object_t *objp) 767c478bd9Sstevel@tonic-gate { 777c478bd9Sstevel@tonic-gate /* 787c478bd9Sstevel@tonic-gate * Free the storage allocated to big integer attributes. 797c478bd9Sstevel@tonic-gate */ 807c478bd9Sstevel@tonic-gate soft_cleanup_object_bigint_attrs(objp); 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate /* 837c478bd9Sstevel@tonic-gate * Free the storage allocated to the extra attribute list. 847c478bd9Sstevel@tonic-gate */ 857c478bd9Sstevel@tonic-gate soft_cleanup_extra_attr(objp); 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate /* 887c478bd9Sstevel@tonic-gate * Free the storage allocated to certificate attributes. 897c478bd9Sstevel@tonic-gate */ 907c478bd9Sstevel@tonic-gate soft_cleanup_cert_object(objp); 917c478bd9Sstevel@tonic-gate } 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate /* 957c478bd9Sstevel@tonic-gate * Create a new object. Copy the attributes that can be modified 967c478bd9Sstevel@tonic-gate * (in the boolean attribute mask field and extra attribute list) 977c478bd9Sstevel@tonic-gate * from the old object to the new object. 987c478bd9Sstevel@tonic-gate * 997c478bd9Sstevel@tonic-gate * The caller of this function holds the lock on the old object. 1007c478bd9Sstevel@tonic-gate */ 1017c478bd9Sstevel@tonic-gate CK_RV 1027c478bd9Sstevel@tonic-gate soft_copy_object(soft_object_t *old_object, soft_object_t **new_object, 1037c478bd9Sstevel@tonic-gate CK_ULONG object_func, soft_session_t *sp) 1047c478bd9Sstevel@tonic-gate { 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 1077c478bd9Sstevel@tonic-gate soft_object_t *new_objp = NULL; 1087c478bd9Sstevel@tonic-gate CK_ATTRIBUTE_INFO_PTR attrp; 1097c478bd9Sstevel@tonic-gate 1107c478bd9Sstevel@tonic-gate /* Allocate new object. */ 1117c478bd9Sstevel@tonic-gate new_objp = calloc(1, sizeof (soft_object_t)); 1127c478bd9Sstevel@tonic-gate if (new_objp == NULL) 1137c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate new_objp->class = old_object->class; 1167c478bd9Sstevel@tonic-gate new_objp->bool_attr_mask = old_object->bool_attr_mask; 1177c478bd9Sstevel@tonic-gate new_objp->cert_type = old_object->cert_type; 1187c478bd9Sstevel@tonic-gate new_objp->object_type = old_object->object_type; 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate attrp = old_object->extra_attrlistp; 1217c478bd9Sstevel@tonic-gate while (attrp) { 1227c478bd9Sstevel@tonic-gate /* 1237c478bd9Sstevel@tonic-gate * Copy the attribute_info struct from the old 1247c478bd9Sstevel@tonic-gate * object to a new attribute_info struct, and add 1257c478bd9Sstevel@tonic-gate * that new struct to the extra attribute list 1267c478bd9Sstevel@tonic-gate * of the new object. 1277c478bd9Sstevel@tonic-gate */ 1287c478bd9Sstevel@tonic-gate rv = soft_copy_extra_attr(attrp, new_objp); 1297c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1307c478bd9Sstevel@tonic-gate soft_cleanup_extra_attr(new_objp); 1317c478bd9Sstevel@tonic-gate free(new_objp); 1327c478bd9Sstevel@tonic-gate return (rv); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate attrp = attrp->next; 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate *new_object = new_objp; 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate if (object_func == SOFT_SET_ATTR_VALUE) { 1407c478bd9Sstevel@tonic-gate /* done with copying all information that can be modified */ 1417c478bd9Sstevel@tonic-gate return (CKR_OK); 1427c478bd9Sstevel@tonic-gate } 1437c478bd9Sstevel@tonic-gate 1447c478bd9Sstevel@tonic-gate /* 1457c478bd9Sstevel@tonic-gate * Copy the rest of the object. 1467c478bd9Sstevel@tonic-gate * Certain fields that are not appropriate for coping will be 1477c478bd9Sstevel@tonic-gate * initialized. 1487c478bd9Sstevel@tonic-gate */ 1497c478bd9Sstevel@tonic-gate new_objp->key_type = old_object->key_type; 1507c478bd9Sstevel@tonic-gate new_objp->magic_marker = old_object->magic_marker; 1517c478bd9Sstevel@tonic-gate new_objp->mechanism = old_object->mechanism; 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate switch (object_func) { 1547c478bd9Sstevel@tonic-gate case SOFT_COPY_OBJ_ORIG_SH: 1557c478bd9Sstevel@tonic-gate new_objp->session_handle = old_object->session_handle; 1567c478bd9Sstevel@tonic-gate break; 1577c478bd9Sstevel@tonic-gate case SOFT_COPY_OBJECT: 1587c478bd9Sstevel@tonic-gate /* 1597c478bd9Sstevel@tonic-gate * Save the session handle of the C_CopyObject function 1607c478bd9Sstevel@tonic-gate * in the new copy of the session object. 1617c478bd9Sstevel@tonic-gate */ 1627c478bd9Sstevel@tonic-gate new_objp->session_handle = (CK_SESSION_HANDLE)sp; 1637c478bd9Sstevel@tonic-gate break; 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate (void) pthread_cond_init(&(new_objp->obj_free_cond), NULL); 1677c478bd9Sstevel@tonic-gate (void) pthread_mutex_init(&(new_objp->object_mutex), NULL); 1687c478bd9Sstevel@tonic-gate /* copy key related information */ 1697c478bd9Sstevel@tonic-gate switch (new_objp->class) { 1707c478bd9Sstevel@tonic-gate case CKO_PUBLIC_KEY: 1717c478bd9Sstevel@tonic-gate rv = soft_copy_public_key_attr(OBJ_PUB(old_object), 1727c478bd9Sstevel@tonic-gate &(OBJ_PUB(new_objp)), new_objp->key_type); 1737c478bd9Sstevel@tonic-gate break; 1747c478bd9Sstevel@tonic-gate case CKO_PRIVATE_KEY: 1757c478bd9Sstevel@tonic-gate rv = soft_copy_private_key_attr(OBJ_PRI(old_object), 1767c478bd9Sstevel@tonic-gate &(OBJ_PRI(new_objp)), new_objp->key_type); 1777c478bd9Sstevel@tonic-gate break; 1787c478bd9Sstevel@tonic-gate case CKO_SECRET_KEY: 1797c478bd9Sstevel@tonic-gate rv = soft_copy_secret_key_attr(OBJ_SEC(old_object), 1807c478bd9Sstevel@tonic-gate &(OBJ_SEC(new_objp))); 1817c478bd9Sstevel@tonic-gate break; 1827c478bd9Sstevel@tonic-gate case CKO_DOMAIN_PARAMETERS: 1837c478bd9Sstevel@tonic-gate rv = soft_copy_domain_attr(OBJ_DOM(old_object), 1847c478bd9Sstevel@tonic-gate &(OBJ_DOM(new_objp)), new_objp->key_type); 1857c478bd9Sstevel@tonic-gate break; 1867c478bd9Sstevel@tonic-gate case CKO_CERTIFICATE: 1877c478bd9Sstevel@tonic-gate rv = soft_copy_certificate(OBJ_CERT(old_object), 1887c478bd9Sstevel@tonic-gate &(OBJ_CERT(new_objp)), new_objp->cert_type); 1897c478bd9Sstevel@tonic-gate break; 1907c478bd9Sstevel@tonic-gate default: 1917c478bd9Sstevel@tonic-gate /* should never be this case */ 1927c478bd9Sstevel@tonic-gate break; 1937c478bd9Sstevel@tonic-gate } 1947c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1957c478bd9Sstevel@tonic-gate /* 1967c478bd9Sstevel@tonic-gate * don't need to cleanup the memory from failure of copying 1977c478bd9Sstevel@tonic-gate * any key related stuff. Each individual function for 1987c478bd9Sstevel@tonic-gate * copying key attr will free the memory if it fails 1997c478bd9Sstevel@tonic-gate */ 2007c478bd9Sstevel@tonic-gate soft_cleanup_extra_attr(new_objp); 2017c478bd9Sstevel@tonic-gate free(new_objp); 2027c478bd9Sstevel@tonic-gate } 2037c478bd9Sstevel@tonic-gate return (rv); 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate /* 2087c478bd9Sstevel@tonic-gate * Copy the attributes (in the boolean attribute mask field and 2097c478bd9Sstevel@tonic-gate * extra attribute list) from the new object back to the original 2107c478bd9Sstevel@tonic-gate * object. Also, clean up and release all the storage in the extra 2117c478bd9Sstevel@tonic-gate * attribute list of the original object. 2127c478bd9Sstevel@tonic-gate * 2137c478bd9Sstevel@tonic-gate * The caller of this function holds the lock on the old object. 2147c478bd9Sstevel@tonic-gate */ 2157c478bd9Sstevel@tonic-gate void 2167c478bd9Sstevel@tonic-gate soft_merge_object(soft_object_t *old_object, soft_object_t *new_object) 2177c478bd9Sstevel@tonic-gate { 2187c478bd9Sstevel@tonic-gate old_object->bool_attr_mask = new_object->bool_attr_mask; 2197c478bd9Sstevel@tonic-gate soft_cleanup_extra_attr(old_object); 2207c478bd9Sstevel@tonic-gate old_object->extra_attrlistp = new_object->extra_attrlistp; 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate /* 2257c478bd9Sstevel@tonic-gate * Create a new object struct, and add it to the session's object list. 2267c478bd9Sstevel@tonic-gate */ 2277c478bd9Sstevel@tonic-gate CK_RV 2287c478bd9Sstevel@tonic-gate soft_add_object(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 2297c478bd9Sstevel@tonic-gate CK_ULONG *objecthandle_p, soft_session_t *sp) 2307c478bd9Sstevel@tonic-gate { 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 2337c478bd9Sstevel@tonic-gate soft_object_t *new_objp = NULL; 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate new_objp = calloc(1, sizeof (soft_object_t)); 2367c478bd9Sstevel@tonic-gate if (new_objp == NULL) { 2377c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate new_objp->extra_attrlistp = NULL; 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate /* 2437c478bd9Sstevel@tonic-gate * Validate attribute template and fill in the attributes 2447c478bd9Sstevel@tonic-gate * in the soft_object_t. 2457c478bd9Sstevel@tonic-gate */ 2467c478bd9Sstevel@tonic-gate rv = soft_build_object(pTemplate, ulCount, new_objp); 2477c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 2487c478bd9Sstevel@tonic-gate goto fail_cleanup1; 2497c478bd9Sstevel@tonic-gate } 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate rv = soft_pin_expired_check(new_objp); 2527c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 2537c478bd9Sstevel@tonic-gate goto fail_cleanup2; 2547c478bd9Sstevel@tonic-gate } 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate rv = soft_object_write_access_check(sp, new_objp); 2577c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 2587c478bd9Sstevel@tonic-gate goto fail_cleanup2; 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate /* Initialize the rest of stuffs in soft_object_t. */ 2627c478bd9Sstevel@tonic-gate (void) pthread_cond_init(&new_objp->obj_free_cond, NULL); 2637c478bd9Sstevel@tonic-gate (void) pthread_mutex_init(&new_objp->object_mutex, NULL); 2647c478bd9Sstevel@tonic-gate new_objp->magic_marker = SOFTTOKEN_OBJECT_MAGIC; 2657c478bd9Sstevel@tonic-gate new_objp->obj_refcnt = 0; 2667c478bd9Sstevel@tonic-gate new_objp->obj_delete_sync = 0; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate /* Write the new token object to the keystore */ 2697c478bd9Sstevel@tonic-gate if (IS_TOKEN_OBJECT(new_objp)) { 27090e0e8c4Sizick if (!soft_keystore_status(KEYSTORE_INITIALIZED)) { 27190e0e8c4Sizick rv = CKR_DEVICE_REMOVED; 27290e0e8c4Sizick goto fail_cleanup2; 27390e0e8c4Sizick } 2747c478bd9Sstevel@tonic-gate new_objp->version = 1; 2757c478bd9Sstevel@tonic-gate rv = soft_put_object_to_keystore(new_objp); 2767c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 2777c478bd9Sstevel@tonic-gate (void) pthread_cond_destroy(&new_objp->obj_free_cond); 2787c478bd9Sstevel@tonic-gate (void) pthread_mutex_destroy(&new_objp->object_mutex); 2797c478bd9Sstevel@tonic-gate goto fail_cleanup2; 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate new_objp->session_handle = (CK_SESSION_HANDLE)NULL; 2827c478bd9Sstevel@tonic-gate soft_add_token_object_to_slot(new_objp); 2837c478bd9Sstevel@tonic-gate /* 2847c478bd9Sstevel@tonic-gate * Type casting the address of an object struct to 2857c478bd9Sstevel@tonic-gate * an object handle. 2867c478bd9Sstevel@tonic-gate */ 2877c478bd9Sstevel@tonic-gate *objecthandle_p = (CK_ULONG)new_objp; 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate return (CKR_OK); 2907c478bd9Sstevel@tonic-gate } 2917c478bd9Sstevel@tonic-gate 2927c478bd9Sstevel@tonic-gate new_objp->session_handle = (CK_SESSION_HANDLE)sp; 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate /* Add the new object to the session's object list. */ 2957c478bd9Sstevel@tonic-gate soft_add_object_to_session(new_objp, sp); 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate /* Type casting the address of an object struct to an object handle. */ 2987c478bd9Sstevel@tonic-gate *objecthandle_p = (CK_ULONG)new_objp; 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate return (CKR_OK); 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate fail_cleanup2: 3037c478bd9Sstevel@tonic-gate /* 3047c478bd9Sstevel@tonic-gate * When any error occurs after soft_build_object(), we will need to 3057c478bd9Sstevel@tonic-gate * clean up the memory allocated by the soft_build_object(). 3067c478bd9Sstevel@tonic-gate */ 3077c478bd9Sstevel@tonic-gate soft_cleanup_object(new_objp); 3087c478bd9Sstevel@tonic-gate 3097c478bd9Sstevel@tonic-gate fail_cleanup1: 3107c478bd9Sstevel@tonic-gate if (new_objp) { 3117c478bd9Sstevel@tonic-gate /* 3127c478bd9Sstevel@tonic-gate * The storage allocated inside of this object should have 3137c478bd9Sstevel@tonic-gate * been cleaned up by the soft_build_object() if it failed. 3147c478bd9Sstevel@tonic-gate * Therefore, we can safely free the object. 3157c478bd9Sstevel@tonic-gate */ 3167c478bd9Sstevel@tonic-gate free(new_objp); 3177c478bd9Sstevel@tonic-gate } 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate return (rv); 3207c478bd9Sstevel@tonic-gate 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate /* 3257c478bd9Sstevel@tonic-gate * Remove an object from the session's object list. 3267c478bd9Sstevel@tonic-gate * 3277c478bd9Sstevel@tonic-gate * The caller of this function holds the session lock. 3287c478bd9Sstevel@tonic-gate */ 3297c478bd9Sstevel@tonic-gate CK_RV 3307c478bd9Sstevel@tonic-gate soft_remove_object_from_session(soft_object_t *objp, soft_session_t *sp) 3317c478bd9Sstevel@tonic-gate { 3327c478bd9Sstevel@tonic-gate soft_object_t *tmp_objp; 3337c478bd9Sstevel@tonic-gate boolean_t found = B_FALSE; 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate /* 3367c478bd9Sstevel@tonic-gate * Remove the object from the session's object list. 3377c478bd9Sstevel@tonic-gate */ 3387c478bd9Sstevel@tonic-gate if ((sp == NULL) || 3397c478bd9Sstevel@tonic-gate (sp->magic_marker != SOFTTOKEN_SESSION_MAGIC)) { 3407c478bd9Sstevel@tonic-gate return (CKR_SESSION_HANDLE_INVALID); 3417c478bd9Sstevel@tonic-gate } 3427c478bd9Sstevel@tonic-gate 3437c478bd9Sstevel@tonic-gate if ((sp->object_list == NULL) || (objp == NULL) || 3447c478bd9Sstevel@tonic-gate (objp->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 3457c478bd9Sstevel@tonic-gate return (CKR_OBJECT_HANDLE_INVALID); 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate 3487c478bd9Sstevel@tonic-gate tmp_objp = sp->object_list; 3497c478bd9Sstevel@tonic-gate while (tmp_objp) { 3507c478bd9Sstevel@tonic-gate if (tmp_objp == objp) { 3517c478bd9Sstevel@tonic-gate found = B_TRUE; 3527c478bd9Sstevel@tonic-gate break; 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate tmp_objp = tmp_objp->next; 3557c478bd9Sstevel@tonic-gate } 3567c478bd9Sstevel@tonic-gate if (!found) 3577c478bd9Sstevel@tonic-gate return (CKR_OBJECT_HANDLE_INVALID); 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate if (sp->object_list == objp) { 3607c478bd9Sstevel@tonic-gate /* Object is the first one in the list. */ 3617c478bd9Sstevel@tonic-gate if (objp->next) { 3627c478bd9Sstevel@tonic-gate sp->object_list = objp->next; 3637c478bd9Sstevel@tonic-gate objp->next->prev = NULL; 3647c478bd9Sstevel@tonic-gate } else { 3657c478bd9Sstevel@tonic-gate /* Object is the only one in the list. */ 3667c478bd9Sstevel@tonic-gate sp->object_list = NULL; 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate } else { 3697c478bd9Sstevel@tonic-gate /* Object is not the first one in the list. */ 3707c478bd9Sstevel@tonic-gate if (objp->next) { 3717c478bd9Sstevel@tonic-gate /* Object is in the middle of the list. */ 3727c478bd9Sstevel@tonic-gate objp->prev->next = objp->next; 3737c478bd9Sstevel@tonic-gate objp->next->prev = objp->prev; 3747c478bd9Sstevel@tonic-gate } else { 3757c478bd9Sstevel@tonic-gate /* Object is the last one in the list. */ 3767c478bd9Sstevel@tonic-gate objp->prev->next = NULL; 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate } 3797c478bd9Sstevel@tonic-gate return (CKR_OK); 3807c478bd9Sstevel@tonic-gate } 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate /* 3837c478bd9Sstevel@tonic-gate * This function adds the to-be-freed session object to a linked list. 3847c478bd9Sstevel@tonic-gate * When the number of objects queued in the linked list reaches the 3857c478bd9Sstevel@tonic-gate * maximum threshold MAX_OBJ_TO_BE_FREED, it will free the first 3867c478bd9Sstevel@tonic-gate * object (FIFO) in the list. 3877c478bd9Sstevel@tonic-gate */ 3887c478bd9Sstevel@tonic-gate void 3897c478bd9Sstevel@tonic-gate object_delay_free(soft_object_t *objp) 3907c478bd9Sstevel@tonic-gate { 3917c478bd9Sstevel@tonic-gate soft_object_t *tmp; 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&obj_delay_freed.obj_to_be_free_mutex); 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate /* Add the newly deleted object at the end of the list */ 3967c478bd9Sstevel@tonic-gate objp->next = NULL; 3977c478bd9Sstevel@tonic-gate if (obj_delay_freed.first == NULL) { 3987c478bd9Sstevel@tonic-gate obj_delay_freed.last = objp; 3997c478bd9Sstevel@tonic-gate obj_delay_freed.first = objp; 4007c478bd9Sstevel@tonic-gate } else { 4017c478bd9Sstevel@tonic-gate obj_delay_freed.last->next = objp; 4027c478bd9Sstevel@tonic-gate obj_delay_freed.last = objp; 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate if (++obj_delay_freed.count >= MAX_OBJ_TO_BE_FREED) { 4067c478bd9Sstevel@tonic-gate /* 4077c478bd9Sstevel@tonic-gate * Free the first object in the list only if 4087c478bd9Sstevel@tonic-gate * the total count reaches maximum threshold. 4097c478bd9Sstevel@tonic-gate */ 4107c478bd9Sstevel@tonic-gate obj_delay_freed.count--; 4117c478bd9Sstevel@tonic-gate tmp = obj_delay_freed.first->next; 4127c478bd9Sstevel@tonic-gate free(obj_delay_freed.first); 4137c478bd9Sstevel@tonic-gate obj_delay_freed.first = tmp; 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&obj_delay_freed.obj_to_be_free_mutex); 4167c478bd9Sstevel@tonic-gate } 4177c478bd9Sstevel@tonic-gate 4187c478bd9Sstevel@tonic-gate static void 4191f49a79aSZdenek Kotala soft_delete_object_cleanup(soft_object_t *objp, boolean_t force) 4207c478bd9Sstevel@tonic-gate { 4217c478bd9Sstevel@tonic-gate /* Acquire the lock on the object. */ 4227c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&objp->object_mutex); 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate /* 4257c478bd9Sstevel@tonic-gate * Make sure another thread hasn't freed the object. 4267c478bd9Sstevel@tonic-gate */ 4277c478bd9Sstevel@tonic-gate if (objp->magic_marker != SOFTTOKEN_OBJECT_MAGIC) { 4287c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&objp->object_mutex); 4297c478bd9Sstevel@tonic-gate return; 4307c478bd9Sstevel@tonic-gate } 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate /* 4337c478bd9Sstevel@tonic-gate * The deletion of an object must be blocked when the object 4347c478bd9Sstevel@tonic-gate * reference count is not zero. This means if any object related 4357c478bd9Sstevel@tonic-gate * operation starts prior to the delete object operation gets in, 4367c478bd9Sstevel@tonic-gate * the object deleting thread must wait for the non-deleting 4377c478bd9Sstevel@tonic-gate * operation to be completed before it can proceed the delete 4387c478bd9Sstevel@tonic-gate * operation. 4391f49a79aSZdenek Kotala * 4401f49a79aSZdenek Kotala * Unless we are being forced to shut everything down, this only 4411f49a79aSZdenek Kotala * happens if the libraries _fini() is running not of someone 4421f49a79aSZdenek Kotala * explicitly called C_Finalize(). 4437c478bd9Sstevel@tonic-gate */ 4441f49a79aSZdenek Kotala if (force) 4451f49a79aSZdenek Kotala objp->obj_refcnt = 0; 4461f49a79aSZdenek Kotala 4477c478bd9Sstevel@tonic-gate while (objp->obj_refcnt != 0) { 4487c478bd9Sstevel@tonic-gate /* 4497c478bd9Sstevel@tonic-gate * We set the OBJECT_REFCNT_WAITING flag before we put 4507c478bd9Sstevel@tonic-gate * this deleting thread in a wait state, so other non-deleting 4517c478bd9Sstevel@tonic-gate * operation thread will signal to wake it up only when 4527c478bd9Sstevel@tonic-gate * the object reference count becomes zero and this flag 4537c478bd9Sstevel@tonic-gate * is set. 4547c478bd9Sstevel@tonic-gate */ 4557c478bd9Sstevel@tonic-gate objp->obj_delete_sync |= OBJECT_REFCNT_WAITING; 4567c478bd9Sstevel@tonic-gate (void) pthread_cond_wait(&objp->obj_free_cond, 4577c478bd9Sstevel@tonic-gate &objp->object_mutex); 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate objp->obj_delete_sync &= ~OBJECT_REFCNT_WAITING; 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate /* Mark object as no longer valid. */ 4637c478bd9Sstevel@tonic-gate objp->magic_marker = 0; 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate (void) pthread_cond_destroy(&objp->obj_free_cond); 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate /* 4687c478bd9Sstevel@tonic-gate * Cleanup the contents of this object such as free all the 4697c478bd9Sstevel@tonic-gate * storage allocated for this object. 4707c478bd9Sstevel@tonic-gate */ 4717c478bd9Sstevel@tonic-gate soft_cleanup_object(objp); 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate /* Reset OBJECT_IS_DELETING flag. */ 4747c478bd9Sstevel@tonic-gate objp->obj_delete_sync &= ~OBJECT_IS_DELETING; 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&objp->object_mutex); 4777c478bd9Sstevel@tonic-gate /* Destroy the object lock */ 4787c478bd9Sstevel@tonic-gate (void) pthread_mutex_destroy(&objp->object_mutex); 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate /* Free the object itself */ 4817c478bd9Sstevel@tonic-gate if (IS_TOKEN_OBJECT(objp)) 4827c478bd9Sstevel@tonic-gate free(objp); 4837c478bd9Sstevel@tonic-gate else 4847c478bd9Sstevel@tonic-gate /* 4857c478bd9Sstevel@tonic-gate * Delay freeing the session object as S1WS/NSS uses session 4867c478bd9Sstevel@tonic-gate * objects for its SSL Handshake. 4877c478bd9Sstevel@tonic-gate */ 4887c478bd9Sstevel@tonic-gate (void) object_delay_free(objp); 4897c478bd9Sstevel@tonic-gate } 4907c478bd9Sstevel@tonic-gate 4917c478bd9Sstevel@tonic-gate /* 4927c478bd9Sstevel@tonic-gate * Delete an object: 4937c478bd9Sstevel@tonic-gate * - Remove the object from the session's object list. 4947c478bd9Sstevel@tonic-gate * Holding the lock on the session which the object was created at 4957c478bd9Sstevel@tonic-gate * is needed to do this. 4967c478bd9Sstevel@tonic-gate * - Release the storage allocated to the object. 4977c478bd9Sstevel@tonic-gate * 4987c478bd9Sstevel@tonic-gate * The boolean argument lock_held is used to indicate that whether 4997c478bd9Sstevel@tonic-gate * the caller holds the session lock or not. 5007c478bd9Sstevel@tonic-gate * - When called by soft_delete_all_objects_in_session() -- the 5017c478bd9Sstevel@tonic-gate * lock_held = TRUE. 5027c478bd9Sstevel@tonic-gate * 5037c478bd9Sstevel@tonic-gate * When the caller does not hold the session lock, this function 5047c478bd9Sstevel@tonic-gate * will acquire that lock in order to proceed, and also release 5057c478bd9Sstevel@tonic-gate * that lock before returning to caller. 5067c478bd9Sstevel@tonic-gate */ 5077c478bd9Sstevel@tonic-gate void 5081f49a79aSZdenek Kotala soft_delete_object(soft_session_t *sp, soft_object_t *objp, 5091f49a79aSZdenek Kotala boolean_t force, boolean_t lock_held) 5107c478bd9Sstevel@tonic-gate { 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate /* 5137c478bd9Sstevel@tonic-gate * Check to see if the caller holds the lock on the session. 5147c478bd9Sstevel@tonic-gate * If not, we need to acquire that lock in order to proceed. 5157c478bd9Sstevel@tonic-gate */ 5167c478bd9Sstevel@tonic-gate if (!lock_held) { 5177c478bd9Sstevel@tonic-gate /* Acquire the session lock. */ 5187c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&sp->session_mutex); 5197c478bd9Sstevel@tonic-gate } 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate /* Remove the object from the session's object list first. */ 5227c478bd9Sstevel@tonic-gate if (soft_remove_object_from_session(objp, sp) != CKR_OK) { 5237c478bd9Sstevel@tonic-gate if (!lock_held) { 5247c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&sp->session_mutex); 5257c478bd9Sstevel@tonic-gate } 5267c478bd9Sstevel@tonic-gate return; 5277c478bd9Sstevel@tonic-gate } 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate if (!lock_held) { 5307c478bd9Sstevel@tonic-gate /* 5317c478bd9Sstevel@tonic-gate * If the session lock is obtained by this function, 5327c478bd9Sstevel@tonic-gate * then release that lock after removing the object 5337c478bd9Sstevel@tonic-gate * from session's object list. 5347c478bd9Sstevel@tonic-gate * We want the releasing of the object storage to 5357c478bd9Sstevel@tonic-gate * be done without holding the session lock. 5367c478bd9Sstevel@tonic-gate */ 5377c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&sp->session_mutex); 5387c478bd9Sstevel@tonic-gate } 5397c478bd9Sstevel@tonic-gate 5401f49a79aSZdenek Kotala soft_delete_object_cleanup(objp, force); 5417c478bd9Sstevel@tonic-gate } 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate 5447c478bd9Sstevel@tonic-gate /* 5457c478bd9Sstevel@tonic-gate * Delete all the objects in a session. The caller holds the lock 5467c478bd9Sstevel@tonic-gate * on the session. 5477c478bd9Sstevel@tonic-gate */ 5487c478bd9Sstevel@tonic-gate void 5491f49a79aSZdenek Kotala soft_delete_all_objects_in_session(soft_session_t *sp, boolean_t force) 5507c478bd9Sstevel@tonic-gate { 5517c478bd9Sstevel@tonic-gate soft_object_t *objp = sp->object_list; 5527c478bd9Sstevel@tonic-gate soft_object_t *objp1; 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate /* Delete all the objects in the session. */ 5557c478bd9Sstevel@tonic-gate while (objp) { 5567c478bd9Sstevel@tonic-gate objp1 = objp->next; 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate /* 5597c478bd9Sstevel@tonic-gate * Delete an object by calling soft_delete_object() 5607c478bd9Sstevel@tonic-gate * with a TRUE boolean argument indicating that 5617c478bd9Sstevel@tonic-gate * the caller holds the lock on the session. 5627c478bd9Sstevel@tonic-gate */ 5631f49a79aSZdenek Kotala soft_delete_object(sp, objp, force, B_TRUE); 5647c478bd9Sstevel@tonic-gate 5657c478bd9Sstevel@tonic-gate objp = objp1; 5667c478bd9Sstevel@tonic-gate } 5677c478bd9Sstevel@tonic-gate } 5687c478bd9Sstevel@tonic-gate 5697c478bd9Sstevel@tonic-gate static CK_RV 5707c478bd9Sstevel@tonic-gate add_to_search_result(soft_object_t *obj, find_context_t *fcontext, 5717c478bd9Sstevel@tonic-gate CK_ULONG *num_result_alloc) 5727c478bd9Sstevel@tonic-gate { 5737c478bd9Sstevel@tonic-gate /* 5747c478bd9Sstevel@tonic-gate * allocate space for storing results if the currently 5757c478bd9Sstevel@tonic-gate * allocated space is not enough 5767c478bd9Sstevel@tonic-gate */ 5777c478bd9Sstevel@tonic-gate if (*num_result_alloc <= fcontext->num_results) { 5787c478bd9Sstevel@tonic-gate fcontext->objs_found = realloc(fcontext->objs_found, 5797c478bd9Sstevel@tonic-gate sizeof (soft_object_t *) * (*num_result_alloc + BUFSIZ)); 5807c478bd9Sstevel@tonic-gate if (fcontext->objs_found == NULL) { 5817c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 5827c478bd9Sstevel@tonic-gate } 5837c478bd9Sstevel@tonic-gate *num_result_alloc += BUFSIZ; 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate (fcontext->objs_found)[(fcontext->num_results)++] = obj; 5877c478bd9Sstevel@tonic-gate return (CKR_OK); 5887c478bd9Sstevel@tonic-gate } 5897c478bd9Sstevel@tonic-gate 5907c478bd9Sstevel@tonic-gate static CK_RV 5917c478bd9Sstevel@tonic-gate search_for_objects(CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 5927c478bd9Sstevel@tonic-gate find_context_t *fcontext) 5937c478bd9Sstevel@tonic-gate { 5947c478bd9Sstevel@tonic-gate soft_session_t *session_p; 5957c478bd9Sstevel@tonic-gate soft_object_t *obj; 596c2e31228SViswanathan Kannappan CK_OBJECT_CLASS pclasses[6]; /* classes attrs possibly exist */ 5977c478bd9Sstevel@tonic-gate CK_ULONG num_pclasses; /* number of possible classes */ 5987c478bd9Sstevel@tonic-gate CK_ULONG num_result_alloc = 0; /* spaces allocated for results */ 5997c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 6007c478bd9Sstevel@tonic-gate /* whether CKA_TOKEN flag specified or not */ 6017c478bd9Sstevel@tonic-gate boolean_t token_specified = B_FALSE; 6027c478bd9Sstevel@tonic-gate /* value of CKA_TOKEN flag, if specified */ 6037c478bd9Sstevel@tonic-gate boolean_t token_flag_val = B_FALSE; 6047c478bd9Sstevel@tonic-gate CK_ULONG i; 6057c478bd9Sstevel@tonic-gate 6067c478bd9Sstevel@tonic-gate if (ulCount > 0) { 6077c478bd9Sstevel@tonic-gate /* there are some search requirement */ 6087c478bd9Sstevel@tonic-gate soft_process_find_attr(pclasses, &num_pclasses, 6097c478bd9Sstevel@tonic-gate pTemplate, ulCount); 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate for (i = 0; i < ulCount; i++) { 6137c478bd9Sstevel@tonic-gate if (pTemplate[i].type == CKA_PRIVATE) { 6147c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_giant_mutex); 6157c478bd9Sstevel@tonic-gate if (soft_slot.userpin_change_needed) { 6167c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_giant_mutex); 6177c478bd9Sstevel@tonic-gate return (CKR_PIN_EXPIRED); 6187c478bd9Sstevel@tonic-gate } 6197c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_giant_mutex); 6207c478bd9Sstevel@tonic-gate } 6217c478bd9Sstevel@tonic-gate } 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate /* 6247c478bd9Sstevel@tonic-gate * look through template and see if it explicitly specifies 6257c478bd9Sstevel@tonic-gate * whether we need to look for token objects or not 6267c478bd9Sstevel@tonic-gate */ 6277c478bd9Sstevel@tonic-gate for (i = 0; i < ulCount; i++) { 6287c478bd9Sstevel@tonic-gate if (pTemplate[i].type == CKA_TOKEN) { 6297c478bd9Sstevel@tonic-gate token_specified = B_TRUE; 6307c478bd9Sstevel@tonic-gate token_flag_val = *((CK_BBOOL *)pTemplate[i].pValue); 6317c478bd9Sstevel@tonic-gate break; 6327c478bd9Sstevel@tonic-gate } 6337c478bd9Sstevel@tonic-gate } 6347c478bd9Sstevel@tonic-gate 6357c478bd9Sstevel@tonic-gate /* 6367c478bd9Sstevel@tonic-gate * Need go through token objects if it explicitly say so, or 6377c478bd9Sstevel@tonic-gate * it is not mentioned in the template. And this will ONLY be 6387c478bd9Sstevel@tonic-gate * done when the keystore exists. Otherwise, we will skip re-loading 6397c478bd9Sstevel@tonic-gate * the token objects. 6407c478bd9Sstevel@tonic-gate * 6417c478bd9Sstevel@tonic-gate * If a session has not logged into the token, only public 6427c478bd9Sstevel@tonic-gate * objects, if any, will be searched. If a session is logged 6437c478bd9Sstevel@tonic-gate * into the token, all public and private objects in the keystore 6447c478bd9Sstevel@tonic-gate * are searched. 6457c478bd9Sstevel@tonic-gate */ 64690e0e8c4Sizick if (((token_flag_val) || (!token_specified)) && 64790e0e8c4Sizick soft_keystore_status(KEYSTORE_INITIALIZED)) { 6487c478bd9Sstevel@tonic-gate /* acquire token session lock */ 6497c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_slot.slot_mutex); 6507c478bd9Sstevel@tonic-gate rv = refresh_token_objects(); 6517c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 6527c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_slot.slot_mutex); 6537c478bd9Sstevel@tonic-gate return (rv); 6547c478bd9Sstevel@tonic-gate } 6557c478bd9Sstevel@tonic-gate obj = soft_slot.token_object_list; 6567c478bd9Sstevel@tonic-gate while (obj) { 6577c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&obj->object_mutex); 6587c478bd9Sstevel@tonic-gate if (((token_specified) && (ulCount > 1)) || 6597c478bd9Sstevel@tonic-gate ((!token_specified) && (ulCount > 0))) { 6607c478bd9Sstevel@tonic-gate if (soft_find_match_attrs(obj, pclasses, 6617c478bd9Sstevel@tonic-gate num_pclasses, pTemplate, ulCount)) { 6627c478bd9Sstevel@tonic-gate rv = add_to_search_result( 6637c478bd9Sstevel@tonic-gate obj, fcontext, &num_result_alloc); 6647c478bd9Sstevel@tonic-gate } 6657c478bd9Sstevel@tonic-gate } else { 6667c478bd9Sstevel@tonic-gate /* no search criteria, just record the object */ 6677c478bd9Sstevel@tonic-gate rv = add_to_search_result(obj, fcontext, 6687c478bd9Sstevel@tonic-gate &num_result_alloc); 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&obj->object_mutex); 6717c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 6727c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock 6737c478bd9Sstevel@tonic-gate (&soft_slot.slot_mutex); 6747c478bd9Sstevel@tonic-gate return (rv); 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate obj = obj->next; 6777c478bd9Sstevel@tonic-gate } 6787c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_slot.slot_mutex); 6797c478bd9Sstevel@tonic-gate } 6807c478bd9Sstevel@tonic-gate 6817c478bd9Sstevel@tonic-gate if (token_flag_val) { 6827c478bd9Sstevel@tonic-gate /* no need to look through session objects */ 6837c478bd9Sstevel@tonic-gate return (rv); 6847c478bd9Sstevel@tonic-gate } 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate /* Acquire the global session list lock */ 6877c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_sessionlist_mutex); 6887c478bd9Sstevel@tonic-gate 6897c478bd9Sstevel@tonic-gate /* 6907c478bd9Sstevel@tonic-gate * Go through all objects in each session. 6917c478bd9Sstevel@tonic-gate * Acquire individual session lock for the session 6927c478bd9Sstevel@tonic-gate * we are searching. 6937c478bd9Sstevel@tonic-gate */ 6947c478bd9Sstevel@tonic-gate session_p = soft_session_list; 6957c478bd9Sstevel@tonic-gate while (session_p) { 6967c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&session_p->session_mutex); 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate obj = session_p->object_list; 6997c478bd9Sstevel@tonic-gate while (obj) { 7007c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&obj->object_mutex); 7017c478bd9Sstevel@tonic-gate if (ulCount > 0) { 7027c478bd9Sstevel@tonic-gate if (soft_find_match_attrs(obj, pclasses, 7037c478bd9Sstevel@tonic-gate num_pclasses, pTemplate, ulCount)) { 7047c478bd9Sstevel@tonic-gate rv = add_to_search_result( 7057c478bd9Sstevel@tonic-gate obj, fcontext, &num_result_alloc); 7067c478bd9Sstevel@tonic-gate } 7077c478bd9Sstevel@tonic-gate } else { 7087c478bd9Sstevel@tonic-gate /* no search criteria, just record the object */ 7097c478bd9Sstevel@tonic-gate rv = add_to_search_result(obj, fcontext, 7107c478bd9Sstevel@tonic-gate &num_result_alloc); 7117c478bd9Sstevel@tonic-gate } 7127c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&obj->object_mutex); 7137c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 7147c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock( 7157c478bd9Sstevel@tonic-gate &session_p->session_mutex); 7167c478bd9Sstevel@tonic-gate goto cleanup; 7177c478bd9Sstevel@tonic-gate } 7187c478bd9Sstevel@tonic-gate obj = obj->next; 7197c478bd9Sstevel@tonic-gate } 7207c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&session_p->session_mutex); 7217c478bd9Sstevel@tonic-gate session_p = session_p->next; 7227c478bd9Sstevel@tonic-gate } 7237c478bd9Sstevel@tonic-gate 7247c478bd9Sstevel@tonic-gate cleanup: 7257c478bd9Sstevel@tonic-gate /* Release the global session list lock */ 7267c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_sessionlist_mutex); 7277c478bd9Sstevel@tonic-gate return (rv); 7287c478bd9Sstevel@tonic-gate } 7297c478bd9Sstevel@tonic-gate 7307c478bd9Sstevel@tonic-gate /* 7317c478bd9Sstevel@tonic-gate * Initialize the context for C_FindObjects() calls 7327c478bd9Sstevel@tonic-gate */ 7337c478bd9Sstevel@tonic-gate CK_RV 7347c478bd9Sstevel@tonic-gate soft_find_objects_init(soft_session_t *sp, CK_ATTRIBUTE_PTR pTemplate, 7357c478bd9Sstevel@tonic-gate CK_ULONG ulCount) 7367c478bd9Sstevel@tonic-gate { 7377c478bd9Sstevel@tonic-gate 7387c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 7397c478bd9Sstevel@tonic-gate CK_OBJECT_CLASS class; /* for soft_validate_attr(). Value unused */ 7407c478bd9Sstevel@tonic-gate find_context_t *fcontext; 7417c478bd9Sstevel@tonic-gate 7427c478bd9Sstevel@tonic-gate if (ulCount) { 7437c478bd9Sstevel@tonic-gate rv = soft_validate_attr(pTemplate, ulCount, &class); 7447c478bd9Sstevel@tonic-gate /* Make sure all attributes in template are valid */ 7457c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 7467c478bd9Sstevel@tonic-gate return (rv); 7477c478bd9Sstevel@tonic-gate } 7487c478bd9Sstevel@tonic-gate } 7497c478bd9Sstevel@tonic-gate 7507c478bd9Sstevel@tonic-gate 7517c478bd9Sstevel@tonic-gate /* prepare the find context */ 7527c478bd9Sstevel@tonic-gate fcontext = calloc(1, sizeof (find_context_t)); 7537c478bd9Sstevel@tonic-gate if (fcontext == NULL) { 7547c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 7557c478bd9Sstevel@tonic-gate } 7567c478bd9Sstevel@tonic-gate 7577c478bd9Sstevel@tonic-gate rv = search_for_objects(pTemplate, ulCount, fcontext); 7587c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 7597c478bd9Sstevel@tonic-gate free(fcontext); 7607c478bd9Sstevel@tonic-gate return (rv); 7617c478bd9Sstevel@tonic-gate } 7627c478bd9Sstevel@tonic-gate 7637c478bd9Sstevel@tonic-gate /* store the find_context in the session */ 7647c478bd9Sstevel@tonic-gate sp->find_objects.context = (CK_VOID_PTR)fcontext; 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate return (rv); 7677c478bd9Sstevel@tonic-gate } 7687c478bd9Sstevel@tonic-gate 7697c478bd9Sstevel@tonic-gate void 7707c478bd9Sstevel@tonic-gate soft_find_objects_final(soft_session_t *sp) 7717c478bd9Sstevel@tonic-gate { 7727c478bd9Sstevel@tonic-gate find_context_t *fcontext; 7737c478bd9Sstevel@tonic-gate 7747c478bd9Sstevel@tonic-gate fcontext = sp->find_objects.context; 7757c478bd9Sstevel@tonic-gate sp->find_objects.context = NULL; 7767c478bd9Sstevel@tonic-gate sp->find_objects.flags = 0; 7777c478bd9Sstevel@tonic-gate if (fcontext->objs_found != NULL) { 7787c478bd9Sstevel@tonic-gate free(fcontext->objs_found); 7797c478bd9Sstevel@tonic-gate } 7807c478bd9Sstevel@tonic-gate 7817c478bd9Sstevel@tonic-gate free(fcontext); 7827c478bd9Sstevel@tonic-gate } 7837c478bd9Sstevel@tonic-gate 7847c478bd9Sstevel@tonic-gate void 7857c478bd9Sstevel@tonic-gate soft_find_objects(soft_session_t *sp, CK_OBJECT_HANDLE *obj_found, 7867c478bd9Sstevel@tonic-gate CK_ULONG max_obj_requested, CK_ULONG *found_obj_count) 7877c478bd9Sstevel@tonic-gate { 7887c478bd9Sstevel@tonic-gate find_context_t *fcontext; 7897c478bd9Sstevel@tonic-gate CK_ULONG num_obj_found = 0; 7907c478bd9Sstevel@tonic-gate CK_ULONG i; 7917c478bd9Sstevel@tonic-gate soft_object_t *obj; 7927c478bd9Sstevel@tonic-gate 7937c478bd9Sstevel@tonic-gate fcontext = sp->find_objects.context; 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate for (i = fcontext->next_result_index; 7967c478bd9Sstevel@tonic-gate ((num_obj_found < max_obj_requested) && 7977c478bd9Sstevel@tonic-gate (i < fcontext->num_results)); 7987c478bd9Sstevel@tonic-gate i++) { 7997c478bd9Sstevel@tonic-gate obj = fcontext->objs_found[i]; 8007c478bd9Sstevel@tonic-gate if (obj != NULL) { 8017c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&obj->object_mutex); 8027c478bd9Sstevel@tonic-gate /* a sanity check to make sure the obj is still valid */ 8037c478bd9Sstevel@tonic-gate if (obj->magic_marker == SOFTTOKEN_OBJECT_MAGIC) { 8047c478bd9Sstevel@tonic-gate obj_found[num_obj_found] = 8057c478bd9Sstevel@tonic-gate (CK_OBJECT_HANDLE)obj; 8067c478bd9Sstevel@tonic-gate num_obj_found++; 8077c478bd9Sstevel@tonic-gate } 8087c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&obj->object_mutex); 8097c478bd9Sstevel@tonic-gate } 8107c478bd9Sstevel@tonic-gate } 8117c478bd9Sstevel@tonic-gate fcontext->next_result_index = i; 8127c478bd9Sstevel@tonic-gate *found_obj_count = num_obj_found; 8137c478bd9Sstevel@tonic-gate } 8147c478bd9Sstevel@tonic-gate 8157c478bd9Sstevel@tonic-gate /* 8167c478bd9Sstevel@tonic-gate * Below are the token object related functions 8177c478bd9Sstevel@tonic-gate */ 8187c478bd9Sstevel@tonic-gate void 8197c478bd9Sstevel@tonic-gate soft_add_token_object_to_slot(soft_object_t *objp) 8207c478bd9Sstevel@tonic-gate { 8217c478bd9Sstevel@tonic-gate 8227c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_slot.slot_mutex); 8237c478bd9Sstevel@tonic-gate 8247c478bd9Sstevel@tonic-gate /* Insert the new object in front of slot's token object list. */ 8257c478bd9Sstevel@tonic-gate if (soft_slot.token_object_list == NULL) { 8267c478bd9Sstevel@tonic-gate soft_slot.token_object_list = objp; 8277c478bd9Sstevel@tonic-gate objp->next = NULL; 8287c478bd9Sstevel@tonic-gate objp->prev = NULL; 8297c478bd9Sstevel@tonic-gate } else { 8307c478bd9Sstevel@tonic-gate soft_slot.token_object_list->prev = objp; 8317c478bd9Sstevel@tonic-gate objp->next = soft_slot.token_object_list; 8327c478bd9Sstevel@tonic-gate objp->prev = NULL; 8337c478bd9Sstevel@tonic-gate soft_slot.token_object_list = objp; 8347c478bd9Sstevel@tonic-gate } 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_slot.slot_mutex); 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate } 8397c478bd9Sstevel@tonic-gate 8407c478bd9Sstevel@tonic-gate void 8417c478bd9Sstevel@tonic-gate soft_remove_token_object_from_slot(soft_object_t *objp, boolean_t lock_held) 8427c478bd9Sstevel@tonic-gate { 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate if (!lock_held) 8457c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_slot.slot_mutex); 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate /* 8487c478bd9Sstevel@tonic-gate * Remove the object from the slot's token object list. 8497c478bd9Sstevel@tonic-gate */ 8507c478bd9Sstevel@tonic-gate if (soft_slot.token_object_list == objp) { 8517c478bd9Sstevel@tonic-gate /* Object is the first one in the list. */ 8527c478bd9Sstevel@tonic-gate if (objp->next) { 8537c478bd9Sstevel@tonic-gate soft_slot.token_object_list = objp->next; 8547c478bd9Sstevel@tonic-gate objp->next->prev = NULL; 8557c478bd9Sstevel@tonic-gate } else { 8567c478bd9Sstevel@tonic-gate /* Object is the only one in the list. */ 8577c478bd9Sstevel@tonic-gate soft_slot.token_object_list = NULL; 8587c478bd9Sstevel@tonic-gate } 8597c478bd9Sstevel@tonic-gate } else { 8607c478bd9Sstevel@tonic-gate /* Object is not the first one in the list. */ 8617c478bd9Sstevel@tonic-gate if (objp->next) { 8627c478bd9Sstevel@tonic-gate /* Object is in the middle of the list. */ 8637c478bd9Sstevel@tonic-gate objp->prev->next = objp->next; 8647c478bd9Sstevel@tonic-gate objp->next->prev = objp->prev; 8657c478bd9Sstevel@tonic-gate } else { 8667c478bd9Sstevel@tonic-gate /* Object is the last one in the list. */ 8677c478bd9Sstevel@tonic-gate objp->prev->next = NULL; 8687c478bd9Sstevel@tonic-gate } 8697c478bd9Sstevel@tonic-gate } 8707c478bd9Sstevel@tonic-gate 8717c478bd9Sstevel@tonic-gate if (!lock_held) 8727c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_slot.slot_mutex); 8737c478bd9Sstevel@tonic-gate } 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate void 8767c478bd9Sstevel@tonic-gate soft_delete_token_object(soft_object_t *objp, boolean_t persistent, 8777c478bd9Sstevel@tonic-gate boolean_t lock_held) 8787c478bd9Sstevel@tonic-gate { 8797c478bd9Sstevel@tonic-gate 8804d25c1d6Smcpowers if (!lock_held) 8814d25c1d6Smcpowers (void) pthread_mutex_lock(&soft_slot.slot_mutex); 8827c478bd9Sstevel@tonic-gate if (persistent) 8837c478bd9Sstevel@tonic-gate /* Delete the object from the keystore. */ 8847c478bd9Sstevel@tonic-gate (void) soft_keystore_del_obj(&objp->ks_handle, B_FALSE); 8857c478bd9Sstevel@tonic-gate 8867c478bd9Sstevel@tonic-gate /* Remove the object from the slot's token object list. */ 8874d25c1d6Smcpowers soft_remove_token_object_from_slot(objp, B_TRUE); 8884d25c1d6Smcpowers if (!lock_held) 8894d25c1d6Smcpowers (void) pthread_mutex_unlock(&soft_slot.slot_mutex); 8907c478bd9Sstevel@tonic-gate 8911f49a79aSZdenek Kotala soft_delete_object_cleanup(objp, B_FALSE); 8927c478bd9Sstevel@tonic-gate } 8937c478bd9Sstevel@tonic-gate 8947c478bd9Sstevel@tonic-gate void 8957c478bd9Sstevel@tonic-gate soft_delete_all_in_core_token_objects(token_obj_type_t type) 8967c478bd9Sstevel@tonic-gate { 8977c478bd9Sstevel@tonic-gate 8987c478bd9Sstevel@tonic-gate soft_object_t *objp; 8997c478bd9Sstevel@tonic-gate soft_object_t *objp1; 9007c478bd9Sstevel@tonic-gate 9017c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_slot.slot_mutex); 9027c478bd9Sstevel@tonic-gate objp = soft_slot.token_object_list; 9037c478bd9Sstevel@tonic-gate 9047c478bd9Sstevel@tonic-gate switch (type) { 9057c478bd9Sstevel@tonic-gate case PRIVATE_TOKEN: 9067c478bd9Sstevel@tonic-gate while (objp) { 9077c478bd9Sstevel@tonic-gate objp1 = objp->next; 9087c478bd9Sstevel@tonic-gate if (objp->object_type == TOKEN_PRIVATE) { 9097c478bd9Sstevel@tonic-gate soft_delete_token_object(objp, B_FALSE, B_TRUE); 9107c478bd9Sstevel@tonic-gate } 9117c478bd9Sstevel@tonic-gate objp = objp1; 9127c478bd9Sstevel@tonic-gate } 9137c478bd9Sstevel@tonic-gate break; 9147c478bd9Sstevel@tonic-gate 9157c478bd9Sstevel@tonic-gate case PUBLIC_TOKEN: 9167c478bd9Sstevel@tonic-gate while (objp) { 9177c478bd9Sstevel@tonic-gate objp1 = objp->next; 9187c478bd9Sstevel@tonic-gate if (objp->object_type == TOKEN_PUBLIC) { 9197c478bd9Sstevel@tonic-gate soft_delete_token_object(objp, B_FALSE, B_TRUE); 9207c478bd9Sstevel@tonic-gate } 9217c478bd9Sstevel@tonic-gate objp = objp1; 9227c478bd9Sstevel@tonic-gate } 9237c478bd9Sstevel@tonic-gate break; 9247c478bd9Sstevel@tonic-gate 9257c478bd9Sstevel@tonic-gate case ALL_TOKEN: 9267c478bd9Sstevel@tonic-gate while (objp) { 9277c478bd9Sstevel@tonic-gate objp1 = objp->next; 9287c478bd9Sstevel@tonic-gate soft_delete_token_object(objp, B_FALSE, B_TRUE); 9297c478bd9Sstevel@tonic-gate objp = objp1; 9307c478bd9Sstevel@tonic-gate } 9317c478bd9Sstevel@tonic-gate break; 9327c478bd9Sstevel@tonic-gate } 9337c478bd9Sstevel@tonic-gate 9347c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_slot.slot_mutex); 9357c478bd9Sstevel@tonic-gate 9367c478bd9Sstevel@tonic-gate } 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate /* 93990e0e8c4Sizick * Mark all the token objects in the global list to be valid. 9407c478bd9Sstevel@tonic-gate */ 9417c478bd9Sstevel@tonic-gate void 9427c478bd9Sstevel@tonic-gate soft_validate_token_objects(boolean_t validate) 9437c478bd9Sstevel@tonic-gate { 9447c478bd9Sstevel@tonic-gate 9457c478bd9Sstevel@tonic-gate soft_object_t *objp; 9467c478bd9Sstevel@tonic-gate 9477c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_slot.slot_mutex); 94890e0e8c4Sizick 9497c478bd9Sstevel@tonic-gate objp = soft_slot.token_object_list; 9507c478bd9Sstevel@tonic-gate 9517c478bd9Sstevel@tonic-gate while (objp) { 9527c478bd9Sstevel@tonic-gate if (validate) 9537c478bd9Sstevel@tonic-gate objp->magic_marker = SOFTTOKEN_OBJECT_MAGIC; 9547c478bd9Sstevel@tonic-gate else 9557c478bd9Sstevel@tonic-gate objp->magic_marker = 0; 9567c478bd9Sstevel@tonic-gate 9577c478bd9Sstevel@tonic-gate objp = objp->next; 9587c478bd9Sstevel@tonic-gate } 9597c478bd9Sstevel@tonic-gate 9607c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_slot.slot_mutex); 9617c478bd9Sstevel@tonic-gate 9627c478bd9Sstevel@tonic-gate } 9637c478bd9Sstevel@tonic-gate 9647c478bd9Sstevel@tonic-gate /* 9657c478bd9Sstevel@tonic-gate * Verify user's write access rule to the token object. 9667c478bd9Sstevel@tonic-gate */ 9677c478bd9Sstevel@tonic-gate CK_RV 9687c478bd9Sstevel@tonic-gate soft_object_write_access_check(soft_session_t *sp, soft_object_t *objp) 9697c478bd9Sstevel@tonic-gate { 9707c478bd9Sstevel@tonic-gate 9717c478bd9Sstevel@tonic-gate /* 9727c478bd9Sstevel@tonic-gate * This function is called by C_CreateObject, C_CopyObject, 9737c478bd9Sstevel@tonic-gate * C_DestroyObject, C_SetAttributeValue, C_GenerateKey, 9747c478bd9Sstevel@tonic-gate * C_GenerateKeyPairs, C_DeriveKey. All of them will write 9757c478bd9Sstevel@tonic-gate * the token object to the keystore. 9767c478bd9Sstevel@tonic-gate */ 9777c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_giant_mutex); 9787c478bd9Sstevel@tonic-gate if (!soft_slot.authenticated) { 9797c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_giant_mutex); 9807c478bd9Sstevel@tonic-gate /* User is not logged in */ 9817c478bd9Sstevel@tonic-gate if (sp->flags & CKF_RW_SESSION) { 9827c478bd9Sstevel@tonic-gate /* 9837c478bd9Sstevel@tonic-gate * For R/W Public Session: 9847c478bd9Sstevel@tonic-gate * we allow write access to public session or token 9857c478bd9Sstevel@tonic-gate * object, but not for private token/session object. 9867c478bd9Sstevel@tonic-gate */ 9877c478bd9Sstevel@tonic-gate if ((objp->object_type == TOKEN_PRIVATE) || 9887c478bd9Sstevel@tonic-gate (objp->object_type == SESSION_PRIVATE)) { 9897c478bd9Sstevel@tonic-gate return (CKR_USER_NOT_LOGGED_IN); 9907c478bd9Sstevel@tonic-gate } 9917c478bd9Sstevel@tonic-gate } else { 9927c478bd9Sstevel@tonic-gate /* 9937c478bd9Sstevel@tonic-gate * For R/O Public Session: 9947c478bd9Sstevel@tonic-gate * we allow write access to public session object. 9957c478bd9Sstevel@tonic-gate */ 9967c478bd9Sstevel@tonic-gate if (objp->object_type != SESSION_PUBLIC) 9977c478bd9Sstevel@tonic-gate return (CKR_SESSION_READ_ONLY); 9987c478bd9Sstevel@tonic-gate } 9997c478bd9Sstevel@tonic-gate } else { 10007c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_giant_mutex); 10017c478bd9Sstevel@tonic-gate /* User is logged in */ 10027c478bd9Sstevel@tonic-gate if (!(sp->flags & CKF_RW_SESSION)) { 10037c478bd9Sstevel@tonic-gate /* 10047c478bd9Sstevel@tonic-gate * For R/O User Function Session: 10057c478bd9Sstevel@tonic-gate * we allow write access to public or private 10067c478bd9Sstevel@tonic-gate * session object, but not for public or private 10077c478bd9Sstevel@tonic-gate * token object. 10087c478bd9Sstevel@tonic-gate */ 10097c478bd9Sstevel@tonic-gate if ((objp->object_type == TOKEN_PUBLIC) || 10107c478bd9Sstevel@tonic-gate (objp->object_type == TOKEN_PRIVATE)) { 10117c478bd9Sstevel@tonic-gate return (CKR_SESSION_READ_ONLY); 10127c478bd9Sstevel@tonic-gate } 10137c478bd9Sstevel@tonic-gate } 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate 10167c478bd9Sstevel@tonic-gate return (CKR_OK); 10177c478bd9Sstevel@tonic-gate } 10187c478bd9Sstevel@tonic-gate 10197c478bd9Sstevel@tonic-gate /* 10207c478bd9Sstevel@tonic-gate * Verify if user is required to setpin when accessing the 10217c478bd9Sstevel@tonic-gate * private token/session object. 10227c478bd9Sstevel@tonic-gate */ 10237c478bd9Sstevel@tonic-gate CK_RV 10247c478bd9Sstevel@tonic-gate soft_pin_expired_check(soft_object_t *objp) 10257c478bd9Sstevel@tonic-gate { 10267c478bd9Sstevel@tonic-gate 10277c478bd9Sstevel@tonic-gate /* 10287c478bd9Sstevel@tonic-gate * This function is called by C_CreateObject, C_CopyObject, 10297c478bd9Sstevel@tonic-gate * C_DestroyObject, C_GenerateKey, 10307c478bd9Sstevel@tonic-gate * C_GenerateKeyPairs, C_DeriveKey. 10317c478bd9Sstevel@tonic-gate * All of them will return CKR_PIN_EXPIRED if the 10327c478bd9Sstevel@tonic-gate * "userpin_change_needed" is set. 10337c478bd9Sstevel@tonic-gate * 10347c478bd9Sstevel@tonic-gate * The following functions will not be necessary to call 10357c478bd9Sstevel@tonic-gate * this routine even though CKR_PIN_EXPIRED is one of the 10367c478bd9Sstevel@tonic-gate * valid error code they might return. These functions are: 10377c478bd9Sstevel@tonic-gate * C_EncryptInit, C_DecryptInit, C_DigestInit, C_SignInit, 10387c478bd9Sstevel@tonic-gate * C_SignRecoverInit, C_VerifyInit, C_VerifyRecoverInit. 10397c478bd9Sstevel@tonic-gate * This is because they will not get the object handle 10407c478bd9Sstevel@tonic-gate * before the above functions are called. 10417c478bd9Sstevel@tonic-gate */ 10427c478bd9Sstevel@tonic-gate 10437c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_giant_mutex); 10447c478bd9Sstevel@tonic-gate if (soft_slot.userpin_change_needed) { 10457c478bd9Sstevel@tonic-gate /* 10467c478bd9Sstevel@tonic-gate * Access private token/session object but user's 10477c478bd9Sstevel@tonic-gate * PIN is expired or never set. 10487c478bd9Sstevel@tonic-gate */ 10497c478bd9Sstevel@tonic-gate if ((objp->object_type == TOKEN_PRIVATE) || 10507c478bd9Sstevel@tonic-gate (objp->object_type == SESSION_PRIVATE)) { 10517c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_giant_mutex); 10527c478bd9Sstevel@tonic-gate return (CKR_PIN_EXPIRED); 10537c478bd9Sstevel@tonic-gate } 10547c478bd9Sstevel@tonic-gate } 10557c478bd9Sstevel@tonic-gate 10567c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_giant_mutex); 10577c478bd9Sstevel@tonic-gate return (CKR_OK); 10587c478bd9Sstevel@tonic-gate } 10597c478bd9Sstevel@tonic-gate 10607c478bd9Sstevel@tonic-gate /* 10617c478bd9Sstevel@tonic-gate * Copy the selected fields from new token object to old 10627c478bd9Sstevel@tonic-gate * token object. 10637c478bd9Sstevel@tonic-gate */ 10647c478bd9Sstevel@tonic-gate CK_RV 10657c478bd9Sstevel@tonic-gate soft_copy_to_old_object(soft_object_t *new, soft_object_t *old) 10667c478bd9Sstevel@tonic-gate { 10677c478bd9Sstevel@tonic-gate 10687c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 10697c478bd9Sstevel@tonic-gate CK_ATTRIBUTE_INFO_PTR attrp; 10707c478bd9Sstevel@tonic-gate 10717c478bd9Sstevel@tonic-gate old->class = new->class; 10727c478bd9Sstevel@tonic-gate old->bool_attr_mask = new->bool_attr_mask; 10737c478bd9Sstevel@tonic-gate soft_cleanup_extra_attr(old); 10747c478bd9Sstevel@tonic-gate attrp = new->extra_attrlistp; 10757c478bd9Sstevel@tonic-gate while (attrp) { 10767c478bd9Sstevel@tonic-gate rv = soft_copy_extra_attr(attrp, old); 10777c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 10787c478bd9Sstevel@tonic-gate soft_cleanup_extra_attr(old); 10797c478bd9Sstevel@tonic-gate return (rv); 10807c478bd9Sstevel@tonic-gate } 10817c478bd9Sstevel@tonic-gate attrp = attrp->next; 10827c478bd9Sstevel@tonic-gate } 10837c478bd9Sstevel@tonic-gate 10847c478bd9Sstevel@tonic-gate /* Done with copying all information that can be modified */ 10857c478bd9Sstevel@tonic-gate return (CKR_OK); 10867c478bd9Sstevel@tonic-gate } 10877c478bd9Sstevel@tonic-gate 10887c478bd9Sstevel@tonic-gate /* 10897c478bd9Sstevel@tonic-gate * Update an existing object with new data from keystore. 10907c478bd9Sstevel@tonic-gate */ 10917c478bd9Sstevel@tonic-gate CK_RV 10927c478bd9Sstevel@tonic-gate soft_update_object(ks_obj_t *ks_obj, soft_object_t *old_obj) 10937c478bd9Sstevel@tonic-gate { 10947c478bd9Sstevel@tonic-gate 10957c478bd9Sstevel@tonic-gate soft_object_t *new_object; 10967c478bd9Sstevel@tonic-gate CK_RV rv; 10977c478bd9Sstevel@tonic-gate 10987c478bd9Sstevel@tonic-gate new_object = calloc(1, sizeof (soft_object_t)); 10997c478bd9Sstevel@tonic-gate if (new_object == NULL) 11007c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 11017c478bd9Sstevel@tonic-gate 11027c478bd9Sstevel@tonic-gate rv = soft_keystore_unpack_obj(new_object, ks_obj); 11037c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 11047c478bd9Sstevel@tonic-gate soft_cleanup_object(new_object); 11057c478bd9Sstevel@tonic-gate free(new_object); 11067c478bd9Sstevel@tonic-gate return (rv); 11077c478bd9Sstevel@tonic-gate } 11087c478bd9Sstevel@tonic-gate rv = soft_copy_to_old_object(new_object, old_obj); 11097c478bd9Sstevel@tonic-gate 11107c478bd9Sstevel@tonic-gate soft_cleanup_object(new_object); 11117c478bd9Sstevel@tonic-gate free(new_object); 11127c478bd9Sstevel@tonic-gate return (CKR_OK); 11137c478bd9Sstevel@tonic-gate } 11147c478bd9Sstevel@tonic-gate 11157c478bd9Sstevel@tonic-gate 11167c478bd9Sstevel@tonic-gate CK_RV 11177c478bd9Sstevel@tonic-gate soft_keystore_load_latest_object(soft_object_t *old_obj) 11187c478bd9Sstevel@tonic-gate { 11197c478bd9Sstevel@tonic-gate 11207c478bd9Sstevel@tonic-gate uint_t version; 11217c478bd9Sstevel@tonic-gate ks_obj_t *ks_obj = NULL; 11227c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 11237c478bd9Sstevel@tonic-gate 11247c478bd9Sstevel@tonic-gate /* 11257c478bd9Sstevel@tonic-gate * Get the current version number from the keystore for 11267c478bd9Sstevel@tonic-gate * the specified token object. 11277c478bd9Sstevel@tonic-gate */ 11287c478bd9Sstevel@tonic-gate if (soft_keystore_get_object_version(&old_obj->ks_handle, &version, 11297c478bd9Sstevel@tonic-gate B_FALSE) == 1) 11307c478bd9Sstevel@tonic-gate return (CKR_FUNCTION_FAILED); 11317c478bd9Sstevel@tonic-gate 11327c478bd9Sstevel@tonic-gate /* 11337c478bd9Sstevel@tonic-gate * If the keystore version is newer than the in-core version, 11347c478bd9Sstevel@tonic-gate * re-read the token object from the keystore. 11357c478bd9Sstevel@tonic-gate */ 11367c478bd9Sstevel@tonic-gate if (old_obj->version != version) { 11377c478bd9Sstevel@tonic-gate rv = soft_keystore_get_single_obj(&old_obj->ks_handle, 11387c478bd9Sstevel@tonic-gate &ks_obj, B_FALSE); 11397c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 11407c478bd9Sstevel@tonic-gate return (rv); 11417c478bd9Sstevel@tonic-gate old_obj->version = version; 11427c478bd9Sstevel@tonic-gate 11437c478bd9Sstevel@tonic-gate /* 11447c478bd9Sstevel@tonic-gate * Update an existing object with new data from keystore. 11457c478bd9Sstevel@tonic-gate */ 11467c478bd9Sstevel@tonic-gate rv = soft_update_object(ks_obj, old_obj); 11477c478bd9Sstevel@tonic-gate free(ks_obj->buf); 11487c478bd9Sstevel@tonic-gate free(ks_obj); 11497c478bd9Sstevel@tonic-gate } 11507c478bd9Sstevel@tonic-gate 11517c478bd9Sstevel@tonic-gate return (rv); 11527c478bd9Sstevel@tonic-gate } 11537c478bd9Sstevel@tonic-gate 11547c478bd9Sstevel@tonic-gate /* 11557c478bd9Sstevel@tonic-gate * Insert an object into a list of soft_object_t objects. It is assumed 11567c478bd9Sstevel@tonic-gate * that the object to be inserted doesn't previously belong to any list 11577c478bd9Sstevel@tonic-gate */ 11587c478bd9Sstevel@tonic-gate static void 11597c478bd9Sstevel@tonic-gate insert_into_list(soft_object_t **list, soft_object_t **end_of_list, 11607c478bd9Sstevel@tonic-gate soft_object_t *objp) 11617c478bd9Sstevel@tonic-gate { 11627c478bd9Sstevel@tonic-gate if (*list == NULL) { 11637c478bd9Sstevel@tonic-gate *list = objp; 11647c478bd9Sstevel@tonic-gate objp->next = NULL; 11657c478bd9Sstevel@tonic-gate objp->prev = NULL; 11667c478bd9Sstevel@tonic-gate *end_of_list = objp; 11677c478bd9Sstevel@tonic-gate } else { 11687c478bd9Sstevel@tonic-gate (*list)->prev = objp; 11697c478bd9Sstevel@tonic-gate objp->next = *list; 11707c478bd9Sstevel@tonic-gate objp->prev = NULL; 11717c478bd9Sstevel@tonic-gate *list = objp; 11727c478bd9Sstevel@tonic-gate } 11737c478bd9Sstevel@tonic-gate } 11747c478bd9Sstevel@tonic-gate 11757c478bd9Sstevel@tonic-gate /* 11767c478bd9Sstevel@tonic-gate * Move an object from an existing list into a new list of 11777c478bd9Sstevel@tonic-gate * soft_object_t objects. 11787c478bd9Sstevel@tonic-gate */ 11797c478bd9Sstevel@tonic-gate static void 11807c478bd9Sstevel@tonic-gate move_into_list(soft_object_t **existing_list, soft_object_t **new_list, 11817c478bd9Sstevel@tonic-gate soft_object_t **end_of_list, soft_object_t *objp) 11827c478bd9Sstevel@tonic-gate { 11837c478bd9Sstevel@tonic-gate 11847c478bd9Sstevel@tonic-gate /* first, remove object from existing list */ 11857c478bd9Sstevel@tonic-gate if (objp == *existing_list) { 11867c478bd9Sstevel@tonic-gate /* first item in list */ 11877c478bd9Sstevel@tonic-gate if (objp->next) { 11887c478bd9Sstevel@tonic-gate *existing_list = objp->next; 11897c478bd9Sstevel@tonic-gate objp->next->prev = NULL; 11907c478bd9Sstevel@tonic-gate } else { 11917c478bd9Sstevel@tonic-gate *existing_list = NULL; 11927c478bd9Sstevel@tonic-gate } 11937c478bd9Sstevel@tonic-gate } else { 11947c478bd9Sstevel@tonic-gate if (objp->next) { 11957c478bd9Sstevel@tonic-gate objp->prev->next = objp->next; 11967c478bd9Sstevel@tonic-gate objp->next->prev = objp->prev; 11977c478bd9Sstevel@tonic-gate } else { 11987c478bd9Sstevel@tonic-gate objp->prev->next = NULL; 11997c478bd9Sstevel@tonic-gate } 12007c478bd9Sstevel@tonic-gate } 12017c478bd9Sstevel@tonic-gate 12027c478bd9Sstevel@tonic-gate /* then, add into new list */ 12037c478bd9Sstevel@tonic-gate insert_into_list(new_list, end_of_list, objp); 12047c478bd9Sstevel@tonic-gate } 12057c478bd9Sstevel@tonic-gate 12067c478bd9Sstevel@tonic-gate /* 12077c478bd9Sstevel@tonic-gate * Insert "new_list" into "existing_list", new list will always be inserted 12087c478bd9Sstevel@tonic-gate * into the front of existing list 12097c478bd9Sstevel@tonic-gate */ 12107c478bd9Sstevel@tonic-gate static void 12117c478bd9Sstevel@tonic-gate insert_list_into_list(soft_object_t **existing_list, 12127c478bd9Sstevel@tonic-gate soft_object_t *new_list, soft_object_t *end_new_list) 12137c478bd9Sstevel@tonic-gate { 12147c478bd9Sstevel@tonic-gate 12157c478bd9Sstevel@tonic-gate if (new_list == NULL) { 12167c478bd9Sstevel@tonic-gate return; 12177c478bd9Sstevel@tonic-gate } 12187c478bd9Sstevel@tonic-gate 12197c478bd9Sstevel@tonic-gate if (*existing_list == NULL) { 12207c478bd9Sstevel@tonic-gate *existing_list = new_list; 12217c478bd9Sstevel@tonic-gate } else { 12227c478bd9Sstevel@tonic-gate (*existing_list)->prev = end_new_list; 12237c478bd9Sstevel@tonic-gate end_new_list->next = *existing_list; 12247c478bd9Sstevel@tonic-gate *existing_list = new_list; 12257c478bd9Sstevel@tonic-gate } 12267c478bd9Sstevel@tonic-gate } 12277c478bd9Sstevel@tonic-gate 12287c478bd9Sstevel@tonic-gate static void 12297c478bd9Sstevel@tonic-gate delete_all_objs_in_list(soft_object_t *list) 12307c478bd9Sstevel@tonic-gate { 12317c478bd9Sstevel@tonic-gate soft_object_t *objp, *objp_next; 12327c478bd9Sstevel@tonic-gate 12337c478bd9Sstevel@tonic-gate if (list == NULL) { 12347c478bd9Sstevel@tonic-gate return; 12357c478bd9Sstevel@tonic-gate } 12367c478bd9Sstevel@tonic-gate 12377c478bd9Sstevel@tonic-gate objp = list; 12387c478bd9Sstevel@tonic-gate while (objp) { 12397c478bd9Sstevel@tonic-gate objp_next = objp->next; 12401f49a79aSZdenek Kotala soft_delete_object_cleanup(objp, B_FALSE); 12417c478bd9Sstevel@tonic-gate objp = objp_next; 12427c478bd9Sstevel@tonic-gate } 12437c478bd9Sstevel@tonic-gate } 12447c478bd9Sstevel@tonic-gate 12457c478bd9Sstevel@tonic-gate /* 12467c478bd9Sstevel@tonic-gate * Makes sure that the list of in-core token objects are up to date 12477c478bd9Sstevel@tonic-gate * with respect to the on disk keystore. Other process/applications 12487c478bd9Sstevel@tonic-gate * might have modified the keystore since the objects are last loaded 12497c478bd9Sstevel@tonic-gate * 12507c478bd9Sstevel@tonic-gate * If there's any error from refreshing the token object list (eg: unable 12517c478bd9Sstevel@tonic-gate * to read, unable to unpack and object...etc), the in-core list 12527c478bd9Sstevel@tonic-gate * will be restored back to the state before the refresh. An error 12537c478bd9Sstevel@tonic-gate * will be returned to indicate the failure. 12547c478bd9Sstevel@tonic-gate * 12557c478bd9Sstevel@tonic-gate * It is assumed that the caller holds the lock for the token slot 12567c478bd9Sstevel@tonic-gate */ 12577c478bd9Sstevel@tonic-gate CK_RV 12587c478bd9Sstevel@tonic-gate refresh_token_objects() 12597c478bd9Sstevel@tonic-gate { 12607c478bd9Sstevel@tonic-gate uint_t on_disk_ks_version; 12617c478bd9Sstevel@tonic-gate ks_obj_t *on_disk_list = NULL, *tmp_on_disk, *next_on_disk; 12627c478bd9Sstevel@tonic-gate soft_object_t *in_core_obj, *tmp_incore_obj, *new_objp = NULL; 12637c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 12647c478bd9Sstevel@tonic-gate 12657c478bd9Sstevel@tonic-gate /* deleted in-core objects */ 1266c2e31228SViswanathan Kannappan soft_object_t *del_objs_list = NULL; 1267c2e31228SViswanathan Kannappan soft_object_t *end_del_objs_list = NULL; 12687c478bd9Sstevel@tonic-gate 12697c478bd9Sstevel@tonic-gate /* modified in-core objects */ 1270c2e31228SViswanathan Kannappan soft_object_t *mod_objs_list = NULL; 1271c2e31228SViswanathan Kannappan soft_object_t *end_mod_objs_list = NULL; 12727c478bd9Sstevel@tonic-gate 12737c478bd9Sstevel@tonic-gate /* 12747c478bd9Sstevel@tonic-gate * copy of modified in-core objects, in case we need 12757c478bd9Sstevel@tonic-gate * undo the change 12767c478bd9Sstevel@tonic-gate */ 1277c2e31228SViswanathan Kannappan soft_object_t *copy_of_mod_objs_list = NULL; 1278c2e31228SViswanathan Kannappan soft_object_t *end_copy_of_mod_objs_list = NULL; 12797c478bd9Sstevel@tonic-gate 12807c478bd9Sstevel@tonic-gate /* objects to be added to the in-core list */ 1281c2e31228SViswanathan Kannappan soft_object_t *added_objs_list = NULL; 1282c2e31228SViswanathan Kannappan soft_object_t *end_added_objs_list = NULL; 12837c478bd9Sstevel@tonic-gate 12847c478bd9Sstevel@tonic-gate if (soft_keystore_get_version(&on_disk_ks_version, B_FALSE) != 0) { 12857c478bd9Sstevel@tonic-gate return (CKR_FUNCTION_FAILED); 12867c478bd9Sstevel@tonic-gate } 12877c478bd9Sstevel@tonic-gate 12887c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_giant_mutex); 12897c478bd9Sstevel@tonic-gate if (on_disk_ks_version == soft_slot.ks_version) { 12907c478bd9Sstevel@tonic-gate /* no change */ 12917c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_giant_mutex); 12927c478bd9Sstevel@tonic-gate return (CKR_OK); 12937c478bd9Sstevel@tonic-gate } 12947c478bd9Sstevel@tonic-gate 12957c478bd9Sstevel@tonic-gate if (soft_slot.authenticated) { 12967c478bd9Sstevel@tonic-gate /* get both public and private objects */ 12977c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_giant_mutex); 12987c478bd9Sstevel@tonic-gate rv = soft_keystore_get_objs(ALL_TOKENOBJS, &on_disk_list, 12997c478bd9Sstevel@tonic-gate B_FALSE); 13007c478bd9Sstevel@tonic-gate } else { 13017c478bd9Sstevel@tonic-gate /* get both public objects only */ 13027c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_giant_mutex); 13037c478bd9Sstevel@tonic-gate rv = soft_keystore_get_objs(PUB_TOKENOBJS, &on_disk_list, 13047c478bd9Sstevel@tonic-gate B_FALSE); 13057c478bd9Sstevel@tonic-gate } 13067c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 13077c478bd9Sstevel@tonic-gate return (rv); 13087c478bd9Sstevel@tonic-gate } 13097c478bd9Sstevel@tonic-gate 13107c478bd9Sstevel@tonic-gate /* 13117c478bd9Sstevel@tonic-gate * The in-core tokens list will be updated as follows: 13127c478bd9Sstevel@tonic-gate * 13137c478bd9Sstevel@tonic-gate * Go through each item in the in-core tokens list. 13147c478bd9Sstevel@tonic-gate * Try to match the in-core object with one of the 13157c478bd9Sstevel@tonic-gate * objects from the on-disk list. If a match is made, 13167c478bd9Sstevel@tonic-gate * check the version number, and update in-core object 13177c478bd9Sstevel@tonic-gate * as necessary. 13187c478bd9Sstevel@tonic-gate * 13197c478bd9Sstevel@tonic-gate * If there's no match between in-core object with on-disk 13207c478bd9Sstevel@tonic-gate * object, that means the object is deleted since 13217c478bd9Sstevel@tonic-gate * last loaded. Will remove object from in-core list. 13227c478bd9Sstevel@tonic-gate * 13237c478bd9Sstevel@tonic-gate * When doing the matching of on-disk object list above, 13247c478bd9Sstevel@tonic-gate * Delete every matched on-disk object from the on-disk list 13257c478bd9Sstevel@tonic-gate * regardless the in-core object need to be deleted or not 13267c478bd9Sstevel@tonic-gate * 13277c478bd9Sstevel@tonic-gate * At the end of matching the in-core tokens list, if 13287c478bd9Sstevel@tonic-gate * any object is still left on the on-disk object list, 13297c478bd9Sstevel@tonic-gate * those are all new objects added since last load, 13307c478bd9Sstevel@tonic-gate * include all of them to the in-core list 13317c478bd9Sstevel@tonic-gate * 13327c478bd9Sstevel@tonic-gate * Since we need to be able to revert the in-core list 13337c478bd9Sstevel@tonic-gate * back to original state if there's any error with the refresh, 13347c478bd9Sstevel@tonic-gate * we need to do the following. 13357c478bd9Sstevel@tonic-gate * When an in-core object is "deleted", it is not immediately 13367c478bd9Sstevel@tonic-gate * deleted. It is moved to the list of "deleted_objects". 13377c478bd9Sstevel@tonic-gate * When an in-core object is "modified", a copy of the 13387c478bd9Sstevel@tonic-gate * unmodified object is made. After the object is modified, 13397c478bd9Sstevel@tonic-gate * it is temporarily moved to the "mod_objects" list 13407c478bd9Sstevel@tonic-gate * from the in-core list. 13417c478bd9Sstevel@tonic-gate * When the refresh is completed without any error, 13427c478bd9Sstevel@tonic-gate * the actual deleted objects and unmodified objects is deleted. 13437c478bd9Sstevel@tonic-gate */ 13447c478bd9Sstevel@tonic-gate in_core_obj = soft_slot.token_object_list; 13457c478bd9Sstevel@tonic-gate while (in_core_obj) { 13467c478bd9Sstevel@tonic-gate /* try to match object with on_disk_list */ 13477c478bd9Sstevel@tonic-gate ks_obj_t *ondisk_obj, *prev_ondisk_obj; 13487c478bd9Sstevel@tonic-gate boolean_t found = B_FALSE; 13497c478bd9Sstevel@tonic-gate soft_object_t *obj_copy; 13507c478bd9Sstevel@tonic-gate 13517c478bd9Sstevel@tonic-gate ondisk_obj = on_disk_list; 13527c478bd9Sstevel@tonic-gate prev_ondisk_obj = NULL; 13537c478bd9Sstevel@tonic-gate 13544d25c1d6Smcpowers /* larval object that has not been written to disk */ 13554d25c1d6Smcpowers if (in_core_obj->ks_handle.name[0] == '\0') { 13564d25c1d6Smcpowers in_core_obj = in_core_obj->next; 13574d25c1d6Smcpowers continue; 13584d25c1d6Smcpowers } 13594d25c1d6Smcpowers 13607c478bd9Sstevel@tonic-gate while ((!found) && (ondisk_obj != NULL)) { 13617c478bd9Sstevel@tonic-gate 13627c478bd9Sstevel@tonic-gate if (strcmp((char *)((ondisk_obj->ks_handle).name), 13637c478bd9Sstevel@tonic-gate (char *)((in_core_obj->ks_handle).name)) == 0) { 13647c478bd9Sstevel@tonic-gate 13657c478bd9Sstevel@tonic-gate /* found a match */ 13667c478bd9Sstevel@tonic-gate found = B_TRUE; 13677c478bd9Sstevel@tonic-gate 13687c478bd9Sstevel@tonic-gate /* update in-core obj if necessary */ 13697c478bd9Sstevel@tonic-gate if (ondisk_obj->obj_version != 13707c478bd9Sstevel@tonic-gate in_core_obj->version) { 13717c478bd9Sstevel@tonic-gate /* make a copy of before updating */ 13727c478bd9Sstevel@tonic-gate rv = soft_copy_object(in_core_obj, 13737c478bd9Sstevel@tonic-gate &obj_copy, SOFT_COPY_OBJ_ORIG_SH, 13747c478bd9Sstevel@tonic-gate NULL); 13757c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 13767c478bd9Sstevel@tonic-gate goto cleanup; 13777c478bd9Sstevel@tonic-gate } 13787c478bd9Sstevel@tonic-gate insert_into_list( 13797c478bd9Sstevel@tonic-gate ©_of_mod_objs_list, 13807c478bd9Sstevel@tonic-gate &end_copy_of_mod_objs_list, 13817c478bd9Sstevel@tonic-gate obj_copy); 13827c478bd9Sstevel@tonic-gate 13837c478bd9Sstevel@tonic-gate rv = soft_update_object(ondisk_obj, 13847c478bd9Sstevel@tonic-gate in_core_obj); 13857c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 13867c478bd9Sstevel@tonic-gate goto cleanup; 13877c478bd9Sstevel@tonic-gate } 13887c478bd9Sstevel@tonic-gate move_into_list( 13897c478bd9Sstevel@tonic-gate &(soft_slot.token_object_list), 13907c478bd9Sstevel@tonic-gate &mod_objs_list, &end_mod_objs_list, 13917c478bd9Sstevel@tonic-gate in_core_obj); 13927c478bd9Sstevel@tonic-gate } 13937c478bd9Sstevel@tonic-gate 13947c478bd9Sstevel@tonic-gate /* remove processed obj from on disk list */ 13957c478bd9Sstevel@tonic-gate if (ondisk_obj == on_disk_list) { 13967c478bd9Sstevel@tonic-gate /* first item */ 13977c478bd9Sstevel@tonic-gate on_disk_list = ondisk_obj->next; 13987c478bd9Sstevel@tonic-gate } else { 13997c478bd9Sstevel@tonic-gate prev_ondisk_obj->next = 14007c478bd9Sstevel@tonic-gate ondisk_obj->next; 14017c478bd9Sstevel@tonic-gate } 14027c478bd9Sstevel@tonic-gate free(ondisk_obj->buf); 14037c478bd9Sstevel@tonic-gate free(ondisk_obj); 14047c478bd9Sstevel@tonic-gate } else { 14057c478bd9Sstevel@tonic-gate prev_ondisk_obj = ondisk_obj; 14067c478bd9Sstevel@tonic-gate ondisk_obj = ondisk_obj->next; 14077c478bd9Sstevel@tonic-gate } 14087c478bd9Sstevel@tonic-gate } 14097c478bd9Sstevel@tonic-gate 14107c478bd9Sstevel@tonic-gate if (!found) { 14117c478bd9Sstevel@tonic-gate tmp_incore_obj = in_core_obj->next; 14127c478bd9Sstevel@tonic-gate move_into_list(&(soft_slot.token_object_list), 14137c478bd9Sstevel@tonic-gate &del_objs_list, &end_del_objs_list, in_core_obj); 14147c478bd9Sstevel@tonic-gate in_core_obj = tmp_incore_obj; 14157c478bd9Sstevel@tonic-gate } else { 14167c478bd9Sstevel@tonic-gate in_core_obj = in_core_obj->next; 14177c478bd9Sstevel@tonic-gate } 14187c478bd9Sstevel@tonic-gate } 14197c478bd9Sstevel@tonic-gate 14207c478bd9Sstevel@tonic-gate /* 14217c478bd9Sstevel@tonic-gate * At this point, if there's still anything on the on_disk_list, they 14227c478bd9Sstevel@tonic-gate * are all newly added objects since in-core list last loaded. 14237c478bd9Sstevel@tonic-gate * include all of them into the in-core list 14247c478bd9Sstevel@tonic-gate */ 14257c478bd9Sstevel@tonic-gate next_on_disk = on_disk_list; 14267c478bd9Sstevel@tonic-gate while (next_on_disk) { 14277c478bd9Sstevel@tonic-gate new_objp = calloc(1, sizeof (soft_object_t)); 14287c478bd9Sstevel@tonic-gate if (new_objp == NULL) { 14297c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 14307c478bd9Sstevel@tonic-gate goto cleanup; 14317c478bd9Sstevel@tonic-gate } 14327c478bd9Sstevel@tonic-gate 14337c478bd9Sstevel@tonic-gate /* Convert the keystore format to memory format */ 14347c478bd9Sstevel@tonic-gate rv = soft_keystore_unpack_obj(new_objp, next_on_disk); 14357c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 14367c478bd9Sstevel@tonic-gate soft_cleanup_object(new_objp); 14377c478bd9Sstevel@tonic-gate free(new_objp); 14387c478bd9Sstevel@tonic-gate goto cleanup; 14397c478bd9Sstevel@tonic-gate } 14407c478bd9Sstevel@tonic-gate 14417c478bd9Sstevel@tonic-gate insert_into_list(&added_objs_list, &end_added_objs_list, 14427c478bd9Sstevel@tonic-gate new_objp); 14437c478bd9Sstevel@tonic-gate 14447c478bd9Sstevel@tonic-gate /* free the on_disk object */ 14457c478bd9Sstevel@tonic-gate tmp_on_disk = next_on_disk; 14467c478bd9Sstevel@tonic-gate next_on_disk = tmp_on_disk->next; 14477c478bd9Sstevel@tonic-gate free(tmp_on_disk->buf); 14487c478bd9Sstevel@tonic-gate free(tmp_on_disk); 14497c478bd9Sstevel@tonic-gate } 14507c478bd9Sstevel@tonic-gate 14517c478bd9Sstevel@tonic-gate if (rv == CKR_OK) { 14527c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&soft_giant_mutex); 14537c478bd9Sstevel@tonic-gate soft_slot.ks_version = on_disk_ks_version; 14547c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&soft_giant_mutex); 14557c478bd9Sstevel@tonic-gate 14567c478bd9Sstevel@tonic-gate /* add the new objects into in-core list */ 14577c478bd9Sstevel@tonic-gate insert_list_into_list(&(soft_slot.token_object_list), 14587c478bd9Sstevel@tonic-gate added_objs_list, end_added_objs_list); 14597c478bd9Sstevel@tonic-gate 14607c478bd9Sstevel@tonic-gate /* add modified objects back into the in-core list */ 14617c478bd9Sstevel@tonic-gate insert_list_into_list(&(soft_slot.token_object_list), 14627c478bd9Sstevel@tonic-gate mod_objs_list, end_mod_objs_list); 14637c478bd9Sstevel@tonic-gate 14647c478bd9Sstevel@tonic-gate /* actually remove deleted objs, and copy of modified objs */ 14657c478bd9Sstevel@tonic-gate delete_all_objs_in_list(copy_of_mod_objs_list); 14667c478bd9Sstevel@tonic-gate delete_all_objs_in_list(del_objs_list); 14677c478bd9Sstevel@tonic-gate } 14687c478bd9Sstevel@tonic-gate 14697c478bd9Sstevel@tonic-gate return (rv); 14707c478bd9Sstevel@tonic-gate 14717c478bd9Sstevel@tonic-gate cleanup: 14727c478bd9Sstevel@tonic-gate next_on_disk = on_disk_list; 14737c478bd9Sstevel@tonic-gate while (next_on_disk) { 14747c478bd9Sstevel@tonic-gate tmp_on_disk = next_on_disk; 14757c478bd9Sstevel@tonic-gate next_on_disk = tmp_on_disk->next; 14767c478bd9Sstevel@tonic-gate free(tmp_on_disk->buf); 14777c478bd9Sstevel@tonic-gate free(tmp_on_disk); 14787c478bd9Sstevel@tonic-gate } 14797c478bd9Sstevel@tonic-gate 14807c478bd9Sstevel@tonic-gate /* 14817c478bd9Sstevel@tonic-gate * restore the in-core list back to the original state by adding 14827c478bd9Sstevel@tonic-gate * copy of original objects and deleted objects back to list 14837c478bd9Sstevel@tonic-gate */ 14847c478bd9Sstevel@tonic-gate insert_list_into_list(&(soft_slot.token_object_list), 14857c478bd9Sstevel@tonic-gate del_objs_list, end_del_objs_list); 14867c478bd9Sstevel@tonic-gate insert_list_into_list(&(soft_slot.token_object_list), 14877c478bd9Sstevel@tonic-gate copy_of_mod_objs_list, end_copy_of_mod_objs_list); 14887c478bd9Sstevel@tonic-gate 14897c478bd9Sstevel@tonic-gate /* 14907c478bd9Sstevel@tonic-gate * remove the modified objects, and newly objects list 14917c478bd9Sstevel@tonic-gate */ 14927c478bd9Sstevel@tonic-gate delete_all_objs_in_list(mod_objs_list); 14937c478bd9Sstevel@tonic-gate delete_all_objs_in_list(added_objs_list); 14947c478bd9Sstevel@tonic-gate return (rv); 14957c478bd9Sstevel@tonic-gate } 1496*726fad2aSDina K Nimeh 1497*726fad2aSDina K Nimeh CK_RV 1498*726fad2aSDina K Nimeh dup_bigint_attr(biginteger_t *bi, CK_BYTE *buf, CK_ULONG buflen) 1499*726fad2aSDina K Nimeh { 1500*726fad2aSDina K Nimeh bi->big_value_len = buflen; 1501*726fad2aSDina K Nimeh if ((bi->big_value = malloc(buflen)) == NULL) { 1502*726fad2aSDina K Nimeh return (CKR_HOST_MEMORY); 1503*726fad2aSDina K Nimeh } 1504*726fad2aSDina K Nimeh (void) memcpy(bi->big_value, buf, buflen); 1505*726fad2aSDina K Nimeh return (CKR_OK); 1506*726fad2aSDina K Nimeh } 1507