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

📄 cryptdev.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 2 页
字号:
		   use the object after this point will be blocked */
		return( CRYPT_OK );
	if( message == RESOURCE_MESSAGE_UNLOCK )
		{
		/* "Wenn drei Leute in ein Zimmer reingehen und fuenf kommen raus,
			dann muessen erst mal zwei wieder reingehen bis das Zimmer leer
			ist" */
		unlockResource( deviceInfoPtr );/* Undo RESOURCE_MESSAGE_LOCK lock */
		unlockResourceExit( deviceInfoPtr, CRYPT_OK );
		}

	/* Process object-specific messages */
	if( message == RESOURCE_MESSAGE_KEY_GETKEY )
		{
		MESSAGE_KEYMGMT_INFO *getkeyInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
		int status = CRYPT_ERROR_NOTAVAIL;

		/* Create a context via an object in the device */
		if( deviceInfoPtr->getItemFunction != NULL )
			status = deviceInfoPtr->getItemFunction( deviceInfoPtr,
								&getkeyInfo->cryptHandle, messageValue,
								getkeyInfo->keyIDtype, getkeyInfo->keyID,
								getkeyInfo->keyIDlength, NULL, 0,
								getkeyInfo->flags );

		unlockResourceExit( deviceInfoPtr, status );
		}
	if( message == RESOURCE_MESSAGE_KEY_SETKEY )
		{
		MESSAGE_KEYMGMT_INFO *setkeyInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
		CRYPT_CERTTYPE_TYPE type;
		int isInited = FALSE, status;

		/* Make sure it's the correct type of certificate object and that
		   it's ready for use */
		status = krnlSendMessage( setkeyInfo->cryptHandle,
								  RESOURCE_IMESSAGE_GETATTRIBUTE,
								  &type, CRYPT_CERTINFO_CERTTYPE );
		if( cryptStatusOK( status ) )
			status = krnlSendMessage( setkeyInfo->cryptHandle,
									  RESOURCE_IMESSAGE_GETATTRIBUTE,
									  &isInited, CRYPT_CERTINFO_IMMUTABLE );
		if( cryptStatusError( status ) || \
			( type != CRYPT_CERTTYPE_CERTIFICATE && \
			  type != CRYPT_CERTTYPE_CERTCHAIN ) || !isInited )
			unlockResourceExit( deviceInfoPtr, CRYPT_ARGERROR_NUM1 );

		/* Update the device with the cert */
		if( deviceInfoPtr->setItemFunction != NULL )
			status = deviceInfoPtr->setItemFunction( deviceInfoPtr,
													 setkeyInfo->cryptHandle );

		unlockResourceExit( deviceInfoPtr, status );
		}
	if( message == RESOURCE_MESSAGE_KEY_DELETEKEY )
		{
		MESSAGE_KEYMGMT_INFO *deletekeyInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
		int status = CRYPT_ERROR_NOTAVAIL;

		/* Delete an object in the device */
		if( deviceInfoPtr->deleteItemFunction != NULL )
			status = deviceInfoPtr->deleteItemFunction( deviceInfoPtr,
							messageValue, deletekeyInfo->keyIDtype,
							deletekeyInfo->keyID, deletekeyInfo->keyIDlength );

		unlockResourceExit( deviceInfoPtr, status );
		}
	if( message == RESOURCE_MESSAGE_KEY_GETFIRSTCERT )
		{
		MESSAGE_KEYMGMT_INFO *getnextcertInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
		int status = CRYPT_ERROR_NOTAVAIL;

		assert( getnextcertInfo->auxInfoLength == sizeof( int ) );
		assert( messageValue == KEYMGMT_ITEM_PUBLICKEY );

		/* Fetch a cert in a cert chain from the device */
		if( deviceInfoPtr->getFirstItemFunction != NULL )
			status = deviceInfoPtr->getFirstItemFunction( deviceInfoPtr,
						&getnextcertInfo->cryptHandle, getnextcertInfo->auxInfo,
						getnextcertInfo->keyIDtype, getnextcertInfo->keyID,
						getnextcertInfo->keyIDlength, messageValue,
						getnextcertInfo->flags );

		unlockResourceExit( deviceInfoPtr, status );
		}
	if( message == RESOURCE_MESSAGE_KEY_GETNEXTCERT )
		{
		MESSAGE_KEYMGMT_INFO *getnextcertInfo = \
								( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;
		int status = CRYPT_ERROR_NOTAVAIL;

		assert( getnextcertInfo->auxInfoLength == sizeof( int ) );

		/* Fetch a cert in a cert chain from the device */
		if( deviceInfoPtr->getNextItemFunction != NULL )
			status = deviceInfoPtr->getNextItemFunction( deviceInfoPtr,
						&getnextcertInfo->cryptHandle, getnextcertInfo->auxInfo,
						getnextcertInfo->flags );

		unlockResourceExit( deviceInfoPtr, status );
		}
	if( message == RESOURCE_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->capabilityInfo,
												messageValue );
		if( capabilityInfoPtr == NULL )
			unlockResourceExit( deviceInfoPtr, CRYPT_ERROR_NOTAVAIL );
		copyCapabilityInfo( capabilityInfoPtr, queryInfo );

		unlockResourceExit( deviceInfoPtr, CRYPT_OK );
		}
	if( message == RESOURCE_MESSAGE_DEV_CREATEOBJECT )
		{
		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 )
			unlockResourceExit( deviceInfoPtr, 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 )
			unlockResourceExit( deviceInfoPtr, CRYPT_ERROR_NOTAVAIL );

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

		/* 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( cryptDevice == SYSTEM_OBJECT_HANDLE )
			{
			unlockResource( deviceInfoPtr );
			status = createObjectFunction( messageDataPtr, auxInfo, 0 );
			}
		else
			{
			/* Send the message to the device.  We can't unlock the device
			   info before we call the create object function because there
			   may be auxiliary info held in the device object which we need
			   to ensure the existence of */
			status = createObjectFunction( messageDataPtr, auxInfo,
										   CREATEOBJECT_FLAG_DUMMY );
			unlockResource( deviceInfoPtr );
			}
		if( cryptStatusError( status ) )
			return( status );

		/* Make the newly-created object a dependent object of the device */
		krnlSendMessage( ( ( MESSAGE_CREATEOBJECT_INFO * ) messageDataPtr )->cryptHandle,
						 RESOURCE_IMESSAGE_SETDEPENDENT, ( void * ) &cryptDevice,
						 SETDEP_OPTION_INCREF );
		return( CRYPT_OK );
		}
	if( message == RESOURCE_MESSAGE_DEV_CREATEOBJECT_INDIRECT )
		{
		int createCertificateIndirect( MESSAGE_CREATEOBJECT_INFO *createInfo,
									   const void *auxDataPtr, const int auxValue );
		int status;

		/* At the moment the only objects where can be created in this manner
		   are certificates */
		assert( messageValue == OBJECT_TYPE_CERTIFICATE );
		assert( cryptDevice == SYSTEM_OBJECT_HANDLE );

		/* Unlock the system object to allow it to be used by others and 
		   dispatch the message */
		unlockResource( deviceInfoPtr );
		status = createCertificateIndirect( messageDataPtr, NULL, 0 );
		if( cryptStatusError( status ) )
			return( status );

		/* Make the newly-created object a dependent object of the device */
		krnlSendMessage( ( ( MESSAGE_CREATEOBJECT_INFO * ) messageDataPtr )->cryptHandle,
						 RESOURCE_IMESSAGE_SETDEPENDENT, ( void * ) &cryptDevice,
						 SETDEP_OPTION_INCREF );
		return( CRYPT_OK );
		}

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

