⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pkcs11_init.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 4 页
字号:
		if( capabilityInfo->keySize < capabilityInfo->minKeySize )
			capabilityInfo->keySize = capabilityInfo->minKeySize;
		capabilityInfo->maxKeySize = min( maxKeySize, 
										  capabilityInfo->maxKeySize );
		if( capabilityInfo->maxKeySize < capabilityInfo->minKeySize )
			{
			/* Serious braindamage in the driver, we'll just have to make
			   a sensible guess */
			assert( DEBUG_WARN );
			capabilityInfo->maxKeySize = \
									( cryptAlgo == CRYPT_ALGO_RSA || \
									  isDlpAlgo( cryptAlgo ) ) ? 128 : 16;
			}
		if( capabilityInfo->keySize > capabilityInfo->maxKeySize )
			capabilityInfo->keySize = capabilityInfo->maxKeySize;
		capabilityInfo->endFunction = genericEndFunction;
		}

	/* Set up the device-specific handlers */
	capabilityInfo->selfTestFunction = selfTestFunction;
	capabilityInfo->getInfoFunction = getDefaultInfo;
	if( cryptAlgo != CRYPT_ALGO_DH && cryptAlgo != CRYPT_ALGO_RSA && \
		cryptAlgo != CRYPT_ALGO_DSA )
		capabilityInfo->initKeyParamsFunction = initKeyParams;
	capabilityInfo->endFunction = mechanismInfoPtr->endFunction;
	capabilityInfo->initKeyFunction = mechanismInfoPtr->initKeyFunction;
	if( pMechanism.flags & keyGenFlag )
		capabilityInfo->generateKeyFunction = \
									mechanismInfoPtr->generateKeyFunction;
	if( pMechanism.flags & CKF_SIGN )
		{
		/* cryptlib treats hashing as an encrypt/decrypt operation while 
		   PKCS #11 treats it as a sign/verify operation, so we have to
		   juggle the function pointers based on the underlying algorithm
		   type */
		if( isPKC )
			capabilityInfo->signFunction = mechanismInfoPtr->signFunction;
		else
			capabilityInfo->encryptFunction = mechanismInfoPtr->encryptFunction;
		}
	if( pMechanism.flags & CKF_VERIFY )
		{
		/* See comment above */
		if( isPKC )
			capabilityInfo->sigCheckFunction = mechanismInfoPtr->sigCheckFunction;
		else
			capabilityInfo->decryptFunction = mechanismInfoPtr->decryptFunction;
		}
	if( pMechanism.flags & CKF_ENCRYPT )
		{
		/* Not all devices implement all modes, so we have to be careful to 
		   set up the pointer for the exact mode that's supported */
		switch( mechanismInfoPtr->cryptMode )
			{
			case CRYPT_MODE_CBC:
				capabilityInfo->encryptCBCFunction = mechanismInfoPtr->encryptFunction;
				break;

			case CRYPT_MODE_CFB:
				capabilityInfo->encryptCFBFunction = mechanismInfoPtr->encryptFunction;
				break;

			case CRYPT_MODE_OFB:
				capabilityInfo->encryptOFBFunction = mechanismInfoPtr->encryptFunction;
				break;

			default:	/* ECB or a PKC */
				capabilityInfo->encryptFunction = mechanismInfoPtr->encryptFunction;
				break;
			}
		}
	if( pMechanism.flags & CKF_DECRYPT )
		{
		/* Not all devices implement all modes, so we have to be careful to 
		   set up the pointer for the exact mode that's supported */
		switch( mechanismInfoPtr->cryptMode )
			{
			case CRYPT_MODE_CBC:
				capabilityInfo->decryptCBCFunction = mechanismInfoPtr->decryptFunction;
				break;

			case CRYPT_MODE_CFB:
				capabilityInfo->decryptCFBFunction = mechanismInfoPtr->decryptFunction;
				break;

			case CRYPT_MODE_OFB:
				capabilityInfo->decryptOFBFunction = mechanismInfoPtr->decryptFunction;
				break;

			default:	/* ECB or a PKC */
				capabilityInfo->decryptFunction = mechanismInfoPtr->decryptFunction;
				break;
			}
		}
	if( cryptAlgo == CRYPT_ALGO_DH && pMechanism.flags & CKF_DERIVE )
		{
		/* DH is a special-case that doesn't really have an encrypt function 
		   and where "decryption" is actually a derivation */
		capabilityInfo->encryptFunction = mechanismInfoPtr->encryptFunction;
		capabilityInfo->decryptFunction = mechanismInfoPtr->decryptFunction;
		}

	/* Keygen capabilities are generally present as separate mechanisms,
	   sometimes CKF_GENERATE/CKF_GENERATE_KEY_PAIR is set for the main 
	   mechanism and sometimes it's set for the separate one so if it isn't 
	   present in the main one we check the alternative one */
	if( !( pMechanism.flags & keyGenFlag ) && \
		( mechanismInfoPtr->keygenMechanism != CKM_NONE ) )
		{
		status = C_GetMechanismInfo( pkcs11Info->slotID, 
									 mechanismInfoPtr->keygenMechanism,
									 &pMechanism );
		if( status == CKR_OK && ( pMechanism.flags & keyGenFlag ) && \
			( !hardwareOnly || ( pMechanism.flags & CKF_HW ) ) )
			/* Some tinkertoy tokens don't implement key generation in 
			   hardware but instead do it on the host PC (!!!) and load the
			   key into the token afterwards, so we have to perform another 
			   check here to make sure that they're doing things right */
			capabilityInfo->generateKeyFunction = \
									mechanismInfoPtr->generateKeyFunction;
		}

	/* Record mechanism-specific parameters if required */
	if( ( cryptAlgo >= CRYPT_ALGO_FIRST_CONVENTIONAL && \
		  cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL ) || \
		( cryptAlgo >= CRYPT_ALGO_FIRST_MAC && \
		  cryptAlgo <= CRYPT_ALGO_LAST_MAC ) )
		{
		capabilityInfo->paramKeyType = mechanismInfoPtr->keyType;
		capabilityInfo->paramKeyGen = mechanismInfoPtr->keygenMechanism;
		capabilityInfo->paramDefaultMech = mechanismInfoPtr->defaultMechanism;
		}

	/* If it's not a conventional encryption algo, we're done */
	if( cryptAlgo < CRYPT_ALGO_FIRST_CONVENTIONAL || \
		cryptAlgo > CRYPT_ALGO_LAST_CONVENTIONAL )
		return( ( CAPABILITY_INFO * ) capabilityInfo );

	/* PKCS #11 handles encryption modes by defining a separate mechanism for
	   each one.  In order to enumerate all the modes available for a 
	   particular algorithm we check for each mechanism in turn and set up 
	   the appropriate function pointers if it's available */
	for( mechanismInfoPtr++, iterationCount = 0; 
		 mechanismInfoPtr->cryptAlgo == cryptAlgo && \
			iterationCount < maxMechanisms; 
		 mechanismInfoPtr++, iterationCount++ )
		{
		/* There's a different form of the existing mechanism available,
		   check whether the driver implements it */
		status = C_GetMechanismInfo( pkcs11Info->slotID, 
									 mechanismInfoPtr->mechanism,
									 &pMechanism );
		if( status != CKR_OK )
			continue;

		/* Set up the pointer for the appropriate encryption mode */
		switch( mechanismInfoPtr->cryptMode )
			{
			case CRYPT_MODE_CBC:
				if( pMechanism.flags & CKF_ENCRYPT )
					capabilityInfo->encryptCBCFunction = \
										mechanismInfoPtr->encryptFunction;
				if( pMechanism.flags & CKF_DECRYPT )
					capabilityInfo->decryptCBCFunction = \
										mechanismInfoPtr->decryptFunction;
				break;
			case CRYPT_MODE_CFB:
				if( pMechanism.flags & CKF_ENCRYPT )
					capabilityInfo->encryptCFBFunction = \
										mechanismInfoPtr->encryptFunction;
				if( pMechanism.flags & CKF_DECRYPT )
					capabilityInfo->decryptCFBFunction = \
										mechanismInfoPtr->decryptFunction;
				break;
			case CRYPT_MODE_OFB:
				if( pMechanism.flags & CKF_ENCRYPT )
					capabilityInfo->encryptOFBFunction = \
										mechanismInfoPtr->encryptFunction;
				if( pMechanism.flags & CKF_DECRYPT )
					capabilityInfo->decryptOFBFunction = \
										mechanismInfoPtr->decryptFunction;
				break;

			default:
				retIntError_Null();
			}
		}
	if( iterationCount >= maxMechanisms )
		retIntError_Null();

	return( ( CAPABILITY_INFO * ) capabilityInfo );
	}

