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

📄 msg_acl.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
			}
		else
			{
			ENSURES( paramInfo( compareACL, 0 ).valueType == PARAM_VALUE_OBJECT );
			if( ( paramInfo( compareACL, 0 ).subTypeA & ~( SUBTYPE_CLASS_A | \
														   ST_CERT_ANY ) ) || \
				paramInfo( compareACL, 0 ).subTypeB != ST_NONE )
				retIntError();
			}
		}
	ENSURES( i < FAILSAFE_ARRAYSIZE( compareACLTbl, COMPARE_ACL ) );

	/* Perform a consistency check on the check ACL */
	for( i = 0; checkACLTbl[ i ].checkType != MESSAGE_CHECK_NONE && \
				i < FAILSAFE_ARRAYSIZE( checkACLTbl, CHECK_ACL ); i++ )
		{
		const CHECK_ACL *checkACL = &checkACLTbl[ i ];
		int j;

		ENSURES( checkACL->checkType > MESSAGE_CHECK_NONE && \
				 checkACL->checkType < MESSAGE_CHECK_LAST && \
				 checkACL->checkType == i + 1 );
		ENSURES( checkACL->actionType == MESSAGE_NONE || \
				 ( checkACL->actionType >= MESSAGE_CTX_ENCRYPT && \
				   checkACL->actionType <= MESSAGE_CRT_SIGCHECK ) );
		if( ( checkACL->objectACL.subTypeA & \
					~( SUBTYPE_CLASS_A | ST_CTX_ANY | ST_CERT_ANY | \
										 ST_KEYSET_ANY | ST_DEV_ANY ) ) || \
			checkACL->objectACL.subTypeB != ST_NONE )
			retIntError();
		ENSURES( !( checkACL->objectACL.flags & ~ACL_FLAG_ANY_STATE ) )
		if( checkACL->altACL == NULL )
			continue;
		for( j = 0; checkACL->altACL[ j ].object != OBJECT_TYPE_NONE && \
					j < FAILSAFE_ITERATIONS_MED; j++ )
			{
			const CHECK_ALT_ACL *checkAltACL = &checkACL->altACL[ j ];

			ENSURES( checkAltACL->object == OBJECT_TYPE_CONTEXT || \
					 checkAltACL->object == OBJECT_TYPE_CERTIFICATE );
			ENSURES( checkAltACL->checkType > MESSAGE_CHECK_NONE && \
					 checkAltACL->checkType < MESSAGE_CHECK_LAST );
			ENSURES( checkAltACL->depObject == OBJECT_TYPE_CONTEXT || \
					 checkAltACL->depObject == OBJECT_TYPE_CERTIFICATE );
			if( ( checkAltACL->depObjectACL.subTypeA & \
						~( SUBTYPE_CLASS_A | ST_CTX_ANY | ST_CERT_ANY ) ) || \
				checkAltACL->depObjectACL.subTypeB != ST_NONE )
				retIntError();
			ENSURES( !( checkAltACL->depObjectACL.flags & ~ACL_FLAG_ANY_STATE ) )
			ENSURES( checkAltACL->fdCheckType > MESSAGE_CHECK_NONE && \
					 checkAltACL->fdCheckType < MESSAGE_CHECK_LAST );
			}
		ENSURES( j < FAILSAFE_ITERATIONS_MED );
		}
	ENSURES( i < FAILSAFE_ARRAYSIZE( checkACLTbl, CHECK_ACL ) );

	/* Perform a consistency check on the cert export pseudo-ACL */
	for( i = 0; formatPseudoACL[ i ].attribute != CRYPT_CERTFORMAT_NONE && \
				i < FAILSAFE_ARRAYSIZE( formatPseudoACL, ATTRIBUTE_ACL_ALT ); 
		 i++ )
		{
		const ATTRIBUTE_ACL_ALT *formatACL = &formatPseudoACL[ i ];

		ENSURES( formatACL->attribute > CRYPT_CERTTYPE_NONE && \
				 formatACL->attribute < CRYPT_CERTTYPE_LAST );
		if( ( formatACL->subTypeA & ~( SUBTYPE_CLASS_A | ST_CERT_ANY ) ) || \
			formatACL->subTypeB != ST_NONE )
			retIntError();
		if( formatACL->attribute < CRYPT_CERTFORMAT_LAST_EXTERNAL )
			{
			ENSURES( formatACL->access == ACCESS_Rxx_xxx );
			}
		else
			{
			ENSURES( formatACL->access == ACCESS_INT_Rxx_xxx || \
					 formatACL->access == ACCESS_INT_Rxx_Rxx );
			}
		ENSURES( formatACL->valueType == ATTRIBUTE_VALUE_STRING && \
				 formatACL->lowRange >= 16 && \
				 formatACL->lowRange < formatACL->highRange && \
				 formatACL->highRange <= 8192 && \
				 formatACL->extendedInfo == NULL );
		}
	ENSURES( i < FAILSAFE_ARRAYSIZE( formatPseudoACL, ATTRIBUTE_ACL_ALT ) );

	/* Perform a consistency check on the create-object ACL */
	for( i = 0; createObjectACL[ i ].type != OBJECT_TYPE_NONE && \
				i < FAILSAFE_ARRAYSIZE( createObjectACL, CREATE_ACL ); 
		 i++ )
		{
		const CREATE_ACL *createACL = &createObjectACL[ i ];

		ENSURES( isValidType( createACL->type ) );
		ENSURES( paramInfo( createACL, 0 ).valueType == PARAM_VALUE_NUMERIC && \
				 paramInfo( createACL, 1 ).valueType == PARAM_VALUE_NUMERIC && \
				 ( paramInfo( createACL, 2 ).valueType == PARAM_VALUE_STRING_NONE || \
				   paramInfo( createACL, 2 ).valueType == PARAM_VALUE_STRING ) && \
				 ( paramInfo( createACL, 3 ).valueType == PARAM_VALUE_STRING_NONE || \
				   paramInfo( createACL, 3 ).valueType == PARAM_VALUE_STRING ) );
		if( createACL->type == OBJECT_TYPE_CONTEXT )
			{
			ENSURES( paramInfo( createACL, 0 ).lowRange > CRYPT_ALGO_NONE && \
					 paramInfo( createACL, 0 ).highRange < CRYPT_ALGO_LAST );
			}
		else
			{
			/* Perform a composite check for a vaguely sensible value.  
			   CRYPT_CERTTYPE_LAST is the highest possible value for all of 
			   the non-context object types */
			ENSURES( paramInfo( createACL, 0 ).lowRange > 0 && \
					 paramInfo( createACL, 0 ).highRange < CRYPT_CERTTYPE_LAST );
			}
		if( createACL->exceptions[ 0 ] == 0 && \
			createACL->exceptions[ 1 ] != 0 )
			retIntError();
		if( ( createACL->exceptions[ 0 ] != 0 || \
			  createACL->exceptions[ 1 ] != 0 ) && \
			createACL->exceptionACL == NULL )
			retIntError();
		}
	ENSURES( i < FAILSAFE_ARRAYSIZE( createObjectACL, CREATE_ACL ) );

	/* Perform a consistency check on the create-object-indirect ACL */
	for( i = 0; createObjectIndirectACL[ i ].type != OBJECT_TYPE_NONE && \
				i < FAILSAFE_ARRAYSIZE( createObjectIndirectACL, CREATE_ACL ); 
		 i++ )
		{
		const CREATE_ACL *createACL = &createObjectIndirectACL[ i ];

		ENSURES( isValidType( createACL->type ) );
		if( paramInfo( createACL, 0 ).valueType != PARAM_VALUE_NUMERIC || \
			paramInfo( createACL, 1 ).valueType != PARAM_VALUE_NUMERIC || \
			paramInfo( createACL, 2 ).valueType != PARAM_VALUE_STRING || \
			( paramInfo( createACL, 3 ).valueType != PARAM_VALUE_STRING_NONE && \
			  paramInfo( createACL, 3 ).valueType != PARAM_VALUE_STRING ) )
			retIntError();
		ENSURES( paramInfo( createACL, 0 ).lowRange >= 0 && \
				 paramInfo( createACL, 0 ).highRange < CRYPT_CERTTYPE_LAST );
				/* The low-range may be 0, which indicates that we're using 
				   automatic format detection */
		ENSURES( paramInfo( createACL, 2 ).lowRange >= 16 && \
				 paramInfo( createACL, 2 ).highRange < MAX_INTLENGTH );
		if( createACL->exceptions[ 0 ] == 0 && \
			createACL->exceptions[ 1 ] != 0 )
			retIntError();
		if( ( createACL->exceptions[ 0 ] != 0 || \
			  createACL->exceptions[ 1 ] != 0 ) && \
			createACL->exceptionACL == NULL )
			retIntError();
		}
	ENSURES( i < FAILSAFE_ARRAYSIZE( createObjectIndirectACL, CREATE_ACL ) );

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

	return( CRYPT_OK );
	}

