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

📄 cryptdev.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 3 页
字号:
			{
			case CRYPT_DEVICE_PKCS11:
				if( msgData->length < \
							deviceInfoPtr->devicePKCS11->minPinSize || \
					msgData->length > \
							deviceInfoPtr->devicePKCS11->maxPinSize )
					return( CRYPT_ARGERROR_NUM1 );

			case CRYPT_DEVICE_FORTEZZA:
				if( msgData->length < \
							deviceInfoPtr->deviceFortezza->minPinSize || \
					msgData->length > \
							deviceInfoPtr->deviceFortezza->maxPinSize )
					return( CRYPT_ARGERROR_NUM1 );
			}

	/* Send the control information to the device */
	status = deviceInfoPtr->controlFunction( deviceInfoPtr, messageValue,
											 msgData->data, msgData->length );
	if( cryptStatusError( status ) )
		return( status );

	/* If the user has logged in and the token has a hardware RNG, grab 256 
	   bits of entropy and send it to the system device.  Since we have no
	   idea how good this entropy is (it could be just a DES-based PRNG using
	   a static key or even an LFSR, which some smart cards use), we don't
	   set any entropy quality indication */
	if( isAuthent && deviceInfoPtr->getRandomFunction != NULL )
		{
		BYTE buffer[ 32 ];

		status = deviceInfoPtr->getRandomFunction( deviceInfoPtr, 
												   buffer, 32 );
		if( cryptStatusOK( status ) )
			{
			RESOURCE_DATA msgData;

			setMessageData( &msgData, buffer, 32 );
			krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_SETATTRIBUTE_S, 
							 &msgData, CRYPT_IATTRIBUTE_ENTROPY );
			}
		zeroise( buffer, 32 );
		}

	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*								Device API Functions						*
*																			*
****************************************************************************/

/* Default object creation routines used when the device code doesn't set
   anything up */

int createContext( MESSAGE_CREATEOBJECT_INFO *createInfo,
				   const void *auxDataPtr, const int auxValue );

static const CREATEOBJECT_FUNCTION_INFO defaultCreateFunctions[] = {
	{ OBJECT_TYPE_CONTEXT, createContext },
	{ OBJECT_TYPE_NONE, NULL }
	};

/* Handle a message sent to a device object */