/* Set the capability information based on device capabilities.  Since
   PKCS #11 devices can have assorted capabilities (and can vary depending
   on what's plugged in), we have to build this up on the fly rather than
   using a fixed table like the built-in capabilities */

static void freeCapabilities( DEVICE_INFO *deviceInfo )
	{
	CAPABILITY_INFO_LIST *capabilityInfoListPtr = \
				( CAPABILITY_INFO_LIST * ) deviceInfo->capabilityInfoList;

	/* If the list was empty, return now */
	if( capabilityInfoListPtr == NULL )
		return;
	deviceInfo->capabilityInfoList = NULL;

	while( capabilityInfoListPtr != NULL )
		{
		CAPABILITY_INFO_LIST *listItemToFree = capabilityInfoListPtr;
		CAPABILITY_INFO *itemToFree = ( CAPABILITY_INFO * ) listItemToFree->info;

		capabilityInfoListPtr = capabilityInfoListPtr->next;
		zeroise( itemToFree, sizeof( CAPABILITY_INFO ) );
		clFree( "freeCapabilities", itemToFree );
		zeroise( listItemToFree, sizeof( CAPABILITY_INFO_LIST ) );
		clFree( "freeCapabilities", listItemToFree );
		}
	}

static int getCapabilities( DEVICE_INFO *deviceInfo,
							const PKCS11_MECHANISM_INFO *mechanismInfoPtr, 
							const int maxMechanisms )
	{
	CAPABILITY_INFO_LIST *capabilityInfoListTail = \
				( CAPABILITY_INFO_LIST * ) deviceInfo->capabilityInfoList;
	int i;

	assert( sizeof( CAPABILITY_INFO ) == sizeof( VARIABLE_CAPABILITY_INFO ) );

	/* Find the end of the list to add new capabilities */
	if( capabilityInfoListTail != NULL )
		{
		while( capabilityInfoListTail->next != NULL )
			capabilityInfoListTail = capabilityInfoListTail->next;
		}

	/* Add capability information for each recognised mechanism type */
	for( i = 0; mechanismInfoPtr[ i ].mechanism != CKM_NONE && \
				i < maxMechanisms; i++ )
		{
		CAPABILITY_INFO_LIST *newCapabilityList;
		CAPABILITY_INFO *newCapability;
		const CRYPT_ALGO_TYPE cryptAlgo = mechanismInfoPtr[ i ].cryptAlgo;

		/* If the assertion below triggers then the PKCS #11 driver is 
		   broken since it's returning inconsistent information such as 
		   illegal key length data, conflicting algorithm information, etc 
		   etc.  This assertion is included here to detect buggy drivers 
		   early on rather than forcing users to step through the PKCS #11 
		   glue code to find out why an operation is failing.
		   
		   Because some tinkertoy implementations support only the bare 
		   minimum functionality (e.g.RSA private key ops and nothing else),
		   we allow asymmetric functionality for PKCs */
		newCapability = getCapability( deviceInfo, &mechanismInfoPtr[ i ],
									   maxMechanisms - i );
		if( newCapability == NULL )
			continue;
		REQUIRES( sanityCheckCapability( newCapability, 
					( newCapability->cryptAlgo >= CRYPT_ALGO_FIRST_PKC && \
					  newCapability->cryptAlgo <= CRYPT_ALGO_LAST_PKC ) ? \
					  TRUE : FALSE ) );
		if( ( newCapabilityList = \
						clAlloc( "getCapabilities", \
								 sizeof( CAPABILITY_INFO_LIST ) ) ) == NULL )
			{
			clFree( "getCapabilities", newCapability );
			continue;
			}
		newCapabilityList->info = newCapability;
		newCapabilityList->next = NULL;
		if( deviceInfo->capabilityInfoList == NULL )
			deviceInfo->capabilityInfoList = newCapabilityList;
		else
			capabilityInfoListTail->next = newCapabilityList;
		capabilityInfoListTail = newCapabilityList;

		/* Since there may be alternative mechanisms to the current one 
		   defined, we have to skip mechanisms until we find a ones for a
		   new algorithm */
		while( mechanismInfoPtr[ i + 1 ].cryptAlgo == cryptAlgo && \
			   i < maxMechanisms )
			i++;
		if( i >= maxMechanisms )
			retIntError();
		}
	if( i >= maxMechanisms )
		retIntError();

	return( ( deviceInfo->capabilityInfoList == NULL ) ? CRYPT_ERROR : CRYPT_OK );
	}

