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

📄 sendmsg.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
	  MESSAGE_HANDLING_FLAG_MAYUNLOCK },
	{ MESSAGE_DEV_CREATEOBJECT_INDIRECT,/* Device: Create obj.from data */
	  ROUTE_FIXED( OBJECT_TYPE_DEVICE ), ST_DEV_ANY, ST_NONE,
	  PARAMTYPE_DATA_OBJTYPE,
	  PRE_POST_DISPATCH( CheckCreate, MakeObjectExternal ),
	  MESSAGE_HANDLING_FLAG_MAYUNLOCK },

	/* Object-type-specific messages: Envelopes */
	{ MESSAGE_ENV_PUSHDATA,			/* Envelope: Push data */
	  ROUTE_FIXED_ALT( OBJECT_TYPE_ENVELOPE, OBJECT_TYPE_SESSION ),
		ST_NONE, ST_ENV_ANY | ST_SESS_ANY_DATA,
	  PARAMTYPE_DATA_NONE,
	  PRE_DISPATCH( CheckData ) },
	{ MESSAGE_ENV_POPDATA,			/* Envelope: Pop data */
	  ROUTE_FIXED_ALT( OBJECT_TYPE_ENVELOPE, OBJECT_TYPE_SESSION ),
		ST_NONE, ST_ENV_ANY | ST_SESS_ANY_DATA,
	  PARAMTYPE_DATA_NONE,
	  PRE_DISPATCH( CheckData ) },

	/* Object-type-specific messages: Keysets */
	{ MESSAGE_KEY_GETKEY,			/* Keyset: Instantiate ctx/cert */
	  ROUTE_FIXED_ALT( OBJECT_TYPE_KEYSET, OBJECT_TYPE_DEVICE ),
		ST_KEYSET_ANY | ST_DEV_ANY_STD, ST_NONE,
	  PARAMTYPE_DATA_ITEMTYPE,
	  PRE_POST_DISPATCH( CheckKeysetAccess, MakeObjectExternal ) },
	{ MESSAGE_KEY_SETKEY,			/* Keyset: Add ctx/cert */
	  ROUTE_FIXED_ALT( OBJECT_TYPE_KEYSET, OBJECT_TYPE_DEVICE ),
		ST_KEYSET_ANY | ST_DEV_ANY_STD, ST_NONE,
	  PARAMTYPE_DATA_ITEMTYPE,
	  PRE_DISPATCH( CheckKeysetAccess ) },
	{ MESSAGE_KEY_DELETEKEY,		/* Keyset: Delete key */
	  ROUTE_FIXED_ALT( OBJECT_TYPE_KEYSET, OBJECT_TYPE_DEVICE ),
		ST_KEYSET_ANY | ST_DEV_ANY_STD, ST_NONE,
	  PARAMTYPE_DATA_ITEMTYPE,
	  PRE_DISPATCH( CheckKeysetAccess ) },
	{ MESSAGE_KEY_GETFIRSTCERT,		/* Keyset: Get first cert in sequence */
	  ROUTE_FIXED_ALT( OBJECT_TYPE_KEYSET, OBJECT_TYPE_DEVICE ),
		ST_KEYSET_ANY | ST_DEV_ANY_STD, ST_NONE,
	  PARAMTYPE_DATA_ITEMTYPE,
	  PRE_DISPATCH( CheckKeysetAccess ) },
	{ MESSAGE_KEY_GETNEXTCERT,		/* Keyset: Get next cert in sequence */
	  ROUTE_FIXED_ALT( OBJECT_TYPE_KEYSET, OBJECT_TYPE_DEVICE ),
		ST_KEYSET_ANY | ST_DEV_ANY_STD, ST_NONE,
	  PARAMTYPE_DATA_ITEMTYPE,
	  PRE_POST_DISPATCH( CheckKeysetAccess, MakeObjectExternal ) },
	{ MESSAGE_KEY_CERTMGMT,			/* Keyset: Cert management */
	  ROUTE_FIXED( OBJECT_TYPE_KEYSET ),
		ST_KEYSET_DBMS_STORE, ST_NONE,
	  PARAMTYPE_DATA_CERTMGMTTYPE,
	  PRE_POST_DISPATCH( CheckCertMgmtAccess, MakeObjectExternal ) },

	/* Object-type-specific messages: Users */
	{ MESSAGE_USER_USERMGMT,		/* User: User management */
	  ROUTE_FIXED( OBJECT_TYPE_USER ), ST_NONE, ST_USER_SO, 
	  PARAMTYPE_ANY_USERMGMTTYPE,
	  PRE_POST_DISPATCH( CheckUserMgmtAccess, HandleZeroise ) },
	{ MESSAGE_USER_TRUSTMGMT,		/* User: Trust management */
	  ROUTE_FIXED( OBJECT_TYPE_USER ), ST_NONE, ST_USER_SO, 
	  PARAMTYPE_ANY_TRUSTMGMTTYPE,
	  PRE_DISPATCH( CheckTrustMgmtAccess ) }
	};

