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

📄 cryptdev.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 3 页
字号:
			}
		else
			/* Create a dummy object, with all details handled by the device.
			   Unlike the system device, we don't unlock the device info 
			   before we call the create object function because there may be 
			   auxiliary info held in the device object that we need in order 
			   to create the object.  This is OK since we're not tying up the 
			   system device but only some auxiliary crypto device */
			status = createObjectFunction( messageDataPtr, auxInfo,
										   CREATEOBJECT_FLAG_DUMMY );
		if( cryptStatusError( status ) )
			return( status );

		/* Make the newly-created object a dependent object of the device */
		return( krnlSendMessage( \
					( ( MESSAGE_CREATEOBJECT_INFO * ) messageDataPtr )->cryptHandle,
					IMESSAGE_SETDEPENDENT, ( void * ) &iCryptDevice,
					SETDEP_OPTION_INCREF ) );
		}
	if( message == MESSAGE_DEV_CREATEOBJECT_INDIRECT )
		{
		CRYPT_DEVICE iCryptDevice = deviceInfoPtr->objectHandle;
		int status;

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

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

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

	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 object 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 : \
			( deviceType == CRYPT_DEVICE_CRYPTOAPI ) ? SUBTYPE_DEV_CRYPTOAPI : 0;
	int storageSize, status;

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

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

	/* Set up subtype-specific information */
	switch( deviceType )
		{
		case CRYPT_DEVICE_NONE:
			storageSize = sizeof( SYSTEMDEV_INFO );
			break;

		case CRYPT_DEVICE_FORTEZZA:
			storageSize = sizeof( FORTEZZA_INFO );
			break;

		case CRYPT_DEVICE_PKCS11:
			storageSize = sizeof( PKCS11_INFO );
			break;

		case CRYPT_DEVICE_CRYPTOAPI:
			storageSize = sizeof( CRYPTOAPI_INFO );
			break;

		default:
			assert( NOTREACHED );
			return( CRYPT_ARGERROR_NUM1 );
		}

	/* Create the device object and connect it to the device */
	status = krnlCreateObject( ( void ** ) &deviceInfoPtr, 
							   sizeof( DEVICE_INFO ) + storageSize, 
							   OBJECT_TYPE_DEVICE, subType, 
							   CREATEOBJECT_FLAG_NONE, cryptOwner, 
							   ACTION_PERM_NONE_ALL, deviceMessageFunction );
	if( cryptStatusError( status ) )
		return( status );
	*deviceInfoPtrPtr = deviceInfoPtr;
	*device = deviceInfoPtr->objectHandle = status;
	deviceInfoPtr->ownerHandle = cryptOwner;
	deviceInfoPtr->type = deviceType;
	switch( deviceType )
		{
		case CRYPT_DEVICE_NONE:
			deviceInfoPtr->deviceSystem = \
							( SYSTEMDEV_INFO * ) deviceInfoPtr->storage;
			break;

		case CRYPT_DEVICE_FORTEZZA:
			deviceInfoPtr->deviceFortezza = \
							( FORTEZZA_INFO * ) deviceInfoPtr->storage;
			break;

		case CRYPT_DEVICE_PKCS11:
			deviceInfoPtr->devicePKCS11 = \
							( PKCS11_INFO * ) deviceInfoPtr->storage;
			break;

		case CRYPT_DEVICE_CRYPTOAPI:
			deviceInfoPtr->deviceCryptoAPI = \
							( CRYPTOAPI_INFO * ) deviceInfoPtr->storage;
			break;
		}
	deviceInfoPtr->storageSize = storageSize;

	/* 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;

		case CRYPT_DEVICE_CRYPTOAPI:
			status = setDeviceCryptoAPI( 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 (non-system) 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.  This also catches any attempts to 
	   create a second system device object, which has an (external) type of 
	   CRYPT_DEVICE_NONE */
	if( createInfo->arg1 <= CRYPT_DEVICE_NONE || \
		createInfo->arg1 >= CRYPT_DEVICE_LAST )
		return( CRYPT_ARGERROR_NUM1 );
	if( ( createInfo->arg1 == CRYPT_DEVICE_PKCS11 || \
		  createInfo->arg1 == CRYPT_DEVICE_CRYPTOAPI ) && \
		createInfo->strArgLen1 <= MIN_NAME_LENGTH )
		return( CRYPT_ARGERROR_STR1 );

	/* Wait for any async device driver binding to complete */
	if( !krnlWaitSemaphore( SEMAPHORE_DRIVERBIND ) )
		/* The kernel is shutting down, bail out */
		return( CRYPT_ERROR_PERMISSION );

	/* 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 init failed, make sure that the object gets destroyed when we 
		   notify the kernel that the setup process is complete */
		krnlSendNotifier( iCryptDevice, IMESSAGE_DESTROY );

	/* We've finished setting up the object-type-specific info, tell the
	   kernel that the object is ready for use */
	status = krnlSendMessage( iCryptDevice, IMESSAGE_SETATTRIBUTE,
							  MESSAGE_VALUE_OK, CRYPT_IATTRIBUTE_STATUS );
	if( cryptStatusOK( status ) && \
		createInfo->arg1 == CRYPT_DEVICE_CRYPTOAPI )
		{
		/* If it's a device that doesn't require an explicit login, move it 
		   into the initialised state */
		status = krnlSendMessage( iCryptDevice, IMESSAGE_SETATTRIBUTE, 
								  MESSAGE_VALUE_UNUSED, 
								  CRYPT_IATTRIBUTE_INITIALISED );
		if( cryptStatusError( status ) )
			krnlSendNotifier( iCryptDevice, IMESSAGE_DESTROY );
		}
	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 (the cryptlib init process).  This causes the init to fail and 
   destroys the object when the kernel shuts down */

static 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 */
		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 and move it into the initialised
	   state */
	status = krnlSendMessage( iSystemObject, IMESSAGE_SETATTRIBUTE,
							  MESSAGE_VALUE_OK, CRYPT_IATTRIBUTE_STATUS );
	if( cryptStatusOK( status ) )
		{
		status = krnlSendMessage( iSystemObject, IMESSAGE_SETATTRIBUTE, 
								  MESSAGE_VALUE_UNUSED, 
								  CRYPT_IATTRIBUTE_INITIALISED );
		if( cryptStatusError( status ) )
			krnlSendNotifier( iSystemObject, IMESSAGE_DESTROY );
		}
	return( status );
	}

