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
soft_add_object_to_session(soft_object_t * objp,soft_session_t * sp)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
soft_cleanup_object(soft_object_t * objp)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
soft_copy_object(soft_object_t * old_object,soft_object_t ** new_object,CK_ULONG object_func,soft_session_t * sp)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
soft_merge_object(soft_object_t * old_object,soft_object_t * new_object)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
soft_add_object(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_ULONG * objecthandle_p,soft_session_t * sp)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
soft_remove_object_from_session(soft_object_t * objp,soft_session_t * sp)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
object_delay_free(soft_object_t * objp)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
soft_delete_object_cleanup(soft_object_t * objp,boolean_t force)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
soft_delete_object(soft_session_t * sp,soft_object_t * objp,boolean_t force,boolean_t lock_held)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
soft_delete_all_objects_in_session(soft_session_t * sp,boolean_t force)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
add_to_search_result(soft_object_t * obj,find_context_t * fcontext,CK_ULONG * num_result_alloc)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
search_for_objects(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,find_context_t * fcontext)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
soft_find_objects_init(soft_session_t * sp,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)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
soft_find_objects_final(soft_session_t * sp)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
soft_find_objects(soft_session_t * sp,CK_OBJECT_HANDLE * obj_found,CK_ULONG max_obj_requested,CK_ULONG * found_obj_count)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
soft_add_token_object_to_slot(soft_object_t * objp)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
soft_remove_token_object_from_slot(soft_object_t * objp,boolean_t lock_held)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
soft_delete_token_object(soft_object_t * objp,boolean_t persistent,boolean_t lock_held)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
soft_delete_all_in_core_token_objects(token_obj_type_t type)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
soft_validate_token_objects(boolean_t validate)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
soft_object_write_access_check(soft_session_t * sp,soft_object_t * objp)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
soft_pin_expired_check(soft_object_t * objp)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
soft_copy_to_old_object(soft_object_t * new,soft_object_t * old)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
soft_update_object(ks_obj_t * ks_obj,soft_object_t * old_obj)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
soft_keystore_load_latest_object(soft_object_t * old_obj)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
insert_into_list(soft_object_t ** list,soft_object_t ** end_of_list,soft_object_t * objp)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
move_into_list(soft_object_t ** existing_list,soft_object_t ** new_list,soft_object_t ** end_of_list,soft_object_t * objp)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
insert_list_into_list(soft_object_t ** existing_list,soft_object_t * new_list,soft_object_t * end_new_list)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
delete_all_objs_in_list(soft_object_t * list)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
refresh_token_objects()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
dup_bigint_attr(biginteger_t * bi,CK_BYTE * buf,CK_ULONG buflen)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