/* Open a device.  This is a common function called to create both the
   internal system device objects and general devices */

static int openDevice( CRYPT_DEVICE *device,
					   const CRYPT_USER cryptOwner,
					   const CRYPT_DEVICE_TYPE deviceType,
					   const char *name, const int nameLength,
					   DEVICE_INFO **deviceInfoPtrPtr )
	{
	DEVICE_INFO *deviceInfoPtr;
	const int subType = \
			( deviceType == CRYPT_DEVICE_NONE ) ? SUBTYPE_DEV_SYSTEM : \
			( deviceType == CRYPT_DEVICE_FORTEZZA ) ? SUBTYPE_DEV_FORTEZZA : \
			( deviceType == CRYPT_DEVICE_PKCS11 ) ? SUBTYPE_DEV_PKCS11 : 0;
	int status;

	assert( deviceInfoPtrPtr != NULL );
	assert( subType != 0 );

	/* Clear the return values */
	*device = CRYPT_ERROR;
	*deviceInfoPtrPtr = NULL;

	/* Create the device object and connect it to the device */
	status = krnlCreateObject( ( void ** ) &deviceInfoPtr, cryptOwner,
							   OBJECT_TYPE_DEVICE, subType,
							   sizeof( DEVICE_INFO ), 0, 0,
							   deviceMessageFunction );
	if( cryptStatusError( status ) )
		return( status );
	initResourceLock( deviceInfoPtr );
	lockResource( deviceInfoPtr );
	*deviceInfoPtrPtr = deviceInfoPtr;
	*device = deviceInfoPtr->objectHandle = status;
	deviceInfoPtr->ownerHandle = cryptOwner;
	deviceInfoPtr->type = deviceType;

	/* Set up the access information for the device and connect to it */
	switch( deviceType )
		{
		case CRYPT_DEVICE_NONE:
			status = setDeviceSystem( deviceInfoPtr );
			break;

		case CRYPT_DEVICE_FORTEZZA:
			status = setDeviceFortezza( deviceInfoPtr );
			break;

		case CRYPT_DEVICE_PKCS11:
			status = setDevicePKCS11( deviceInfoPtr, name, nameLength );
			break;

		default:
			assert( NOTREACHED );
		}
	if( cryptStatusOK( status ) )
		status = deviceInfoPtr->initFunction( deviceInfoPtr, name, 
											  nameLength );
	if( cryptStatusOK( status ) && \
		deviceInfoPtr->createObjectFunctions == NULL )
		/* The device-specific code hasn't set up anything, use the default
		   create-object functions (which just create encryption contexts
		   using the device capability information) */
		deviceInfoPtr->createObjectFunctions = defaultCreateFunctions;

	return( status );
	}