/****************************************************************************
*																			*
*							Init/Shutdown Functions							*
*																			*
****************************************************************************/

int initSendMessage( KERNEL_DATA *krnlDataPtr )
	{
	int i;

	PRE( isWritePtr( krnlDataPtr, sizeof( KERNEL_DATA ) ) );

	/* Perform a consistency check on various things that need to be set
	   up in a certain way for things to work properly */
	assert( MESSAGE_CTX_DECRYPT == MESSAGE_CTX_ENCRYPT + 1 );
	assert( MESSAGE_CTX_SIGN == MESSAGE_CTX_DECRYPT + 1 );
	assert( MESSAGE_CTX_SIGCHECK == MESSAGE_CTX_SIGN + 1 );
	assert( MESSAGE_CTX_HASH == MESSAGE_CTX_SIGCHECK + 1 );
	assert( MESSAGE_CTX_GENKEY == MESSAGE_CTX_HASH + 1 );
	assert( MESSAGE_GETATTRIBUTE_S == MESSAGE_GETATTRIBUTE + 1 );
	assert( MESSAGE_SETATTRIBUTE == MESSAGE_GETATTRIBUTE_S + 1 );
	assert( MESSAGE_SETATTRIBUTE_S == MESSAGE_SETATTRIBUTE + 1 );
	assert( MESSAGE_DELETEATTRIBUTE == MESSAGE_SETATTRIBUTE_S + 1 );

	/* Perform a consistency check on various internal values and constants */
	assert( ACTION_PERM_COUNT == 6 );

	/* Perform a consistency check on the parameter ACL */
	for( i = 0; messageParamACLTbl[ i ].type != MESSAGE_NONE && \
				i < FAILSAFE_ARRAYSIZE( messageParamACLTbl, MESSAGE_ACL ); 
		 i++ )
		{
		const MESSAGE_ACL *messageParamACL = &messageParamACLTbl[ i ];

		ENSURES( isParamMessage( messageParamACL->type ) && \
				 !( messageParamACL->objectACL.subTypeA & SUBTYPE_CLASS_B ) && \
				 !( messageParamACL->objectACL.subTypeB & SUBTYPE_CLASS_A ) );
		}
	ENSURES( i < FAILSAFE_ARRAYSIZE( messageParamACLTbl, MESSAGE_ACL ) );

	/* Perform a consistency check on the message handling information */
	for( i = MESSAGE_NONE + 1; i < MESSAGE_LAST; i++ )
		{
		const MESSAGE_HANDLING_INFO *messageInfo = &messageHandlingInfo[ i ];

		ENSURES( messageInfo->messageType == i && \
				 messageInfo->paramCheck >= PARAMTYPE_NONE_NONE && \
				 messageInfo->paramCheck < PARAMTYPE_LAST );
		ENSURES( ( messageInfo->messageType >= MESSAGE_ENV_PUSHDATA && \
				   messageInfo->messageType <= MESSAGE_KEY_GETNEXTCERT ) || \
				 ( messageInfo->routingTarget >= OBJECT_TYPE_NONE && \
				   messageInfo->routingTarget <= OBJECT_TYPE_LAST ) );
		ENSURES( messageInfo->messageType == MESSAGE_CLONE || \
				 messageInfo->messageType == MESSAGE_COMPARE || \
				 ( messageInfo->routingTarget == OBJECT_TYPE_NONE && \
				   messageInfo->routingFunction == NULL ) || \
				 ( messageInfo->routingTarget != OBJECT_TYPE_NONE && \
				   messageInfo->routingFunction != NULL ) );
		ENSURES( !( messageInfo->subTypeA & SUBTYPE_CLASS_B ) && \
				 !( messageInfo->subTypeB & SUBTYPE_CLASS_A ) );
		ENSURES( ( messageInfo->flags & MESSAGE_HANDLING_FLAG_INTERNAL ) || \
				 messageInfo->messageType == MESSAGE_SELFTEST || \
				 messageInfo->messageType == MESSAGE_CHANGENOTIFY || \
				 messageInfo->messageType == MESSAGE_CTX_GENIV || \
				 messageInfo->messageType == MESSAGE_DEV_QUERYCAPABILITY || \
				 messageInfo->preDispatchFunction != NULL );
		ENSURES( messageInfo->messageType == MESSAGE_SELFTEST || \
				 messageInfo->messageType == MESSAGE_CHANGENOTIFY || \
				 messageInfo->messageType == MESSAGE_CTX_GENIV || \
				 messageInfo->messageType == MESSAGE_DEV_QUERYCAPABILITY || \
				 ( messageInfo->preDispatchFunction != NULL || \
				   messageInfo->postDispatchFunction != NULL || \
				   messageInfo->internalHandlerFunction != NULL ) );
		ENSURES( ( ( messageInfo->flags & MESSAGE_HANDLING_FLAG_INTERNAL ) && \
					 messageInfo->internalHandlerFunction != NULL ) || \
				 ( !( messageInfo->flags & MESSAGE_HANDLING_FLAG_INTERNAL ) && \
					  messageInfo->internalHandlerFunction == NULL ) );
		}

	/* Set up the reference to the kernel data block */
	krnlData = krnlDataPtr;

	return( CRYPT_OK );
	}

