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
5034448feSmcpowers * Common Development and Distribution License (the "License").
6034448feSmcpowers * 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 */
217c478bd9Sstevel@tonic-gate /*
22*8cae6764SAnthony Scarpino * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate * Object Management Functions
287c478bd9Sstevel@tonic-gate * (as defined in PKCS#11 spec section 11.7)
297c478bd9Sstevel@tonic-gate */
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate #include <strings.h>
327c478bd9Sstevel@tonic-gate #include "metaGlobal.h"
337c478bd9Sstevel@tonic-gate #include <stdio.h>
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate #define FIND_OBJ_BUF_SIZE 512 /* size of buf used for C_FindObjects */
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate /*
387c478bd9Sstevel@tonic-gate * Argument related return codes. Will return to the caller immediately,
397c478bd9Sstevel@tonic-gate * and not try the operation on another slot.
407c478bd9Sstevel@tonic-gate */
417c478bd9Sstevel@tonic-gate static CK_RV stop_rv[] = {
427c478bd9Sstevel@tonic-gate CKR_ARGUMENTS_BAD,
437c478bd9Sstevel@tonic-gate CKR_ATTRIBUTE_TYPE_INVALID,
447c478bd9Sstevel@tonic-gate CKR_DOMAIN_PARAMS_INVALID,
457c478bd9Sstevel@tonic-gate CKR_TEMPLATE_INCOMPLETE
467c478bd9Sstevel@tonic-gate };
477c478bd9Sstevel@tonic-gate static int num_stop_rv = sizeof (stop_rv) / sizeof (CK_RV);
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate /*
507c478bd9Sstevel@tonic-gate * Return codes that are related to a specific slot.
517c478bd9Sstevel@tonic-gate * Will try to perform the operation in the next available slot.
527c478bd9Sstevel@tonic-gate * If all attempts failed, will return the error code from the first slot.
537c478bd9Sstevel@tonic-gate *
547c478bd9Sstevel@tonic-gate * This list is here for reference only, it is commented out because
557c478bd9Sstevel@tonic-gate * it doesn't need to be used by the code at this point.
567c478bd9Sstevel@tonic-gate *
577c478bd9Sstevel@tonic-gate * static CK_RV try_again_rv[] = {
587c478bd9Sstevel@tonic-gate * CKR_DEVICE_ERROR,
597c478bd9Sstevel@tonic-gate * CKR_DEVICE_MEMORY,
607c478bd9Sstevel@tonic-gate * CKR_DEVICE_REMOVED,
617c478bd9Sstevel@tonic-gate * CKR_FUNCTION_FAILED,
627c478bd9Sstevel@tonic-gate * CKR_GENERAL_ERROR,
637c478bd9Sstevel@tonic-gate * CKR_HOST_MEMORY,
647c478bd9Sstevel@tonic-gate * CKR_TEMPLATE_INCONSISTENT,
657c478bd9Sstevel@tonic-gate * CKR_ATTRIBUTE_READ_ONLY,
667c478bd9Sstevel@tonic-gate * CKR_ATTRIBUTE_VALUE_INVALID
677c478bd9Sstevel@tonic-gate * };
687c478bd9Sstevel@tonic-gate * static int num_try_again_rv = sizeof (try_again_rv) / sizeof (CK_RV);
697c478bd9Sstevel@tonic-gate */
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate /*
727c478bd9Sstevel@tonic-gate * We should never get these return codes because
737c478bd9Sstevel@tonic-gate * MetaSlot is the one that actually created the
747c478bd9Sstevel@tonic-gate * sessions. When we get these errors in C_CreateObject,
757c478bd9Sstevel@tonic-gate * will try to create the object in the next available slot.
767c478bd9Sstevel@tonic-gate * If all attempts failed, will return CKR_FUNCTION_FAILED
777c478bd9Sstevel@tonic-gate * to the caller.
787c478bd9Sstevel@tonic-gate */
797c478bd9Sstevel@tonic-gate static CK_RV other_rv[] = {
807c478bd9Sstevel@tonic-gate CKR_CRYPTOKI_NOT_INITIALIZED,
817c478bd9Sstevel@tonic-gate CKR_SESSION_CLOSED,
827c478bd9Sstevel@tonic-gate CKR_SESSION_HANDLE_INVALID,
837c478bd9Sstevel@tonic-gate CKR_SESSION_READ_ONLY
847c478bd9Sstevel@tonic-gate };
857c478bd9Sstevel@tonic-gate static int num_other_rv = sizeof (other_rv) / sizeof (CK_RV);
867c478bd9Sstevel@tonic-gate
877c478bd9Sstevel@tonic-gate /*
887c478bd9Sstevel@tonic-gate * This function is only used by the C_CreateObject and C_CopyObject.
897c478bd9Sstevel@tonic-gate *
907c478bd9Sstevel@tonic-gate * It is used to determine if the operation should be tried on another slot
917c478bd9Sstevel@tonic-gate * based on the return code
927c478bd9Sstevel@tonic-gate */
937c478bd9Sstevel@tonic-gate static boolean_t
try_again(CK_RV rv)947c478bd9Sstevel@tonic-gate try_again(CK_RV rv)
957c478bd9Sstevel@tonic-gate {
967c478bd9Sstevel@tonic-gate int i;
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate for (i = 0; i < num_stop_rv; i++) {
997c478bd9Sstevel@tonic-gate if (rv == stop_rv[i]) {
1007c478bd9Sstevel@tonic-gate return (B_FALSE);
1017c478bd9Sstevel@tonic-gate }
1027c478bd9Sstevel@tonic-gate }
1037c478bd9Sstevel@tonic-gate return (B_TRUE);
1047c478bd9Sstevel@tonic-gate }
1057c478bd9Sstevel@tonic-gate
1067c478bd9Sstevel@tonic-gate
1077c478bd9Sstevel@tonic-gate /*
1087c478bd9Sstevel@tonic-gate * meta_CreateObject
1097c478bd9Sstevel@tonic-gate *
1107c478bd9Sstevel@tonic-gate */
1117c478bd9Sstevel@tonic-gate CK_RV
meta_CreateObject(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phObject)1127c478bd9Sstevel@tonic-gate meta_CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
1137c478bd9Sstevel@tonic-gate CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject)
1147c478bd9Sstevel@tonic-gate {
1157c478bd9Sstevel@tonic-gate CK_RV rv;
1167c478bd9Sstevel@tonic-gate meta_session_t *session;
1177c478bd9Sstevel@tonic-gate slot_session_t *slot_session = NULL;
1187c478bd9Sstevel@tonic-gate meta_object_t *object = NULL;
1197c478bd9Sstevel@tonic-gate slot_object_t *slot_object = NULL;
120034448feSmcpowers CK_OBJECT_HANDLE hNewObject;
121034448feSmcpowers CK_ULONG slot_num, keystore_slotnum;
122034448feSmcpowers CK_RV first_rv;
1237c478bd9Sstevel@tonic-gate
1247c478bd9Sstevel@tonic-gate if (pTemplate == NULL || ulCount < 1 || phObject == NULL)
1257c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
1267c478bd9Sstevel@tonic-gate
1277c478bd9Sstevel@tonic-gate rv = meta_handle2session(hSession, &session);
1287c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
1297c478bd9Sstevel@tonic-gate return (rv);
1307c478bd9Sstevel@tonic-gate
1317c478bd9Sstevel@tonic-gate rv = meta_object_alloc(session, &object);
1327c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
1337c478bd9Sstevel@tonic-gate goto cleanup;
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate /*
1367c478bd9Sstevel@tonic-gate * Create a clone of the object
1377c478bd9Sstevel@tonic-gate */
1387c478bd9Sstevel@tonic-gate rv = meta_slot_object_alloc(&slot_object);
1397c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
1407c478bd9Sstevel@tonic-gate goto cleanup;
1417c478bd9Sstevel@tonic-gate
142034448feSmcpowers /*
143034448feSmcpowers * Set to true (token object) if template has CKA_TOKEN=true;
144034448feSmcpowers * otherwise, it is false (session object).
145034448feSmcpowers */
1467c478bd9Sstevel@tonic-gate (void) get_template_boolean(CKA_TOKEN, pTemplate, ulCount,
1477c478bd9Sstevel@tonic-gate &(object->isToken));
1487c478bd9Sstevel@tonic-gate
1495b0c7657Sizick /* Can't create token objects in a read-only session. */
1505b0c7657Sizick if ((IS_READ_ONLY_SESSION(session->session_flags)) && object->isToken) {
1515b0c7657Sizick rv = CKR_SESSION_READ_ONLY;
1525b0c7657Sizick goto cleanup;
1535b0c7657Sizick }
1545b0c7657Sizick
155034448feSmcpowers /*
156034448feSmcpowers * Set to true (private object) if template has CKA_PRIVATE=true;
157034448feSmcpowers * otherwise, it is false (public object).
158034448feSmcpowers */
159034448feSmcpowers (void) get_template_boolean(CKA_PRIVATE, pTemplate, ulCount,
160034448feSmcpowers &(object->isPrivate));
161034448feSmcpowers
162034448feSmcpowers /* Assume object is extractable unless template has otherwise */
163034448feSmcpowers object->isExtractable = B_TRUE;
164034448feSmcpowers (void) get_template_boolean(CKA_EXTRACTABLE, pTemplate, ulCount,
165034448feSmcpowers &(object->isExtractable));
166034448feSmcpowers
167034448feSmcpowers /*
168034448feSmcpowers * Set to true (sensitive object) if template has CKA_SENSITIVE=true;
169034448feSmcpowers * otherwise, it is false.
170034448feSmcpowers */
171034448feSmcpowers (void) get_template_boolean(CKA_SENSITIVE, pTemplate, ulCount,
172034448feSmcpowers &(object->isSensitive));
173034448feSmcpowers
174034448feSmcpowers /*
175034448feSmcpowers * Check if this can be a FreeObject.
176034448feSmcpowers *
177034448feSmcpowers * For creating objects, this check is mostly for preventing
178034448feSmcpowers * non-keystore hardware from creating CKA_PRIVATE objects without
179034448feSmcpowers * logging in.
180034448feSmcpowers */
181034448feSmcpowers
182034448feSmcpowers if (meta_freeobject_check(session, object, NULL, pTemplate, ulCount,
183034448feSmcpowers NULL)) {
184034448feSmcpowers /*
185034448feSmcpowers * Make sure we are logged into the keystore if this is a
186034448feSmcpowers * private freetoken object.
187034448feSmcpowers */
188034448feSmcpowers if (object->isPrivate && !metaslot_logged_in())
189034448feSmcpowers return (CKR_USER_NOT_LOGGED_IN);
190034448feSmcpowers
191034448feSmcpowers if (!meta_freeobject_set(object, pTemplate, ulCount, B_TRUE))
192034448feSmcpowers goto cleanup;
193034448feSmcpowers }
194034448feSmcpowers
1957c478bd9Sstevel@tonic-gate
1967c478bd9Sstevel@tonic-gate keystore_slotnum = get_keystore_slotnum();
1977c478bd9Sstevel@tonic-gate
198034448feSmcpowers if (object->isToken || object->isFreeToken == FREE_ENABLED) {
199034448feSmcpowers
200034448feSmcpowers /*
201034448feSmcpowers * If this is a token object or a FreeToken then create it
202034448feSmcpowers * on the keystore slot.
203034448feSmcpowers */
204034448feSmcpowers
205034448feSmcpowers slot_num = keystore_slotnum;
206034448feSmcpowers rv = meta_get_slot_session(slot_num, &slot_session,
2077c478bd9Sstevel@tonic-gate session->session_flags);
2087c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
2097c478bd9Sstevel@tonic-gate goto cleanup;
2107c478bd9Sstevel@tonic-gate
211034448feSmcpowers object->tried_create_clone[slot_num] = B_TRUE;
2127c478bd9Sstevel@tonic-gate rv = FUNCLIST(slot_session->fw_st_id)->C_CreateObject(
2135b0c7657Sizick slot_session->hSession, pTemplate, ulCount, &hNewObject);
214034448feSmcpowers
215034448feSmcpowers if (rv != CKR_OK)
2167c478bd9Sstevel@tonic-gate goto cleanup;
2177c478bd9Sstevel@tonic-gate
2187c478bd9Sstevel@tonic-gate } else {
2197c478bd9Sstevel@tonic-gate
2207c478bd9Sstevel@tonic-gate /*
2217c478bd9Sstevel@tonic-gate * Create a clone of the object in the first available slot.
2227c478bd9Sstevel@tonic-gate *
2237c478bd9Sstevel@tonic-gate * If creating a clone in a specific slot failed, it will
2247c478bd9Sstevel@tonic-gate * either stop and return the error to the user, or try
2257c478bd9Sstevel@tonic-gate * again in the next available slot until it succeeds. The
2267c478bd9Sstevel@tonic-gate * decision to stop or continue is made based on the return
2277c478bd9Sstevel@tonic-gate * code.
2287c478bd9Sstevel@tonic-gate */
229034448feSmcpowers CK_ULONG num_slots = meta_slotManager_get_slotcount();
2307c478bd9Sstevel@tonic-gate
2317c478bd9Sstevel@tonic-gate for (slot_num = 0; slot_num < num_slots; slot_num++) {
232034448feSmcpowers /*
233034448feSmcpowers * If this is a free token and we are on the keystore
234034448feSmcpowers * slot, bypass this because it was already created
235034448feSmcpowers */
236034448feSmcpowers
2377c478bd9Sstevel@tonic-gate rv = meta_get_slot_session(slot_num, &slot_session,
2387c478bd9Sstevel@tonic-gate session->session_flags);
239034448feSmcpowers if (rv != CKR_OK)
2407c478bd9Sstevel@tonic-gate goto cleanup;
2417c478bd9Sstevel@tonic-gate
2427c478bd9Sstevel@tonic-gate object->tried_create_clone[slot_num] = B_TRUE;
2437c478bd9Sstevel@tonic-gate rv = FUNCLIST(slot_session->fw_st_id)->C_CreateObject(
2447c478bd9Sstevel@tonic-gate slot_session->hSession, pTemplate, ulCount,
2457c478bd9Sstevel@tonic-gate &hNewObject);
246034448feSmcpowers if (rv == CKR_OK)
2477c478bd9Sstevel@tonic-gate break;
2487c478bd9Sstevel@tonic-gate
249034448feSmcpowers if (!try_again(rv))
2507c478bd9Sstevel@tonic-gate goto cleanup;
2517c478bd9Sstevel@tonic-gate
2527c478bd9Sstevel@tonic-gate /* save first rv for other errors */
253034448feSmcpowers if (slot_num == 0)
2547c478bd9Sstevel@tonic-gate first_rv = rv;
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate meta_release_slot_session(slot_session);
2577c478bd9Sstevel@tonic-gate slot_session = NULL;
2587c478bd9Sstevel@tonic-gate
2597c478bd9Sstevel@tonic-gate }
260034448feSmcpowers }
2617c478bd9Sstevel@tonic-gate
2627c478bd9Sstevel@tonic-gate if (rv == CKR_OK) {
2637c478bd9Sstevel@tonic-gate slot_object->hObject = hNewObject;
2647c478bd9Sstevel@tonic-gate object->clones[slot_num] = slot_object;
2657c478bd9Sstevel@tonic-gate object->master_clone_slotnum = slot_num;
266034448feSmcpowers
267*8cae6764SAnthony Scarpino /* Allow FreeToken to activate onto token obj list */
268*8cae6764SAnthony Scarpino if (object->isFreeToken == FREE_ENABLED)
269*8cae6764SAnthony Scarpino object->isToken = B_TRUE;
270*8cae6764SAnthony Scarpino
271*8cae6764SAnthony Scarpino meta_slot_object_activate(slot_object, slot_session,
272*8cae6764SAnthony Scarpino object->isToken);
273034448feSmcpowers
2747c478bd9Sstevel@tonic-gate slot_object = NULL;
2757c478bd9Sstevel@tonic-gate meta_release_slot_session(slot_session);
2767c478bd9Sstevel@tonic-gate slot_session = NULL;
277034448feSmcpowers
2787c478bd9Sstevel@tonic-gate } else {
2797c478bd9Sstevel@tonic-gate /*
2807c478bd9Sstevel@tonic-gate * return either first error code or
2817c478bd9Sstevel@tonic-gate * CKR_FUNCTION_FAILED depending on the failure
2827c478bd9Sstevel@tonic-gate */
2837c478bd9Sstevel@tonic-gate int i;
2847c478bd9Sstevel@tonic-gate for (i = 0; i < num_other_rv; i++) {
2857c478bd9Sstevel@tonic-gate if (rv == other_rv[i]) {
2867c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
2877c478bd9Sstevel@tonic-gate goto cleanup;
2887c478bd9Sstevel@tonic-gate }
2897c478bd9Sstevel@tonic-gate }
2907c478bd9Sstevel@tonic-gate /* need to return first rv */
2917c478bd9Sstevel@tonic-gate rv = first_rv;
2927c478bd9Sstevel@tonic-gate goto cleanup;
2937c478bd9Sstevel@tonic-gate }
2947c478bd9Sstevel@tonic-gate
2957c478bd9Sstevel@tonic-gate
2967c478bd9Sstevel@tonic-gate /*
2977c478bd9Sstevel@tonic-gate * always keep a copy of the template for C_CreateObject,
2987c478bd9Sstevel@tonic-gate * so clones can be created on other slots if necessary.
2997c478bd9Sstevel@tonic-gate * This is done even when the CKA_EXTRACTABLE=FALSE flag
3007c478bd9Sstevel@tonic-gate * is set for the object. The supplied template is
3017c478bd9Sstevel@tonic-gate * "owned" by metaslot. The application should not be
3027c478bd9Sstevel@tonic-gate * penalized just because metaslot choose to try creating
3037c478bd9Sstevel@tonic-gate * the object in a slot that's not capable of performing
3047c478bd9Sstevel@tonic-gate * any future operation.
3057c478bd9Sstevel@tonic-gate */
3067c478bd9Sstevel@tonic-gate rv = get_master_attributes_by_template(pTemplate, ulCount,
3077c478bd9Sstevel@tonic-gate &object->attributes, &object->num_attributes);
3087c478bd9Sstevel@tonic-gate if (rv == CKR_OK) {
3097c478bd9Sstevel@tonic-gate CK_ULONG i;
3107c478bd9Sstevel@tonic-gate for (i = 0; i < ulCount; i++) {
3117c478bd9Sstevel@tonic-gate rv = attribute_set_value(&(pTemplate[i]),
3127c478bd9Sstevel@tonic-gate object->attributes, object->num_attributes);
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate }
3157c478bd9Sstevel@tonic-gate
3167c478bd9Sstevel@tonic-gate meta_object_activate(object);
3177c478bd9Sstevel@tonic-gate *phObject = (CK_OBJECT_HANDLE) object;
3187c478bd9Sstevel@tonic-gate
3197c478bd9Sstevel@tonic-gate REFRELEASE(session);
3207c478bd9Sstevel@tonic-gate
3217c478bd9Sstevel@tonic-gate return (CKR_OK);
3227c478bd9Sstevel@tonic-gate
3237c478bd9Sstevel@tonic-gate cleanup:
3247c478bd9Sstevel@tonic-gate if (slot_object)
3257c478bd9Sstevel@tonic-gate meta_slot_object_dealloc(slot_object);
3267c478bd9Sstevel@tonic-gate if (slot_session)
3277c478bd9Sstevel@tonic-gate meta_release_slot_session(slot_session);
3287c478bd9Sstevel@tonic-gate if (object)
329*8cae6764SAnthony Scarpino (void) meta_object_dealloc(session, object, B_TRUE);
3307c478bd9Sstevel@tonic-gate
3317c478bd9Sstevel@tonic-gate REFRELEASE(session);
3327c478bd9Sstevel@tonic-gate
3337c478bd9Sstevel@tonic-gate return (rv);
3347c478bd9Sstevel@tonic-gate }
3357c478bd9Sstevel@tonic-gate
3367c478bd9Sstevel@tonic-gate
3377c478bd9Sstevel@tonic-gate /*
3387c478bd9Sstevel@tonic-gate * meta_CopyObject
3397c478bd9Sstevel@tonic-gate *
3407c478bd9Sstevel@tonic-gate */
3417c478bd9Sstevel@tonic-gate CK_RV
meta_CopyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phNewObject)3427c478bd9Sstevel@tonic-gate meta_CopyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
3437c478bd9Sstevel@tonic-gate CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
3447c478bd9Sstevel@tonic-gate CK_OBJECT_HANDLE_PTR phNewObject)
3457c478bd9Sstevel@tonic-gate {
3467c478bd9Sstevel@tonic-gate CK_RV rv, first_rv;
3477c478bd9Sstevel@tonic-gate meta_session_t *session;
3487c478bd9Sstevel@tonic-gate meta_object_t *src_object, *dst_object = NULL;
3497c478bd9Sstevel@tonic-gate slot_session_t *slot_session = NULL;
3507c478bd9Sstevel@tonic-gate slot_object_t *dst_slot_object = NULL;
3517c478bd9Sstevel@tonic-gate CK_ULONG i;
3527c478bd9Sstevel@tonic-gate slot_object_t *src_slot_object;
3537c478bd9Sstevel@tonic-gate CK_ULONG slotnum, num_slots;
3547c478bd9Sstevel@tonic-gate boolean_t found;
3557c478bd9Sstevel@tonic-gate
3567c478bd9Sstevel@tonic-gate if (pTemplate == NULL && ulCount != 0)
3577c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
3587c478bd9Sstevel@tonic-gate if (phNewObject == NULL)
3597c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
3607c478bd9Sstevel@tonic-gate
3617c478bd9Sstevel@tonic-gate rv = meta_handle2session(hSession, &session);
3627c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
3637c478bd9Sstevel@tonic-gate return (rv);
3647c478bd9Sstevel@tonic-gate
3657c478bd9Sstevel@tonic-gate rv = meta_handle2object(hObject, &src_object);
3667c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
3677c478bd9Sstevel@tonic-gate REFRELEASE(session);
3687c478bd9Sstevel@tonic-gate return (rv);
3697c478bd9Sstevel@tonic-gate }
3707c478bd9Sstevel@tonic-gate
3717c478bd9Sstevel@tonic-gate rv = meta_object_alloc(session, &dst_object);
3727c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
3737c478bd9Sstevel@tonic-gate goto finish;
3747c478bd9Sstevel@tonic-gate
3757c478bd9Sstevel@tonic-gate found = get_template_boolean(CKA_TOKEN,
3767c478bd9Sstevel@tonic-gate pTemplate, ulCount, &(dst_object->isToken));
3777c478bd9Sstevel@tonic-gate if (!found) {
3787c478bd9Sstevel@tonic-gate dst_object->isToken = src_object->isToken;
3795b0c7657Sizick if (src_object->isFreeToken == FREE_ENABLED)
3805b0c7657Sizick dst_object->isToken = TRUE;
3815b0c7657Sizick else
3825b0c7657Sizick dst_object->isToken = src_object->isToken;
3837c478bd9Sstevel@tonic-gate }
3847c478bd9Sstevel@tonic-gate
3857c478bd9Sstevel@tonic-gate /* Can't create token objects in a read-only session. */
3867c478bd9Sstevel@tonic-gate if ((IS_READ_ONLY_SESSION(session->session_flags)) &&
3877c478bd9Sstevel@tonic-gate (dst_object->isToken)) {
3887c478bd9Sstevel@tonic-gate rv = CKR_SESSION_READ_ONLY;
3897c478bd9Sstevel@tonic-gate goto finish;
3907c478bd9Sstevel@tonic-gate }
3917c478bd9Sstevel@tonic-gate
3927c478bd9Sstevel@tonic-gate if (dst_object->isToken) {
3937c478bd9Sstevel@tonic-gate
3947c478bd9Sstevel@tonic-gate /*
3957c478bd9Sstevel@tonic-gate * if the dst object is a token object, and the source
3967c478bd9Sstevel@tonic-gate * object is not, the source object needs to be extractable.
3977c478bd9Sstevel@tonic-gate * Otherwise, the source object needs to reside in the
3987c478bd9Sstevel@tonic-gate * token object slot
3997c478bd9Sstevel@tonic-gate */
4007c478bd9Sstevel@tonic-gate if ((!src_object->isExtractable) &&
4017c478bd9Sstevel@tonic-gate (src_object->master_clone_slotnum
4027c478bd9Sstevel@tonic-gate != get_keystore_slotnum())) {
4037c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
4047c478bd9Sstevel@tonic-gate goto finish;
4057c478bd9Sstevel@tonic-gate }
4067c478bd9Sstevel@tonic-gate
4077c478bd9Sstevel@tonic-gate /* determine if dst is going to be private object or not */
4087c478bd9Sstevel@tonic-gate found = get_template_boolean(CKA_PRIVATE,
4097c478bd9Sstevel@tonic-gate pTemplate, ulCount, &(dst_object->isPrivate));
4107c478bd9Sstevel@tonic-gate if (!found) {
4117c478bd9Sstevel@tonic-gate /* will be the same as the source object */
4127c478bd9Sstevel@tonic-gate dst_object->isPrivate = src_object->isPrivate;
4137c478bd9Sstevel@tonic-gate }
4147c478bd9Sstevel@tonic-gate
4157c478bd9Sstevel@tonic-gate slotnum = get_keystore_slotnum();
4167c478bd9Sstevel@tonic-gate } else {
4177c478bd9Sstevel@tonic-gate
4187c478bd9Sstevel@tonic-gate /* try create the obj in the same slot as the source obj */
4197c478bd9Sstevel@tonic-gate slotnum = src_object->master_clone_slotnum;
4207c478bd9Sstevel@tonic-gate }
4217c478bd9Sstevel@tonic-gate
4227c478bd9Sstevel@tonic-gate rv = meta_slot_object_alloc(&dst_slot_object);
4237c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
4247c478bd9Sstevel@tonic-gate goto finish;
4257c478bd9Sstevel@tonic-gate
4267c478bd9Sstevel@tonic-gate rv = meta_get_slot_session(slotnum, &slot_session,
4277c478bd9Sstevel@tonic-gate session->session_flags);
4287c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
4297c478bd9Sstevel@tonic-gate goto finish;
4307c478bd9Sstevel@tonic-gate
4317c478bd9Sstevel@tonic-gate rv = meta_object_get_clone(src_object, slotnum,
4327c478bd9Sstevel@tonic-gate slot_session, &src_slot_object);
4337c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
4347c478bd9Sstevel@tonic-gate goto finish;
4357c478bd9Sstevel@tonic-gate
4367c478bd9Sstevel@tonic-gate dst_object->tried_create_clone[slotnum] = B_TRUE;
4377c478bd9Sstevel@tonic-gate rv = FUNCLIST(slot_session->fw_st_id)->C_CopyObject(
4387c478bd9Sstevel@tonic-gate slot_session->hSession, src_slot_object->hObject, pTemplate,
4397c478bd9Sstevel@tonic-gate ulCount, &(dst_slot_object->hObject));
4407c478bd9Sstevel@tonic-gate
4417c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
4427c478bd9Sstevel@tonic-gate if (dst_object->isToken) {
4437c478bd9Sstevel@tonic-gate /*
4447c478bd9Sstevel@tonic-gate * token obj can only be created in the
4457c478bd9Sstevel@tonic-gate * token slot. No need to try anywhere else
4467c478bd9Sstevel@tonic-gate */
4477c478bd9Sstevel@tonic-gate goto finish;
4487c478bd9Sstevel@tonic-gate }
4497c478bd9Sstevel@tonic-gate if ((!src_object->isExtractable) ||
4507c478bd9Sstevel@tonic-gate ((src_object->isSensitive) && (src_object->isToken) &&
4517c478bd9Sstevel@tonic-gate (!metaslot_auto_key_migrate))) {
4527c478bd9Sstevel@tonic-gate /* source object isn't clonable in another slot */
4537c478bd9Sstevel@tonic-gate goto finish;
4547c478bd9Sstevel@tonic-gate }
4557c478bd9Sstevel@tonic-gate
4567c478bd9Sstevel@tonic-gate if (!try_again(rv)) {
4577c478bd9Sstevel@tonic-gate goto finish;
4587c478bd9Sstevel@tonic-gate }
4597c478bd9Sstevel@tonic-gate
4607c478bd9Sstevel@tonic-gate first_rv = rv;
4617c478bd9Sstevel@tonic-gate
4627c478bd9Sstevel@tonic-gate meta_release_slot_session(slot_session);
4637c478bd9Sstevel@tonic-gate slot_session = NULL;
4647c478bd9Sstevel@tonic-gate
4657c478bd9Sstevel@tonic-gate num_slots = meta_slotManager_get_slotcount();
4667c478bd9Sstevel@tonic-gate
4677c478bd9Sstevel@tonic-gate /* Try operation on other slots if the object is clonable */
4687c478bd9Sstevel@tonic-gate for (slotnum = 0; slotnum < num_slots; slotnum++) {
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate if (slotnum == src_object->master_clone_slotnum) {
4717c478bd9Sstevel@tonic-gate /* already tried, don't need to try again */
4727c478bd9Sstevel@tonic-gate continue;
4737c478bd9Sstevel@tonic-gate }
4747c478bd9Sstevel@tonic-gate
4757c478bd9Sstevel@tonic-gate rv = meta_get_slot_session(slotnum, &slot_session,
4767c478bd9Sstevel@tonic-gate session->session_flags);
4777c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
4787c478bd9Sstevel@tonic-gate goto finish;
4797c478bd9Sstevel@tonic-gate }
4807c478bd9Sstevel@tonic-gate
4817c478bd9Sstevel@tonic-gate rv = meta_object_get_clone(src_object, slotnum,
4827c478bd9Sstevel@tonic-gate slot_session, &src_slot_object);
4837c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
4847c478bd9Sstevel@tonic-gate goto finish;
4857c478bd9Sstevel@tonic-gate
4867c478bd9Sstevel@tonic-gate dst_object->tried_create_clone[slotnum] = B_TRUE;
4877c478bd9Sstevel@tonic-gate
4887c478bd9Sstevel@tonic-gate rv = FUNCLIST(slot_session->fw_st_id)->C_CopyObject(
4897c478bd9Sstevel@tonic-gate slot_session->hSession, src_slot_object->hObject,
4907c478bd9Sstevel@tonic-gate pTemplate, ulCount, &dst_slot_object->hObject);
4917c478bd9Sstevel@tonic-gate
4927c478bd9Sstevel@tonic-gate if (rv == CKR_OK) {
4937c478bd9Sstevel@tonic-gate break;
4947c478bd9Sstevel@tonic-gate }
4957c478bd9Sstevel@tonic-gate
4967c478bd9Sstevel@tonic-gate if (!try_again(rv)) {
4977c478bd9Sstevel@tonic-gate goto finish;
4987c478bd9Sstevel@tonic-gate }
4997c478bd9Sstevel@tonic-gate meta_release_slot_session(slot_session);
5007c478bd9Sstevel@tonic-gate slot_session = NULL;
5017c478bd9Sstevel@tonic-gate }
5027c478bd9Sstevel@tonic-gate }
5037c478bd9Sstevel@tonic-gate
5047c478bd9Sstevel@tonic-gate if (rv == CKR_OK) {
5057c478bd9Sstevel@tonic-gate
5067c478bd9Sstevel@tonic-gate rv = meta_object_get_attr(slot_session,
5077c478bd9Sstevel@tonic-gate dst_slot_object->hObject, dst_object);
5087c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
5097c478bd9Sstevel@tonic-gate goto finish;
5107c478bd9Sstevel@tonic-gate }
5117c478bd9Sstevel@tonic-gate
5127c478bd9Sstevel@tonic-gate if (src_object->attributes != NULL) {
5137c478bd9Sstevel@tonic-gate
5147c478bd9Sstevel@tonic-gate /* Keep a copy of the template for the future */
5157c478bd9Sstevel@tonic-gate
5167c478bd9Sstevel@tonic-gate /*
5177c478bd9Sstevel@tonic-gate * Don't allow attributes to change while
5187c478bd9Sstevel@tonic-gate * we look at them.
5197c478bd9Sstevel@tonic-gate */
5207c478bd9Sstevel@tonic-gate (void) pthread_rwlock_rdlock(
5217c478bd9Sstevel@tonic-gate &src_object->attribute_lock);
5227c478bd9Sstevel@tonic-gate
5237c478bd9Sstevel@tonic-gate rv = get_master_attributes_by_duplication(
5247c478bd9Sstevel@tonic-gate src_object->attributes,
5257c478bd9Sstevel@tonic-gate src_object->num_attributes,
5267c478bd9Sstevel@tonic-gate &dst_object->attributes,
5277c478bd9Sstevel@tonic-gate &dst_object->num_attributes);
5287c478bd9Sstevel@tonic-gate
5297c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(
5307c478bd9Sstevel@tonic-gate &src_object->attribute_lock);
5317c478bd9Sstevel@tonic-gate
5327c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
5337c478bd9Sstevel@tonic-gate goto finish;
5347c478bd9Sstevel@tonic-gate
5357c478bd9Sstevel@tonic-gate for (i = 0; i < ulCount; i++) {
5367c478bd9Sstevel@tonic-gate rv = attribute_set_value(pTemplate + i,
5377c478bd9Sstevel@tonic-gate dst_object->attributes,
5387c478bd9Sstevel@tonic-gate dst_object->num_attributes);
5397c478bd9Sstevel@tonic-gate
5407c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
5417c478bd9Sstevel@tonic-gate goto finish;
5427c478bd9Sstevel@tonic-gate }
5437c478bd9Sstevel@tonic-gate }
5447c478bd9Sstevel@tonic-gate
545*8cae6764SAnthony Scarpino /* Allow FreeToken to activate onto token obj list */
546*8cae6764SAnthony Scarpino if (dst_object->isFreeToken == FREE_ENABLED)
547*8cae6764SAnthony Scarpino dst_object->isToken = TRUE;
548*8cae6764SAnthony Scarpino
5497c478bd9Sstevel@tonic-gate meta_slot_object_activate(dst_slot_object,
5507c478bd9Sstevel@tonic-gate slot_session, dst_object->isToken);
5517c478bd9Sstevel@tonic-gate
5527c478bd9Sstevel@tonic-gate dst_object->clones[slotnum] = dst_slot_object;
5537c478bd9Sstevel@tonic-gate dst_object->master_clone_slotnum = slotnum;
5547c478bd9Sstevel@tonic-gate dst_slot_object = NULL; /* for error cleanup */
5557c478bd9Sstevel@tonic-gate
5567c478bd9Sstevel@tonic-gate meta_release_slot_session(slot_session);
5577c478bd9Sstevel@tonic-gate slot_session = NULL; /* for error cleanup */
5587c478bd9Sstevel@tonic-gate
5597c478bd9Sstevel@tonic-gate } else {
5607c478bd9Sstevel@tonic-gate /*
5617c478bd9Sstevel@tonic-gate * return either first error code or
5627c478bd9Sstevel@tonic-gate * CKR_FUNCTION_FAILED depending on the failure
5637c478bd9Sstevel@tonic-gate */
5647c478bd9Sstevel@tonic-gate int j;
5657c478bd9Sstevel@tonic-gate for (j = 0; j < num_other_rv; j++) {
5667c478bd9Sstevel@tonic-gate if (rv == other_rv[j]) {
5677c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
5687c478bd9Sstevel@tonic-gate goto finish;
5697c478bd9Sstevel@tonic-gate }
5707c478bd9Sstevel@tonic-gate }
5717c478bd9Sstevel@tonic-gate /* need to return first rv */
5727c478bd9Sstevel@tonic-gate rv = first_rv;
5737c478bd9Sstevel@tonic-gate goto finish;
5747c478bd9Sstevel@tonic-gate }
5757c478bd9Sstevel@tonic-gate meta_object_activate(dst_object);
5767c478bd9Sstevel@tonic-gate *phNewObject = (CK_OBJECT_HANDLE) dst_object;
5777c478bd9Sstevel@tonic-gate
5787c478bd9Sstevel@tonic-gate finish:
5797c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
5807c478bd9Sstevel@tonic-gate if (dst_slot_object)
5817c478bd9Sstevel@tonic-gate meta_slot_object_dealloc(dst_slot_object);
5827c478bd9Sstevel@tonic-gate
5837c478bd9Sstevel@tonic-gate if (dst_object)
584*8cae6764SAnthony Scarpino (void) meta_object_dealloc(session, dst_object,
585*8cae6764SAnthony Scarpino B_TRUE);
5867c478bd9Sstevel@tonic-gate
5877c478bd9Sstevel@tonic-gate if (slot_session)
5887c478bd9Sstevel@tonic-gate meta_release_slot_session(slot_session);
5897c478bd9Sstevel@tonic-gate }
5907c478bd9Sstevel@tonic-gate
5917c478bd9Sstevel@tonic-gate OBJRELEASE(src_object);
5927c478bd9Sstevel@tonic-gate REFRELEASE(session);
5937c478bd9Sstevel@tonic-gate
5947c478bd9Sstevel@tonic-gate return (rv);
5957c478bd9Sstevel@tonic-gate }
5967c478bd9Sstevel@tonic-gate
5977c478bd9Sstevel@tonic-gate
5987c478bd9Sstevel@tonic-gate /*
5997c478bd9Sstevel@tonic-gate * meta_DestroyObject
6007c478bd9Sstevel@tonic-gate *
6017c478bd9Sstevel@tonic-gate * This function destroys an object by first removing it from the
6027c478bd9Sstevel@tonic-gate * list of valid objects for a given session (if session object) or
6037c478bd9Sstevel@tonic-gate * the global token object list. And then, calling C_DestroyObject
6047c478bd9Sstevel@tonic-gate * on all the slots on which we have created a clone of this object.
6057c478bd9Sstevel@tonic-gate */
6067c478bd9Sstevel@tonic-gate CK_RV
meta_DestroyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject)6077c478bd9Sstevel@tonic-gate meta_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
6087c478bd9Sstevel@tonic-gate {
6097c478bd9Sstevel@tonic-gate CK_RV rv;
6107c478bd9Sstevel@tonic-gate meta_session_t *session;
6117c478bd9Sstevel@tonic-gate meta_object_t *object;
6127c478bd9Sstevel@tonic-gate
6137c478bd9Sstevel@tonic-gate rv = meta_handle2session(hSession, &session);
6147c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
6157c478bd9Sstevel@tonic-gate return (rv);
6167c478bd9Sstevel@tonic-gate
6177c478bd9Sstevel@tonic-gate rv = meta_handle2object(hObject, &object);
6187c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
6197c478bd9Sstevel@tonic-gate REFRELEASE(session);
6207c478bd9Sstevel@tonic-gate return (rv);
6217c478bd9Sstevel@tonic-gate }
6227c478bd9Sstevel@tonic-gate
6237c478bd9Sstevel@tonic-gate /* Can't delete token objects from a read-only session. */
6245b0c7657Sizick if ((IS_READ_ONLY_SESSION(session->session_flags)) &&
6255b0c7657Sizick (object->isToken || object->isFreeToken == FREE_ENABLED)) {
6267c478bd9Sstevel@tonic-gate OBJRELEASE(object);
6277c478bd9Sstevel@tonic-gate REFRELEASE(session);
6287c478bd9Sstevel@tonic-gate return (CKR_SESSION_READ_ONLY);
6297c478bd9Sstevel@tonic-gate }
6307c478bd9Sstevel@tonic-gate
6317c478bd9Sstevel@tonic-gate /* Remove object from list of valid meta_objects */
6327c478bd9Sstevel@tonic-gate rv = meta_object_deactivate(object, B_FALSE, B_TRUE);
6337c478bd9Sstevel@tonic-gate
6347c478bd9Sstevel@tonic-gate /*
6357c478bd9Sstevel@tonic-gate * Actually call C_DestroyObject on all the slots on which we have
6367c478bd9Sstevel@tonic-gate * created a clone of this object.
6377c478bd9Sstevel@tonic-gate */
6387c478bd9Sstevel@tonic-gate if (rv == CKR_OK)
639*8cae6764SAnthony Scarpino rv = meta_object_dealloc(session, object, B_TRUE);
6407c478bd9Sstevel@tonic-gate
6417c478bd9Sstevel@tonic-gate REFRELEASE(session);
6427c478bd9Sstevel@tonic-gate
6437c478bd9Sstevel@tonic-gate return (rv);
6447c478bd9Sstevel@tonic-gate }
6457c478bd9Sstevel@tonic-gate
6467c478bd9Sstevel@tonic-gate
6477c478bd9Sstevel@tonic-gate /*
6487c478bd9Sstevel@tonic-gate * meta_GetObjectSize
6497c478bd9Sstevel@tonic-gate *
6507c478bd9Sstevel@tonic-gate * NOTES:
6517c478bd9Sstevel@tonic-gate * 1) Because the "size" is so poorly defined in the spec, we have deemed
6527c478bd9Sstevel@tonic-gate * it useless and won't support it. This is especially true for the
6537c478bd9Sstevel@tonic-gate * metaslot, because the mulitple providers it uses may each interpret
6547c478bd9Sstevel@tonic-gate * the size differently.
6557c478bd9Sstevel@tonic-gate */
6567c478bd9Sstevel@tonic-gate /* ARGSUSED */
6577c478bd9Sstevel@tonic-gate CK_RV
meta_GetObjectSize(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ULONG_PTR pulSize)6587c478bd9Sstevel@tonic-gate meta_GetObjectSize(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
6597c478bd9Sstevel@tonic-gate CK_ULONG_PTR pulSize)
6607c478bd9Sstevel@tonic-gate {
6617c478bd9Sstevel@tonic-gate return (CKR_FUNCTION_NOT_SUPPORTED);
6627c478bd9Sstevel@tonic-gate }
6637c478bd9Sstevel@tonic-gate
6647c478bd9Sstevel@tonic-gate
6657c478bd9Sstevel@tonic-gate /*
6667c478bd9Sstevel@tonic-gate * meta_GetAttributeValue
6677c478bd9Sstevel@tonic-gate *
6687c478bd9Sstevel@tonic-gate */
6697c478bd9Sstevel@tonic-gate CK_RV
meta_GetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)6707c478bd9Sstevel@tonic-gate meta_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
6717c478bd9Sstevel@tonic-gate CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
6727c478bd9Sstevel@tonic-gate {
6737c478bd9Sstevel@tonic-gate CK_RV rv;
6747c478bd9Sstevel@tonic-gate meta_session_t *session;
6757c478bd9Sstevel@tonic-gate meta_object_t *object;
6767c478bd9Sstevel@tonic-gate CK_ULONG slotnum;
6777c478bd9Sstevel@tonic-gate slot_session_t *slot_session;
6787c478bd9Sstevel@tonic-gate
6797c478bd9Sstevel@tonic-gate if (pTemplate == NULL || ulCount < 1)
6807c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
6817c478bd9Sstevel@tonic-gate
6827c478bd9Sstevel@tonic-gate rv = meta_handle2session(hSession, &session);
6837c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
6847c478bd9Sstevel@tonic-gate return (rv);
6857c478bd9Sstevel@tonic-gate
6867c478bd9Sstevel@tonic-gate rv = meta_handle2object(hObject, &object);
6877c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
6887c478bd9Sstevel@tonic-gate REFRELEASE(session);
6897c478bd9Sstevel@tonic-gate return (rv);
6907c478bd9Sstevel@tonic-gate }
6917c478bd9Sstevel@tonic-gate
6927c478bd9Sstevel@tonic-gate slotnum = object->master_clone_slotnum;
6937c478bd9Sstevel@tonic-gate
6947c478bd9Sstevel@tonic-gate rv = meta_get_slot_session(slotnum, &slot_session,
6957c478bd9Sstevel@tonic-gate session->session_flags);
6967c478bd9Sstevel@tonic-gate if (rv == CKR_OK) {
6977c478bd9Sstevel@tonic-gate rv = FUNCLIST(slot_session->fw_st_id)->C_GetAttributeValue(
6987c478bd9Sstevel@tonic-gate slot_session->hSession, object->clones[slotnum]->hObject,
6997c478bd9Sstevel@tonic-gate pTemplate, ulCount);
7007c478bd9Sstevel@tonic-gate
7017c478bd9Sstevel@tonic-gate meta_release_slot_session(slot_session);
7027c478bd9Sstevel@tonic-gate }
7037c478bd9Sstevel@tonic-gate
7047c478bd9Sstevel@tonic-gate OBJRELEASE(object);
7057c478bd9Sstevel@tonic-gate REFRELEASE(session);
7067c478bd9Sstevel@tonic-gate
7077c478bd9Sstevel@tonic-gate return (rv);
7087c478bd9Sstevel@tonic-gate
7097c478bd9Sstevel@tonic-gate }
7107c478bd9Sstevel@tonic-gate
7117c478bd9Sstevel@tonic-gate
7127c478bd9Sstevel@tonic-gate /*
7137c478bd9Sstevel@tonic-gate * meta_SetAttributeValue
7147c478bd9Sstevel@tonic-gate *
7157c478bd9Sstevel@tonic-gate * Call C_SetAttributeValue on all the clones. If the operation fails on
7167c478bd9Sstevel@tonic-gate * all clones, return the failure.
7177c478bd9Sstevel@tonic-gate *
7187c478bd9Sstevel@tonic-gate * If the operation fails on some clones and not the others, delete all the
7197c478bd9Sstevel@tonic-gate * clones that have failed the operation. If any of the deleted clone is the
7207c478bd9Sstevel@tonic-gate * master clone, use one of the remaining clone as the master clone.
7217c478bd9Sstevel@tonic-gate *
7227c478bd9Sstevel@tonic-gate * If the operation is successful and the master template already exists,
7237c478bd9Sstevel@tonic-gate * update the master template with new values.
7247c478bd9Sstevel@tonic-gate */
7257c478bd9Sstevel@tonic-gate CK_RV
meta_SetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)7267c478bd9Sstevel@tonic-gate meta_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
7277c478bd9Sstevel@tonic-gate CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
7287c478bd9Sstevel@tonic-gate {
7297c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK, save_rv = CKR_OK;
7307c478bd9Sstevel@tonic-gate meta_session_t *session;
7317c478bd9Sstevel@tonic-gate meta_object_t *object;
7327c478bd9Sstevel@tonic-gate CK_ULONG slotnum, num_slots;
7337c478bd9Sstevel@tonic-gate /* Keep track of which slot's SetAttributeValue failed */
7347c478bd9Sstevel@tonic-gate boolean_t *clone_failed_op = NULL;
7357c478bd9Sstevel@tonic-gate int num_clones = 0, num_clones_failed = 0;
7367c478bd9Sstevel@tonic-gate slot_session_t *slot_session;
7377c478bd9Sstevel@tonic-gate slot_object_t *slot_object;
7387c478bd9Sstevel@tonic-gate boolean_t need_update_master_clone = B_FALSE;
7397c478bd9Sstevel@tonic-gate
7407c478bd9Sstevel@tonic-gate if (pTemplate == NULL || ulCount < 1)
7417c478bd9Sstevel@tonic-gate return (CKR_ARGUMENTS_BAD);
7427c478bd9Sstevel@tonic-gate
7437c478bd9Sstevel@tonic-gate rv = meta_handle2session(hSession, &session);
7447c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
7457c478bd9Sstevel@tonic-gate return (rv);
7467c478bd9Sstevel@tonic-gate
7477c478bd9Sstevel@tonic-gate rv = meta_handle2object(hObject, &object);
7487c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
7497c478bd9Sstevel@tonic-gate REFRELEASE(session);
7507c478bd9Sstevel@tonic-gate return (rv);
7517c478bd9Sstevel@tonic-gate }
7527c478bd9Sstevel@tonic-gate
7537c478bd9Sstevel@tonic-gate if ((IS_READ_ONLY_SESSION(session->session_flags)) &&
7545b0c7657Sizick (object->isToken || object->isFreeToken == FREE_ENABLED)) {
7557c478bd9Sstevel@tonic-gate rv = CKR_SESSION_READ_ONLY;
7567c478bd9Sstevel@tonic-gate goto finish;
7577c478bd9Sstevel@tonic-gate }
7587c478bd9Sstevel@tonic-gate
7597c478bd9Sstevel@tonic-gate if ((!object->isExtractable) && (object->attributes == NULL)) {
7607c478bd9Sstevel@tonic-gate /*
7617c478bd9Sstevel@tonic-gate * object has no clone, just need to do the operation
7627c478bd9Sstevel@tonic-gate * in the master clone slot
7637c478bd9Sstevel@tonic-gate */
7647c478bd9Sstevel@tonic-gate slot_session_t *slot_session;
7657c478bd9Sstevel@tonic-gate slotnum = object->master_clone_slotnum;
7667c478bd9Sstevel@tonic-gate
7677c478bd9Sstevel@tonic-gate rv = meta_get_slot_session(slotnum, &slot_session,
7687c478bd9Sstevel@tonic-gate session->session_flags);
7697c478bd9Sstevel@tonic-gate if (rv == CKR_OK) {
7707c478bd9Sstevel@tonic-gate rv = FUNCLIST(slot_session->fw_st_id)->\
7717c478bd9Sstevel@tonic-gate C_SetAttributeValue(slot_session->hSession,
7727c478bd9Sstevel@tonic-gate object->clones[slotnum]->hObject, pTemplate,
7737c478bd9Sstevel@tonic-gate ulCount);
7747c478bd9Sstevel@tonic-gate
7757c478bd9Sstevel@tonic-gate meta_release_slot_session(slot_session);
7767c478bd9Sstevel@tonic-gate }
7777c478bd9Sstevel@tonic-gate goto finish;
7787c478bd9Sstevel@tonic-gate }
7797c478bd9Sstevel@tonic-gate
7807c478bd9Sstevel@tonic-gate
7817c478bd9Sstevel@tonic-gate num_slots = meta_slotManager_get_slotcount();
7827c478bd9Sstevel@tonic-gate
7837c478bd9Sstevel@tonic-gate /*
7847c478bd9Sstevel@tonic-gate * object might have clones, need to do operation in all clones
7857c478bd9Sstevel@tonic-gate *
7867c478bd9Sstevel@tonic-gate * If the C_SetAttributeValue() call fails in a clone, the
7877c478bd9Sstevel@tonic-gate * clone that failed the operation can not be deleted right
7887c478bd9Sstevel@tonic-gate * away. The clone with the failed operation is recorded, and
7897c478bd9Sstevel@tonic-gate * the deletion will happen in a separate loop.
7907c478bd9Sstevel@tonic-gate *
7917c478bd9Sstevel@tonic-gate * This is necessary because if ALL the clones failed
7927c478bd9Sstevel@tonic-gate * C_SetAttributeVAlue(), then, the app's call to C_SetAttributeValue()
7937c478bd9Sstevel@tonic-gate * is considered failed, and there shouldn't be any changes to the
7947c478bd9Sstevel@tonic-gate * object, none of the clones should be deleted.
7957c478bd9Sstevel@tonic-gate * On the other hand, if C_SetAttributeValue() fails in some clones
7967c478bd9Sstevel@tonic-gate * and succeeds in other clones, the C_SetAttributeValue() operation
7977c478bd9Sstevel@tonic-gate * is considered successful, and those clones that failed the
7987c478bd9Sstevel@tonic-gate * operation is deleted.
7997c478bd9Sstevel@tonic-gate */
8007c478bd9Sstevel@tonic-gate clone_failed_op = calloc(num_slots, sizeof (boolean_t));
8017c478bd9Sstevel@tonic-gate if (clone_failed_op == NULL) {
8027c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY;
8037c478bd9Sstevel@tonic-gate goto finish;
8047c478bd9Sstevel@tonic-gate }
8057c478bd9Sstevel@tonic-gate for (slotnum = 0; slotnum < num_slots; slotnum++) {
8067c478bd9Sstevel@tonic-gate if (object->clones[slotnum] != NULL) {
8077c478bd9Sstevel@tonic-gate num_clones++;
8087c478bd9Sstevel@tonic-gate rv = meta_get_slot_session(slotnum, &slot_session,
8097c478bd9Sstevel@tonic-gate session->session_flags);
8107c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
8117c478bd9Sstevel@tonic-gate goto finish;
8127c478bd9Sstevel@tonic-gate }
8137c478bd9Sstevel@tonic-gate
8147c478bd9Sstevel@tonic-gate rv = FUNCLIST(slot_session->fw_st_id)->\
8157c478bd9Sstevel@tonic-gate C_SetAttributeValue(slot_session->hSession,
8167c478bd9Sstevel@tonic-gate object->clones[slotnum]->hObject, pTemplate,
8177c478bd9Sstevel@tonic-gate ulCount);
8187c478bd9Sstevel@tonic-gate
8197c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
8207c478bd9Sstevel@tonic-gate num_clones_failed++;
8217c478bd9Sstevel@tonic-gate clone_failed_op[slotnum] = B_TRUE;
8227c478bd9Sstevel@tonic-gate if (save_rv == CKR_OK) {
8237c478bd9Sstevel@tonic-gate save_rv = rv;
8247c478bd9Sstevel@tonic-gate }
8257c478bd9Sstevel@tonic-gate }
8267c478bd9Sstevel@tonic-gate meta_release_slot_session(slot_session);
8277c478bd9Sstevel@tonic-gate }
8287c478bd9Sstevel@tonic-gate }
8297c478bd9Sstevel@tonic-gate
8307c478bd9Sstevel@tonic-gate if (num_clones_failed == num_clones) {
8317c478bd9Sstevel@tonic-gate /* all operations failed */
8327c478bd9Sstevel@tonic-gate rv = save_rv;
8337c478bd9Sstevel@tonic-gate goto finish;
8347c478bd9Sstevel@tonic-gate }
8357c478bd9Sstevel@tonic-gate
8367c478bd9Sstevel@tonic-gate if (num_clones_failed > 0) {
8377c478bd9Sstevel@tonic-gate /*
8387c478bd9Sstevel@tonic-gate * C_SetAttributeValue in some of the clones failed.
8397c478bd9Sstevel@tonic-gate * Find out which ones failed, and delete the clones
8407c478bd9Sstevel@tonic-gate * in those failed slots
8417c478bd9Sstevel@tonic-gate */
8427c478bd9Sstevel@tonic-gate for (slotnum = 0; slotnum < num_slots; slotnum++) {
8437c478bd9Sstevel@tonic-gate if (clone_failed_op[slotnum]) {
8447c478bd9Sstevel@tonic-gate
8457c478bd9Sstevel@tonic-gate slot_object_t *clone = object->clones[slotnum];
8467c478bd9Sstevel@tonic-gate
8477c478bd9Sstevel@tonic-gate rv = meta_get_slot_session(slotnum,
8487c478bd9Sstevel@tonic-gate &slot_session, session->session_flags);
8497c478bd9Sstevel@tonic-gate if (rv == CKR_OK) {
8507c478bd9Sstevel@tonic-gate (void) FUNCLIST(
8517c478bd9Sstevel@tonic-gate slot_session->fw_st_id)->
8527c478bd9Sstevel@tonic-gate C_DestroyObject(
8537c478bd9Sstevel@tonic-gate slot_session->hSession,
8547c478bd9Sstevel@tonic-gate clone->hObject);
8557c478bd9Sstevel@tonic-gate
8567c478bd9Sstevel@tonic-gate meta_release_slot_session(slot_session);
8577c478bd9Sstevel@tonic-gate
8587c478bd9Sstevel@tonic-gate }
8597c478bd9Sstevel@tonic-gate
8607c478bd9Sstevel@tonic-gate meta_slot_object_deactivate(clone);
8617c478bd9Sstevel@tonic-gate meta_slot_object_dealloc(clone);
8627c478bd9Sstevel@tonic-gate object->clones[slotnum] = NULL;
8637c478bd9Sstevel@tonic-gate
8647c478bd9Sstevel@tonic-gate if (slotnum == object->master_clone_slotnum) {
8657c478bd9Sstevel@tonic-gate need_update_master_clone = B_TRUE;
8667c478bd9Sstevel@tonic-gate }
8677c478bd9Sstevel@tonic-gate }
8687c478bd9Sstevel@tonic-gate }
8697c478bd9Sstevel@tonic-gate
8707c478bd9Sstevel@tonic-gate if (need_update_master_clone) {
8717c478bd9Sstevel@tonic-gate /* make first available clone the master */
8727c478bd9Sstevel@tonic-gate for (slotnum = 0; slotnum < num_slots; slotnum++) {
8737c478bd9Sstevel@tonic-gate if (object->clones[slotnum]) {
8747c478bd9Sstevel@tonic-gate object->master_clone_slotnum = slotnum;
8757c478bd9Sstevel@tonic-gate need_update_master_clone = B_FALSE;
8767c478bd9Sstevel@tonic-gate break;
8777c478bd9Sstevel@tonic-gate }
8787c478bd9Sstevel@tonic-gate }
8797c478bd9Sstevel@tonic-gate
8807c478bd9Sstevel@tonic-gate }
8817c478bd9Sstevel@tonic-gate if (need_update_master_clone) {
8827c478bd9Sstevel@tonic-gate /*
8837c478bd9Sstevel@tonic-gate * something is very wrong, can't continue
8847c478bd9Sstevel@tonic-gate * it should never be this case.
8857c478bd9Sstevel@tonic-gate */
8867c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED;
8877c478bd9Sstevel@tonic-gate goto finish;
8887c478bd9Sstevel@tonic-gate }
8897c478bd9Sstevel@tonic-gate rv = CKR_OK;
8907c478bd9Sstevel@tonic-gate }
8917c478bd9Sstevel@tonic-gate
8927c478bd9Sstevel@tonic-gate /*
8937c478bd9Sstevel@tonic-gate * Update the attribute information we keep in our metaslot object
8947c478bd9Sstevel@tonic-gate */
8957c478bd9Sstevel@tonic-gate slot_object = object->clones[object->master_clone_slotnum];
8967c478bd9Sstevel@tonic-gate rv = meta_get_slot_session(object->master_clone_slotnum,
8977c478bd9Sstevel@tonic-gate &slot_session, session->session_flags);
8987c478bd9Sstevel@tonic-gate if (rv == CKR_OK) {
8997c478bd9Sstevel@tonic-gate (void) meta_object_get_attr(slot_session,
9007c478bd9Sstevel@tonic-gate slot_object->hObject, object);
9017c478bd9Sstevel@tonic-gate meta_release_slot_session(slot_session);
9027c478bd9Sstevel@tonic-gate }
9037c478bd9Sstevel@tonic-gate
9047c478bd9Sstevel@tonic-gate /* if there's a copy of the attributes, keep it up to date */
9057c478bd9Sstevel@tonic-gate if (object->attributes != NULL) {
9067c478bd9Sstevel@tonic-gate
9077c478bd9Sstevel@tonic-gate CK_ULONG i;
9087c478bd9Sstevel@tonic-gate
9097c478bd9Sstevel@tonic-gate /* Make sure no one else is looking at attributes. */
9107c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(&object->attribute_lock);
9117c478bd9Sstevel@tonic-gate
9127c478bd9Sstevel@tonic-gate for (i = 0; i < ulCount; i++) {
9137c478bd9Sstevel@tonic-gate (void) attribute_set_value(pTemplate + i,
9147c478bd9Sstevel@tonic-gate object->attributes, object->num_attributes);
9157c478bd9Sstevel@tonic-gate
9167c478bd9Sstevel@tonic-gate }
9177c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&object->attribute_lock);
9187c478bd9Sstevel@tonic-gate }
9197c478bd9Sstevel@tonic-gate
9207c478bd9Sstevel@tonic-gate finish:
9217c478bd9Sstevel@tonic-gate if (clone_failed_op) {
9227c478bd9Sstevel@tonic-gate free(clone_failed_op);
9237c478bd9Sstevel@tonic-gate }
9247c478bd9Sstevel@tonic-gate OBJRELEASE(object);
9257c478bd9Sstevel@tonic-gate REFRELEASE(session);
9267c478bd9Sstevel@tonic-gate
9277c478bd9Sstevel@tonic-gate return (rv);
9287c478bd9Sstevel@tonic-gate }
9297c478bd9Sstevel@tonic-gate
9307c478bd9Sstevel@tonic-gate static boolean_t
meta_object_in_list(meta_object_t * obj,meta_object_t ** objs_list,int num_objs)9317c478bd9Sstevel@tonic-gate meta_object_in_list(meta_object_t *obj, meta_object_t **objs_list, int num_objs)
9327c478bd9Sstevel@tonic-gate {
9337c478bd9Sstevel@tonic-gate int i;
9347c478bd9Sstevel@tonic-gate
9357c478bd9Sstevel@tonic-gate for (i = 0; i < num_objs; i++) {
9367c478bd9Sstevel@tonic-gate if (objs_list[i] == obj) {
9377c478bd9Sstevel@tonic-gate return (B_TRUE);
9387c478bd9Sstevel@tonic-gate }
9397c478bd9Sstevel@tonic-gate }
9407c478bd9Sstevel@tonic-gate return (B_FALSE);
9417c478bd9Sstevel@tonic-gate }
9427c478bd9Sstevel@tonic-gate
9437c478bd9Sstevel@tonic-gate static CK_RV
add_to_search_result(meta_object_t * object,find_objs_info_t * info,int * num_results_alloc)9447c478bd9Sstevel@tonic-gate add_to_search_result(meta_object_t *object, find_objs_info_t *info,
9457c478bd9Sstevel@tonic-gate int *num_results_alloc)
9467c478bd9Sstevel@tonic-gate {
9477c478bd9Sstevel@tonic-gate /*
9487c478bd9Sstevel@tonic-gate * allocate space for storing results if the currently
9497c478bd9Sstevel@tonic-gate * allocated space is not enough
9507c478bd9Sstevel@tonic-gate */
9517c478bd9Sstevel@tonic-gate if (*num_results_alloc <= info->num_matched_objs) {
9527c478bd9Sstevel@tonic-gate *num_results_alloc += FIND_OBJ_BUF_SIZE;
9537c478bd9Sstevel@tonic-gate info->matched_objs = realloc(info->matched_objs,
9547c478bd9Sstevel@tonic-gate sizeof (meta_object_t *) * (*num_results_alloc));
9557c478bd9Sstevel@tonic-gate if (info->matched_objs == NULL) {
9567c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY);
9577c478bd9Sstevel@tonic-gate }
9587c478bd9Sstevel@tonic-gate }
9597c478bd9Sstevel@tonic-gate (info->matched_objs)[(info->num_matched_objs)++] = object;
9607c478bd9Sstevel@tonic-gate return (CKR_OK);
9617c478bd9Sstevel@tonic-gate }
9627c478bd9Sstevel@tonic-gate
9637c478bd9Sstevel@tonic-gate static CK_RV
process_find_results(CK_OBJECT_HANDLE * results,CK_ULONG num_results,int * num_results_allocated,find_objs_info_t * info,CK_ULONG slotnum,boolean_t token_only,slot_session_t * slot_session,meta_session_t * session)9647c478bd9Sstevel@tonic-gate process_find_results(CK_OBJECT_HANDLE *results, CK_ULONG num_results,
9657c478bd9Sstevel@tonic-gate int *num_results_allocated, find_objs_info_t *info, CK_ULONG slotnum,
9667c478bd9Sstevel@tonic-gate boolean_t token_only, slot_session_t *slot_session,
9677c478bd9Sstevel@tonic-gate meta_session_t *session)
9687c478bd9Sstevel@tonic-gate {
9697c478bd9Sstevel@tonic-gate CK_ULONG i;
9707c478bd9Sstevel@tonic-gate meta_object_t *object;
9717c478bd9Sstevel@tonic-gate CK_RV rv;
9727c478bd9Sstevel@tonic-gate
9737c478bd9Sstevel@tonic-gate for (i = 0; i < num_results; i++) {
9747c478bd9Sstevel@tonic-gate
9757c478bd9Sstevel@tonic-gate object = meta_object_find_by_handle(results[i], slotnum,
9767c478bd9Sstevel@tonic-gate token_only);
9777c478bd9Sstevel@tonic-gate
9787c478bd9Sstevel@tonic-gate /*
9797c478bd9Sstevel@tonic-gate * a token object is found from the keystore,
9807c478bd9Sstevel@tonic-gate * need to create a meta object for it
9817c478bd9Sstevel@tonic-gate */
9827c478bd9Sstevel@tonic-gate if (object == NULL) {
9837c478bd9Sstevel@tonic-gate slot_object_t *slot_object;
9847c478bd9Sstevel@tonic-gate
9857c478bd9Sstevel@tonic-gate rv = meta_object_alloc(session, &object);
9867c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
9877c478bd9Sstevel@tonic-gate return (rv);
9887c478bd9Sstevel@tonic-gate }
9897c478bd9Sstevel@tonic-gate
9907c478bd9Sstevel@tonic-gate rv = meta_slot_object_alloc(&slot_object);
9917c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
992*8cae6764SAnthony Scarpino (void) meta_object_dealloc(session, object,
993*8cae6764SAnthony Scarpino B_TRUE);
9947c478bd9Sstevel@tonic-gate return (rv);
9957c478bd9Sstevel@tonic-gate }
9967c478bd9Sstevel@tonic-gate
9977c478bd9Sstevel@tonic-gate slot_object->hObject = results[i];
9987c478bd9Sstevel@tonic-gate object->master_clone_slotnum = slotnum;
9997c478bd9Sstevel@tonic-gate object->clones[slotnum] = slot_object;
10007c478bd9Sstevel@tonic-gate
10017c478bd9Sstevel@tonic-gate /* get in the attributes we keep in meta_object */
10027c478bd9Sstevel@tonic-gate
10037c478bd9Sstevel@tonic-gate rv = meta_object_get_attr(slot_session,
10047c478bd9Sstevel@tonic-gate slot_object->hObject, object);
10057c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
1006*8cae6764SAnthony Scarpino (void) meta_object_dealloc(session, object,
1007*8cae6764SAnthony Scarpino B_TRUE);
10087c478bd9Sstevel@tonic-gate return (rv);
10097c478bd9Sstevel@tonic-gate }
10107c478bd9Sstevel@tonic-gate
10117c478bd9Sstevel@tonic-gate meta_slot_object_activate(slot_object, slot_session,
10127c478bd9Sstevel@tonic-gate B_TRUE);
10137c478bd9Sstevel@tonic-gate meta_object_activate(object);
10147c478bd9Sstevel@tonic-gate slot_object = NULL;
10157c478bd9Sstevel@tonic-gate }
10167c478bd9Sstevel@tonic-gate
10177c478bd9Sstevel@tonic-gate if (!meta_object_in_list(object, info->matched_objs,
10187c478bd9Sstevel@tonic-gate info->num_matched_objs)) {
10197c478bd9Sstevel@tonic-gate rv = add_to_search_result(object, info,
10207c478bd9Sstevel@tonic-gate num_results_allocated);
10217c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
10227c478bd9Sstevel@tonic-gate return (rv);
10237c478bd9Sstevel@tonic-gate }
10247c478bd9Sstevel@tonic-gate }
10257c478bd9Sstevel@tonic-gate }
10267c478bd9Sstevel@tonic-gate return (CKR_OK);
10277c478bd9Sstevel@tonic-gate }
10287c478bd9Sstevel@tonic-gate
10297c478bd9Sstevel@tonic-gate static CK_RV
meta_search_for_objects(meta_session_t * session,find_objs_info_t * info,slot_session_t * slot_session,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_ULONG slotnum,boolean_t token_only,int * num_results_alloc)10307c478bd9Sstevel@tonic-gate meta_search_for_objects(meta_session_t *session, find_objs_info_t *info,
10317c478bd9Sstevel@tonic-gate slot_session_t *slot_session, CK_ATTRIBUTE_PTR pTemplate,
10327c478bd9Sstevel@tonic-gate CK_ULONG ulCount, CK_ULONG slotnum, boolean_t token_only,
10337c478bd9Sstevel@tonic-gate int *num_results_alloc)
10347c478bd9Sstevel@tonic-gate {
10357c478bd9Sstevel@tonic-gate CK_ULONG tmp_num_results;
10367c478bd9Sstevel@tonic-gate CK_OBJECT_HANDLE tmp_results[FIND_OBJ_BUF_SIZE];
10377c478bd9Sstevel@tonic-gate CK_SESSION_HANDLE hSession = slot_session->hSession;
10387c478bd9Sstevel@tonic-gate CK_RV rv;
10397c478bd9Sstevel@tonic-gate CK_SLOT_ID fw_st_id = slot_session->fw_st_id;
10407c478bd9Sstevel@tonic-gate
10417c478bd9Sstevel@tonic-gate rv = FUNCLIST(fw_st_id)->C_FindObjectsInit(hSession,
10427c478bd9Sstevel@tonic-gate pTemplate, ulCount);
10437c478bd9Sstevel@tonic-gate
10447c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
10457c478bd9Sstevel@tonic-gate return (rv);
10467c478bd9Sstevel@tonic-gate }
10477c478bd9Sstevel@tonic-gate
10487c478bd9Sstevel@tonic-gate tmp_num_results = 0;
10497c478bd9Sstevel@tonic-gate rv = FUNCLIST(fw_st_id)->C_FindObjects(hSession, tmp_results,
10507c478bd9Sstevel@tonic-gate FIND_OBJ_BUF_SIZE, &tmp_num_results);
10517c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
10527c478bd9Sstevel@tonic-gate return (rv);
10537c478bd9Sstevel@tonic-gate }
10547c478bd9Sstevel@tonic-gate
10557c478bd9Sstevel@tonic-gate rv = process_find_results(tmp_results, tmp_num_results,
10567c478bd9Sstevel@tonic-gate num_results_alloc, info, slotnum, token_only,
10577c478bd9Sstevel@tonic-gate slot_session, session);
10587c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
10597c478bd9Sstevel@tonic-gate return (rv);
10607c478bd9Sstevel@tonic-gate }
10617c478bd9Sstevel@tonic-gate
10627c478bd9Sstevel@tonic-gate while (tmp_num_results == FIND_OBJ_BUF_SIZE) {
10637c478bd9Sstevel@tonic-gate /* might be more results, need to call C_FindObjects again */
10647c478bd9Sstevel@tonic-gate rv = FUNCLIST(fw_st_id)->C_FindObjects(hSession, tmp_results,
10657c478bd9Sstevel@tonic-gate FIND_OBJ_BUF_SIZE, &tmp_num_results);
10667c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
10677c478bd9Sstevel@tonic-gate return (rv);
10687c478bd9Sstevel@tonic-gate }
10697c478bd9Sstevel@tonic-gate
10707c478bd9Sstevel@tonic-gate rv = process_find_results(tmp_results, tmp_num_results,
10717c478bd9Sstevel@tonic-gate num_results_alloc, info, slotnum, token_only,
10727c478bd9Sstevel@tonic-gate slot_session, session);
10737c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
10747c478bd9Sstevel@tonic-gate return (rv);
10757c478bd9Sstevel@tonic-gate }
10767c478bd9Sstevel@tonic-gate }
10777c478bd9Sstevel@tonic-gate
10787c478bd9Sstevel@tonic-gate rv = FUNCLIST(fw_st_id)->C_FindObjectsFinal(hSession);
10797c478bd9Sstevel@tonic-gate return (rv);
10807c478bd9Sstevel@tonic-gate }
10817c478bd9Sstevel@tonic-gate
10827c478bd9Sstevel@tonic-gate
10837c478bd9Sstevel@tonic-gate /*
10847c478bd9Sstevel@tonic-gate * meta_FindObjectsInit
10857c478bd9Sstevel@tonic-gate *
10867c478bd9Sstevel@tonic-gate * This function actually will do ALL the work of searching for objects
10877c478bd9Sstevel@tonic-gate * that match all requirements specified in the template.
10887c478bd9Sstevel@tonic-gate *
10897c478bd9Sstevel@tonic-gate * Objects that matched the template will be stored in the
10907c478bd9Sstevel@tonic-gate * session's data structure. When the subsequent C_FindObjects()
10917c478bd9Sstevel@tonic-gate * calls are made, results saved will be returned.
10927c478bd9Sstevel@tonic-gate *
10937c478bd9Sstevel@tonic-gate */
10947c478bd9Sstevel@tonic-gate CK_RV
meta_FindObjectsInit(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)10957c478bd9Sstevel@tonic-gate meta_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
10967c478bd9Sstevel@tonic-gate CK_ULONG ulCount)
10977c478bd9Sstevel@tonic-gate {
10987c478bd9Sstevel@tonic-gate CK_RV rv;
10997c478bd9Sstevel@tonic-gate meta_session_t *session;
11007c478bd9Sstevel@tonic-gate CK_ULONG slot_num = 0;
11017c478bd9Sstevel@tonic-gate boolean_t have_token_attr, tokenTrue = B_FALSE;
11027c478bd9Sstevel@tonic-gate slot_session_t *slot_find_session = NULL;
11037c478bd9Sstevel@tonic-gate int num_results_allocated = 0;
11047c478bd9Sstevel@tonic-gate CK_ULONG keystore_slotnum;
11057c478bd9Sstevel@tonic-gate
11067c478bd9Sstevel@tonic-gate rv = meta_handle2session(hSession, &session);
11077c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
11087c478bd9Sstevel@tonic-gate return (rv);
11097c478bd9Sstevel@tonic-gate
11107c478bd9Sstevel@tonic-gate if ((session->find_objs_info).op_active) {
11117c478bd9Sstevel@tonic-gate REFRELEASE(session);
11127c478bd9Sstevel@tonic-gate return (CKR_OPERATION_ACTIVE);
11137c478bd9Sstevel@tonic-gate }
11147c478bd9Sstevel@tonic-gate
11157c478bd9Sstevel@tonic-gate (session->find_objs_info).op_active = B_TRUE;
11167c478bd9Sstevel@tonic-gate
11177c478bd9Sstevel@tonic-gate REFRELEASE(session);
11187c478bd9Sstevel@tonic-gate
11197c478bd9Sstevel@tonic-gate /* see if the template indicates token object only or not */
11207c478bd9Sstevel@tonic-gate have_token_attr = get_template_boolean(CKA_TOKEN, pTemplate, ulCount,
11217c478bd9Sstevel@tonic-gate &tokenTrue);
11227c478bd9Sstevel@tonic-gate
11237c478bd9Sstevel@tonic-gate keystore_slotnum = get_keystore_slotnum();
11247c478bd9Sstevel@tonic-gate
11257c478bd9Sstevel@tonic-gate if (have_token_attr && tokenTrue) {
11267c478bd9Sstevel@tonic-gate
11277c478bd9Sstevel@tonic-gate
11287c478bd9Sstevel@tonic-gate /*
11297c478bd9Sstevel@tonic-gate * only interested in token objects, just need to search
11307c478bd9Sstevel@tonic-gate * token object slot
11317c478bd9Sstevel@tonic-gate */
11327c478bd9Sstevel@tonic-gate rv = meta_get_slot_session(keystore_slotnum,
11337c478bd9Sstevel@tonic-gate &slot_find_session, session->session_flags);
11347c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
11357c478bd9Sstevel@tonic-gate goto finish;
11367c478bd9Sstevel@tonic-gate }
11377c478bd9Sstevel@tonic-gate rv = meta_search_for_objects(session,
11387c478bd9Sstevel@tonic-gate &(session->find_objs_info), slot_find_session, pTemplate,
11397c478bd9Sstevel@tonic-gate ulCount, keystore_slotnum, B_TRUE, &num_results_allocated);
11407c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
11417c478bd9Sstevel@tonic-gate goto finish;
11427c478bd9Sstevel@tonic-gate }
11437c478bd9Sstevel@tonic-gate } else {
11447c478bd9Sstevel@tonic-gate CK_ULONG num_slots = meta_slotManager_get_slotcount();
11457c478bd9Sstevel@tonic-gate for (slot_num = 0; slot_num < num_slots; slot_num++) {
11467c478bd9Sstevel@tonic-gate rv = meta_get_slot_session(slot_num,
11477c478bd9Sstevel@tonic-gate &slot_find_session, session->session_flags);
11487c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
11497c478bd9Sstevel@tonic-gate goto finish;
11507c478bd9Sstevel@tonic-gate }
11517c478bd9Sstevel@tonic-gate
11527c478bd9Sstevel@tonic-gate /*
11537c478bd9Sstevel@tonic-gate * if the slot is NOT the token object slot, and
11547c478bd9Sstevel@tonic-gate * CKA_TOKEN is not specified, need to specified
11557c478bd9Sstevel@tonic-gate * it to be false explicitly. This will prevent
11567c478bd9Sstevel@tonic-gate * us from using token objects that doesn't
11577c478bd9Sstevel@tonic-gate * belong to the token slot in the case that
11587c478bd9Sstevel@tonic-gate * more than one slot supports token objects.
11597c478bd9Sstevel@tonic-gate */
11607c478bd9Sstevel@tonic-gate
11617c478bd9Sstevel@tonic-gate if ((slot_num != keystore_slotnum) &&
11627c478bd9Sstevel@tonic-gate (!have_token_attr)) {
11637c478bd9Sstevel@tonic-gate CK_BBOOL false = FALSE;
11647c478bd9Sstevel@tonic-gate CK_ATTRIBUTE_PTR newTemplate;
11657c478bd9Sstevel@tonic-gate
11667c478bd9Sstevel@tonic-gate newTemplate = malloc((ulCount + 1) *
11677c478bd9Sstevel@tonic-gate sizeof (CK_ATTRIBUTE));
11687c478bd9Sstevel@tonic-gate if (newTemplate == NULL) {
11697c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY;
11707c478bd9Sstevel@tonic-gate goto finish;
11717c478bd9Sstevel@tonic-gate }
11727c478bd9Sstevel@tonic-gate (void) memcpy(newTemplate + 1, pTemplate,
11737c478bd9Sstevel@tonic-gate ulCount * sizeof (CK_ATTRIBUTE));
11747c478bd9Sstevel@tonic-gate newTemplate[0].type = CKA_TOKEN;
11757c478bd9Sstevel@tonic-gate newTemplate[0].pValue = &false;
11767c478bd9Sstevel@tonic-gate newTemplate[0].ulValueLen = sizeof (false);
11777c478bd9Sstevel@tonic-gate
11787c478bd9Sstevel@tonic-gate rv = meta_search_for_objects(session,
11797c478bd9Sstevel@tonic-gate &(session->find_objs_info),
11807c478bd9Sstevel@tonic-gate slot_find_session, newTemplate,
11817c478bd9Sstevel@tonic-gate ulCount+1, slot_num, B_FALSE,
11827c478bd9Sstevel@tonic-gate &num_results_allocated);
11837c478bd9Sstevel@tonic-gate free(newTemplate);
11847c478bd9Sstevel@tonic-gate } else {
11857c478bd9Sstevel@tonic-gate rv = meta_search_for_objects(session,
11867c478bd9Sstevel@tonic-gate &(session->find_objs_info),
11877c478bd9Sstevel@tonic-gate slot_find_session, pTemplate, ulCount,
11887c478bd9Sstevel@tonic-gate slot_num, B_FALSE,
11897c478bd9Sstevel@tonic-gate &num_results_allocated);
11907c478bd9Sstevel@tonic-gate }
11917c478bd9Sstevel@tonic-gate
11927c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
11937c478bd9Sstevel@tonic-gate goto finish;
11947c478bd9Sstevel@tonic-gate }
11957c478bd9Sstevel@tonic-gate meta_release_slot_session(slot_find_session);
11967c478bd9Sstevel@tonic-gate slot_find_session = NULL;
11977c478bd9Sstevel@tonic-gate }
11987c478bd9Sstevel@tonic-gate }
11997c478bd9Sstevel@tonic-gate
12007c478bd9Sstevel@tonic-gate finish:
12017c478bd9Sstevel@tonic-gate if (slot_find_session != NULL) {
12027c478bd9Sstevel@tonic-gate meta_release_slot_session(slot_find_session);
12037c478bd9Sstevel@tonic-gate }
12047c478bd9Sstevel@tonic-gate if (rv != CKR_OK) {
12057c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(&session->session_lock);
12067c478bd9Sstevel@tonic-gate if (((session->find_objs_info).matched_objs) != NULL) {
12077c478bd9Sstevel@tonic-gate free((session->find_objs_info).matched_objs);
12087c478bd9Sstevel@tonic-gate }
12097c478bd9Sstevel@tonic-gate bzero(&(session->find_objs_info), sizeof (find_objs_info_t));
12107c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&(session->session_lock));
12117c478bd9Sstevel@tonic-gate }
12127c478bd9Sstevel@tonic-gate
12137c478bd9Sstevel@tonic-gate return (rv);
12147c478bd9Sstevel@tonic-gate }
12157c478bd9Sstevel@tonic-gate
12167c478bd9Sstevel@tonic-gate /*
12177c478bd9Sstevel@tonic-gate * meta_FindObjects
12187c478bd9Sstevel@tonic-gate *
12197c478bd9Sstevel@tonic-gate * This function actually doesn't do any real work in search for the
12207c478bd9Sstevel@tonic-gate * matching object. All the work is done in FindObjectsInit(). This
12217c478bd9Sstevel@tonic-gate * function will only return the matching objects store in the session's
12227c478bd9Sstevel@tonic-gate * "find_objs_info" variable.
12237c478bd9Sstevel@tonic-gate *
12247c478bd9Sstevel@tonic-gate */
12257c478bd9Sstevel@tonic-gate CK_RV
meta_FindObjects(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount,CK_ULONG_PTR pulObjectCount)12267c478bd9Sstevel@tonic-gate meta_FindObjects(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject,
12277c478bd9Sstevel@tonic-gate CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount)
12287c478bd9Sstevel@tonic-gate {
12297c478bd9Sstevel@tonic-gate CK_RV rv;
12307c478bd9Sstevel@tonic-gate find_objs_info_t *info;
12317c478bd9Sstevel@tonic-gate CK_ULONG num_objs_found = 0;
12327c478bd9Sstevel@tonic-gate meta_object_t *obj;
12337c478bd9Sstevel@tonic-gate meta_session_t *session;
12347c478bd9Sstevel@tonic-gate int i;
12357c478bd9Sstevel@tonic-gate
12367c478bd9Sstevel@tonic-gate rv = meta_handle2session(hSession, &session);
12377c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
12387c478bd9Sstevel@tonic-gate return (rv);
12397c478bd9Sstevel@tonic-gate
12407c478bd9Sstevel@tonic-gate info = &(session->find_objs_info);
12417c478bd9Sstevel@tonic-gate
12427c478bd9Sstevel@tonic-gate if (!(info->op_active)) {
12437c478bd9Sstevel@tonic-gate REFRELEASE(session);
12447c478bd9Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED);
12457c478bd9Sstevel@tonic-gate }
12467c478bd9Sstevel@tonic-gate
12477c478bd9Sstevel@tonic-gate for (i = info->next_result_index;
12487c478bd9Sstevel@tonic-gate ((num_objs_found < ulMaxObjectCount) &&
12497c478bd9Sstevel@tonic-gate (i < info->num_matched_objs));
12507c478bd9Sstevel@tonic-gate i++) {
12517c478bd9Sstevel@tonic-gate obj = info->matched_objs[i];
12527c478bd9Sstevel@tonic-gate if (obj != NULL) {
12537c478bd9Sstevel@tonic-gate /* sanity check to see if object is still valid */
12547c478bd9Sstevel@tonic-gate (void) pthread_rwlock_rdlock(&obj->object_lock);
12557c478bd9Sstevel@tonic-gate if (obj->magic_marker == METASLOT_OBJECT_MAGIC) {
12567c478bd9Sstevel@tonic-gate phObject[num_objs_found++] =
12577c478bd9Sstevel@tonic-gate (CK_OBJECT_HANDLE)obj;
12587c478bd9Sstevel@tonic-gate }
12597c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&obj->object_lock);
12607c478bd9Sstevel@tonic-gate }
12617c478bd9Sstevel@tonic-gate }
12627c478bd9Sstevel@tonic-gate info->next_result_index = i;
12637c478bd9Sstevel@tonic-gate *pulObjectCount = num_objs_found;
12647c478bd9Sstevel@tonic-gate REFRELEASE(session);
12657c478bd9Sstevel@tonic-gate return (rv);
12667c478bd9Sstevel@tonic-gate }
12677c478bd9Sstevel@tonic-gate
12687c478bd9Sstevel@tonic-gate
12697c478bd9Sstevel@tonic-gate /*
12707c478bd9Sstevel@tonic-gate * meta_FindObjectsFinal
12717c478bd9Sstevel@tonic-gate *
12727c478bd9Sstevel@tonic-gate */
12737c478bd9Sstevel@tonic-gate CK_RV
meta_FindObjectsFinal(CK_SESSION_HANDLE hSession)12747c478bd9Sstevel@tonic-gate meta_FindObjectsFinal(CK_SESSION_HANDLE hSession)
12757c478bd9Sstevel@tonic-gate {
12767c478bd9Sstevel@tonic-gate CK_RV rv;
12777c478bd9Sstevel@tonic-gate find_objs_info_t *info;
12787c478bd9Sstevel@tonic-gate meta_session_t *session;
12797c478bd9Sstevel@tonic-gate
12807c478bd9Sstevel@tonic-gate rv = meta_handle2session(hSession, &session);
12817c478bd9Sstevel@tonic-gate if (rv != CKR_OK)
12827c478bd9Sstevel@tonic-gate return (rv);
12837c478bd9Sstevel@tonic-gate
12847c478bd9Sstevel@tonic-gate info = &(session->find_objs_info);
12857c478bd9Sstevel@tonic-gate
12867c478bd9Sstevel@tonic-gate if (!info->op_active) {
12877c478bd9Sstevel@tonic-gate REFRELEASE(session);
12887c478bd9Sstevel@tonic-gate return (CKR_OPERATION_NOT_INITIALIZED);
12897c478bd9Sstevel@tonic-gate }
12907c478bd9Sstevel@tonic-gate
12917c478bd9Sstevel@tonic-gate if (info->matched_objs) {
12927c478bd9Sstevel@tonic-gate free(info->matched_objs);
12937c478bd9Sstevel@tonic-gate }
12947c478bd9Sstevel@tonic-gate
12957c478bd9Sstevel@tonic-gate bzero(info, sizeof (find_objs_info_t));
12967c478bd9Sstevel@tonic-gate REFRELEASE(session);
12977c478bd9Sstevel@tonic-gate return (rv);
12987c478bd9Sstevel@tonic-gate }
1299