/* Create a device object */

int createDevice( MESSAGE_CREATEOBJECT_INFO *createInfo,
				  const void *auxDataPtr, const int auxValue )
	{
	CRYPT_DEVICE iCryptDevice;
	DEVICE_INFO *deviceInfoPtr;
	int initStatus, status;

	assert( auxDataPtr == NULL );
	assert( auxValue == 0 );

	/* Perform basic error checking */
	if( createInfo->arg1 <= CRYPT_DEVICE_NONE || \
		createInfo->arg1 >= CRYPT_DEVICE_LAST )
		return( CRYPT_ARGERROR_NUM1 );
	if( createInfo->arg1 == CRYPT_DEVICE_PKCS11 && \
		createInfo->strArgLen1 <= 2 )
		return( CRYPT_ARGERROR_STR1 );

	/* Wait for any async device driver binding to complete */
	waitSemaphore( SEMAPHORE_DRIVERBIND );

	/* Pass the call on to the lower-level open function */
	initStatus = openDevice( &iCryptDevice, createInfo->cryptOwner,
							 createInfo->arg1, createInfo->strArg1,
							 createInfo->strArgLen1, &deviceInfoPtr );
	if( deviceInfoPtr == NULL )
		return( initStatus );	/* Create object failed, return immediately */
	if( cryptStatusError( initStatus ) )
		/* The device open failed, make sure the object gets destroyed when
		   we notify the kernel that the setup process is complete */
		krnlSendNotifier( iCryptDevice, RESOURCE_IMESSAGE_DESTROY );

	/* We've finished setting up the object-type-specific info, tell the
	   kernel the object is ready for use */
	unlockResource( deviceInfoPtr );
	status = krnlSendMessage( iCryptDevice, RESOURCE_IMESSAGE_SETATTRIBUTE,
							  MESSAGE_VALUE_OK, CRYPT_IATTRIBUTE_STATUS );
	if( cryptStatusError( initStatus ) || cryptStatusError( status ) )
		return( cryptStatusError( initStatus ) ? initStatus : status );
	createInfo->cryptHandle = iCryptDevice;
	return( CRYPT_OK );
	}

