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 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Slot and Token Management functions 28 * (as defined in PKCS#11 spec section 11.5) 29 */ 30 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include "metaGlobal.h" 35 36 extern CK_ULONG num_meta_sessions; 37 extern CK_ULONG num_rw_meta_sessions; 38 39 /* 40 * meta_GetSlotList 41 * 42 * For the metaslot, this is a trivial function. The metaslot module, 43 * by defination, provides exactly one slot. The token is always present. 44 * 45 * This function is actually not called. 46 */ 47 /* ARGSUSED */ 48 CK_RV 49 meta_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, 50 CK_ULONG_PTR pulCount) 51 { 52 CK_RV rv; 53 54 if (pulCount == NULL) 55 return (CKR_ARGUMENTS_BAD); 56 57 if (pSlotList == NULL) { 58 *pulCount = 1; 59 return (CKR_OK); 60 } 61 62 if (*pulCount < 1) { 63 rv = CKR_BUFFER_TOO_SMALL; 64 } else { 65 pSlotList[0] = METASLOT_SLOTID; 66 rv = CKR_OK; 67 } 68 *pulCount = 1; 69 70 return (rv); 71 } 72 73 74 /* 75 * meta_GetSlotInfo 76 * 77 * Returns basic information about the metaslot. 78 * 79 * The slotID argument is ignored. 80 */ 81 /*ARGSUSED*/ 82 CK_RV 83 meta_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) 84 { 85 CK_SLOT_INFO slotinfo; 86 CK_SLOT_ID true_id; 87 CK_RV rv; 88 89 if (!metaslot_enabled) { 90 return (CKR_SLOT_ID_INVALID); 91 } 92 93 if (pInfo == NULL) { 94 return (CKR_ARGUMENTS_BAD); 95 } 96 97 /* Provide information about the slot in the provided buffer */ 98 (void) memcpy(pInfo->slotDescription, METASLOT_SLOT_DESCRIPTION, 64); 99 (void) memcpy(pInfo->manufacturerID, METASLOT_MANUFACTURER_ID, 32); 100 pInfo->hardwareVersion.major = METASLOT_HARDWARE_VERSION_MAJOR; 101 pInfo->hardwareVersion.minor = METASLOT_HARDWARE_VERSION_MINOR; 102 pInfo->firmwareVersion.major = METASLOT_FIRMWARE_VERSION_MAJOR; 103 pInfo->firmwareVersion.minor = METASLOT_FIRMWARE_VERSION_MINOR; 104 105 /* Find out token is present in the underlying keystore */ 106 true_id = TRUEID(metaslot_keystore_slotid); 107 108 rv = FUNCLIST(metaslot_keystore_slotid)->C_GetSlotInfo(true_id, 109 &slotinfo); 110 if ((rv == CKR_OK) && (slotinfo.flags & CKF_TOKEN_PRESENT)) { 111 /* 112 * store the token present flag if it is successfully 113 * received from the keystore slot. 114 * If not, this flag will not be set. 115 */ 116 pInfo->flags = CKF_TOKEN_PRESENT; 117 } 118 119 return (CKR_OK); 120 } 121 122 123 /* 124 * meta_GetTokenInfo 125 * 126 * Returns basic information about the metaslot "token." 127 * 128 * The slotID argument is ignored. 129 * 130 */ 131 /*ARGSUSED*/ 132 CK_RV 133 meta_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) 134 { 135 CK_RV rv; 136 CK_TOKEN_INFO metainfo; 137 CK_SLOT_ID true_id; 138 139 if (!metaslot_enabled) { 140 return (CKR_SLOT_ID_INVALID); 141 } 142 143 if (pInfo == NULL) 144 return (CKR_ARGUMENTS_BAD); 145 146 true_id = TRUEID(metaslot_keystore_slotid); 147 148 rv = FUNCLIST(metaslot_keystore_slotid)->C_GetTokenInfo(true_id, 149 &metainfo); 150 151 /* 152 * If we could not get information about the object token, use 153 * default values. This allows metaslot to be used even if there 154 * are problems with the object token (eg, it's not present). 155 */ 156 if (rv != CKR_OK) { 157 metainfo.ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION; 158 metainfo.ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION; 159 metainfo.ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION; 160 metainfo.ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION; 161 162 metainfo.flags = CKF_WRITE_PROTECTED; 163 164 metainfo.ulMaxPinLen = 0; 165 metainfo.ulMinPinLen = 0; 166 metainfo.hardwareVersion.major = 167 METASLOT_HARDWARE_VERSION_MAJOR; 168 metainfo.hardwareVersion.minor = 169 METASLOT_HARDWARE_VERSION_MINOR; 170 metainfo.firmwareVersion.major = 171 METASLOT_FIRMWARE_VERSION_MAJOR; 172 metainfo.firmwareVersion.minor = 173 METASLOT_FIRMWARE_VERSION_MINOR; 174 } 175 176 /* 177 * Override some values that the object token may have set. They 178 * can be inappropriate/misleading when used in the context of 179 * metaslot. 180 */ 181 (void) memcpy(metainfo.label, METASLOT_TOKEN_LABEL, 32); 182 (void) memcpy(metainfo.manufacturerID, 183 METASLOT_MANUFACTURER_ID, 32); 184 (void) memcpy(metainfo.model, METASLOT_TOKEN_MODEL, 16); 185 (void) memset(metainfo.serialNumber, ' ', 16); 186 187 metainfo.ulMaxSessionCount = CK_EFFECTIVELY_INFINITE; 188 metainfo.ulSessionCount = num_meta_sessions; 189 metainfo.ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE; 190 metainfo.ulRwSessionCount = num_rw_meta_sessions; 191 192 metainfo.flags |= CKF_RNG; 193 metainfo.flags &= ~CKF_RESTORE_KEY_NOT_NEEDED; 194 metainfo.flags |= CKF_TOKEN_INITIALIZED; 195 metainfo.flags &= ~CKF_SECONDARY_AUTHENTICATION; 196 197 /* Clear the time field if the token does not have a clock. */ 198 if (!(metainfo.flags & CKF_CLOCK_ON_TOKEN)) 199 (void) memset(metainfo.utcTime, ' ', 16); 200 201 *pInfo = metainfo; 202 203 return (CKR_OK); 204 } 205 206 207 /* 208 * meta_WaitForSlotEvent 209 * 210 * The metaslot never generates events, so this function doesn't do anything 211 * useful. We do not pass on provider events because we want to hide details 212 * of the providers. 213 * 214 * If CKF_DONT_BLOCK flag is turned on, CKR_NO_EVENT will be return. 215 * Otherwise, return CKR_FUNCTION_FAILED. 216 * 217 */ 218 /* ARGSUSED */ 219 CK_RV 220 meta_WaitForSlotEvent(CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, 221 CK_VOID_PTR pReserved) 222 { 223 if (flags & CKF_DONT_BLOCK) { 224 return (CKR_NO_EVENT); 225 } else { 226 return (CKR_FUNCTION_FAILED); 227 } 228 } 229 230 231 /* 232 * meta_GetMechanismList 233 * 234 * The slotID argument is not used. 235 * 236 */ 237 /*ARGSUSED*/ 238 CK_RV 239 meta_GetMechanismList(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, 240 CK_ULONG_PTR pulCount) 241 { 242 CK_RV rv; 243 244 if (!metaslot_enabled) { 245 return (CKR_SLOT_ID_INVALID); 246 } 247 248 if (pulCount == NULL) 249 return (CKR_ARGUMENTS_BAD); 250 251 rv = meta_mechManager_get_mechs(pMechanismList, pulCount); 252 253 if ((rv == CKR_BUFFER_TOO_SMALL) && (pMechanismList == NULL)) { 254 /* 255 * if pMechanismList is not provided, just need to 256 * return count 257 */ 258 rv = CKR_OK; 259 } 260 return (rv); 261 } 262 263 264 /* 265 * meta_GetMechanismInfo 266 * 267 * The slotID argument is not used. 268 */ 269 /*ARGSUSED*/ 270 CK_RV 271 meta_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, 272 CK_MECHANISM_INFO_PTR pInfo) 273 { 274 CK_RV rv; 275 mechinfo_t **slots = NULL; 276 unsigned long i, slotCount = 0; 277 mech_support_info_t mech_support_info; 278 279 if (!metaslot_enabled) { 280 return (CKR_SLOT_ID_INVALID); 281 } 282 283 if (pInfo == NULL) { 284 return (CKR_ARGUMENTS_BAD); 285 } 286 287 mech_support_info.supporting_slots = 288 malloc(meta_slotManager_get_slotcount() * sizeof (mechinfo_t *)); 289 if (mech_support_info.supporting_slots == NULL) { 290 return (CKR_HOST_MEMORY); 291 } 292 293 mech_support_info.mech = type; 294 295 rv = meta_mechManager_get_slots(&mech_support_info, TRUE, NULL); 296 if (rv != CKR_OK) { 297 free(mech_support_info.supporting_slots); 298 return (rv); 299 } 300 301 slotCount = mech_support_info.num_supporting_slots; 302 slots = mech_support_info.supporting_slots; 303 304 /* Merge mechanism info from all slots. */ 305 (void) memcpy(pInfo, &(slots[0]->mechanism_info), 306 sizeof (CK_MECHANISM_INFO)); 307 308 /* no need to look at index 0, since that's what we started with */ 309 for (i = 1; i < slotCount; i++) { 310 CK_ULONG thisValue; 311 312 /* MinKeySize should be smallest of all slots. */ 313 thisValue = slots[i]->mechanism_info.ulMinKeySize; 314 if (thisValue < pInfo->ulMinKeySize) { 315 pInfo->ulMinKeySize = thisValue; 316 } 317 318 /* MaxKeySize should be largest of all slots. */ 319 thisValue = slots[i]->mechanism_info.ulMaxKeySize; 320 if (thisValue > pInfo->ulMaxKeySize) { 321 pInfo->ulMaxKeySize = thisValue; 322 } 323 324 pInfo->flags |= slots[i]->mechanism_info.flags; 325 } 326 327 /* Clear the CKF_HW flag. We might select a software provider later. */ 328 pInfo->flags &= ~CKF_HW; 329 330 /* Clear the extenstion flag. Spec says is should never even be set. */ 331 pInfo->flags &= ~CKF_EXTENSION; 332 333 free(mech_support_info.supporting_slots); 334 335 return (CKR_OK); 336 } 337 338 339 /* 340 * meta_InitToken 341 * 342 * Not supported. The metaslot "token" is always initialized. The token object 343 * token must already be initialized. Other vendors don't seem to support 344 * this anyway. 345 */ 346 /* ARGSUSED */ 347 CK_RV 348 meta_InitToken(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, 349 CK_UTF8CHAR_PTR pLabel) 350 { 351 return (CKR_FUNCTION_NOT_SUPPORTED); 352 } 353 354 355 /* 356 * meta_InitPIN 357 * 358 * Not supported. Same reason as C_InitToken. 359 */ 360 /* ARGSUSED */ 361 CK_RV 362 meta_InitPIN(CK_SESSION_HANDLE hSession, 363 CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen) 364 { 365 return (CKR_FUNCTION_NOT_SUPPORTED); 366 } 367 368 369 /* 370 * meta_SetPIN 371 * 372 * This is basically just a pass-thru to the object token. No need to 373 * even check the arguments, since we don't use them. 374 */ 375 CK_RV 376 meta_SetPIN(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, 377 CK_ULONG ulOldPinLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewPinLen) 378 { 379 CK_RV rv; 380 meta_session_t *session; 381 slot_session_t *slot_session; 382 383 rv = meta_handle2session(hSession, &session); 384 if (rv != CKR_OK) 385 return (rv); 386 387 if (IS_READ_ONLY_SESSION(session->session_flags)) { 388 REFRELEASE(session); 389 return (CKR_SESSION_READ_ONLY); 390 } 391 392 rv = meta_get_slot_session(get_keystore_slotnum(), &slot_session, 393 session->session_flags); 394 if (rv != CKR_OK) { 395 REFRELEASE(session); 396 return (rv); 397 } 398 399 rv = FUNCLIST(slot_session->fw_st_id)->C_SetPIN(slot_session->hSession, 400 pOldPin, ulOldPinLen, pNewPin, ulNewPinLen); 401 402 meta_release_slot_session(slot_session); 403 404 REFRELEASE(session); 405 return (rv); 406 } 407