/****************************************************************************
*																			*
*					Device Init/Shutdown/Device Control Routines			*
*																			*
****************************************************************************/

/* Close a previously-opened session with the device.  We have to have this
   before the init function since it may be called by it if the init process
   fails */

static void shutdownFunction( DEVICE_INFO *deviceInfo )
	{
	PKCS11_INFO *pkcs11Info = deviceInfo->devicePKCS11;

	/* Log out and close the session with the device */
	if( deviceInfo->flags & DEVICE_LOGGEDIN )
		C_Logout( pkcs11Info->hSession );
	C_CloseSession( pkcs11Info->hSession );
	pkcs11Info->hSession = CK_OBJECT_NONE;
	deviceInfo->flags &= ~( DEVICE_ACTIVE | DEVICE_LOGGEDIN );

	/* Free the device capability information */
	freeCapabilities( deviceInfo );
	}

/* Open a session with the device */

static int initFunction( DEVICE_INFO *deviceInfo, const char *name,
						 const int nameLength )
	{
	CK_SESSION_HANDLE hSession;
	CK_SLOT_ID slotList[ MAX_PKCS11_SLOTS + 8 ];
	CK_ULONG slotCount = MAX_PKCS11_SLOTS;
	CK_SLOT_INFO slotInfo;
	CK_TOKEN_INFO tokenInfo;
	CK_RV status;
	PKCS11_INFO *pkcs11Info = deviceInfo->devicePKCS11;
	const PKCS11_MECHANISM_INFO *mechanismInfoPtr;
	char *labelPtr;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -