1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 30*7c478bd9Sstevel@tonic-gate #include <string.h> 31*7c478bd9Sstevel@tonic-gate #include <strings.h> 32*7c478bd9Sstevel@tonic-gate #include <errno.h> 33*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 36*7c478bd9Sstevel@tonic-gate #include "metaGlobal.h" 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate /* Size of the template for creating key used for wrap/unwrap */ 39*7c478bd9Sstevel@tonic-gate #define WRAP_KEY_TEMPLATE_SIZE 7 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate /* 42*7c478bd9Sstevel@tonic-gate * Information necessary to create keys for C_WrapKey/C_UnwrapKey 43*7c478bd9Sstevel@tonic-gate */ 44*7c478bd9Sstevel@tonic-gate typedef struct _wrap_info { 45*7c478bd9Sstevel@tonic-gate CK_OBJECT_CLASS class; /* class of the key for wrap/unwrap */ 46*7c478bd9Sstevel@tonic-gate CK_KEY_TYPE key_type; /* key type of key for wrap/unwrap */ 47*7c478bd9Sstevel@tonic-gate CK_ULONG key_length; /* length of key */ 48*7c478bd9Sstevel@tonic-gate CK_MECHANISM_TYPE mech_type; /* mech used for wrap/unwrap */ 49*7c478bd9Sstevel@tonic-gate CK_ULONG iv_length; /* length of iv for mech */ 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate boolean_t src_supports; 52*7c478bd9Sstevel@tonic-gate boolean_t dst_supports; 53*7c478bd9Sstevel@tonic-gate } wrap_info_t; 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate extern pthread_rwlock_t meta_sessionlist_lock; 56*7c478bd9Sstevel@tonic-gate extern meta_session_t *meta_sessionlist_head; 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate static wrap_info_t common_wrap_info[] = { 59*7c478bd9Sstevel@tonic-gate {CKO_SECRET_KEY, CKK_AES, 16, CKM_AES_CBC_PAD, 16, B_FALSE, B_FALSE}, 60*7c478bd9Sstevel@tonic-gate {CKO_SECRET_KEY, CKK_DES3, 24, CKM_DES3_CBC_PAD, 8, B_FALSE, B_FALSE}, 61*7c478bd9Sstevel@tonic-gate {CKO_SECRET_KEY, CKK_DES, 8, CKM_DES_CBC_PAD, 8, B_FALSE, B_FALSE}, 62*7c478bd9Sstevel@tonic-gate }; 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate static unsigned int num_common_wrap_info = 65*7c478bd9Sstevel@tonic-gate sizeof (common_wrap_info) / sizeof (wrap_info_t); 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate static wrap_info_t special_wrap_info[] = { 68*7c478bd9Sstevel@tonic-gate {CKO_SECRET_KEY, CKK_SKIPJACK, 12, CKM_SKIPJACK_WRAP, 0, 69*7c478bd9Sstevel@tonic-gate B_FALSE, B_FALSE}, 70*7c478bd9Sstevel@tonic-gate {CKO_SECRET_KEY, CKK_BATON, 40, CKM_BATON_WRAP, 0, 71*7c478bd9Sstevel@tonic-gate B_FALSE, B_FALSE}, 72*7c478bd9Sstevel@tonic-gate {CKO_SECRET_KEY, CKK_JUNIPER, 40, CKM_JUNIPER_WRAP, 0, 73*7c478bd9Sstevel@tonic-gate B_FALSE, B_FALSE}, 74*7c478bd9Sstevel@tonic-gate }; 75*7c478bd9Sstevel@tonic-gate static unsigned int num_special_wrap_info = 76*7c478bd9Sstevel@tonic-gate sizeof (special_wrap_info) / sizeof (wrap_info_t); 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate static wrap_info_t rsa_wrap_info[] = { 79*7c478bd9Sstevel@tonic-gate {CKO_PUBLIC_KEY, CKK_RSA, 0, CKM_RSA_PKCS, 0, 80*7c478bd9Sstevel@tonic-gate B_FALSE, B_FALSE}, 81*7c478bd9Sstevel@tonic-gate {CKO_PUBLIC_KEY, CKK_RSA, 0, CKM_RSA_X_509, 0, 82*7c478bd9Sstevel@tonic-gate B_FALSE, B_FALSE}, 83*7c478bd9Sstevel@tonic-gate }; 84*7c478bd9Sstevel@tonic-gate static unsigned int num_rsa_wrap_info = 85*7c478bd9Sstevel@tonic-gate sizeof (rsa_wrap_info) / sizeof (wrap_info_t); 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate static pthread_rwlock_t meta_objectclose_lock; 89*7c478bd9Sstevel@tonic-gate static pthread_rwlock_t tokenobject_list_lock; 90*7c478bd9Sstevel@tonic-gate static meta_object_t *tokenobject_list_head; 91*7c478bd9Sstevel@tonic-gate 92*7c478bd9Sstevel@tonic-gate static CK_BBOOL falsevalue = FALSE; 93*7c478bd9Sstevel@tonic-gate static CK_BBOOL truevalue = TRUE; 94*7c478bd9Sstevel@tonic-gate 95*7c478bd9Sstevel@tonic-gate /* 96*7c478bd9Sstevel@tonic-gate * Public and private exponent, and Module value for 97*7c478bd9Sstevel@tonic-gate * creating the RSA public/private key. 98*7c478bd9Sstevel@tonic-gate * 99*7c478bd9Sstevel@tonic-gate */ 100*7c478bd9Sstevel@tonic-gate static CK_BYTE PubExpo[3] = {0x01, 0x00, 0x01}; 101*7c478bd9Sstevel@tonic-gate CK_BYTE PriExpo[128] = { 102*7c478bd9Sstevel@tonic-gate 0x8e, 0xc9, 0x70, 0x57, 0x6b, 0xcd, 0xfb, 0xa9, 103*7c478bd9Sstevel@tonic-gate 0x19, 0xad, 0xcd, 0x91, 0x69, 0xd5, 0x52, 0xec, 104*7c478bd9Sstevel@tonic-gate 0x72, 0x1e, 0x45, 0x15, 0x06, 0xdc, 0x65, 0x2d, 105*7c478bd9Sstevel@tonic-gate 0x98, 0xc4, 0xce, 0x33, 0x54, 0x15, 0x70, 0x8d, 106*7c478bd9Sstevel@tonic-gate 0xfa, 0x65, 0xea, 0x53, 0x44, 0xf3, 0x3e, 0x3f, 107*7c478bd9Sstevel@tonic-gate 0xb4, 0x4c, 0x60, 0xd5, 0x01, 0x2d, 0xa4, 0x12, 108*7c478bd9Sstevel@tonic-gate 0x99, 0xbf, 0x3f, 0x0b, 0xcd, 0xbb, 0x24, 0x10, 109*7c478bd9Sstevel@tonic-gate 0x60, 0x30, 0x5e, 0x58, 0xf8, 0x59, 0xaa, 0xd1, 110*7c478bd9Sstevel@tonic-gate 0x63, 0x3b, 0xbc, 0xcb, 0x94, 0x58, 0x38, 0x24, 111*7c478bd9Sstevel@tonic-gate 0xfc, 0x65, 0x25, 0xc5, 0xa6, 0x51, 0xa2, 0x2e, 112*7c478bd9Sstevel@tonic-gate 0xf1, 0x5e, 0xf5, 0xc1, 0xf5, 0x46, 0xf7, 0xbd, 113*7c478bd9Sstevel@tonic-gate 0xc7, 0x62, 0xa8, 0xe2, 0x27, 0xd6, 0x94, 0x5b, 114*7c478bd9Sstevel@tonic-gate 0xd3, 0xa2, 0xb5, 0x76, 0x42, 0x67, 0x6b, 0x86, 115*7c478bd9Sstevel@tonic-gate 0x91, 0x97, 0x4d, 0x07, 0x92, 0x00, 0x4a, 0xdf, 116*7c478bd9Sstevel@tonic-gate 0x0b, 0x65, 0x64, 0x05, 0x03, 0x48, 0x27, 0xeb, 117*7c478bd9Sstevel@tonic-gate 0xce, 0x9a, 0x49, 0x7f, 0x3e, 0x10, 0xe0, 0x01}; 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate static CK_BYTE Modulus[128] = { 120*7c478bd9Sstevel@tonic-gate 0x94, 0x32, 0xb9, 0x12, 0x1d, 0x68, 0x2c, 0xda, 121*7c478bd9Sstevel@tonic-gate 0x2b, 0xe0, 0xe4, 0x97, 0x1b, 0x4d, 0xdc, 0x43, 122*7c478bd9Sstevel@tonic-gate 0xdf, 0x38, 0x6e, 0x7b, 0x9f, 0x07, 0x58, 0xae, 123*7c478bd9Sstevel@tonic-gate 0x9d, 0x82, 0x1e, 0xc7, 0xbc, 0x92, 0xbf, 0xd3, 124*7c478bd9Sstevel@tonic-gate 0xce, 0x00, 0xbb, 0x91, 0xc9, 0x79, 0x06, 0x03, 125*7c478bd9Sstevel@tonic-gate 0x1f, 0xbc, 0x9f, 0x94, 0x75, 0x29, 0x5f, 0xd7, 126*7c478bd9Sstevel@tonic-gate 0xc5, 0xf3, 0x73, 0x8a, 0xa4, 0x35, 0x43, 0x7a, 127*7c478bd9Sstevel@tonic-gate 0x00, 0x32, 0x97, 0x3e, 0x86, 0xef, 0x70, 0x6f, 128*7c478bd9Sstevel@tonic-gate 0x18, 0x56, 0x15, 0xaa, 0x6a, 0x87, 0xe7, 0x8d, 129*7c478bd9Sstevel@tonic-gate 0x7d, 0xdd, 0x1f, 0xa4, 0xe4, 0x31, 0xd4, 0x7a, 130*7c478bd9Sstevel@tonic-gate 0x8c, 0x0e, 0x20, 0xd2, 0x23, 0xf5, 0x57, 0x3c, 131*7c478bd9Sstevel@tonic-gate 0x1b, 0xa8, 0x44, 0xa4, 0x57, 0x8f, 0x33, 0x52, 132*7c478bd9Sstevel@tonic-gate 0xad, 0x83, 0xae, 0x4a, 0x97, 0xa6, 0x1e, 0xa6, 133*7c478bd9Sstevel@tonic-gate 0x2b, 0xfa, 0xea, 0xeb, 0x6e, 0x71, 0xb8, 0xb6, 134*7c478bd9Sstevel@tonic-gate 0x0a, 0x36, 0xed, 0x83, 0xce, 0xb0, 0xdf, 0xc1, 135*7c478bd9Sstevel@tonic-gate 0xd4, 0x3a, 0xe9, 0x99, 0x6f, 0xf3, 0x96, 0xb7}; 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate static CK_RV 138*7c478bd9Sstevel@tonic-gate meta_clone_template_setup(meta_object_t *object, 139*7c478bd9Sstevel@tonic-gate const generic_attr_t *attributes, size_t num_attributes); 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate /* 142*7c478bd9Sstevel@tonic-gate * meta_objectManager_initialize 143*7c478bd9Sstevel@tonic-gate * 144*7c478bd9Sstevel@tonic-gate * Called from meta_Initialize. Initializes all the variables used 145*7c478bd9Sstevel@tonic-gate * by the object manager. 146*7c478bd9Sstevel@tonic-gate */ 147*7c478bd9Sstevel@tonic-gate CK_RV 148*7c478bd9Sstevel@tonic-gate meta_objectManager_initialize() 149*7c478bd9Sstevel@tonic-gate { 150*7c478bd9Sstevel@tonic-gate if (pthread_rwlock_init(&meta_objectclose_lock, NULL) != 0) { 151*7c478bd9Sstevel@tonic-gate return (CKR_FUNCTION_FAILED); 152*7c478bd9Sstevel@tonic-gate } 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate if (pthread_rwlock_init(&tokenobject_list_lock, NULL) != 0) { 155*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_destroy(&meta_objectclose_lock); 156*7c478bd9Sstevel@tonic-gate return (CKR_FUNCTION_FAILED); 157*7c478bd9Sstevel@tonic-gate } 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate tokenobject_list_head = NULL; 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate return (CKR_OK); 162*7c478bd9Sstevel@tonic-gate } 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate void 165*7c478bd9Sstevel@tonic-gate meta_objectManager_finalize() 166*7c478bd9Sstevel@tonic-gate { 167*7c478bd9Sstevel@tonic-gate /* 168*7c478bd9Sstevel@tonic-gate * If there are still any token object in the list, need to 169*7c478bd9Sstevel@tonic-gate * deactivate all of them. 170*7c478bd9Sstevel@tonic-gate */ 171*7c478bd9Sstevel@tonic-gate (void) meta_token_object_deactivate(ALL_TOKEN); 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_destroy(&meta_objectclose_lock); 174*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_destroy(&tokenobject_list_lock); 175*7c478bd9Sstevel@tonic-gate } 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate /* 180*7c478bd9Sstevel@tonic-gate * meta_handle2object 181*7c478bd9Sstevel@tonic-gate * 182*7c478bd9Sstevel@tonic-gate * Convert a CK_OBJECT_HANDLE to the corresponding metaobject. If 183*7c478bd9Sstevel@tonic-gate * successful, a reader-lock on the object will be held to indicate 184*7c478bd9Sstevel@tonic-gate * that it's in use. Call OBJRELEASE() when finished. 185*7c478bd9Sstevel@tonic-gate * 186*7c478bd9Sstevel@tonic-gate */ 187*7c478bd9Sstevel@tonic-gate CK_RV 188*7c478bd9Sstevel@tonic-gate meta_handle2object(CK_OBJECT_HANDLE hObject, meta_object_t **object) 189*7c478bd9Sstevel@tonic-gate { 190*7c478bd9Sstevel@tonic-gate meta_object_t *tmp_object = (meta_object_t *)(hObject); 191*7c478bd9Sstevel@tonic-gate 192*7c478bd9Sstevel@tonic-gate /* Check for bad args (eg CK_INVALID_HANDLE, which is 0/NULL). */ 193*7c478bd9Sstevel@tonic-gate if (tmp_object == NULL) { 194*7c478bd9Sstevel@tonic-gate *object = NULL; 195*7c478bd9Sstevel@tonic-gate return (CKR_OBJECT_HANDLE_INVALID); 196*7c478bd9Sstevel@tonic-gate } 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate /* Lock to ensure the magic-check + read-lock is atomic. */ 200*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_rdlock(&meta_objectclose_lock); 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate if (tmp_object->magic_marker != METASLOT_OBJECT_MAGIC) { 203*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&meta_objectclose_lock); 204*7c478bd9Sstevel@tonic-gate *object = NULL; 205*7c478bd9Sstevel@tonic-gate return (CKR_OBJECT_HANDLE_INVALID); 206*7c478bd9Sstevel@tonic-gate } 207*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_rdlock(&tmp_object->object_lock); 208*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&meta_objectclose_lock); 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate *object = tmp_object; 211*7c478bd9Sstevel@tonic-gate return (CKR_OK); 212*7c478bd9Sstevel@tonic-gate } 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate /* 216*7c478bd9Sstevel@tonic-gate * meta_object_alloc 217*7c478bd9Sstevel@tonic-gate * 218*7c478bd9Sstevel@tonic-gate * Creates a new metaobject, but does not yet add it to the object list. 219*7c478bd9Sstevel@tonic-gate * Once the caller has finished initializing the object (by setting 220*7c478bd9Sstevel@tonic-gate * object attributes), meta_object_add should be called. This two-step 221*7c478bd9Sstevel@tonic-gate * process prevents others from seeing the object until fully intitialized. 222*7c478bd9Sstevel@tonic-gate * 223*7c478bd9Sstevel@tonic-gate */ 224*7c478bd9Sstevel@tonic-gate CK_RV 225*7c478bd9Sstevel@tonic-gate meta_object_alloc(meta_session_t *session, meta_object_t **object) 226*7c478bd9Sstevel@tonic-gate { 227*7c478bd9Sstevel@tonic-gate meta_object_t *new_object; 228*7c478bd9Sstevel@tonic-gate CK_ULONG num_slots; 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate /* Allocate memory for the object. */ 231*7c478bd9Sstevel@tonic-gate new_object = calloc(1, sizeof (meta_object_t)); 232*7c478bd9Sstevel@tonic-gate if (new_object == NULL) 233*7c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate num_slots = meta_slotManager_get_slotcount(); 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate new_object->clones = calloc(num_slots, sizeof (slot_object_t *)); 238*7c478bd9Sstevel@tonic-gate if (new_object->clones == NULL) { 239*7c478bd9Sstevel@tonic-gate free(new_object); 240*7c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate new_object->tried_create_clone = calloc(num_slots, sizeof (boolean_t)); 244*7c478bd9Sstevel@tonic-gate if (new_object->tried_create_clone == NULL) { 245*7c478bd9Sstevel@tonic-gate free(new_object->clones); 246*7c478bd9Sstevel@tonic-gate free(new_object); 247*7c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate /* Initialize the object fields. */ 251*7c478bd9Sstevel@tonic-gate new_object->magic_marker = METASLOT_OBJECT_MAGIC; 252*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_init(&new_object->object_lock, NULL); 253*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_init(&new_object->attribute_lock, NULL); 254*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_init(&new_object->clone_create_lock, NULL); 255*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_init(&new_object->isClosingObject_lock, NULL); 256*7c478bd9Sstevel@tonic-gate new_object->creator_session = session; 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate *object = new_object; 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate return (CKR_OK); 261*7c478bd9Sstevel@tonic-gate } 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate /* 265*7c478bd9Sstevel@tonic-gate * meta_object_get_attr 266*7c478bd9Sstevel@tonic-gate * 267*7c478bd9Sstevel@tonic-gate * Get attribute values to fill in attribute values 268*7c478bd9Sstevel@tonic-gate * being kept in the metaslot object. The following 4 attributes 269*7c478bd9Sstevel@tonic-gate * in the meta_object_t structure will be filled in: 270*7c478bd9Sstevel@tonic-gate * isToken, isPrivate, isSensitive, isExtractable 271*7c478bd9Sstevel@tonic-gate * 272*7c478bd9Sstevel@tonic-gate * It's basically an easy way to do a C_GetAttributeValue. 273*7c478bd9Sstevel@tonic-gate * So, the hSession argument is assumed 274*7c478bd9Sstevel@tonic-gate * to be valid, and the pointer to meta_object_t is also assumed 275*7c478bd9Sstevel@tonic-gate * to be valid. 276*7c478bd9Sstevel@tonic-gate */ 277*7c478bd9Sstevel@tonic-gate CK_RV 278*7c478bd9Sstevel@tonic-gate meta_object_get_attr(slot_session_t *slot_session, CK_OBJECT_HANDLE hObject, 279*7c478bd9Sstevel@tonic-gate meta_object_t *object) 280*7c478bd9Sstevel@tonic-gate { 281*7c478bd9Sstevel@tonic-gate CK_BBOOL is_sensitive, is_extractable, is_token, is_private; 282*7c478bd9Sstevel@tonic-gate CK_OBJECT_CLASS class; 283*7c478bd9Sstevel@tonic-gate CK_ATTRIBUTE attrs[3]; 284*7c478bd9Sstevel@tonic-gate CK_RV rv; 285*7c478bd9Sstevel@tonic-gate CK_SESSION_HANDLE hSession = slot_session->hSession; 286*7c478bd9Sstevel@tonic-gate CK_SLOT_ID fw_st_id = slot_session->fw_st_id; 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate attrs[0].type = CKA_CLASS; 289*7c478bd9Sstevel@tonic-gate attrs[0].pValue = &class; 290*7c478bd9Sstevel@tonic-gate attrs[0].ulValueLen = sizeof (class); 291*7c478bd9Sstevel@tonic-gate 292*7c478bd9Sstevel@tonic-gate attrs[1].type = CKA_TOKEN; 293*7c478bd9Sstevel@tonic-gate attrs[1].pValue = &is_token; 294*7c478bd9Sstevel@tonic-gate attrs[1].ulValueLen = sizeof (is_token); 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate attrs[2].type = CKA_PRIVATE; 297*7c478bd9Sstevel@tonic-gate attrs[2].pValue = &is_private; 298*7c478bd9Sstevel@tonic-gate attrs[2].ulValueLen = sizeof (is_private); 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate rv = FUNCLIST(fw_st_id)->C_GetAttributeValue(hSession, hObject, 301*7c478bd9Sstevel@tonic-gate attrs, 3); 302*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 303*7c478bd9Sstevel@tonic-gate return (rv); 304*7c478bd9Sstevel@tonic-gate } 305*7c478bd9Sstevel@tonic-gate 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate if ((class == CKO_PRIVATE_KEY) || (class == CKO_SECRET_KEY)) { 308*7c478bd9Sstevel@tonic-gate /* 309*7c478bd9Sstevel@tonic-gate * CKA_SENSITIVE and CKA_EXTRACTABLE only applies to private 310*7c478bd9Sstevel@tonic-gate * and secret keys. 311*7c478bd9Sstevel@tonic-gate */ 312*7c478bd9Sstevel@tonic-gate attrs[0].type = CKA_SENSITIVE; 313*7c478bd9Sstevel@tonic-gate attrs[0].pValue = &is_sensitive; 314*7c478bd9Sstevel@tonic-gate attrs[0].ulValueLen = sizeof (is_sensitive); 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate attrs[1].type = CKA_EXTRACTABLE; 317*7c478bd9Sstevel@tonic-gate attrs[1].pValue = &is_extractable; 318*7c478bd9Sstevel@tonic-gate attrs[1].ulValueLen = sizeof (is_extractable); 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate rv = FUNCLIST(fw_st_id)->C_GetAttributeValue(hSession, 321*7c478bd9Sstevel@tonic-gate hObject, attrs, 2); 322*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 323*7c478bd9Sstevel@tonic-gate return (rv); 324*7c478bd9Sstevel@tonic-gate } 325*7c478bd9Sstevel@tonic-gate } else { 326*7c478bd9Sstevel@tonic-gate is_sensitive = CK_FALSE; 327*7c478bd9Sstevel@tonic-gate is_extractable = CK_TRUE; 328*7c478bd9Sstevel@tonic-gate } 329*7c478bd9Sstevel@tonic-gate 330*7c478bd9Sstevel@tonic-gate object->isToken = is_token; 331*7c478bd9Sstevel@tonic-gate object->isPrivate = is_private; 332*7c478bd9Sstevel@tonic-gate object->isSensitive = is_sensitive; 333*7c478bd9Sstevel@tonic-gate object->isExtractable = is_extractable; 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate return (CKR_OK); 336*7c478bd9Sstevel@tonic-gate } 337*7c478bd9Sstevel@tonic-gate 338*7c478bd9Sstevel@tonic-gate 339*7c478bd9Sstevel@tonic-gate /* 340*7c478bd9Sstevel@tonic-gate * meta_object_activate 341*7c478bd9Sstevel@tonic-gate * 342*7c478bd9Sstevel@tonic-gate * Add a new metaobject to the list of objects. See also meta_object_create, 343*7c478bd9Sstevel@tonic-gate * which would be called to create an object before it is added. 344*7c478bd9Sstevel@tonic-gate */ 345*7c478bd9Sstevel@tonic-gate void 346*7c478bd9Sstevel@tonic-gate meta_object_activate(meta_object_t *new_object) 347*7c478bd9Sstevel@tonic-gate { 348*7c478bd9Sstevel@tonic-gate pthread_rwlock_t *list_lock; 349*7c478bd9Sstevel@tonic-gate meta_object_t **list_head; 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate /* 352*7c478bd9Sstevel@tonic-gate * For session objects, we keep the list in the session that created 353*7c478bd9Sstevel@tonic-gate * this object, because this object will be destroyed when that session 354*7c478bd9Sstevel@tonic-gate * is closed. 355*7c478bd9Sstevel@tonic-gate * 356*7c478bd9Sstevel@tonic-gate * For token objects, the list is global (ie, not associated with any 357*7c478bd9Sstevel@tonic-gate * particular session). 358*7c478bd9Sstevel@tonic-gate */ 359*7c478bd9Sstevel@tonic-gate if (new_object->isToken) { 360*7c478bd9Sstevel@tonic-gate list_lock = &tokenobject_list_lock; 361*7c478bd9Sstevel@tonic-gate list_head = &tokenobject_list_head; 362*7c478bd9Sstevel@tonic-gate } else { 363*7c478bd9Sstevel@tonic-gate list_lock = &new_object->creator_session->object_list_lock; 364*7c478bd9Sstevel@tonic-gate list_head = &new_object->creator_session->object_list_head; 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate /* Add object to the list of objects. */ 368*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(list_lock); 369*7c478bd9Sstevel@tonic-gate INSERT_INTO_LIST(*list_head, new_object); 370*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(list_lock); 371*7c478bd9Sstevel@tonic-gate } 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate 374*7c478bd9Sstevel@tonic-gate /* 375*7c478bd9Sstevel@tonic-gate * meta_object_deactivate 376*7c478bd9Sstevel@tonic-gate * 377*7c478bd9Sstevel@tonic-gate * Removes the object from the list of valid meta objects. Note 378*7c478bd9Sstevel@tonic-gate * that this function does not clean up any allocated 379*7c478bd9Sstevel@tonic-gate * resources (memory, object clones, etc). Cleaning up of 380*7c478bd9Sstevel@tonic-gate * allocated resources is done by calling the meta_object_deallocate() 381*7c478bd9Sstevel@tonic-gate * 382*7c478bd9Sstevel@tonic-gate */ 383*7c478bd9Sstevel@tonic-gate CK_RV 384*7c478bd9Sstevel@tonic-gate meta_object_deactivate(meta_object_t *object, boolean_t have_list_lock, 385*7c478bd9Sstevel@tonic-gate boolean_t have_object_lock) 386*7c478bd9Sstevel@tonic-gate { 387*7c478bd9Sstevel@tonic-gate pthread_rwlock_t *list_lock; 388*7c478bd9Sstevel@tonic-gate meta_object_t **list_head; 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate if (!have_object_lock) { 391*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_rdlock(&object->object_lock); 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&object->isClosingObject_lock); 395*7c478bd9Sstevel@tonic-gate if (object->isClosingObject) { 396*7c478bd9Sstevel@tonic-gate /* Lost a delete race. */ 397*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object->isClosingObject_lock); 398*7c478bd9Sstevel@tonic-gate OBJRELEASE(object); 399*7c478bd9Sstevel@tonic-gate return (CKR_OBJECT_HANDLE_INVALID); 400*7c478bd9Sstevel@tonic-gate } 401*7c478bd9Sstevel@tonic-gate object->isClosingObject = B_TRUE; 402*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object->isClosingObject_lock); 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate if (object->isToken) { 405*7c478bd9Sstevel@tonic-gate list_lock = &tokenobject_list_lock; 406*7c478bd9Sstevel@tonic-gate list_head = &tokenobject_list_head; 407*7c478bd9Sstevel@tonic-gate } else { 408*7c478bd9Sstevel@tonic-gate list_lock = &object->creator_session->object_list_lock; 409*7c478bd9Sstevel@tonic-gate list_head = &object->creator_session->object_list_head; 410*7c478bd9Sstevel@tonic-gate } 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate /* 413*7c478bd9Sstevel@tonic-gate * Remove object from the object list. Once removed, it will not 414*7c478bd9Sstevel@tonic-gate * be possible for another thread to begin using the object. 415*7c478bd9Sstevel@tonic-gate */ 416*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(&meta_objectclose_lock); 417*7c478bd9Sstevel@tonic-gate if (!have_list_lock) { 418*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(list_lock); 419*7c478bd9Sstevel@tonic-gate } 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate object->magic_marker = METASLOT_OBJECT_BADMAGIC; 423*7c478bd9Sstevel@tonic-gate /* 424*7c478bd9Sstevel@tonic-gate * Can't use the regular REMOVE_FROM_LIST() function because 425*7c478bd9Sstevel@tonic-gate * that will miss the "error cleanup" situation where object is not yet 426*7c478bd9Sstevel@tonic-gate * in the list (object->next == NULL && object->prev == NULL) 427*7c478bd9Sstevel@tonic-gate */ 428*7c478bd9Sstevel@tonic-gate if (*list_head == object) { 429*7c478bd9Sstevel@tonic-gate /* Object is the first one in the list */ 430*7c478bd9Sstevel@tonic-gate if (object->next) { 431*7c478bd9Sstevel@tonic-gate *list_head = object->next; 432*7c478bd9Sstevel@tonic-gate object->next->prev = NULL; 433*7c478bd9Sstevel@tonic-gate } else { 434*7c478bd9Sstevel@tonic-gate /* Object is the only one in the list */ 435*7c478bd9Sstevel@tonic-gate *list_head = NULL; 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate } else if (object->next != NULL || object->prev != NULL) { 438*7c478bd9Sstevel@tonic-gate if (object->next) { 439*7c478bd9Sstevel@tonic-gate object->prev->next = object->next; 440*7c478bd9Sstevel@tonic-gate object->next->prev = object->prev; 441*7c478bd9Sstevel@tonic-gate } else { 442*7c478bd9Sstevel@tonic-gate /* Object is the last one in the list */ 443*7c478bd9Sstevel@tonic-gate object->prev->next = NULL; 444*7c478bd9Sstevel@tonic-gate } 445*7c478bd9Sstevel@tonic-gate } 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate if (!have_list_lock) { 448*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(list_lock); 449*7c478bd9Sstevel@tonic-gate } 450*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&meta_objectclose_lock); 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate /* 453*7c478bd9Sstevel@tonic-gate * Wait for anyone already using object to finish, by obtaining 454*7c478bd9Sstevel@tonic-gate * a writer-lock (need to release our reader-lock first). Once we 455*7c478bd9Sstevel@tonic-gate * get the write lock, we can just release it and finish cleaning 456*7c478bd9Sstevel@tonic-gate * up the object. 457*7c478bd9Sstevel@tonic-gate */ 458*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&object->object_lock); /* rdlock */ 459*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(&object->object_lock); 460*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&object->object_lock); /* wrlock */ 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate 463*7c478bd9Sstevel@tonic-gate return (CKR_OK); 464*7c478bd9Sstevel@tonic-gate } 465*7c478bd9Sstevel@tonic-gate 466*7c478bd9Sstevel@tonic-gate 467*7c478bd9Sstevel@tonic-gate /* 468*7c478bd9Sstevel@tonic-gate * meta_object_dealloc 469*7c478bd9Sstevel@tonic-gate * 470*7c478bd9Sstevel@tonic-gate * Performs final object cleanup, releasing any allocated memory and 471*7c478bd9Sstevel@tonic-gate * destroying any clones on other slots. Caller is assumed to have 472*7c478bd9Sstevel@tonic-gate * called meta_object_deactivate() before this function. 473*7c478bd9Sstevel@tonic-gate * 474*7c478bd9Sstevel@tonic-gate * Caller is assumed to have only reference to object, but should have 475*7c478bd9Sstevel@tonic-gate * released any lock. 476*7c478bd9Sstevel@tonic-gate * 477*7c478bd9Sstevel@tonic-gate * If "nukeSourceObj" argument is true, we will actually delete the 478*7c478bd9Sstevel@tonic-gate * object from the underlying slot. 479*7c478bd9Sstevel@tonic-gate */ 480*7c478bd9Sstevel@tonic-gate CK_RV 481*7c478bd9Sstevel@tonic-gate meta_object_dealloc(meta_object_t *object, boolean_t nukeSourceObj) 482*7c478bd9Sstevel@tonic-gate { 483*7c478bd9Sstevel@tonic-gate CK_RV rv, save_rv = CKR_OK; 484*7c478bd9Sstevel@tonic-gate CK_ULONG slotnum, num_slots; 485*7c478bd9Sstevel@tonic-gate CK_ULONG i; 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate /* First, delete all the clones of this object on other slots. */ 488*7c478bd9Sstevel@tonic-gate num_slots = meta_slotManager_get_slotcount(); 489*7c478bd9Sstevel@tonic-gate for (slotnum = 0; slotnum < num_slots; slotnum++) { 490*7c478bd9Sstevel@tonic-gate slot_session_t *obj_session; 491*7c478bd9Sstevel@tonic-gate slot_object_t *clone; 492*7c478bd9Sstevel@tonic-gate 493*7c478bd9Sstevel@tonic-gate clone = object->clones[slotnum]; 494*7c478bd9Sstevel@tonic-gate if (clone == NULL) 495*7c478bd9Sstevel@tonic-gate continue; 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate if (nukeSourceObj || !object->isToken) { 498*7c478bd9Sstevel@tonic-gate 499*7c478bd9Sstevel@tonic-gate rv = meta_get_slot_session(slotnum, &obj_session, 500*7c478bd9Sstevel@tonic-gate object->creator_session->session_flags); 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate if (rv == CKR_OK) { 503*7c478bd9Sstevel@tonic-gate rv = FUNCLIST(obj_session->fw_st_id)->\ 504*7c478bd9Sstevel@tonic-gate C_DestroyObject(obj_session->hSession, 505*7c478bd9Sstevel@tonic-gate clone->hObject); 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate meta_release_slot_session(obj_session); 508*7c478bd9Sstevel@tonic-gate if ((rv != CKR_OK) && (save_rv == CKR_OK)) { 509*7c478bd9Sstevel@tonic-gate save_rv = rv; 510*7c478bd9Sstevel@tonic-gate } 511*7c478bd9Sstevel@tonic-gate } 512*7c478bd9Sstevel@tonic-gate 513*7c478bd9Sstevel@tonic-gate } 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate meta_slot_object_deactivate(clone); 516*7c478bd9Sstevel@tonic-gate meta_slot_object_dealloc(clone); 517*7c478bd9Sstevel@tonic-gate 518*7c478bd9Sstevel@tonic-gate object->clones[slotnum] = NULL; 519*7c478bd9Sstevel@tonic-gate } 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate /* Now erase and delete any attributes in the metaobject. */ 522*7c478bd9Sstevel@tonic-gate dealloc_attributes(object->attributes, object->num_attributes); 523*7c478bd9Sstevel@tonic-gate 524*7c478bd9Sstevel@tonic-gate free(object->clones); 525*7c478bd9Sstevel@tonic-gate free(object->tried_create_clone); 526*7c478bd9Sstevel@tonic-gate 527*7c478bd9Sstevel@tonic-gate if (object->clone_template) { 528*7c478bd9Sstevel@tonic-gate for (i = 0; i < object->clone_template_size; i++) { 529*7c478bd9Sstevel@tonic-gate free(((object->clone_template)[i]).pValue); 530*7c478bd9Sstevel@tonic-gate } 531*7c478bd9Sstevel@tonic-gate free(object->clone_template); 532*7c478bd9Sstevel@tonic-gate } 533*7c478bd9Sstevel@tonic-gate 534*7c478bd9Sstevel@tonic-gate /* Cleanup remaining object fields. */ 535*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_destroy(&object->object_lock); 536*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_destroy(&object->attribute_lock); 537*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_destroy(&object->isClosingObject_lock); 538*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_destroy(&object->clone_create_lock); 539*7c478bd9Sstevel@tonic-gate 540*7c478bd9Sstevel@tonic-gate meta_object_delay_free(object); 541*7c478bd9Sstevel@tonic-gate 542*7c478bd9Sstevel@tonic-gate return (save_rv); 543*7c478bd9Sstevel@tonic-gate } 544*7c478bd9Sstevel@tonic-gate 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate /* 547*7c478bd9Sstevel@tonic-gate * meta_slot_object_alloc 548*7c478bd9Sstevel@tonic-gate */ 549*7c478bd9Sstevel@tonic-gate CK_RV 550*7c478bd9Sstevel@tonic-gate meta_slot_object_alloc(slot_object_t **object) { 551*7c478bd9Sstevel@tonic-gate slot_object_t *new_object; 552*7c478bd9Sstevel@tonic-gate 553*7c478bd9Sstevel@tonic-gate new_object = calloc(1, sizeof (slot_object_t)); 554*7c478bd9Sstevel@tonic-gate if (new_object == NULL) 555*7c478bd9Sstevel@tonic-gate return (CKR_HOST_MEMORY); 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate *object = new_object; 558*7c478bd9Sstevel@tonic-gate return (CKR_OK); 559*7c478bd9Sstevel@tonic-gate } 560*7c478bd9Sstevel@tonic-gate 561*7c478bd9Sstevel@tonic-gate 562*7c478bd9Sstevel@tonic-gate /* 563*7c478bd9Sstevel@tonic-gate * meta_slot_object_activate 564*7c478bd9Sstevel@tonic-gate */ 565*7c478bd9Sstevel@tonic-gate void 566*7c478bd9Sstevel@tonic-gate meta_slot_object_activate(slot_object_t *object, 567*7c478bd9Sstevel@tonic-gate slot_session_t *creator_session, boolean_t isToken) 568*7c478bd9Sstevel@tonic-gate { 569*7c478bd9Sstevel@tonic-gate object->creator_session = creator_session; 570*7c478bd9Sstevel@tonic-gate 571*7c478bd9Sstevel@tonic-gate if (isToken) { 572*7c478bd9Sstevel@tonic-gate extern slot_data_t *slots; 573*7c478bd9Sstevel@tonic-gate slot_data_t *slot; 574*7c478bd9Sstevel@tonic-gate 575*7c478bd9Sstevel@tonic-gate slot = &(slots[object->creator_session->slotnum]); 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(&slot->tokenobject_list_lock); 578*7c478bd9Sstevel@tonic-gate INSERT_INTO_LIST(slot->tokenobject_list_head, object); 579*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&slot->tokenobject_list_lock); 580*7c478bd9Sstevel@tonic-gate } else { 581*7c478bd9Sstevel@tonic-gate slot_session_t *session = object->creator_session; 582*7c478bd9Sstevel@tonic-gate 583*7c478bd9Sstevel@tonic-gate /* Add to session's list of session objects. */ 584*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(&session->object_list_lock); 585*7c478bd9Sstevel@tonic-gate INSERT_INTO_LIST(session->object_list_head, object); 586*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&session->object_list_lock); 587*7c478bd9Sstevel@tonic-gate } 588*7c478bd9Sstevel@tonic-gate object->isToken = isToken; 589*7c478bd9Sstevel@tonic-gate } 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate /* 593*7c478bd9Sstevel@tonic-gate * meta_slot_object_deactivate 594*7c478bd9Sstevel@tonic-gate * 595*7c478bd9Sstevel@tonic-gate * Remove the specified slot object from the appropriate object list. 596*7c478bd9Sstevel@tonic-gate */ 597*7c478bd9Sstevel@tonic-gate void 598*7c478bd9Sstevel@tonic-gate meta_slot_object_deactivate(slot_object_t *object) 599*7c478bd9Sstevel@tonic-gate { 600*7c478bd9Sstevel@tonic-gate slot_object_t **list_head; 601*7c478bd9Sstevel@tonic-gate pthread_rwlock_t *list_lock; 602*7c478bd9Sstevel@tonic-gate 603*7c478bd9Sstevel@tonic-gate if (object->isToken) { 604*7c478bd9Sstevel@tonic-gate extern slot_data_t *slots; 605*7c478bd9Sstevel@tonic-gate slot_data_t *slot; 606*7c478bd9Sstevel@tonic-gate 607*7c478bd9Sstevel@tonic-gate slot = &(slots[object->creator_session->slotnum]); 608*7c478bd9Sstevel@tonic-gate 609*7c478bd9Sstevel@tonic-gate list_head = &slot->tokenobject_list_head; 610*7c478bd9Sstevel@tonic-gate list_lock = &slot->tokenobject_list_lock; 611*7c478bd9Sstevel@tonic-gate } else { 612*7c478bd9Sstevel@tonic-gate list_head = &object->creator_session->object_list_head; 613*7c478bd9Sstevel@tonic-gate list_lock = &object->creator_session->object_list_lock; 614*7c478bd9Sstevel@tonic-gate } 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(list_lock); 617*7c478bd9Sstevel@tonic-gate REMOVE_FROM_LIST(*list_head, object); 618*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(list_lock); 619*7c478bd9Sstevel@tonic-gate } 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate 622*7c478bd9Sstevel@tonic-gate /* 623*7c478bd9Sstevel@tonic-gate * meta_slot_object_dealloc 624*7c478bd9Sstevel@tonic-gate */ 625*7c478bd9Sstevel@tonic-gate void 626*7c478bd9Sstevel@tonic-gate meta_slot_object_dealloc(slot_object_t *object) 627*7c478bd9Sstevel@tonic-gate { 628*7c478bd9Sstevel@tonic-gate /* Not much cleanup for slot objects, unlike meta objects... */ 629*7c478bd9Sstevel@tonic-gate free(object); 630*7c478bd9Sstevel@tonic-gate } 631*7c478bd9Sstevel@tonic-gate 632*7c478bd9Sstevel@tonic-gate 633*7c478bd9Sstevel@tonic-gate /* 634*7c478bd9Sstevel@tonic-gate * meta_object_copyin 635*7c478bd9Sstevel@tonic-gate * 636*7c478bd9Sstevel@tonic-gate * When a key is generated/derived/unwrapped, the attribute values 637*7c478bd9Sstevel@tonic-gate * created by the token are not immediately read into our copy of the 638*7c478bd9Sstevel@tonic-gate * attributes. We defer this work until we actually need to know. 639*7c478bd9Sstevel@tonic-gate */ 640*7c478bd9Sstevel@tonic-gate CK_RV 641*7c478bd9Sstevel@tonic-gate meta_object_copyin(meta_object_t *object) 642*7c478bd9Sstevel@tonic-gate { 643*7c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 644*7c478bd9Sstevel@tonic-gate slot_session_t *session = NULL; 645*7c478bd9Sstevel@tonic-gate CK_ATTRIBUTE *attrs = NULL, *attrs_with_val = NULL; 646*7c478bd9Sstevel@tonic-gate slot_object_t *slot_object = NULL; 647*7c478bd9Sstevel@tonic-gate CK_ULONG num_attrs = 0, i, num_attrs_with_val; 648*7c478bd9Sstevel@tonic-gate CK_SESSION_HANDLE hSession; 649*7c478bd9Sstevel@tonic-gate CK_SLOT_ID fw_st_id; 650*7c478bd9Sstevel@tonic-gate 651*7c478bd9Sstevel@tonic-gate /* Make sure no one else is looking at attributes. */ 652*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(&object->attribute_lock); 653*7c478bd9Sstevel@tonic-gate 654*7c478bd9Sstevel@tonic-gate /* Did we just lose a copyin race with another thread */ 655*7c478bd9Sstevel@tonic-gate if (object->attributes != NULL) { 656*7c478bd9Sstevel@tonic-gate goto finish; 657*7c478bd9Sstevel@tonic-gate } 658*7c478bd9Sstevel@tonic-gate 659*7c478bd9Sstevel@tonic-gate slot_object = object->clones[object->master_clone_slotnum]; 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate rv = meta_get_slot_session(object->master_clone_slotnum, &session, 662*7c478bd9Sstevel@tonic-gate object->creator_session->session_flags); 663*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 664*7c478bd9Sstevel@tonic-gate goto finish; 665*7c478bd9Sstevel@tonic-gate } 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate /* 668*7c478bd9Sstevel@tonic-gate * first, get the master template of all the attributes 669*7c478bd9Sstevel@tonic-gate * for this object 670*7c478bd9Sstevel@tonic-gate */ 671*7c478bd9Sstevel@tonic-gate rv = get_master_attributes_by_object(session, slot_object, 672*7c478bd9Sstevel@tonic-gate &(object->attributes), &(object->num_attributes)); 673*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 674*7c478bd9Sstevel@tonic-gate goto finish; 675*7c478bd9Sstevel@tonic-gate } 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate /* 678*7c478bd9Sstevel@tonic-gate * Get value for each attribute items. 679*7c478bd9Sstevel@tonic-gate * 680*7c478bd9Sstevel@tonic-gate * Some attributes are required by the given object type. 681*7c478bd9Sstevel@tonic-gate * Some are optional. Get all the values first, and then 682*7c478bd9Sstevel@tonic-gate * make sure we have value for all required values, 683*7c478bd9Sstevel@tonic-gate */ 684*7c478bd9Sstevel@tonic-gate attrs = calloc(object->num_attributes, sizeof (CK_ATTRIBUTE)); 685*7c478bd9Sstevel@tonic-gate if (attrs == NULL) { 686*7c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 687*7c478bd9Sstevel@tonic-gate goto finish; 688*7c478bd9Sstevel@tonic-gate } 689*7c478bd9Sstevel@tonic-gate 690*7c478bd9Sstevel@tonic-gate 691*7c478bd9Sstevel@tonic-gate for (i = 0; i < object->num_attributes; i++) { 692*7c478bd9Sstevel@tonic-gate attrs[i].type = 693*7c478bd9Sstevel@tonic-gate ((object->attributes[i]).attribute).type; 694*7c478bd9Sstevel@tonic-gate } 695*7c478bd9Sstevel@tonic-gate num_attrs = object->num_attributes; 696*7c478bd9Sstevel@tonic-gate 697*7c478bd9Sstevel@tonic-gate hSession = session->hSession; 698*7c478bd9Sstevel@tonic-gate fw_st_id = session->fw_st_id; 699*7c478bd9Sstevel@tonic-gate 700*7c478bd9Sstevel@tonic-gate /* first, call C_GetAttributeValue() to get size for each attribute */ 701*7c478bd9Sstevel@tonic-gate rv = FUNCLIST(fw_st_id)->C_GetAttributeValue(hSession, 702*7c478bd9Sstevel@tonic-gate slot_object->hObject, attrs, num_attrs); 703*7c478bd9Sstevel@tonic-gate /* 704*7c478bd9Sstevel@tonic-gate * If the return value is not CKR_OK, allow it to be 705*7c478bd9Sstevel@tonic-gate * CKR_ATTRIBUTE_TYPE_INVALID for now. 706*7c478bd9Sstevel@tonic-gate * Some attributes defined in PKCS#11 version 2.11 707*7c478bd9Sstevel@tonic-gate * might not be defined in earlier versions. We will 708*7c478bd9Sstevel@tonic-gate * TRY to work with those providers if the attribute 709*7c478bd9Sstevel@tonic-gate * is optional. 710*7c478bd9Sstevel@tonic-gate */ 711*7c478bd9Sstevel@tonic-gate if ((rv != CKR_OK) && (rv != CKR_ATTRIBUTE_TYPE_INVALID)) { 712*7c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; /* make sure rv is appropriate */ 713*7c478bd9Sstevel@tonic-gate goto finish; 714*7c478bd9Sstevel@tonic-gate } 715*7c478bd9Sstevel@tonic-gate 716*7c478bd9Sstevel@tonic-gate /* 717*7c478bd9Sstevel@tonic-gate * allocate space. 718*7c478bd9Sstevel@tonic-gate * Since we don't know how many attributes have 719*7c478bd9Sstevel@tonic-gate * values at this time, just assume all of them 720*7c478bd9Sstevel@tonic-gate * have values so we save one loop to count the number 721*7c478bd9Sstevel@tonic-gate * of attributes that have value. 722*7c478bd9Sstevel@tonic-gate */ 723*7c478bd9Sstevel@tonic-gate attrs_with_val = calloc(num_attrs, sizeof (CK_ATTRIBUTE)); 724*7c478bd9Sstevel@tonic-gate if (attrs_with_val == NULL) { 725*7c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 726*7c478bd9Sstevel@tonic-gate goto finish; 727*7c478bd9Sstevel@tonic-gate } 728*7c478bd9Sstevel@tonic-gate 729*7c478bd9Sstevel@tonic-gate 730*7c478bd9Sstevel@tonic-gate num_attrs_with_val = 0; 731*7c478bd9Sstevel@tonic-gate for (i = 0; i < num_attrs; i++) { 732*7c478bd9Sstevel@tonic-gate if (!(((CK_LONG)(attrs[i].ulValueLen)) > 0)) { 733*7c478bd9Sstevel@tonic-gate /* if it isn't an optional attr, len should be > 0 */ 734*7c478bd9Sstevel@tonic-gate if (!object->attributes[i].canBeEmptyValue) { 735*7c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 736*7c478bd9Sstevel@tonic-gate goto finish; 737*7c478bd9Sstevel@tonic-gate } 738*7c478bd9Sstevel@tonic-gate } else { 739*7c478bd9Sstevel@tonic-gate attrs_with_val[num_attrs_with_val].type = attrs[i].type; 740*7c478bd9Sstevel@tonic-gate attrs_with_val[num_attrs_with_val].ulValueLen = 741*7c478bd9Sstevel@tonic-gate attrs[i].ulValueLen; 742*7c478bd9Sstevel@tonic-gate attrs_with_val[num_attrs_with_val].pValue = 743*7c478bd9Sstevel@tonic-gate malloc(attrs[i].ulValueLen); 744*7c478bd9Sstevel@tonic-gate if (attrs_with_val[num_attrs_with_val].pValue == NULL) { 745*7c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 746*7c478bd9Sstevel@tonic-gate goto finish; 747*7c478bd9Sstevel@tonic-gate } 748*7c478bd9Sstevel@tonic-gate num_attrs_with_val++; 749*7c478bd9Sstevel@tonic-gate } 750*7c478bd9Sstevel@tonic-gate } 751*7c478bd9Sstevel@tonic-gate 752*7c478bd9Sstevel@tonic-gate rv = FUNCLIST(fw_st_id)->C_GetAttributeValue(hSession, 753*7c478bd9Sstevel@tonic-gate slot_object->hObject, attrs_with_val, num_attrs_with_val); 754*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 755*7c478bd9Sstevel@tonic-gate goto finish; 756*7c478bd9Sstevel@tonic-gate } 757*7c478bd9Sstevel@tonic-gate 758*7c478bd9Sstevel@tonic-gate /* store these values into the meta object */ 759*7c478bd9Sstevel@tonic-gate for (i = 0; i < num_attrs_with_val; i++) { 760*7c478bd9Sstevel@tonic-gate rv = attribute_set_value(&(attrs_with_val[i]), 761*7c478bd9Sstevel@tonic-gate object->attributes, object->num_attributes); 762*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 763*7c478bd9Sstevel@tonic-gate goto finish; 764*7c478bd9Sstevel@tonic-gate } 765*7c478bd9Sstevel@tonic-gate } 766*7c478bd9Sstevel@tonic-gate 767*7c478bd9Sstevel@tonic-gate finish: 768*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&object->attribute_lock); 769*7c478bd9Sstevel@tonic-gate 770*7c478bd9Sstevel@tonic-gate if (session) 771*7c478bd9Sstevel@tonic-gate meta_release_slot_session(session); 772*7c478bd9Sstevel@tonic-gate 773*7c478bd9Sstevel@tonic-gate if (attrs) { 774*7c478bd9Sstevel@tonic-gate for (i = 0; i < num_attrs; i++) { 775*7c478bd9Sstevel@tonic-gate if (attrs[i].pValue != NULL) { 776*7c478bd9Sstevel@tonic-gate free(attrs[i].pValue); 777*7c478bd9Sstevel@tonic-gate } 778*7c478bd9Sstevel@tonic-gate } 779*7c478bd9Sstevel@tonic-gate free(attrs); 780*7c478bd9Sstevel@tonic-gate } 781*7c478bd9Sstevel@tonic-gate 782*7c478bd9Sstevel@tonic-gate if (attrs_with_val) { 783*7c478bd9Sstevel@tonic-gate for (i = 0; i < num_attrs; i++) { 784*7c478bd9Sstevel@tonic-gate if (attrs_with_val[i].pValue != NULL) { 785*7c478bd9Sstevel@tonic-gate free(attrs_with_val[i].pValue); 786*7c478bd9Sstevel@tonic-gate } 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate free(attrs_with_val); 789*7c478bd9Sstevel@tonic-gate } 790*7c478bd9Sstevel@tonic-gate return (rv); 791*7c478bd9Sstevel@tonic-gate } 792*7c478bd9Sstevel@tonic-gate 793*7c478bd9Sstevel@tonic-gate /* 794*7c478bd9Sstevel@tonic-gate * Create an object to be used for wrapping and unwrapping. 795*7c478bd9Sstevel@tonic-gate * The same template will be used for all wrapping/unwrapping keys all 796*7c478bd9Sstevel@tonic-gate * the time 797*7c478bd9Sstevel@tonic-gate */ 798*7c478bd9Sstevel@tonic-gate 799*7c478bd9Sstevel@tonic-gate static CK_RV 800*7c478bd9Sstevel@tonic-gate create_wrap_unwrap_key(slot_session_t *slot_session, CK_OBJECT_HANDLE *hObject, 801*7c478bd9Sstevel@tonic-gate wrap_info_t *wrap_info, char *key_data, CK_ULONG key_len) 802*7c478bd9Sstevel@tonic-gate { 803*7c478bd9Sstevel@tonic-gate 804*7c478bd9Sstevel@tonic-gate CK_OBJECT_CLASS objclass; 805*7c478bd9Sstevel@tonic-gate CK_KEY_TYPE keytype; 806*7c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 807*7c478bd9Sstevel@tonic-gate int i; 808*7c478bd9Sstevel@tonic-gate CK_ATTRIBUTE template[WRAP_KEY_TEMPLATE_SIZE]; 809*7c478bd9Sstevel@tonic-gate 810*7c478bd9Sstevel@tonic-gate i = 0; 811*7c478bd9Sstevel@tonic-gate objclass = wrap_info->class; 812*7c478bd9Sstevel@tonic-gate template[i].type = CKA_CLASS; 813*7c478bd9Sstevel@tonic-gate template[i].pValue = &objclass; 814*7c478bd9Sstevel@tonic-gate template[i].ulValueLen = sizeof (objclass); 815*7c478bd9Sstevel@tonic-gate 816*7c478bd9Sstevel@tonic-gate i++; 817*7c478bd9Sstevel@tonic-gate keytype = wrap_info->key_type; 818*7c478bd9Sstevel@tonic-gate template[i].type = CKA_KEY_TYPE; 819*7c478bd9Sstevel@tonic-gate template[i].pValue = &keytype; 820*7c478bd9Sstevel@tonic-gate template[i].ulValueLen = sizeof (keytype); 821*7c478bd9Sstevel@tonic-gate 822*7c478bd9Sstevel@tonic-gate i++; 823*7c478bd9Sstevel@tonic-gate template[i].type = CKA_TOKEN; 824*7c478bd9Sstevel@tonic-gate template[i].pValue = &falsevalue; 825*7c478bd9Sstevel@tonic-gate template[i].ulValueLen = sizeof (falsevalue); 826*7c478bd9Sstevel@tonic-gate 827*7c478bd9Sstevel@tonic-gate 828*7c478bd9Sstevel@tonic-gate if (objclass == CKO_SECRET_KEY) { 829*7c478bd9Sstevel@tonic-gate i++; 830*7c478bd9Sstevel@tonic-gate template[i].type = CKA_VALUE; 831*7c478bd9Sstevel@tonic-gate template[i].pValue = key_data; 832*7c478bd9Sstevel@tonic-gate template[i].ulValueLen = key_len; 833*7c478bd9Sstevel@tonic-gate 834*7c478bd9Sstevel@tonic-gate i++; 835*7c478bd9Sstevel@tonic-gate template[i].type = CKA_WRAP; 836*7c478bd9Sstevel@tonic-gate template[i].pValue = &truevalue; 837*7c478bd9Sstevel@tonic-gate template[i].ulValueLen = sizeof (truevalue); 838*7c478bd9Sstevel@tonic-gate 839*7c478bd9Sstevel@tonic-gate i++; 840*7c478bd9Sstevel@tonic-gate template[i].type = CKA_UNWRAP; 841*7c478bd9Sstevel@tonic-gate template[i].pValue = &truevalue; 842*7c478bd9Sstevel@tonic-gate template[i].ulValueLen = sizeof (truevalue); 843*7c478bd9Sstevel@tonic-gate } else { 844*7c478bd9Sstevel@tonic-gate /* Modulus is the same for rsa public and private key */ 845*7c478bd9Sstevel@tonic-gate i++; 846*7c478bd9Sstevel@tonic-gate template[i].type = CKA_MODULUS; 847*7c478bd9Sstevel@tonic-gate template[i].pValue = Modulus; 848*7c478bd9Sstevel@tonic-gate template[i].ulValueLen = sizeof (Modulus); 849*7c478bd9Sstevel@tonic-gate 850*7c478bd9Sstevel@tonic-gate if (objclass == CKO_PUBLIC_KEY) { 851*7c478bd9Sstevel@tonic-gate /* RSA public key */ 852*7c478bd9Sstevel@tonic-gate i++; 853*7c478bd9Sstevel@tonic-gate template[i].type = CKA_PUBLIC_EXPONENT; 854*7c478bd9Sstevel@tonic-gate template[i].pValue = PubExpo; 855*7c478bd9Sstevel@tonic-gate template[i].ulValueLen = sizeof (PubExpo); 856*7c478bd9Sstevel@tonic-gate 857*7c478bd9Sstevel@tonic-gate i++; 858*7c478bd9Sstevel@tonic-gate template[i].type = CKA_WRAP; 859*7c478bd9Sstevel@tonic-gate template[i].pValue = &truevalue; 860*7c478bd9Sstevel@tonic-gate template[i].ulValueLen = sizeof (truevalue); 861*7c478bd9Sstevel@tonic-gate } else { 862*7c478bd9Sstevel@tonic-gate /* RSA private key */ 863*7c478bd9Sstevel@tonic-gate i++; 864*7c478bd9Sstevel@tonic-gate template[i].type = CKA_PRIVATE_EXPONENT; 865*7c478bd9Sstevel@tonic-gate template[i].pValue = PriExpo; 866*7c478bd9Sstevel@tonic-gate template[i].ulValueLen = sizeof (PriExpo); 867*7c478bd9Sstevel@tonic-gate 868*7c478bd9Sstevel@tonic-gate i++; 869*7c478bd9Sstevel@tonic-gate template[i].type = CKA_UNWRAP; 870*7c478bd9Sstevel@tonic-gate template[i].pValue = &truevalue; 871*7c478bd9Sstevel@tonic-gate template[i].ulValueLen = sizeof (truevalue); 872*7c478bd9Sstevel@tonic-gate } 873*7c478bd9Sstevel@tonic-gate } 874*7c478bd9Sstevel@tonic-gate 875*7c478bd9Sstevel@tonic-gate rv = FUNCLIST(slot_session->fw_st_id)->C_CreateObject( 876*7c478bd9Sstevel@tonic-gate slot_session->hSession, template, i + 1, hObject); 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate return (rv); 879*7c478bd9Sstevel@tonic-gate } 880*7c478bd9Sstevel@tonic-gate 881*7c478bd9Sstevel@tonic-gate 882*7c478bd9Sstevel@tonic-gate /* 883*7c478bd9Sstevel@tonic-gate * Create a clone of a non-sensitive and extractable object. 884*7c478bd9Sstevel@tonic-gate * If the template required for creating the clone doesn't exist, 885*7c478bd9Sstevel@tonic-gate * it will be retrieved from the master clone. 886*7c478bd9Sstevel@tonic-gate */ 887*7c478bd9Sstevel@tonic-gate static CK_RV 888*7c478bd9Sstevel@tonic-gate clone_by_create(meta_object_t *object, slot_object_t *new_clone, 889*7c478bd9Sstevel@tonic-gate slot_session_t *dst_slot_session) 890*7c478bd9Sstevel@tonic-gate { 891*7c478bd9Sstevel@tonic-gate 892*7c478bd9Sstevel@tonic-gate CK_RV rv; 893*7c478bd9Sstevel@tonic-gate 894*7c478bd9Sstevel@tonic-gate if (object->attributes == NULL) { 895*7c478bd9Sstevel@tonic-gate rv = meta_object_copyin(object); 896*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 897*7c478bd9Sstevel@tonic-gate return (rv); 898*7c478bd9Sstevel@tonic-gate } 899*7c478bd9Sstevel@tonic-gate } 900*7c478bd9Sstevel@tonic-gate 901*7c478bd9Sstevel@tonic-gate if (object->clone_template == NULL) { 902*7c478bd9Sstevel@tonic-gate rv = meta_clone_template_setup(object, object->attributes, 903*7c478bd9Sstevel@tonic-gate object->num_attributes); 904*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 905*7c478bd9Sstevel@tonic-gate return (rv); 906*7c478bd9Sstevel@tonic-gate } 907*7c478bd9Sstevel@tonic-gate } 908*7c478bd9Sstevel@tonic-gate 909*7c478bd9Sstevel@tonic-gate /* Create the clone... */ 910*7c478bd9Sstevel@tonic-gate rv = FUNCLIST(dst_slot_session->fw_st_id)->C_CreateObject( 911*7c478bd9Sstevel@tonic-gate dst_slot_session->hSession, object->clone_template, 912*7c478bd9Sstevel@tonic-gate object->clone_template_size, &(new_clone->hObject)); 913*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 914*7c478bd9Sstevel@tonic-gate return (rv); 915*7c478bd9Sstevel@tonic-gate } 916*7c478bd9Sstevel@tonic-gate 917*7c478bd9Sstevel@tonic-gate return (CKR_OK); 918*7c478bd9Sstevel@tonic-gate } 919*7c478bd9Sstevel@tonic-gate 920*7c478bd9Sstevel@tonic-gate /* 921*7c478bd9Sstevel@tonic-gate * Goes through the list of wraping mechanisms, and returns the first 922*7c478bd9Sstevel@tonic-gate * one that is supported by both the source and the destination slot. 923*7c478bd9Sstevel@tonic-gate * If none of the mechanisms are supported by both slot, return the 924*7c478bd9Sstevel@tonic-gate * first mechanism that's supported by the source slot 925*7c478bd9Sstevel@tonic-gate */ 926*7c478bd9Sstevel@tonic-gate static CK_RV 927*7c478bd9Sstevel@tonic-gate find_best_match_wrap_mech(wrap_info_t *wrap_info, int num_info, 928*7c478bd9Sstevel@tonic-gate CK_ULONG src_slotnum, CK_ULONG dst_slotnum, int *first_both_mech, 929*7c478bd9Sstevel@tonic-gate int *first_src_mech) 930*7c478bd9Sstevel@tonic-gate { 931*7c478bd9Sstevel@tonic-gate 932*7c478bd9Sstevel@tonic-gate int i; 933*7c478bd9Sstevel@tonic-gate boolean_t src_supports, dst_supports; 934*7c478bd9Sstevel@tonic-gate CK_RV rv; 935*7c478bd9Sstevel@tonic-gate 936*7c478bd9Sstevel@tonic-gate for (i = 0; i < num_info; i++) { 937*7c478bd9Sstevel@tonic-gate src_supports = B_FALSE; 938*7c478bd9Sstevel@tonic-gate dst_supports = B_FALSE; 939*7c478bd9Sstevel@tonic-gate 940*7c478bd9Sstevel@tonic-gate rv = meta_mechManager_slot_supports_mech( 941*7c478bd9Sstevel@tonic-gate (wrap_info[i]).mech_type, src_slotnum, 942*7c478bd9Sstevel@tonic-gate &src_supports, NULL, B_FALSE); 943*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 944*7c478bd9Sstevel@tonic-gate return (rv); 945*7c478bd9Sstevel@tonic-gate } 946*7c478bd9Sstevel@tonic-gate 947*7c478bd9Sstevel@tonic-gate rv = meta_mechManager_slot_supports_mech( 948*7c478bd9Sstevel@tonic-gate (wrap_info[i]).mech_type, dst_slotnum, 949*7c478bd9Sstevel@tonic-gate &dst_supports, NULL, B_FALSE); 950*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 951*7c478bd9Sstevel@tonic-gate return (rv); 952*7c478bd9Sstevel@tonic-gate } 953*7c478bd9Sstevel@tonic-gate 954*7c478bd9Sstevel@tonic-gate /* both source and destination supports the mech */ 955*7c478bd9Sstevel@tonic-gate if ((src_supports) && (dst_supports)) { 956*7c478bd9Sstevel@tonic-gate *first_both_mech = i; 957*7c478bd9Sstevel@tonic-gate return (CKR_OK); 958*7c478bd9Sstevel@tonic-gate } 959*7c478bd9Sstevel@tonic-gate 960*7c478bd9Sstevel@tonic-gate if ((src_supports) && (*first_src_mech == -1)) { 961*7c478bd9Sstevel@tonic-gate *first_src_mech = i; 962*7c478bd9Sstevel@tonic-gate } 963*7c478bd9Sstevel@tonic-gate } 964*7c478bd9Sstevel@tonic-gate return (CKR_OK); 965*7c478bd9Sstevel@tonic-gate } 966*7c478bd9Sstevel@tonic-gate 967*7c478bd9Sstevel@tonic-gate /* 968*7c478bd9Sstevel@tonic-gate * Determine the wrapping/unwrapping mechanism to be used 969*7c478bd9Sstevel@tonic-gate * 970*7c478bd9Sstevel@tonic-gate * If possible, select a mechanism that's supported by both source 971*7c478bd9Sstevel@tonic-gate * and destination slot. If none of the mechanisms are supported 972*7c478bd9Sstevel@tonic-gate * by both slot, then, select the first one supported by 973*7c478bd9Sstevel@tonic-gate * the source slot. 974*7c478bd9Sstevel@tonic-gate */ 975*7c478bd9Sstevel@tonic-gate 976*7c478bd9Sstevel@tonic-gate static CK_RV 977*7c478bd9Sstevel@tonic-gate get_wrap_mechanism(CK_OBJECT_CLASS obj_class, CK_KEY_TYPE key_type, 978*7c478bd9Sstevel@tonic-gate CK_ULONG src_slotnum, CK_ULONG dst_slotnum, wrap_info_t *wrap_info) 979*7c478bd9Sstevel@tonic-gate { 980*7c478bd9Sstevel@tonic-gate wrap_info_t *wrap_info_to_search = NULL; 981*7c478bd9Sstevel@tonic-gate unsigned int num_wrap_info; 982*7c478bd9Sstevel@tonic-gate CK_RV rv; 983*7c478bd9Sstevel@tonic-gate int i; 984*7c478bd9Sstevel@tonic-gate boolean_t src_supports = B_FALSE, dst_supports = B_FALSE; 985*7c478bd9Sstevel@tonic-gate int first_src_mech, rsa_first_src_mech, first_both_mech; 986*7c478bd9Sstevel@tonic-gate 987*7c478bd9Sstevel@tonic-gate if ((obj_class == CKO_PRIVATE_KEY) && (key_type == CKK_KEA)) { 988*7c478bd9Sstevel@tonic-gate /* 989*7c478bd9Sstevel@tonic-gate * only SKIPJACK keys can be used for wrapping 990*7c478bd9Sstevel@tonic-gate * KEA private keys 991*7c478bd9Sstevel@tonic-gate */ 992*7c478bd9Sstevel@tonic-gate 993*7c478bd9Sstevel@tonic-gate for (i = 0; i < num_special_wrap_info; i++) { 994*7c478bd9Sstevel@tonic-gate if ((special_wrap_info[i]).mech_type 995*7c478bd9Sstevel@tonic-gate != CKM_SKIPJACK_WRAP) { 996*7c478bd9Sstevel@tonic-gate continue; 997*7c478bd9Sstevel@tonic-gate } 998*7c478bd9Sstevel@tonic-gate 999*7c478bd9Sstevel@tonic-gate src_supports = B_FALSE; 1000*7c478bd9Sstevel@tonic-gate dst_supports = B_FALSE; 1001*7c478bd9Sstevel@tonic-gate 1002*7c478bd9Sstevel@tonic-gate rv = meta_mechManager_slot_supports_mech( 1003*7c478bd9Sstevel@tonic-gate (special_wrap_info[i]).mech_type, src_slotnum, 1004*7c478bd9Sstevel@tonic-gate &src_supports, NULL, B_FALSE); 1005*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1006*7c478bd9Sstevel@tonic-gate goto finish; 1007*7c478bd9Sstevel@tonic-gate } 1008*7c478bd9Sstevel@tonic-gate 1009*7c478bd9Sstevel@tonic-gate rv = meta_mechManager_slot_supports_mech( 1010*7c478bd9Sstevel@tonic-gate (special_wrap_info[i]).mech_type, dst_slotnum, 1011*7c478bd9Sstevel@tonic-gate &dst_supports, NULL, B_FALSE); 1012*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1013*7c478bd9Sstevel@tonic-gate goto finish; 1014*7c478bd9Sstevel@tonic-gate } 1015*7c478bd9Sstevel@tonic-gate 1016*7c478bd9Sstevel@tonic-gate if (src_supports) { 1017*7c478bd9Sstevel@tonic-gate /* 1018*7c478bd9Sstevel@tonic-gate * both src and dst supports the mech or 1019*7c478bd9Sstevel@tonic-gate * only the src supports the mech 1020*7c478bd9Sstevel@tonic-gate */ 1021*7c478bd9Sstevel@tonic-gate (void) memcpy(wrap_info, 1022*7c478bd9Sstevel@tonic-gate &(special_wrap_info[i]), 1023*7c478bd9Sstevel@tonic-gate sizeof (wrap_info_t)); 1024*7c478bd9Sstevel@tonic-gate 1025*7c478bd9Sstevel@tonic-gate wrap_info->src_supports = src_supports; 1026*7c478bd9Sstevel@tonic-gate wrap_info->dst_supports = dst_supports; 1027*7c478bd9Sstevel@tonic-gate rv = CKR_OK; 1028*7c478bd9Sstevel@tonic-gate goto finish; 1029*7c478bd9Sstevel@tonic-gate } 1030*7c478bd9Sstevel@tonic-gate 1031*7c478bd9Sstevel@tonic-gate } 1032*7c478bd9Sstevel@tonic-gate 1033*7c478bd9Sstevel@tonic-gate /* 1034*7c478bd9Sstevel@tonic-gate * if we are here, that means neither the source slot 1035*7c478bd9Sstevel@tonic-gate * nor the destination slots suppports CKM_SKIPJACK_WRAP 1036*7c478bd9Sstevel@tonic-gate */ 1037*7c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 1038*7c478bd9Sstevel@tonic-gate goto finish; 1039*7c478bd9Sstevel@tonic-gate } 1040*7c478bd9Sstevel@tonic-gate 1041*7c478bd9Sstevel@tonic-gate if ((key_type == CKK_SKIPJACK) || (key_type == CKK_BATON) || 1042*7c478bd9Sstevel@tonic-gate (key_type == CKK_JUNIPER)) { 1043*7c478bd9Sstevel@tonic-gate /* special key types */ 1044*7c478bd9Sstevel@tonic-gate wrap_info_to_search = special_wrap_info; 1045*7c478bd9Sstevel@tonic-gate num_wrap_info = num_special_wrap_info; 1046*7c478bd9Sstevel@tonic-gate } else { 1047*7c478bd9Sstevel@tonic-gate /* use the regular wrapping mechanisms */ 1048*7c478bd9Sstevel@tonic-gate wrap_info_to_search = common_wrap_info; 1049*7c478bd9Sstevel@tonic-gate num_wrap_info = num_common_wrap_info; 1050*7c478bd9Sstevel@tonic-gate } 1051*7c478bd9Sstevel@tonic-gate 1052*7c478bd9Sstevel@tonic-gate first_both_mech = -1; 1053*7c478bd9Sstevel@tonic-gate first_src_mech = -1; 1054*7c478bd9Sstevel@tonic-gate 1055*7c478bd9Sstevel@tonic-gate rv = find_best_match_wrap_mech(wrap_info_to_search, num_wrap_info, 1056*7c478bd9Sstevel@tonic-gate src_slotnum, dst_slotnum, &first_both_mech, &first_src_mech); 1057*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1058*7c478bd9Sstevel@tonic-gate goto finish; 1059*7c478bd9Sstevel@tonic-gate } 1060*7c478bd9Sstevel@tonic-gate 1061*7c478bd9Sstevel@tonic-gate if (first_both_mech != -1) { 1062*7c478bd9Sstevel@tonic-gate (void) memcpy(wrap_info, 1063*7c478bd9Sstevel@tonic-gate &(wrap_info_to_search[first_both_mech]), 1064*7c478bd9Sstevel@tonic-gate sizeof (wrap_info_t)); 1065*7c478bd9Sstevel@tonic-gate 1066*7c478bd9Sstevel@tonic-gate wrap_info->src_supports = B_TRUE; 1067*7c478bd9Sstevel@tonic-gate wrap_info->dst_supports = B_TRUE; 1068*7c478bd9Sstevel@tonic-gate rv = CKR_OK; 1069*7c478bd9Sstevel@tonic-gate goto finish; 1070*7c478bd9Sstevel@tonic-gate } 1071*7c478bd9Sstevel@tonic-gate 1072*7c478bd9Sstevel@tonic-gate /* 1073*7c478bd9Sstevel@tonic-gate * If we are here, we did not find a mechanism that's supported 1074*7c478bd9Sstevel@tonic-gate * by both source and destination slot. 1075*7c478bd9Sstevel@tonic-gate * 1076*7c478bd9Sstevel@tonic-gate * If it is a secret key, can also try to wrap it with 1077*7c478bd9Sstevel@tonic-gate * a RSA public key 1078*7c478bd9Sstevel@tonic-gate */ 1079*7c478bd9Sstevel@tonic-gate if (obj_class == CKO_SECRET_KEY) { 1080*7c478bd9Sstevel@tonic-gate first_both_mech = -1; 1081*7c478bd9Sstevel@tonic-gate rsa_first_src_mech = -1; 1082*7c478bd9Sstevel@tonic-gate 1083*7c478bd9Sstevel@tonic-gate rv = find_best_match_wrap_mech(rsa_wrap_info, 1084*7c478bd9Sstevel@tonic-gate num_rsa_wrap_info, src_slotnum, dst_slotnum, 1085*7c478bd9Sstevel@tonic-gate &first_both_mech, &rsa_first_src_mech); 1086*7c478bd9Sstevel@tonic-gate 1087*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1088*7c478bd9Sstevel@tonic-gate goto finish; 1089*7c478bd9Sstevel@tonic-gate } 1090*7c478bd9Sstevel@tonic-gate 1091*7c478bd9Sstevel@tonic-gate if (first_both_mech > -1) { 1092*7c478bd9Sstevel@tonic-gate (void) memcpy(wrap_info, 1093*7c478bd9Sstevel@tonic-gate &(rsa_wrap_info[first_both_mech]), 1094*7c478bd9Sstevel@tonic-gate sizeof (wrap_info_t)); 1095*7c478bd9Sstevel@tonic-gate 1096*7c478bd9Sstevel@tonic-gate wrap_info->src_supports = B_TRUE; 1097*7c478bd9Sstevel@tonic-gate wrap_info->dst_supports = B_TRUE; 1098*7c478bd9Sstevel@tonic-gate rv = CKR_OK; 1099*7c478bd9Sstevel@tonic-gate goto finish; 1100*7c478bd9Sstevel@tonic-gate } 1101*7c478bd9Sstevel@tonic-gate } 1102*7c478bd9Sstevel@tonic-gate 1103*7c478bd9Sstevel@tonic-gate /* 1104*7c478bd9Sstevel@tonic-gate * if we are here, that means none of the mechanisms are supported 1105*7c478bd9Sstevel@tonic-gate * by both the source and the destination 1106*7c478bd9Sstevel@tonic-gate */ 1107*7c478bd9Sstevel@tonic-gate if (first_src_mech > -1) { 1108*7c478bd9Sstevel@tonic-gate /* source slot support one of the secret key mechs */ 1109*7c478bd9Sstevel@tonic-gate (void) memcpy(wrap_info, 1110*7c478bd9Sstevel@tonic-gate &(wrap_info_to_search[first_src_mech]), 1111*7c478bd9Sstevel@tonic-gate sizeof (wrap_info_t)); 1112*7c478bd9Sstevel@tonic-gate wrap_info->src_supports = B_TRUE; 1113*7c478bd9Sstevel@tonic-gate wrap_info->dst_supports = B_FALSE; 1114*7c478bd9Sstevel@tonic-gate rv = CKR_OK; 1115*7c478bd9Sstevel@tonic-gate } else if (rsa_first_src_mech > -1) { 1116*7c478bd9Sstevel@tonic-gate /* source slot support one of the RSA mechs */ 1117*7c478bd9Sstevel@tonic-gate (void) memcpy(wrap_info, &(rsa_wrap_info[rsa_first_src_mech]), 1118*7c478bd9Sstevel@tonic-gate sizeof (wrap_info_t)); 1119*7c478bd9Sstevel@tonic-gate 1120*7c478bd9Sstevel@tonic-gate wrap_info->src_supports = B_TRUE; 1121*7c478bd9Sstevel@tonic-gate wrap_info->dst_supports = B_FALSE; 1122*7c478bd9Sstevel@tonic-gate rv = CKR_OK; 1123*7c478bd9Sstevel@tonic-gate } else { 1124*7c478bd9Sstevel@tonic-gate /* neither source nor destination support any wrap mechs */ 1125*7c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 1126*7c478bd9Sstevel@tonic-gate } 1127*7c478bd9Sstevel@tonic-gate 1128*7c478bd9Sstevel@tonic-gate finish: 1129*7c478bd9Sstevel@tonic-gate return (rv); 1130*7c478bd9Sstevel@tonic-gate } 1131*7c478bd9Sstevel@tonic-gate 1132*7c478bd9Sstevel@tonic-gate 1133*7c478bd9Sstevel@tonic-gate /* 1134*7c478bd9Sstevel@tonic-gate * This is called if the object to be cloned is a sensitive object 1135*7c478bd9Sstevel@tonic-gate */ 1136*7c478bd9Sstevel@tonic-gate static CK_RV 1137*7c478bd9Sstevel@tonic-gate clone_by_wrap(meta_object_t *object, slot_object_t *new_clone, 1138*7c478bd9Sstevel@tonic-gate slot_session_t *dst_slot_session) 1139*7c478bd9Sstevel@tonic-gate { 1140*7c478bd9Sstevel@tonic-gate slot_session_t *src_slot_session = NULL; 1141*7c478bd9Sstevel@tonic-gate CK_OBJECT_HANDLE wrappingKey = NULL, unwrappingKey = NULL; 1142*7c478bd9Sstevel@tonic-gate CK_MECHANISM wrappingMech; 1143*7c478bd9Sstevel@tonic-gate CK_BYTE *wrappedKey = NULL; 1144*7c478bd9Sstevel@tonic-gate CK_ULONG wrappedKeyLen = 0; 1145*7c478bd9Sstevel@tonic-gate slot_object_t *slot_object = NULL; 1146*7c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 1147*7c478bd9Sstevel@tonic-gate CK_OBJECT_HANDLE unwrapped_obj; 1148*7c478bd9Sstevel@tonic-gate meta_object_t *tmp_meta_obj = NULL; 1149*7c478bd9Sstevel@tonic-gate slot_object_t *tmp_slot_obj = NULL; 1150*7c478bd9Sstevel@tonic-gate CK_OBJECT_CLASS obj_class; 1151*7c478bd9Sstevel@tonic-gate CK_KEY_TYPE key_type; 1152*7c478bd9Sstevel@tonic-gate meta_session_t *tmp_meta_session = NULL; 1153*7c478bd9Sstevel@tonic-gate CK_ATTRIBUTE unwrap_template[4]; 1154*7c478bd9Sstevel@tonic-gate char key_data[1024]; /* should be big enough for any key size */ 1155*7c478bd9Sstevel@tonic-gate char ivbuf[1024]; /* should be big enough for any mech */ 1156*7c478bd9Sstevel@tonic-gate wrap_info_t wrap_info; 1157*7c478bd9Sstevel@tonic-gate CK_ULONG key_len, unwrap_template_size; 1158*7c478bd9Sstevel@tonic-gate 1159*7c478bd9Sstevel@tonic-gate slot_object = object->clones[object->master_clone_slotnum]; 1160*7c478bd9Sstevel@tonic-gate 1161*7c478bd9Sstevel@tonic-gate rv = meta_get_slot_session(object->master_clone_slotnum, 1162*7c478bd9Sstevel@tonic-gate &src_slot_session, object->creator_session->session_flags); 1163*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1164*7c478bd9Sstevel@tonic-gate return (rv); 1165*7c478bd9Sstevel@tonic-gate } 1166*7c478bd9Sstevel@tonic-gate 1167*7c478bd9Sstevel@tonic-gate /* 1168*7c478bd9Sstevel@tonic-gate * get the object class and key type for unwrap template 1169*7c478bd9Sstevel@tonic-gate * This information will also be used for determining 1170*7c478bd9Sstevel@tonic-gate * which wrap mechanism and which key to use for 1171*7c478bd9Sstevel@tonic-gate * doing the wrapping 1172*7c478bd9Sstevel@tonic-gate */ 1173*7c478bd9Sstevel@tonic-gate unwrap_template[0].type = CKA_CLASS; 1174*7c478bd9Sstevel@tonic-gate unwrap_template[0].pValue = &obj_class; 1175*7c478bd9Sstevel@tonic-gate unwrap_template[0].ulValueLen = sizeof (obj_class); 1176*7c478bd9Sstevel@tonic-gate 1177*7c478bd9Sstevel@tonic-gate unwrap_template[1].type = CKA_KEY_TYPE; 1178*7c478bd9Sstevel@tonic-gate unwrap_template[1].pValue = &key_type; 1179*7c478bd9Sstevel@tonic-gate unwrap_template[1].ulValueLen = sizeof (key_type); 1180*7c478bd9Sstevel@tonic-gate 1181*7c478bd9Sstevel@tonic-gate rv = FUNCLIST(src_slot_session->fw_st_id)->C_GetAttributeValue( 1182*7c478bd9Sstevel@tonic-gate src_slot_session->hSession, slot_object->hObject, 1183*7c478bd9Sstevel@tonic-gate unwrap_template, 2); 1184*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1185*7c478bd9Sstevel@tonic-gate goto finish; 1186*7c478bd9Sstevel@tonic-gate } 1187*7c478bd9Sstevel@tonic-gate 1188*7c478bd9Sstevel@tonic-gate rv = get_wrap_mechanism(obj_class, key_type, src_slot_session->slotnum, 1189*7c478bd9Sstevel@tonic-gate dst_slot_session->slotnum, &wrap_info); 1190*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1191*7c478bd9Sstevel@tonic-gate goto finish; 1192*7c478bd9Sstevel@tonic-gate } 1193*7c478bd9Sstevel@tonic-gate 1194*7c478bd9Sstevel@tonic-gate /* 1195*7c478bd9Sstevel@tonic-gate * open the random device and read number of bytes required for 1196*7c478bd9Sstevel@tonic-gate * creating a secret key for wrapping and unwrapping 1197*7c478bd9Sstevel@tonic-gate */ 1198*7c478bd9Sstevel@tonic-gate if (wrap_info.class == CKO_SECRET_KEY) { 1199*7c478bd9Sstevel@tonic-gate 1200*7c478bd9Sstevel@tonic-gate /* 1201*7c478bd9Sstevel@tonic-gate * /dev/urandom will be used for generating the key used 1202*7c478bd9Sstevel@tonic-gate * for doing the wrap/unwrap. It's should be ok to 1203*7c478bd9Sstevel@tonic-gate * use /dev/urandom because this key is used for this 1204*7c478bd9Sstevel@tonic-gate * one time operation only. It doesn't need to be stored. 1205*7c478bd9Sstevel@tonic-gate */ 1206*7c478bd9Sstevel@tonic-gate int fd; 1207*7c478bd9Sstevel@tonic-gate 1208*7c478bd9Sstevel@tonic-gate while ((fd = open(RANDOM_DEVICE, O_RDONLY)) < 0) { 1209*7c478bd9Sstevel@tonic-gate if (errno != EINTR) 1210*7c478bd9Sstevel@tonic-gate break; 1211*7c478bd9Sstevel@tonic-gate } 1212*7c478bd9Sstevel@tonic-gate if (fd == -1) { 1213*7c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 1214*7c478bd9Sstevel@tonic-gate goto finish; 1215*7c478bd9Sstevel@tonic-gate } 1216*7c478bd9Sstevel@tonic-gate key_len = wrap_info.key_length; 1217*7c478bd9Sstevel@tonic-gate 1218*7c478bd9Sstevel@tonic-gate if (looping_read(fd, key_data, key_len) != key_len) { 1219*7c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 1220*7c478bd9Sstevel@tonic-gate goto finish; 1221*7c478bd9Sstevel@tonic-gate } 1222*7c478bd9Sstevel@tonic-gate 1223*7c478bd9Sstevel@tonic-gate if (wrap_info.iv_length > 0) { 1224*7c478bd9Sstevel@tonic-gate if (looping_read(fd, ivbuf, wrap_info.iv_length) 1225*7c478bd9Sstevel@tonic-gate != wrap_info.iv_length) { 1226*7c478bd9Sstevel@tonic-gate rv = CKR_FUNCTION_FAILED; 1227*7c478bd9Sstevel@tonic-gate goto finish; 1228*7c478bd9Sstevel@tonic-gate } 1229*7c478bd9Sstevel@tonic-gate } 1230*7c478bd9Sstevel@tonic-gate 1231*7c478bd9Sstevel@tonic-gate (void) close(fd); 1232*7c478bd9Sstevel@tonic-gate } 1233*7c478bd9Sstevel@tonic-gate 1234*7c478bd9Sstevel@tonic-gate /* create the wrapping key */ 1235*7c478bd9Sstevel@tonic-gate rv = create_wrap_unwrap_key(src_slot_session, &wrappingKey, 1236*7c478bd9Sstevel@tonic-gate &wrap_info, key_data, key_len); 1237*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1238*7c478bd9Sstevel@tonic-gate goto finish; 1239*7c478bd9Sstevel@tonic-gate } 1240*7c478bd9Sstevel@tonic-gate 1241*7c478bd9Sstevel@tonic-gate wrappingMech.mechanism = wrap_info.mech_type; 1242*7c478bd9Sstevel@tonic-gate wrappingMech.pParameter = ((wrap_info.iv_length > 0) ? ivbuf : NULL); 1243*7c478bd9Sstevel@tonic-gate wrappingMech.ulParameterLen = wrap_info.iv_length; 1244*7c478bd9Sstevel@tonic-gate 1245*7c478bd9Sstevel@tonic-gate /* get the size of the wrapped key */ 1246*7c478bd9Sstevel@tonic-gate rv = FUNCLIST(src_slot_session->fw_st_id)->C_WrapKey( 1247*7c478bd9Sstevel@tonic-gate src_slot_session->hSession, &wrappingMech, 1248*7c478bd9Sstevel@tonic-gate wrappingKey, slot_object->hObject, NULL, &wrappedKeyLen); 1249*7c478bd9Sstevel@tonic-gate 1250*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1251*7c478bd9Sstevel@tonic-gate goto finish; 1252*7c478bd9Sstevel@tonic-gate } 1253*7c478bd9Sstevel@tonic-gate 1254*7c478bd9Sstevel@tonic-gate wrappedKey = malloc(wrappedKeyLen * sizeof (CK_BYTE)); 1255*7c478bd9Sstevel@tonic-gate if (wrappedKey == NULL) { 1256*7c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 1257*7c478bd9Sstevel@tonic-gate goto finish; 1258*7c478bd9Sstevel@tonic-gate } 1259*7c478bd9Sstevel@tonic-gate 1260*7c478bd9Sstevel@tonic-gate /* do the actual key wrapping */ 1261*7c478bd9Sstevel@tonic-gate rv = FUNCLIST(src_slot_session->fw_st_id)->C_WrapKey( 1262*7c478bd9Sstevel@tonic-gate src_slot_session->hSession, &wrappingMech, 1263*7c478bd9Sstevel@tonic-gate wrappingKey, slot_object->hObject, wrappedKey, &wrappedKeyLen); 1264*7c478bd9Sstevel@tonic-gate 1265*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1266*7c478bd9Sstevel@tonic-gate goto finish; 1267*7c478bd9Sstevel@tonic-gate } 1268*7c478bd9Sstevel@tonic-gate 1269*7c478bd9Sstevel@tonic-gate /* explicitly force the unwrapped object to be not sensitive */ 1270*7c478bd9Sstevel@tonic-gate unwrap_template[2].type = CKA_SENSITIVE; 1271*7c478bd9Sstevel@tonic-gate unwrap_template[2].pValue = &falsevalue; 1272*7c478bd9Sstevel@tonic-gate unwrap_template[2].ulValueLen = sizeof (falsevalue); 1273*7c478bd9Sstevel@tonic-gate 1274*7c478bd9Sstevel@tonic-gate unwrap_template[3].type = CKA_TOKEN; 1275*7c478bd9Sstevel@tonic-gate unwrap_template[3].pValue = &falsevalue; 1276*7c478bd9Sstevel@tonic-gate unwrap_template[3].ulValueLen = sizeof (falsevalue); 1277*7c478bd9Sstevel@tonic-gate 1278*7c478bd9Sstevel@tonic-gate unwrap_template_size = 1279*7c478bd9Sstevel@tonic-gate sizeof (unwrap_template) / sizeof (CK_ATTRIBUTE); 1280*7c478bd9Sstevel@tonic-gate 1281*7c478bd9Sstevel@tonic-gate if (!wrap_info.dst_supports) { 1282*7c478bd9Sstevel@tonic-gate /* 1283*7c478bd9Sstevel@tonic-gate * if we know for sure that the destination slot doesn't 1284*7c478bd9Sstevel@tonic-gate * support the wrapping mechanism, no point in trying. 1285*7c478bd9Sstevel@tonic-gate * go directly to unwrap in source slot, and create key 1286*7c478bd9Sstevel@tonic-gate * in destination 1287*7c478bd9Sstevel@tonic-gate */ 1288*7c478bd9Sstevel@tonic-gate goto unwrap_in_source; 1289*7c478bd9Sstevel@tonic-gate } 1290*7c478bd9Sstevel@tonic-gate 1291*7c478bd9Sstevel@tonic-gate /* create the unwrapping key in destination slot */ 1292*7c478bd9Sstevel@tonic-gate if (wrap_info.key_type == CKK_RSA) { 1293*7c478bd9Sstevel@tonic-gate /* for RSA key, the unwrapping key need to be private key */ 1294*7c478bd9Sstevel@tonic-gate wrap_info.class = CKO_PRIVATE_KEY; 1295*7c478bd9Sstevel@tonic-gate } 1296*7c478bd9Sstevel@tonic-gate rv = create_wrap_unwrap_key(dst_slot_session, 1297*7c478bd9Sstevel@tonic-gate &unwrappingKey, &wrap_info, key_data, key_len); 1298*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1299*7c478bd9Sstevel@tonic-gate goto finish; 1300*7c478bd9Sstevel@tonic-gate } 1301*7c478bd9Sstevel@tonic-gate 1302*7c478bd9Sstevel@tonic-gate rv = FUNCLIST(dst_slot_session->fw_st_id)->C_UnwrapKey( 1303*7c478bd9Sstevel@tonic-gate dst_slot_session->hSession, &wrappingMech, 1304*7c478bd9Sstevel@tonic-gate unwrappingKey, wrappedKey, wrappedKeyLen, unwrap_template, 1305*7c478bd9Sstevel@tonic-gate unwrap_template_size, &(new_clone->hObject)); 1306*7c478bd9Sstevel@tonic-gate 1307*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1308*7c478bd9Sstevel@tonic-gate unwrap_in_source: 1309*7c478bd9Sstevel@tonic-gate 1310*7c478bd9Sstevel@tonic-gate /* 1311*7c478bd9Sstevel@tonic-gate * There seemed to be a problem with unwrapping in the 1312*7c478bd9Sstevel@tonic-gate * destination slot. 1313*7c478bd9Sstevel@tonic-gate * Try to do the unwrap in the src slot so it becomes 1314*7c478bd9Sstevel@tonic-gate * a non-sensitive object, then, get all the attributes 1315*7c478bd9Sstevel@tonic-gate * and create the object in the destination slot 1316*7c478bd9Sstevel@tonic-gate */ 1317*7c478bd9Sstevel@tonic-gate 1318*7c478bd9Sstevel@tonic-gate 1319*7c478bd9Sstevel@tonic-gate if (wrap_info.class == CKO_SECRET_KEY) { 1320*7c478bd9Sstevel@tonic-gate /* unwrap with same key used for wrapping */ 1321*7c478bd9Sstevel@tonic-gate rv = FUNCLIST(src_slot_session->fw_st_id)->C_UnwrapKey( 1322*7c478bd9Sstevel@tonic-gate src_slot_session->hSession, 1323*7c478bd9Sstevel@tonic-gate &wrappingMech, wrappingKey, wrappedKey, 1324*7c478bd9Sstevel@tonic-gate wrappedKeyLen, unwrap_template, 1325*7c478bd9Sstevel@tonic-gate unwrap_template_size, &(unwrapped_obj)); 1326*7c478bd9Sstevel@tonic-gate } else { 1327*7c478bd9Sstevel@tonic-gate /* 1328*7c478bd9Sstevel@tonic-gate * If the object is wrapping with RSA public key, need 1329*7c478bd9Sstevel@tonic-gate * need to create RSA private key for unwrapping 1330*7c478bd9Sstevel@tonic-gate */ 1331*7c478bd9Sstevel@tonic-gate wrap_info.class = CKO_PRIVATE_KEY; 1332*7c478bd9Sstevel@tonic-gate rv = create_wrap_unwrap_key(src_slot_session, 1333*7c478bd9Sstevel@tonic-gate &unwrappingKey, &wrap_info, key_data, key_len); 1334*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1335*7c478bd9Sstevel@tonic-gate goto finish; 1336*7c478bd9Sstevel@tonic-gate } 1337*7c478bd9Sstevel@tonic-gate rv = FUNCLIST(src_slot_session->fw_st_id)->C_UnwrapKey( 1338*7c478bd9Sstevel@tonic-gate src_slot_session->hSession, 1339*7c478bd9Sstevel@tonic-gate &wrappingMech, unwrappingKey, wrappedKey, 1340*7c478bd9Sstevel@tonic-gate wrappedKeyLen, unwrap_template, 1341*7c478bd9Sstevel@tonic-gate unwrap_template_size, &(unwrapped_obj)); 1342*7c478bd9Sstevel@tonic-gate } 1343*7c478bd9Sstevel@tonic-gate 1344*7c478bd9Sstevel@tonic-gate 1345*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1346*7c478bd9Sstevel@tonic-gate goto finish; 1347*7c478bd9Sstevel@tonic-gate } 1348*7c478bd9Sstevel@tonic-gate 1349*7c478bd9Sstevel@tonic-gate rv = meta_session_alloc(&tmp_meta_session); 1350*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1351*7c478bd9Sstevel@tonic-gate goto finish; 1352*7c478bd9Sstevel@tonic-gate } 1353*7c478bd9Sstevel@tonic-gate 1354*7c478bd9Sstevel@tonic-gate tmp_meta_session->session_flags = CKF_SERIAL_SESSION; 1355*7c478bd9Sstevel@tonic-gate 1356*7c478bd9Sstevel@tonic-gate rv = meta_object_alloc(tmp_meta_session, &tmp_meta_obj); 1357*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1358*7c478bd9Sstevel@tonic-gate goto finish; 1359*7c478bd9Sstevel@tonic-gate } 1360*7c478bd9Sstevel@tonic-gate 1361*7c478bd9Sstevel@tonic-gate rv = meta_slot_object_alloc(&tmp_slot_obj); 1362*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1363*7c478bd9Sstevel@tonic-gate goto finish; 1364*7c478bd9Sstevel@tonic-gate } 1365*7c478bd9Sstevel@tonic-gate 1366*7c478bd9Sstevel@tonic-gate tmp_meta_obj->master_clone_slotnum = src_slot_session->slotnum; 1367*7c478bd9Sstevel@tonic-gate tmp_slot_obj->hObject = unwrapped_obj; 1368*7c478bd9Sstevel@tonic-gate tmp_meta_obj->clones[tmp_meta_obj->master_clone_slotnum] 1369*7c478bd9Sstevel@tonic-gate = tmp_slot_obj; 1370*7c478bd9Sstevel@tonic-gate meta_slot_object_activate(tmp_slot_obj, src_slot_session, 1371*7c478bd9Sstevel@tonic-gate B_FALSE); 1372*7c478bd9Sstevel@tonic-gate tmp_slot_obj = NULL; 1373*7c478bd9Sstevel@tonic-gate 1374*7c478bd9Sstevel@tonic-gate rv = clone_by_create(tmp_meta_obj, new_clone, 1375*7c478bd9Sstevel@tonic-gate dst_slot_session); 1376*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1377*7c478bd9Sstevel@tonic-gate goto finish; 1378*7c478bd9Sstevel@tonic-gate } 1379*7c478bd9Sstevel@tonic-gate } 1380*7c478bd9Sstevel@tonic-gate 1381*7c478bd9Sstevel@tonic-gate finish: 1382*7c478bd9Sstevel@tonic-gate if (unwrappingKey) { 1383*7c478bd9Sstevel@tonic-gate (void) FUNCLIST(dst_slot_session->fw_st_id)->C_DestroyObject( 1384*7c478bd9Sstevel@tonic-gate dst_slot_session->hSession, unwrappingKey); 1385*7c478bd9Sstevel@tonic-gate } 1386*7c478bd9Sstevel@tonic-gate 1387*7c478bd9Sstevel@tonic-gate if (wrappingKey) { 1388*7c478bd9Sstevel@tonic-gate (void) FUNCLIST(src_slot_session->fw_st_id)->C_DestroyObject( 1389*7c478bd9Sstevel@tonic-gate src_slot_session->hSession, wrappingKey); 1390*7c478bd9Sstevel@tonic-gate } 1391*7c478bd9Sstevel@tonic-gate 1392*7c478bd9Sstevel@tonic-gate if (tmp_slot_obj) { 1393*7c478bd9Sstevel@tonic-gate (void) meta_slot_object_dealloc(tmp_slot_obj); 1394*7c478bd9Sstevel@tonic-gate } 1395*7c478bd9Sstevel@tonic-gate 1396*7c478bd9Sstevel@tonic-gate if (tmp_meta_obj) { 1397*7c478bd9Sstevel@tonic-gate (void) meta_object_dealloc(tmp_meta_obj, B_TRUE); 1398*7c478bd9Sstevel@tonic-gate } 1399*7c478bd9Sstevel@tonic-gate 1400*7c478bd9Sstevel@tonic-gate if (tmp_meta_session) { 1401*7c478bd9Sstevel@tonic-gate (void) meta_session_dealloc(tmp_meta_session); 1402*7c478bd9Sstevel@tonic-gate } 1403*7c478bd9Sstevel@tonic-gate 1404*7c478bd9Sstevel@tonic-gate if (wrappedKey) { 1405*7c478bd9Sstevel@tonic-gate free(wrappedKey); 1406*7c478bd9Sstevel@tonic-gate } 1407*7c478bd9Sstevel@tonic-gate 1408*7c478bd9Sstevel@tonic-gate if (src_slot_session) { 1409*7c478bd9Sstevel@tonic-gate meta_release_slot_session(src_slot_session); 1410*7c478bd9Sstevel@tonic-gate } 1411*7c478bd9Sstevel@tonic-gate 1412*7c478bd9Sstevel@tonic-gate return (rv); 1413*7c478bd9Sstevel@tonic-gate 1414*7c478bd9Sstevel@tonic-gate } 1415*7c478bd9Sstevel@tonic-gate 1416*7c478bd9Sstevel@tonic-gate 1417*7c478bd9Sstevel@tonic-gate /* 1418*7c478bd9Sstevel@tonic-gate * meta_object_get_clone 1419*7c478bd9Sstevel@tonic-gate * 1420*7c478bd9Sstevel@tonic-gate * Creates a "clone" of a metaobject on the specified slot. A clone is a 1421*7c478bd9Sstevel@tonic-gate * copy of the object. 1422*7c478bd9Sstevel@tonic-gate * 1423*7c478bd9Sstevel@tonic-gate * Clones are cached, so that they can be reused with subsquent operations. 1424*7c478bd9Sstevel@tonic-gate */ 1425*7c478bd9Sstevel@tonic-gate CK_RV 1426*7c478bd9Sstevel@tonic-gate meta_object_get_clone(meta_object_t *object, 1427*7c478bd9Sstevel@tonic-gate CK_ULONG slot_num, slot_session_t *slot_session, 1428*7c478bd9Sstevel@tonic-gate slot_object_t **clone) 1429*7c478bd9Sstevel@tonic-gate { 1430*7c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 1431*7c478bd9Sstevel@tonic-gate slot_object_t *newclone = NULL; 1432*7c478bd9Sstevel@tonic-gate 1433*7c478bd9Sstevel@tonic-gate /* Does a clone already exist? */ 1434*7c478bd9Sstevel@tonic-gate if (object->clones[slot_num] != NULL) { 1435*7c478bd9Sstevel@tonic-gate *clone = object->clones[slot_num]; 1436*7c478bd9Sstevel@tonic-gate return (CKR_OK); 1437*7c478bd9Sstevel@tonic-gate } 1438*7c478bd9Sstevel@tonic-gate 1439*7c478bd9Sstevel@tonic-gate if ((object->isSensitive) && (object->isToken) && 1440*7c478bd9Sstevel@tonic-gate (!metaslot_auto_key_migrate)) { 1441*7c478bd9Sstevel@tonic-gate /* 1442*7c478bd9Sstevel@tonic-gate * if the object is a sensitive token object, and auto 1443*7c478bd9Sstevel@tonic-gate * key migrate is not allowed, will not create the clone 1444*7c478bd9Sstevel@tonic-gate * in another slot 1445*7c478bd9Sstevel@tonic-gate */ 1446*7c478bd9Sstevel@tonic-gate return (CKR_FUNCTION_FAILED); 1447*7c478bd9Sstevel@tonic-gate } 1448*7c478bd9Sstevel@tonic-gate 1449*7c478bd9Sstevel@tonic-gate /* object attributes can't be extracted and attributes are not known */ 1450*7c478bd9Sstevel@tonic-gate if ((!object->isExtractable) && (object->attributes == NULL)) { 1451*7c478bd9Sstevel@tonic-gate return (CKR_FUNCTION_FAILED); 1452*7c478bd9Sstevel@tonic-gate } 1453*7c478bd9Sstevel@tonic-gate 1454*7c478bd9Sstevel@tonic-gate /* 1455*7c478bd9Sstevel@tonic-gate * has an attempt already been made to create this object in 1456*7c478bd9Sstevel@tonic-gate * slot? If yes, and there's no clone, as indicated above, 1457*7c478bd9Sstevel@tonic-gate * that means this object can't be created in this slot. 1458*7c478bd9Sstevel@tonic-gate */ 1459*7c478bd9Sstevel@tonic-gate if (object->tried_create_clone[slot_num]) { 1460*7c478bd9Sstevel@tonic-gate return (CKR_FUNCTION_FAILED); 1461*7c478bd9Sstevel@tonic-gate } 1462*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&object->clone_create_lock); 1463*7c478bd9Sstevel@tonic-gate 1464*7c478bd9Sstevel@tonic-gate /* Maybe someone just created one? */ 1465*7c478bd9Sstevel@tonic-gate if (object->clones[slot_num] != NULL) { 1466*7c478bd9Sstevel@tonic-gate *clone = object->clones[slot_num]; 1467*7c478bd9Sstevel@tonic-gate goto finish; 1468*7c478bd9Sstevel@tonic-gate } 1469*7c478bd9Sstevel@tonic-gate 1470*7c478bd9Sstevel@tonic-gate 1471*7c478bd9Sstevel@tonic-gate rv = meta_slot_object_alloc(&newclone); 1472*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) 1473*7c478bd9Sstevel@tonic-gate goto finish; 1474*7c478bd9Sstevel@tonic-gate 1475*7c478bd9Sstevel@tonic-gate object->tried_create_clone[slot_num] = B_TRUE; 1476*7c478bd9Sstevel@tonic-gate 1477*7c478bd9Sstevel@tonic-gate if (object->isSensitive) { 1478*7c478bd9Sstevel@tonic-gate rv = clone_by_wrap(object, newclone, slot_session); 1479*7c478bd9Sstevel@tonic-gate } else { 1480*7c478bd9Sstevel@tonic-gate rv = clone_by_create(object, newclone, slot_session); 1481*7c478bd9Sstevel@tonic-gate } 1482*7c478bd9Sstevel@tonic-gate 1483*7c478bd9Sstevel@tonic-gate if (rv != CKR_OK) { 1484*7c478bd9Sstevel@tonic-gate goto finish; 1485*7c478bd9Sstevel@tonic-gate } 1486*7c478bd9Sstevel@tonic-gate 1487*7c478bd9Sstevel@tonic-gate object->clones[slot_num] = newclone; 1488*7c478bd9Sstevel@tonic-gate meta_slot_object_activate(newclone, slot_session, object->isToken); 1489*7c478bd9Sstevel@tonic-gate 1490*7c478bd9Sstevel@tonic-gate *clone = newclone; 1491*7c478bd9Sstevel@tonic-gate newclone = NULL; 1492*7c478bd9Sstevel@tonic-gate finish: 1493*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&object->clone_create_lock); 1494*7c478bd9Sstevel@tonic-gate 1495*7c478bd9Sstevel@tonic-gate if (newclone) 1496*7c478bd9Sstevel@tonic-gate meta_slot_object_dealloc(newclone); 1497*7c478bd9Sstevel@tonic-gate 1498*7c478bd9Sstevel@tonic-gate return (rv); 1499*7c478bd9Sstevel@tonic-gate } 1500*7c478bd9Sstevel@tonic-gate 1501*7c478bd9Sstevel@tonic-gate 1502*7c478bd9Sstevel@tonic-gate /* 1503*7c478bd9Sstevel@tonic-gate * meta_setup_clone_template 1504*7c478bd9Sstevel@tonic-gate * 1505*7c478bd9Sstevel@tonic-gate * Create a clone template for the specified object. 1506*7c478bd9Sstevel@tonic-gate */ 1507*7c478bd9Sstevel@tonic-gate static CK_RV 1508*7c478bd9Sstevel@tonic-gate meta_clone_template_setup(meta_object_t *object, 1509*7c478bd9Sstevel@tonic-gate const generic_attr_t *attributes, size_t num_attributes) 1510*7c478bd9Sstevel@tonic-gate { 1511*7c478bd9Sstevel@tonic-gate CK_RV rv = CKR_OK; 1512*7c478bd9Sstevel@tonic-gate CK_ATTRIBUTE *clone_template; 1513*7c478bd9Sstevel@tonic-gate size_t i, c = 0; 1514*7c478bd9Sstevel@tonic-gate 1515*7c478bd9Sstevel@tonic-gate clone_template = malloc(num_attributes * sizeof (CK_ATTRIBUTE)); 1516*7c478bd9Sstevel@tonic-gate if (clone_template == NULL) { 1517*7c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 1518*7c478bd9Sstevel@tonic-gate goto finish; 1519*7c478bd9Sstevel@tonic-gate } 1520*7c478bd9Sstevel@tonic-gate 1521*7c478bd9Sstevel@tonic-gate /* Don't allow attributes to change while we look at them. */ 1522*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_rdlock(&object->attribute_lock); 1523*7c478bd9Sstevel@tonic-gate 1524*7c478bd9Sstevel@tonic-gate for (i = 0; i < num_attributes; i++) { 1525*7c478bd9Sstevel@tonic-gate if (!attributes[i].isCloneAttr) { 1526*7c478bd9Sstevel@tonic-gate continue; 1527*7c478bd9Sstevel@tonic-gate } 1528*7c478bd9Sstevel@tonic-gate if ((!(attributes[i].hasValueForClone)) && 1529*7c478bd9Sstevel@tonic-gate (attributes[i].canBeEmptyValue)) { 1530*7c478bd9Sstevel@tonic-gate continue; 1531*7c478bd9Sstevel@tonic-gate } 1532*7c478bd9Sstevel@tonic-gate 1533*7c478bd9Sstevel@tonic-gate clone_template[c].type = attributes[i].attribute.type; 1534*7c478bd9Sstevel@tonic-gate clone_template[c].ulValueLen = 1535*7c478bd9Sstevel@tonic-gate attributes[i].attribute.ulValueLen; 1536*7c478bd9Sstevel@tonic-gate /* Allocate space to store the attribute value. */ 1537*7c478bd9Sstevel@tonic-gate clone_template[c].pValue = malloc(clone_template[c].ulValueLen); 1538*7c478bd9Sstevel@tonic-gate if (clone_template[c].pValue == NULL) { 1539*7c478bd9Sstevel@tonic-gate rv = CKR_HOST_MEMORY; 1540*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&object->attribute_lock); 1541*7c478bd9Sstevel@tonic-gate goto finish; 1542*7c478bd9Sstevel@tonic-gate } 1543*7c478bd9Sstevel@tonic-gate 1544*7c478bd9Sstevel@tonic-gate (void) memcpy(clone_template[c].pValue, 1545*7c478bd9Sstevel@tonic-gate object->attributes[i].attribute.pValue, 1546*7c478bd9Sstevel@tonic-gate clone_template[c].ulValueLen); 1547*7c478bd9Sstevel@tonic-gate c++; 1548*7c478bd9Sstevel@tonic-gate } 1549*7c478bd9Sstevel@tonic-gate 1550*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&object->attribute_lock); 1551*7c478bd9Sstevel@tonic-gate 1552*7c478bd9Sstevel@tonic-gate object->clone_template = clone_template; 1553*7c478bd9Sstevel@tonic-gate object->clone_template_size = c; 1554*7c478bd9Sstevel@tonic-gate 1555*7c478bd9Sstevel@tonic-gate finish: 1556*7c478bd9Sstevel@tonic-gate return (rv); 1557*7c478bd9Sstevel@tonic-gate } 1558*7c478bd9Sstevel@tonic-gate 1559*7c478bd9Sstevel@tonic-gate 1560*7c478bd9Sstevel@tonic-gate /* 1561*7c478bd9Sstevel@tonic-gate * meta_object_find_by_handle 1562*7c478bd9Sstevel@tonic-gate * 1563*7c478bd9Sstevel@tonic-gate * Search for an existing metaobject, using the object handle of a clone 1564*7c478bd9Sstevel@tonic-gate * on a particular slot. 1565*7c478bd9Sstevel@tonic-gate * 1566*7c478bd9Sstevel@tonic-gate * Returns a matching metaobject, or NULL if no match was found. 1567*7c478bd9Sstevel@tonic-gate */ 1568*7c478bd9Sstevel@tonic-gate meta_object_t * 1569*7c478bd9Sstevel@tonic-gate meta_object_find_by_handle(CK_OBJECT_HANDLE hObject, CK_ULONG slotnum, 1570*7c478bd9Sstevel@tonic-gate boolean_t token_only) 1571*7c478bd9Sstevel@tonic-gate { 1572*7c478bd9Sstevel@tonic-gate meta_object_t *object = NULL, *tmp_obj; 1573*7c478bd9Sstevel@tonic-gate meta_session_t *session; 1574*7c478bd9Sstevel@tonic-gate 1575*7c478bd9Sstevel@tonic-gate if (!token_only) { 1576*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_rdlock(&meta_sessionlist_lock); 1577*7c478bd9Sstevel@tonic-gate session = meta_sessionlist_head; 1578*7c478bd9Sstevel@tonic-gate while (session != NULL) { 1579*7c478bd9Sstevel@tonic-gate /* lock the objects list while we look at it */ 1580*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_rdlock( 1581*7c478bd9Sstevel@tonic-gate &(session->object_list_lock)); 1582*7c478bd9Sstevel@tonic-gate tmp_obj = session->object_list_head; 1583*7c478bd9Sstevel@tonic-gate while (tmp_obj != NULL) { 1584*7c478bd9Sstevel@tonic-gate slot_object_t *slot_object; 1585*7c478bd9Sstevel@tonic-gate 1586*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_rdlock( 1587*7c478bd9Sstevel@tonic-gate &(tmp_obj->object_lock)); 1588*7c478bd9Sstevel@tonic-gate slot_object = tmp_obj->clones[slotnum]; 1589*7c478bd9Sstevel@tonic-gate if (slot_object != NULL) { 1590*7c478bd9Sstevel@tonic-gate if (slot_object->hObject == hObject) { 1591*7c478bd9Sstevel@tonic-gate object = tmp_obj; 1592*7c478bd9Sstevel@tonic-gate } 1593*7c478bd9Sstevel@tonic-gate } 1594*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock( 1595*7c478bd9Sstevel@tonic-gate &(tmp_obj->object_lock)); 1596*7c478bd9Sstevel@tonic-gate if (object != NULL) { 1597*7c478bd9Sstevel@tonic-gate break; 1598*7c478bd9Sstevel@tonic-gate } 1599*7c478bd9Sstevel@tonic-gate tmp_obj = tmp_obj->next; 1600*7c478bd9Sstevel@tonic-gate } 1601*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock( 1602*7c478bd9Sstevel@tonic-gate &(session->object_list_lock)); 1603*7c478bd9Sstevel@tonic-gate if (object != NULL) { 1604*7c478bd9Sstevel@tonic-gate break; 1605*7c478bd9Sstevel@tonic-gate } 1606*7c478bd9Sstevel@tonic-gate session = session->next; 1607*7c478bd9Sstevel@tonic-gate } 1608*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&meta_sessionlist_lock); 1609*7c478bd9Sstevel@tonic-gate } 1610*7c478bd9Sstevel@tonic-gate 1611*7c478bd9Sstevel@tonic-gate if (object != NULL) { 1612*7c478bd9Sstevel@tonic-gate /* found the object, no need to look further */ 1613*7c478bd9Sstevel@tonic-gate return (object); 1614*7c478bd9Sstevel@tonic-gate } 1615*7c478bd9Sstevel@tonic-gate 1616*7c478bd9Sstevel@tonic-gate /* 1617*7c478bd9Sstevel@tonic-gate * Look at list of token objects 1618*7c478bd9Sstevel@tonic-gate */ 1619*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_rdlock(&tokenobject_list_lock); 1620*7c478bd9Sstevel@tonic-gate tmp_obj = tokenobject_list_head; 1621*7c478bd9Sstevel@tonic-gate 1622*7c478bd9Sstevel@tonic-gate while (tmp_obj != NULL) { 1623*7c478bd9Sstevel@tonic-gate slot_object_t *slot_object; 1624*7c478bd9Sstevel@tonic-gate 1625*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_rdlock(&(tmp_obj->object_lock)); 1626*7c478bd9Sstevel@tonic-gate slot_object = tmp_obj->clones[slotnum]; 1627*7c478bd9Sstevel@tonic-gate if (slot_object != NULL) { 1628*7c478bd9Sstevel@tonic-gate if (slot_object->hObject == hObject) 1629*7c478bd9Sstevel@tonic-gate object = tmp_obj; 1630*7c478bd9Sstevel@tonic-gate } 1631*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&(tmp_obj->object_lock)); 1632*7c478bd9Sstevel@tonic-gate if (object != NULL) { 1633*7c478bd9Sstevel@tonic-gate break; 1634*7c478bd9Sstevel@tonic-gate } 1635*7c478bd9Sstevel@tonic-gate tmp_obj = tmp_obj->next; 1636*7c478bd9Sstevel@tonic-gate } 1637*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&tokenobject_list_lock); 1638*7c478bd9Sstevel@tonic-gate 1639*7c478bd9Sstevel@tonic-gate return (object); 1640*7c478bd9Sstevel@tonic-gate } 1641*7c478bd9Sstevel@tonic-gate 1642*7c478bd9Sstevel@tonic-gate CK_RV 1643*7c478bd9Sstevel@tonic-gate meta_token_object_deactivate(token_obj_type_t token_type) 1644*7c478bd9Sstevel@tonic-gate { 1645*7c478bd9Sstevel@tonic-gate meta_object_t *object, *tmp_object; 1646*7c478bd9Sstevel@tonic-gate CK_RV save_rv = CKR_OK, rv; 1647*7c478bd9Sstevel@tonic-gate 1648*7c478bd9Sstevel@tonic-gate /* get a write lock on the token object list */ 1649*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_wrlock(&tokenobject_list_lock); 1650*7c478bd9Sstevel@tonic-gate 1651*7c478bd9Sstevel@tonic-gate object = tokenobject_list_head; 1652*7c478bd9Sstevel@tonic-gate 1653*7c478bd9Sstevel@tonic-gate /* go through each object and delete the one with matching type */ 1654*7c478bd9Sstevel@tonic-gate while (object != NULL) { 1655*7c478bd9Sstevel@tonic-gate tmp_object = object->next; 1656*7c478bd9Sstevel@tonic-gate 1657*7c478bd9Sstevel@tonic-gate if ((token_type == ALL_TOKEN) || 1658*7c478bd9Sstevel@tonic-gate ((object->isPrivate) && (token_type == PRIVATE_TOKEN)) || 1659*7c478bd9Sstevel@tonic-gate ((!object->isPrivate) && (token_type == PUBLIC_TOKEN))) { 1660*7c478bd9Sstevel@tonic-gate rv = meta_object_deactivate(object, B_TRUE, B_FALSE); 1661*7c478bd9Sstevel@tonic-gate if ((rv != CKR_OK) && (save_rv == CKR_OK)) { 1662*7c478bd9Sstevel@tonic-gate save_rv = rv; 1663*7c478bd9Sstevel@tonic-gate goto finish; 1664*7c478bd9Sstevel@tonic-gate } 1665*7c478bd9Sstevel@tonic-gate rv = meta_object_dealloc(object, B_FALSE); 1666*7c478bd9Sstevel@tonic-gate if ((rv != CKR_OK) && (save_rv == CKR_OK)) { 1667*7c478bd9Sstevel@tonic-gate save_rv = rv; 1668*7c478bd9Sstevel@tonic-gate goto finish; 1669*7c478bd9Sstevel@tonic-gate } 1670*7c478bd9Sstevel@tonic-gate } 1671*7c478bd9Sstevel@tonic-gate object = tmp_object; 1672*7c478bd9Sstevel@tonic-gate } 1673*7c478bd9Sstevel@tonic-gate finish: 1674*7c478bd9Sstevel@tonic-gate (void) pthread_rwlock_unlock(&tokenobject_list_lock); 1675*7c478bd9Sstevel@tonic-gate return (save_rv); 1676*7c478bd9Sstevel@tonic-gate } 1677*7c478bd9Sstevel@tonic-gate 1678*7c478bd9Sstevel@tonic-gate /* 1679*7c478bd9Sstevel@tonic-gate * This function adds the to-be-freed meta object to a linked list. 1680*7c478bd9Sstevel@tonic-gate * When the number of objects queued in the linked list reaches the 1681*7c478bd9Sstevel@tonic-gate * maximum threshold MAX_OBJ_TO_BE_FREED, it will free the first 1682*7c478bd9Sstevel@tonic-gate * object (FIFO) in the list. 1683*7c478bd9Sstevel@tonic-gate */ 1684*7c478bd9Sstevel@tonic-gate void 1685*7c478bd9Sstevel@tonic-gate meta_object_delay_free(meta_object_t *objp) 1686*7c478bd9Sstevel@tonic-gate { 1687*7c478bd9Sstevel@tonic-gate meta_object_t *tmp; 1688*7c478bd9Sstevel@tonic-gate 1689*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_lock(&obj_delay_freed.obj_to_be_free_mutex); 1690*7c478bd9Sstevel@tonic-gate 1691*7c478bd9Sstevel@tonic-gate /* Add the newly deleted object at the end of the list */ 1692*7c478bd9Sstevel@tonic-gate objp->next = NULL; 1693*7c478bd9Sstevel@tonic-gate if (obj_delay_freed.first == NULL) { 1694*7c478bd9Sstevel@tonic-gate obj_delay_freed.last = objp; 1695*7c478bd9Sstevel@tonic-gate obj_delay_freed.first = objp; 1696*7c478bd9Sstevel@tonic-gate } else { 1697*7c478bd9Sstevel@tonic-gate obj_delay_freed.last->next = objp; 1698*7c478bd9Sstevel@tonic-gate obj_delay_freed.last = objp; 1699*7c478bd9Sstevel@tonic-gate } 1700*7c478bd9Sstevel@tonic-gate 1701*7c478bd9Sstevel@tonic-gate if (++obj_delay_freed.count >= MAX_OBJ_TO_BE_FREED) { 1702*7c478bd9Sstevel@tonic-gate /* 1703*7c478bd9Sstevel@tonic-gate * Free the first object in the list only if 1704*7c478bd9Sstevel@tonic-gate * the total count reaches maximum threshold. 1705*7c478bd9Sstevel@tonic-gate */ 1706*7c478bd9Sstevel@tonic-gate obj_delay_freed.count--; 1707*7c478bd9Sstevel@tonic-gate tmp = obj_delay_freed.first->next; 1708*7c478bd9Sstevel@tonic-gate free(obj_delay_freed.first); 1709*7c478bd9Sstevel@tonic-gate obj_delay_freed.first = tmp; 1710*7c478bd9Sstevel@tonic-gate } 1711*7c478bd9Sstevel@tonic-gate (void) pthread_mutex_unlock(&obj_delay_freed.obj_to_be_free_mutex); 1712*7c478bd9Sstevel@tonic-gate } 1713