/* Generic management function for this class of object.  Unlike the usual 
   multilevel init process which is followed for other objects, the devices 
   have an OR rather than an AND relationship since the devices are 
   logically independent, so we set a flag for each device type that is 
   successfully initialised rather than recording an init level */

#define DEV_NONE_INITED			0x00
#define DEV_FORTEZZA_INITED		0x01
#define DEV_PKCS11_INITED		0x02
#define DEV_CRYPTOAPI_INITED	0x04

int deviceManagementFunction( const MANAGEMENT_ACTION_TYPE action )
	{
	static int initFlags = DEV_NONE_INITED;

	assert( action == MANAGEMENT_ACTION_PRE_INIT || \
			action == MANAGEMENT_ACTION_INIT || \
			action == MANAGEMENT_ACTION_PRE_SHUTDOWN || \
			action == MANAGEMENT_ACTION_SHUTDOWN );
	
	switch( action )
		{
		case MANAGEMENT_ACTION_PRE_INIT:
			return( createSystemDeviceObject() );

		case MANAGEMENT_ACTION_INIT:
			if( cryptStatusOK( deviceInitFortezza() ) )
				initFlags |= DEV_FORTEZZA_INITED;
			if( krnlIsExiting() )
				/* The kernel is shutting down, exit */
				return( CRYPT_ERROR_PERMISSION );
			if( cryptStatusOK( deviceInitPKCS11() ) )
				initFlags |= DEV_PKCS11_INITED;
			if( krnlIsExiting() )
				/* The kernel is shutting down, exit */
				return( CRYPT_ERROR_PERMISSION );
			if( cryptStatusOK( deviceInitCryptoAPI() ) )
				initFlags |= DEV_CRYPTOAPI_INITED;
			return( CRYPT_OK );
		
		case MANAGEMENT_ACTION_PRE_SHUTDOWN:
			/* In theory we could signal the background entropy poll to 
			   start wrapping up at this point, however if the background 
			   polling is being performed in a thread or task the shutdown
			   is already signalled via the kernel shutdown flag.  If it's
			   performed by forking off a process, as it is on Unix systems, 
			   there's no easy way to communicate with this process so the 
			   shutdown function just kill()s it.  Because of this we don't 
			   try and do anything here, although this call is left in place 
			   as a no-op in case it's needed in the future */
			return( CRYPT_OK );
		
		case MANAGEMENT_ACTION_SHUTDOWN:
			if( initFlags & DEV_FORTEZZA_INITED )
				deviceEndFortezza();
			if( initFlags & DEV_PKCS11_INITED )
				deviceEndPKCS11();
			if( initFlags & DEV_CRYPTOAPI_INITED )
				deviceEndCryptoAPI();
			initFlags = DEV_NONE_INITED;
			return( CRYPT_OK );
		}

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

⌨️ 快捷键说明

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