void endMessageACL( void )
	{
	krnlData = NULL;
	}

/****************************************************************************
*																			*
*							Message Pre-dispatch Handlers					*
*																			*
****************************************************************************/

/* If it's a destroy object message, adjust the reference counts of any
   dependent objects and set the object's state to signalled.  We do this
   before we send the destroy message to the object in order that any
   further attempts to access it will fail.  This is handled anyway by the
   message dispatcher, but setting the status to signalled now means that
   it's rejected immediately rather than being enqueued and then dequeued
   again once the destroy message has been processed */

int preDispatchSignalDependentObjects( const int objectHandle,
									   const MESSAGE_TYPE message,	/* Unused */
									   const void *messageDataPtr,	/* Unused */
									   const int messageValue,		/* Unused */
									   const void *dummy )
	{
	OBJECT_INFO *objectInfoPtr = &krnlData->objectTable[ objectHandle ];
	STDC_UNUSED int status;

	/* Preconditions */
	PRE( isValidObject( objectHandle ) && \
		 objectHandle >= NO_SYSTEM_OBJECTS );
	PRE( isValidMessage( message & MESSAGE_MASK ) );

	/* An inability to change the reference counts of the dependent objects 
	   doesn't affect the object itself so we can't report it as an error, 
	   however we can at least warn about it in debug mode */
	if( isValidObject( objectInfoPtr->dependentDevice ) )
		{
		/* Velisurmaaja */
		status = decRefCount( objectInfoPtr->dependentDevice, 0, NULL, TRUE );
		assert( cryptStatusOK( status ) );
		}
	if( isValidObject( objectInfoPtr->dependentObject ) )
		{
		status = decRefCount( objectInfoPtr->dependentObject, 0, NULL, TRUE );
		assert( cryptStatusOK( status ) );
		}
	objectInfoPtr->flags |= OBJECT_FLAG_SIGNALLED;

	/* Postcondition: The object is now in the destroyed state as far as
	   other objects are concerned */
	POST( isInvalidObjectState( objectHandle ) );

	return( CRYPT_OK );
	}

/* If it's an attribute get/set/delete, check the access conditions for the
   object and the message parameters */

int preDispatchCheckAttributeAccess( const int objectHandle,
									 const MESSAGE_TYPE message,
									 const void *messageDataPtr,
									 const int messageValue,
									 const void *auxInfo )
	{
	static const int FAR_BSS accessTypeTbl[ 5 ][ 2 ] = {
		/* MESSAGE_GETATTRIBUTE */			/* MESSAGE_GETATTRIBUTE_S */
		{ ACCESS_FLAG_R, ACCESS_FLAG_H_R }, { ACCESS_FLAG_R, ACCESS_FLAG_H_R },
		/* MESSAGE_SETATTRIBUTE */			/* MESSAGE_SETATTRIBUTE_S */
		{ ACCESS_FLAG_W, ACCESS_FLAG_H_W }, { ACCESS_FLAG_W, ACCESS_FLAG_H_W },
		/* MESSAGE_DELETEATTRIBUTE */
		{ ACCESS_FLAG_D, ACCESS_FLAG_H_D }
		};
	const ATTRIBUTE_ACL *attributeACL = ( ATTRIBUTE_ACL * ) auxInfo;
	const OBJECT_INFO *objectTable = krnlData->objectTable;
	const OBJECT_INFO *objectInfo = &objectTable[ objectHandle ];
	const MESSAGE_TYPE localMessage = message & MESSAGE_MASK;
	const int subType = objectInfo->subType;
	int accessType = \
			accessTypeTbl[ localMessage - MESSAGE_GETATTRIBUTE ]\
						 [ ( objectInfo->flags & OBJECT_FLAG_HIGH ) ? 1 : 0 ];
	const BOOLEAN isInternalMessage = isInternalMessage( message ) ? \
									  TRUE : FALSE;

	/* Preconditions */
	PRE( isValidType( objectInfo->type ) );
	PRE( isAttributeMessage( localMessage ) );
	PRE( isAttribute( messageValue ) || isInternalAttribute( messageValue ) );
	PRE( localMessage == MESSAGE_DELETEATTRIBUTE || messageDataPtr != NULL );
	PRE( isReadPtr( attributeACL, sizeof( ATTRIBUTE_ACL ) ) && \
		 attributeACL->attribute == messageValue );

	/* If it's an internal message, use the internal access permssions */
	if( isInternalMessage )
		accessType = MK_ACCESS_INTERNAL( accessType );

	/* Make sure that the attribute is valid for this object subtype */
	if( !isValidSubtype( attributeACL->subTypeA, subType ) && \
		!isValidSubtype( attributeACL->subTypeB, subType ) )
		return( CRYPT_ARGERROR_VALUE );

	/* Make sure that this type of access is valid for this attribute */
	if( !( attributeACL->access & accessType ) )
		{
		/* If it's an internal-only attribute being accessed through an
		   external message, it isn't visible to the user so we return
		   an attribute value error */
		if( !( attributeACL->access & ACCESS_MASK_EXTERNAL ) && \
			!isInternalMessage )
			return( CRYPT_ARGERROR_VALUE );

		/* It is visible, return a standard permission error */
		return( CRYPT_ERROR_PERMISSION );
		}

	/* Inner precondition: The attribute is valid for this subtype and is
	   externally visible or it's an internal message, and this type of
	   access is allowed */
	PRE( isValidSubtype( attributeACL->subTypeA, subType ) || \
		 isValidSubtype( attributeACL->subTypeB, subType ) );
	PRE( ( attributeACL->access & ACCESS_MASK_EXTERNAL ) || \
		 isInternalMessage );
	PRE( attributeACL->access & accessType );

	/* If it's a delete attribute message, there's no attribute data being
	   communicated so we can exit now */
	if( localMessage == MESSAGE_DELETEATTRIBUTE )
		{
		assert( messageDataPtr == NULL );
		return( CRYPT_OK );
		}

	/* Inner precondition: We're getting or setting the value of an attribute */
	PRE( localMessage == MESSAGE_GETATTRIBUTE || \
		 localMessage == MESSAGE_GETATTRIBUTE_S || \
		 localMessage == MESSAGE_SETATTRIBUTE || \
		 localMessage == MESSAGE_SETATTRIBUTE_S );

	/* Safety check for invalid pointers passed from an internal function */
	if( attributeACL->valueType != ATTRIBUTE_VALUE_SPECIAL && \
		!isReadPtr( messageDataPtr, \
					( attributeACL->valueType == ATTRIBUTE_VALUE_STRING || \
					  attributeACL->valueType == ATTRIBUTE_VALUE_WCSTRING || \
					  attributeACL->valueType == ATTRIBUTE_VALUE_TIME ) ? \
						sizeof( MESSAGE_DATA ) : sizeof( int ) ) )
		retIntError();

	/* Make sure that the attribute type matches the supplied value type.
	   We assert the preconditions for internal messages before the general
	   check to ensure that we throw an exception rather than just returning
	   an error code for internal programming errors */
	switch( attributeACL->valueType )
		{
		case ATTRIBUTE_VALUE_BOOLEAN:
			/* Inner precondition: If it's an internal message, it must be
			   a numeric value */
			PRE( !isInternalMessage || \
				 localMessage == MESSAGE_GETATTRIBUTE || \
				 localMessage == MESSAGE_SETATTRIBUTE );
			PRE( isReadPtr( messageDataPtr, sizeof( int ) ) );

			/* Must be a numeric value */
			if( localMessage != MESSAGE_GETATTRIBUTE && \
				localMessage != MESSAGE_SETATTRIBUTE )
				return( CRYPT_ARGERROR_VALUE );

			/* If we're sending the data back to the caller, the only thing
			   that we can check is the presence of a writeable output
			   buffer */
			if( localMessage == MESSAGE_GETATTRIBUTE )
				{
				if( !isWritePtr( ( void * ) messageDataPtr, sizeof( int ) ) )
					return( CRYPT_ARGERROR_STR1 );
				}
			break;

		case ATTRIBUTE_VALUE_NUMERIC:
			{
			const int *valuePtr = messageDataPtr;

			/* Inner precondition: If it's an internal message, it must be
			   a numeric value */
			PRE( !isInternalMessage || \
				 localMessage == MESSAGE_GETATTRIBUTE || \
				 localMessage == MESSAGE_SETATTRIBUTE );
			PRE( isReadPtr( messageDataPtr, sizeof( int ) ) );

			/* Must be a numeric value */
			if( localMessage != MESSAGE_GETATTRIBUTE && \
				localMessage != MESSAGE_SETATTRIBUTE )
				return( CRYPT_ARGERROR_VALUE );

			/* If we're sending the data back to the caller, the only thing
			   that we can check is the presence of a writeable output
			   buffer */
			if( localMessage == MESSAGE_GETATTRIBUTE )
				{

⌨️ 快捷键说明

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