void endSendMessage( void )
	{
	krnlData = NULL;
	}

/****************************************************************************
*																			*
*								Message Queue								*
*																			*
****************************************************************************/

/* Enqueue a message */

CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
static int enqueueMessage( const int objectHandle,
						   const MESSAGE_HANDLING_INFO *handlingInfoPtr,
						   const MESSAGE_TYPE message,
						   IN_OPT const void *messageDataPtr,
						   const int messageValue )
	{
	MESSAGE_QUEUE_DATA *messageQueue = krnlData->messageQueue;
	int queuePos, i, iterationCount;
	ORIGINAL_INT_VAR( queueEnd, krnlData->queueEnd );

	/* Precondition: It's a valid message being sent to a valid object */
	PRE( isValidObject( objectHandle ) );
	PRE( isReadPtr( handlingInfoPtr, sizeof( MESSAGE_HANDLING_INFO ) ) );
	PRE( isValidMessage( message & MESSAGE_MASK ) );

	/* Sanity-check the state/make sure that we don't overflow the queue 
	   (this object is not responding to messages... now all we need is 
	   GPF's).  We return a timeout error on overflow to indicate that there 
	   are too many messages queued for this (or other) objects */
	if( krnlData->queueEnd < 0 || \
		krnlData->queueEnd >= MESSAGE_QUEUE_SIZE - 1 )
		{
		ENSURES( krnlData->queueEnd >= 0 );
		assert( DEBUG_WARN );
		return( CRYPT_ERROR_TIMEOUT );
		}

	/* Precondition: There's room to enqueue the message */
	PRE( krnlData->queueEnd >= 0 && \
		 krnlData->queueEnd < MESSAGE_QUEUE_SIZE - 1 );

	/* Check whether a message to this object is already present in the
	   queue */
	for( queuePos = krnlData->queueEnd - 1, iterationCount = 0; 
		 queuePos >= 0 && iterationCount++ < MESSAGE_QUEUE_SIZE; queuePos-- )
		{
		if( messageQueue[ queuePos ].objectHandle == objectHandle )
			break;
		}
	ENSURES( iterationCount < MESSAGE_QUEUE_SIZE );

	/* Postcondition: queuePos = -1 if not present, position in queue if
	   present */
	POST( queuePos == -1 || \
		  ( queuePos >= 0 && queuePos < krnlData->queueEnd ) );

	/* Sanity-check the queue positioning */
	ENSURES( queuePos >= -1 && queuePos < krnlData->queueEnd );

	/* Enqueue the message:

		+---------------+		+---------------+
		|.|.|x|x|y|z|   |	->	|.|.|x|x|#|y|z| |
		+---------------+		+---------------+
			   ^	 ^					 ^	   ^
			  qPos	qEnd				qPos  qEnd */
	queuePos++;		/* Insert after current position */
	for( i = krnlData->queueEnd - 1, iterationCount = 0; 
		 i >= queuePos && iterationCount < MESSAGE_QUEUE_SIZE; 
		 i--, iterationCount++ )
		messageQueue[ i + 1 ] = messageQueue[ i ];
	ENSURES( iterationCount < MESSAGE_QUEUE_SIZE );
	memset( &messageQueue[ queuePos ], 0, sizeof( MESSAGE_QUEUE_DATA ) );
	messageQueue[ queuePos ].objectHandle = objectHandle;
	messageQueue[ queuePos ].handlingInfoPtr = handlingInfoPtr;
	messageQueue[ queuePos ].message = message;
	messageQueue[ queuePos ].messageDataPtr = messageDataPtr;
	messageQueue[ queuePos ].messageValue = messageValue;
	krnlData->queueEnd++;

	/* Postcondition: The queue is within bounds and has grown by one 
	   element */
	POST( krnlData->queueEnd > 0 && \
		  krnlData->queueEnd <= MESSAGE_QUEUE_SIZE - 1 );
	POST( krnlData->queueEnd == ORIGINAL_VALUE( queueEnd ) + 1 );

	/* If a message for this object is already present tell the caller to 
	   defer processing */
	if( queuePos > 0 )
		return( OK_SPECIAL );

	return( CRYPT_OK );
	}

