1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * General-Purpose Functions 28 * (as defined in PKCS#11 spec section 11.4) 29 */ 30 31 #include <unistd.h> 32 #include <errno.h> 33 #include <string.h> 34 #include "metaGlobal.h" 35 36 extern meta_session_t *meta_sessionlist_head; 37 38 struct CK_FUNCTION_LIST metaslot_functionList = { 39 { 2, 20 }, /* version */ 40 meta_Initialize, 41 meta_Finalize, 42 meta_GetInfo, 43 meta_GetFunctionList, 44 meta_GetSlotList, 45 meta_GetSlotInfo, 46 meta_GetTokenInfo, 47 meta_GetMechanismList, 48 meta_GetMechanismInfo, 49 meta_InitToken, 50 meta_InitPIN, 51 meta_SetPIN, 52 meta_OpenSession, 53 meta_CloseSession, 54 meta_CloseAllSessions, 55 meta_GetSessionInfo, 56 meta_GetOperationState, 57 meta_SetOperationState, 58 meta_Login, 59 meta_Logout, 60 meta_CreateObject, 61 meta_CopyObject, 62 meta_DestroyObject, 63 meta_GetObjectSize, 64 meta_GetAttributeValue, 65 meta_SetAttributeValue, 66 meta_FindObjectsInit, 67 meta_FindObjects, 68 meta_FindObjectsFinal, 69 meta_EncryptInit, 70 meta_Encrypt, 71 meta_EncryptUpdate, 72 meta_EncryptFinal, 73 meta_DecryptInit, 74 meta_Decrypt, 75 meta_DecryptUpdate, 76 meta_DecryptFinal, 77 meta_DigestInit, 78 meta_Digest, 79 meta_DigestUpdate, 80 meta_DigestKey, 81 meta_DigestFinal, 82 meta_SignInit, 83 meta_Sign, 84 meta_SignUpdate, 85 meta_SignFinal, 86 meta_SignRecoverInit, 87 meta_SignRecover, 88 meta_VerifyInit, 89 meta_Verify, 90 meta_VerifyUpdate, 91 meta_VerifyFinal, 92 meta_VerifyRecoverInit, 93 meta_VerifyRecover, 94 meta_DigestEncryptUpdate, 95 meta_DecryptDigestUpdate, 96 meta_SignEncryptUpdate, 97 meta_DecryptVerifyUpdate, 98 meta_GenerateKey, 99 meta_GenerateKeyPair, 100 meta_WrapKey, 101 meta_UnwrapKey, 102 meta_DeriveKey, 103 meta_SeedRandom, 104 meta_GenerateRandom, 105 meta_GetFunctionStatus, 106 meta_CancelFunction, 107 meta_WaitForSlotEvent 108 }; 109 110 pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER; 111 112 ses_to_be_freed_list_t ses_delay_freed; 113 object_to_be_freed_list_t obj_delay_freed; 114 115 /* 116 * meta_Initialize 117 * 118 * This function is never called by the application. It is only 119 * called by uCF to initialize metaslot. The pInitArgs argument is ignored. 120 * 121 */ 122 /*ARGSUSED*/ 123 CK_RV 124 meta_Initialize(CK_VOID_PTR pInitArgs) 125 { 126 CK_RV rv; 127 128 /* Make sure function hasn't been called twice */ 129 (void) pthread_mutex_lock(&initmutex); 130 131 rv = meta_slotManager_initialize(); 132 if (rv != CKR_OK) { 133 (void) pthread_mutex_unlock(&initmutex); 134 return (rv); 135 } 136 137 rv = meta_mechManager_initialize(); 138 if (rv != CKR_OK) { 139 (void) meta_slotManager_finalize(); 140 (void) pthread_mutex_unlock(&initmutex); 141 return (rv); 142 } 143 144 rv = meta_objectManager_initialize(); 145 if (rv != CKR_OK) { 146 (void) meta_slotManager_finalize(); 147 (void) meta_mechManager_finalize(); 148 (void) pthread_mutex_unlock(&initmutex); 149 return (rv); 150 } 151 152 rv = meta_sessionManager_initialize(); 153 if (rv != CKR_OK) { 154 (void) meta_slotManager_finalize(); 155 (void) meta_mechManager_finalize(); 156 (void) meta_objectManager_finalize(); 157 (void) pthread_mutex_unlock(&initmutex); 158 return (rv); 159 } 160 161 meta_slotManager_find_object_token(); 162 163 /* Initialize the object_to_be_freed list */ 164 (void) pthread_mutex_init(&obj_delay_freed.obj_to_be_free_mutex, NULL); 165 obj_delay_freed.count = 0; 166 obj_delay_freed.first = NULL; 167 obj_delay_freed.last = NULL; 168 169 /* Initialize the session_to_be_freed list */ 170 (void) pthread_mutex_init(&ses_delay_freed.ses_to_be_free_mutex, NULL); 171 ses_delay_freed.count = 0; 172 ses_delay_freed.first = NULL; 173 ses_delay_freed.last = NULL; 174 175 (void) pthread_mutex_unlock(&initmutex); 176 177 return (CKR_OK); 178 } 179 180 181 /* 182 * meta_Finalize 183 * 184 * Called by uCF only, "pReserved" argument is ignored. 185 */ 186 /*ARGSUSED*/ 187 CK_RV 188 meta_Finalize(CK_VOID_PTR pReserved) 189 { 190 CK_RV rv = CKR_OK; 191 meta_object_t *delay_free_obj, *tmpo; 192 meta_session_t *delay_free_ses, *tmps; 193 194 if (pReserved != NULL) 195 return (CKR_ARGUMENTS_BAD); 196 197 (void) pthread_mutex_lock(&initmutex); 198 199 pkcs11_close_urandom(); 200 pkcs11_close_urandom_seed(); 201 202 meta_objectManager_finalize(); 203 204 meta_sessionManager_finalize(); 205 206 meta_mechManager_finalize(); 207 208 meta_slotManager_finalize(); 209 210 /* 211 * free all entries in the delay_freed list 212 */ 213 delay_free_obj = obj_delay_freed.first; 214 while (delay_free_obj != NULL) { 215 tmpo = delay_free_obj->next; 216 free(delay_free_obj); 217 delay_free_obj = tmpo; 218 } 219 (void) pthread_mutex_destroy(&obj_delay_freed.obj_to_be_free_mutex); 220 221 delay_free_ses = ses_delay_freed.first; 222 while (delay_free_ses != NULL) { 223 tmps = delay_free_ses->next; 224 free(delay_free_ses); 225 delay_free_ses = tmps; 226 } 227 (void) pthread_mutex_destroy(&ses_delay_freed.ses_to_be_free_mutex); 228 229 (void) pthread_mutex_unlock(&initmutex); 230 231 return (rv); 232 } 233 234 /* 235 * meta_GetInfo 236 * 237 * NOTE: This function will never be called by applications because it's 238 * hidden behind the uCF C_GetInfo. So, it is not implemented. 239 */ 240 /*ARGSUSED*/ 241 CK_RV 242 meta_GetInfo(CK_INFO_PTR pInfo) 243 { 244 return (CKR_FUNCTION_NOT_SUPPORTED); 245 } 246 247 248 /* 249 * meta_GetFunctionList 250 * 251 * This function is not implemented because metaslot is part of the framework, 252 * so, the framework can just do a static assignment to metaslot's 253 * function list instead of calling this function. 254 */ 255 /*ARGSUSED*/ 256 CK_RV 257 meta_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) 258 { 259 return (CKR_FUNCTION_NOT_SUPPORTED); 260 } 261 262 263 /* 264 * Parallel Function Management Function 265 * (as defined in PKCS#11 spec section 11.16) 266 */ 267 268 /* 269 * This function is no longer supported in this revision of the PKCS#11 270 * standard. It is maintained for backwards compatibility only. 271 */ 272 /* ARGSUSED */ 273 CK_RV 274 meta_GetFunctionStatus(CK_SESSION_HANDLE hSession) 275 { 276 return (CKR_FUNCTION_NOT_PARALLEL); 277 } 278 279 280 /* 281 * This function is no longer supported in this revision of the PKCS#11 282 * standard. It is maintained for backwards compatibility only. 283 */ 284 /* ARGSUSED */ 285 CK_RV 286 meta_CancelFunction(CK_SESSION_HANDLE hSession) 287 { 288 return (CKR_FUNCTION_NOT_PARALLEL); 289 } 290