/* Create the internal system device object.  This is somewhat special in
   that it can't be destroyed through a normal message (it can only be done
   from one place in the kernel) so if the open fails we don't use the normal
   signalling mechanism to destroy it but simply return an error code to the
   caller, which causes the cryptlib init to fail and destroys the object
   when the kernel shuts down */

int createSystemDeviceObject( void )
	{
	CRYPT_DEVICE iSystemObject;
	DEVICE_INFO *deviceInfoPtr;
	int status;

	/* Pass the call on to the lower-level open function.  This device is
	   unique and has no owner or type */
	status = openDevice( &iSystemObject, CRYPT_UNUSED, CRYPT_DEVICE_NONE,
						 NULL, 0, &deviceInfoPtr );
	if( deviceInfoPtr == NULL )
		return( status );	/* Create object failed, return immediately */
	if( cryptStatusError( status ) )
		{
		/* The device open failed, we'd normally have to signal the device
		   object to destroy itself when the init completes, however we don't
		   have the privileges to do this so we just pass the error code back
		   to the caller which causes the cryptlib init to fail */
		unlockResource( deviceInfoPtr );
		return( status );
		}
	assert( iSystemObject == SYSTEM_OBJECT_HANDLE );

	/* We've finished setting up the object-type-specific info, tell the
	   kernel the object is ready for use */
	unlockResource( deviceInfoPtr );
	return( krnlSendMessage( iSystemObject, RESOURCE_IMESSAGE_SETATTRIBUTE,
							 MESSAGE_VALUE_OK, CRYPT_IATTRIBUTE_STATUS ) );
	}

/* Peform an extended control function on the device */

C_RET cryptDeviceControlEx( C_IN CRYPT_DEVICE device,
							C_IN CRYPT_ATTRIBUTE_TYPE controlType,
							C_IN void C_PTR data1, C_IN int data1Length,
							C_IN void C_PTR data2, C_IN int data2Length )
	{
	DEVICE_INFO *deviceInfoPtr;
	int status;

	/* Perform basic error checking */
	getCheckResource( device, deviceInfoPtr, OBJECT_TYPE_DEVICE,
					  CRYPT_ERROR_PARAM1 );
	if( controlType != CRYPT_DEVINFO_SET_AUTHENT_USER && \
		controlType != CRYPT_DEVINFO_SET_AUTHENT_SUPERVISOR )
		unlockResourceExit( deviceInfoPtr, CRYPT_ERROR_PARAM2 );
	if( data1 == NULL )
		unlockResourceExit( deviceInfoPtr, CRYPT_ERROR_PARAM3 );
	if( data1Length < 0 )
		unlockResourceExit( deviceInfoPtr, CRYPT_ERROR_PARAM4 );
	if( data2 == NULL )
		unlockResourceExit( deviceInfoPtr, CRYPT_ERROR_PARAM5 );
	if( data2Length < 0 )
		unlockResourceExit( deviceInfoPtr, CRYPT_ERROR_PARAM6 );

	/* Make sure the PIN sizes are valid */
	if( data1Length < deviceInfoPtr->minPinSize || \
		data1Length > deviceInfoPtr->maxPinSize )
		unlockResourceExit( deviceInfoPtr, CRYPT_ERROR_PARAM4 );
	if( data2Length < deviceInfoPtr->minPinSize || \
		data2Length > deviceInfoPtr->maxPinSize )
		unlockResourceExit( deviceInfoPtr, CRYPT_ERROR_PARAM6 );

	/* Send the control information to the device */
	status = deviceInfoPtr->controlFunction( deviceInfoPtr, controlType,
											 data1, data1Length,
											 data2, data2Length );
	unlockResourceExit( deviceInfoPtr, status );
	}

⌨️ 快捷键说明

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