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