/* Dequeue a message */

CHECK_RETVAL \
static int dequeueMessage( const int messagePosition )
	{
	MESSAGE_QUEUE_DATA *messageQueue = krnlData->messageQueue;
	int i, iterationCount;
	ORIGINAL_INT_VAR( queueEnd, krnlData->queueEnd );

	/* Precondition: We're deleting a valid queue position */
	PRE( messagePosition >= 0 && messagePosition < krnlData->queueEnd );

	/* Sanity-check the state */
	ENSURES( messagePosition >= 0 && \
			 messagePosition < krnlData->queueEnd && \
			 krnlData->queueEnd > 0 && \
			 krnlData->queueEnd < MESSAGE_QUEUE_SIZE );

	/* Move the remaining messages down and clear the last entry */
	for( i = messagePosition, iterationCount = 0; 
		 i < krnlData->queueEnd - 1 && \
			iterationCount++ < MESSAGE_QUEUE_SIZE; i++ )
		messageQueue[ i ] = messageQueue[ i + 1 ];
	ENSURES( iterationCount < MESSAGE_QUEUE_SIZE );
	zeroise( &messageQueue[ krnlData->queueEnd - 1 ],
			 sizeof( MESSAGE_QUEUE_DATA ) );
	krnlData->queueEnd--;

	/* Postcondition: the queue is one element shorter, all queue entries 
	   are valid, and all non-queue entries are empty */
	POST( krnlData->queueEnd == ORIGINAL_VALUE( queueEnd ) - 1 );
	POST( krnlData->queueEnd >= 0 && \
		  krnlData->queueEnd < MESSAGE_QUEUE_SIZE - 1 );
	FORALL( i, 0, krnlData->queueEnd,
			messageQueue[ i ].handlingInfoPtr != NULL );
	FORALL( i, krnlData->queueEnd, MESSAGE_QUEUE_SIZE,
			messageQueue[ i ].handlingInfoPtr == NULL );

	return( CRYPT_OK );
	}

/* Get the next message in the queue */

CHECK_RETVAL \
static BOOLEAN getNextMessage( const int objectHandle,
							   OUT_OPT MESSAGE_QUEUE_DATA *messageQueueInfo )
	{
	MESSAGE_QUEUE_DATA *messageQueue = krnlData->messageQueue;
	int i;

	/* Preconditions: It's a valid object table entry.  It's not necessarily
	   a valid object since we may be de-queueing messages for it because 
	   it's just been destroyed */
	PRE( objectHandle == SYSTEM_OBJECT_HANDLE || \
		 objectHandle == DEFAULTUSER_OBJECT_HANDLE || \
		 isHandleRangeValid( objectHandle ) );
	PRE( messageQueueInfo == NULL || \
		 isWritePtr( messageQueueInfo, sizeof( MESSAGE_QUEUE_DATA ) ) );

	/* Clear return value */
	if( messageQueueInfo != NULL )
		memset( messageQueueInfo, 0, sizeof( MESSAGE_QUEUE_DATA ) );

	/* Sanity-check the state */
	ENSURES( krnlData->queueEnd >= 0 && \
			 krnlData->queueEnd < MESSAGE_QUEUE_SIZE );

	/* Find the next message for this object.  Since other messages can have
	   come and gone in the meantime, we have to scan from the start each
	   time */
	for( i = 0; i < krnlData->queueEnd && i < MESSAGE_QUEUE_SIZE; i++ )
		{
		if( messageQueue[ i ].objectHandle == objectHandle )
			{
			int status;

⌨️ 快捷键说明

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