static int deviceMessageFunction( const void *objectInfoPtr,
								  const MESSAGE_TYPE message,
								  void *messageDataPtr,
								  const int messageValue )
	{
	DEVICE_INFO *deviceInfoPtr = ( DEVICE_INFO * ) objectInfoPtr;

	/* Process the destroy object message */
	if( message == MESSAGE_DESTROY )
		{
		/* Shut down the device if required */
		if( deviceInfoPtr->flags & DEVICE_ACTIVE && \
			deviceInfoPtr->shutdownFunction != NULL )
			deviceInfoPtr->shutdownFunction( deviceInfoPtr );

		return( CRYPT_OK );
		}

	/* Process attribute get/set/delete messages */
	if( isAttributeMessage( message ) )
		{
		assert( message == MESSAGE_GETATTRIBUTE || \
				message == MESSAGE_GETATTRIBUTE_S || \
				message == MESSAGE_SETATTRIBUTE || \
				message == MESSAGE_SETATTRIBUTE_S );

		if( message == MESSAGE_GETATTRIBUTE )
			return( processGetAttribute( deviceInfoPtr, messageDataPtr,
										 messageValue ) );
		if( message == MESSAGE_GETATTRIBUTE_S )
			return( processGetAttributeS( deviceInfoPtr, messageDataPtr,
										  messageValue ) );
		if( message == MESSAGE_SETATTRIBUTE )
			return( processSetAttribute( deviceInfoPtr, messageDataPtr,
										 messageValue ) );
		if( message == MESSAGE_SETATTRIBUTE_S )
			return( processSetAttributeS( deviceInfoPtr, messageDataPtr,
										  messageValue ) );

		assert( NOTREACHED );
		return( CRYPT_ERROR );	/* Get rid of compiler warning */
		}

	/* Process action messages */
	if( isMechanismActionMessage( message ) )
		{
		CRYPT_DEVICE localCryptDevice = deviceInfoPtr->objectHandle;
		MECHANISM_FUNCTION mechanismFunction = NULL;
		int status;

		/* Find the function to handle this action and mechanism */
		if( deviceInfoPtr->mechanismFunctions != NULL )
			{
			int i = 0;

			while( deviceInfoPtr->mechanismFunctions[ i ].action != MESSAGE_NONE )
				{
				if( deviceInfoPtr->mechanismFunctions[ i ].action == message && \
					deviceInfoPtr->mechanismFunctions[ i ].mechanism == messageValue )
					{
					mechanismFunction = \
						deviceInfoPtr->mechanismFunctions[ i ].function;
					break;
					}
				i++;
				}
			}
		if( mechanismFunction == NULL && \
			localCryptDevice != SYSTEM_OBJECT_HANDLE )
			{
			int i = 0;

			/* This isn't the system object, fall back to the system object
			   and see if it can handle the mechanism.  We do it this way
			   rather than sending the message through the kernel a second
			   time because all the kernel checking of message parameters has
			   already been done (in terms of access control checks, we can
			   always send the message to the system object so this isn't a
			   problem), this saves the overhead of a second, redundant
			   kernel pass.  This code is currently only ever used with 
			   Fortezza devices, with PKCS #11 devices the support for 
			   various mechanisms is too patchy to allow us to rely on it, 
			   so we always use system mechanisms which we know will get it
			   right.  Because it should never be used in normal use, we 
			   throw an exception if we get here inadvertently (if this 
			   doesn't stop execution, the krnlAcquireObject() will since it 
			   will refuse to allocate the system object) */
			assert( NOTREACHED );
			krnlReleaseObject( deviceInfoPtr->objectHandle );
			localCryptDevice = SYSTEM_OBJECT_HANDLE;
			status = krnlAcquireObject( localCryptDevice, OBJECT_TYPE_DEVICE, 
										( void ** ) &deviceInfoPtr, 
										CRYPT_ERROR_SIGNALLED );
			if( cryptStatusError( status ) )
				return( status );
			assert( deviceInfoPtr->mechanismFunctions != NULL );
			while( deviceInfoPtr->mechanismFunctions[ i ].action != MESSAGE_NONE )
				{
				if( deviceInfoPtr->mechanismFunctions[ i ].action == message && \
					deviceInfoPtr->mechanismFunctions[ i ].mechanism == messageValue )
					{
					mechanismFunction = \
							deviceInfoPtr->mechanismFunctions[ i ].function;
					break;
					}
				i++;
				}
			}
		if( mechanismFunction == NULL )
			{
			krnlReleaseObject( deviceInfoPtr->objectHandle );
			return( CRYPT_ERROR_NOTAVAIL );
			}

		/* If the message has been sent to the system object, unlock it to
		   allow it to be used by others and dispatch the message */
		if( localCryptDevice == SYSTEM_OBJECT_HANDLE )
			{
			krnlReleaseObject( deviceInfoPtr->objectHandle );
			return( mechanismFunction( NULL, messageDataPtr ) );
			}

		/* Send the message to the device */
		return( mechanismFunction( deviceInfoPtr, messageDataPtr ) );
		}

	/* Process messages that check a device */
	if( message == MESSAGE_CHECK )
		{
		/* The check for whether this device type can contain an object that 
		   can perform the requested operation has already been performed by 
		   the kernel, so there's nothing further to do here */
		assert( ( messageValue == MESSAGE_CHECK_PKC_ENCRYPT_AVAIL || \
				  messageValue == MESSAGE_CHECK_PKC_DECRYPT_AVAIL || \
				  messageValue == MESSAGE_CHECK_PKC_SIGCHECK_AVAIL || \
				  messageValue == MESSAGE_CHECK_PKC_SIGN_AVAIL ) && \
				( deviceInfoPtr->type == CRYPT_DEVICE_FORTEZZA || \
				  deviceInfoPtr->type == CRYPT_DEVICE_PKCS11 || \
				  deviceInfoPtr->type == CRYPT_DEVICE_CRYPTOAPI ) );

		return( CRYPT_OK );
		}

	/* Process object-specific messages */
	if( message == MESSAGE_KEY_GETKEY )
		{
		MESSAGE_KEYMGMT_INFO *getkeyInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
		assert( deviceInfoPtr->getItemFunction != NULL );

		/* Create a context via an object in the device */
		return( deviceInfoPtr->getItemFunction( deviceInfoPtr,
								&getkeyInfo->cryptHandle, messageValue,
								getkeyInfo->keyIDtype, getkeyInfo->keyID,
								getkeyInfo->keyIDlength, getkeyInfo->auxInfo, 
								&getkeyInfo->auxInfoLength, 
								getkeyInfo->flags ) );
		}
	if( message == MESSAGE_KEY_SETKEY )
		{
		MESSAGE_KEYMGMT_INFO *setkeyInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
		assert( deviceInfoPtr->setItemFunction != NULL );

		/* Update the device with the cert */
		return( deviceInfoPtr->setItemFunction( deviceInfoPtr,
												setkeyInfo->cryptHandle ) );
		}
	if( message == MESSAGE_KEY_DELETEKEY )
		{
		MESSAGE_KEYMGMT_INFO *deletekeyInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
		assert( deviceInfoPtr->deleteItemFunction != NULL );

		/* Delete an object in the device */
		return( deviceInfoPtr->deleteItemFunction( deviceInfoPtr,
						messageValue, deletekeyInfo->keyIDtype,
						deletekeyInfo->keyID, deletekeyInfo->keyIDlength ) );
		}
	if( message == MESSAGE_KEY_GETFIRSTCERT )
		{
		MESSAGE_KEYMGMT_INFO *getnextcertInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;

		assert( getnextcertInfo->auxInfoLength == sizeof( int ) );
		assert( messageValue == KEYMGMT_ITEM_PUBLICKEY );
		assert( deviceInfoPtr->getFirstItemFunction != NULL );

		/* Fetch a cert in a cert chain from the device */
		return( deviceInfoPtr->getFirstItemFunction( deviceInfoPtr,
						&getnextcertInfo->cryptHandle, getnextcertInfo->auxInfo,
						getnextcertInfo->keyIDtype, getnextcertInfo->keyID,
						getnextcertInfo->keyIDlength, messageValue,
						getnextcertInfo->flags ) );
		}
	if( message == MESSAGE_KEY_GETNEXTCERT )
		{
		MESSAGE_KEYMGMT_INFO *getnextcertInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;

		assert( getnextcertInfo->auxInfoLength == sizeof( int ) );
		assert( deviceInfoPtr->getNextItemFunction != NULL );

		/* Fetch a cert in a cert chain from the device */
		return( deviceInfoPtr->getNextItemFunction( deviceInfoPtr,
						&getnextcertInfo->cryptHandle, getnextcertInfo->auxInfo,
						getnextcertInfo->flags ) );
		}
	if( message == MESSAGE_DEV_QUERYCAPABILITY )
		{
		const void FAR_BSS *capabilityInfoPtr;
		CRYPT_QUERY_INFO *queryInfo = ( CRYPT_QUERY_INFO * ) messageDataPtr;

		/* Find the information for this algorithm and return the appropriate
		   information */
		capabilityInfoPtr = findCapabilityInfo( deviceInfoPtr->capabilityInfoList,
												messageValue );
		if( capabilityInfoPtr == NULL )
			return( CRYPT_ERROR_NOTAVAIL );
		getCapabilityInfo( queryInfo, capabilityInfoPtr );

		return( CRYPT_OK );
		}
	if( message == MESSAGE_DEV_CREATEOBJECT )
		{
		CRYPT_DEVICE iCryptDevice = deviceInfoPtr->objectHandle;
		CREATEOBJECT_FUNCTION createObjectFunction = NULL;
		const void *auxInfo = NULL;
		int status;

		assert( messageValue > OBJECT_TYPE_NONE && \
				messageValue < OBJECT_TYPE_LAST );

		/* If the device can't have objects created within it, complain */
		if( deviceInfoPtr->flags & DEVICE_READONLY )
			return( CRYPT_ERROR_PERMISSION );

		/* Find the function to handle this object */
		if( deviceInfoPtr->createObjectFunctions != NULL )
			{
			int i = 0;

			while( deviceInfoPtr->createObjectFunctions[ i ].type != OBJECT_TYPE_NONE )
				{
				if( deviceInfoPtr->createObjectFunctions[ i ].type == messageValue )
					{
					createObjectFunction  = \
						deviceInfoPtr->createObjectFunctions[ i ].function;
					break;
					}
				i++;
				}
			}
		if( createObjectFunction  == NULL )
			return( CRYPT_ERROR_NOTAVAIL );

		/* Get any auxiliary info that we may need to create the object */
		if( messageValue == OBJECT_TYPE_CONTEXT )
			auxInfo = deviceInfoPtr->capabilityInfoList;

		/* If the message has been sent to the system object, unlock it to
		   allow it to be used by others and dispatch the message.  This is 
		   safe because the auxInfo for the system device is in a static,
		   read-only segment and persists even if the system device is
		   destroyed */
		if( deviceInfoPtr->objectHandle == SYSTEM_OBJECT_HANDLE )
			{
			krnlReleaseObject( deviceInfoPtr->objectHandle );
			status = createObjectFunction( messageDataPtr, auxInfo, 
										   CREATEOBJECT_FLAG_NONE );

⌨️ 快捷键说明

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