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

📄 msg_acl.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
										   const void *rangeInfo,
										   const int value )
	{
	/* Precondition: The range checking information is valid */
	PRE( rangeType > RANGEVAL_NONE && rangeType < RANGEVAL_LAST );
	PRE( rangeInfo != NULL );

	/* RANGEVAL_ALLOWEDVALUES contains an int [] of permitted values,
	   terminated by CRYPT_ERROR */
	if( rangeType == RANGEVAL_ALLOWEDVALUES )
		{
		const int *allowedValuesInfo = rangeInfo;
		int i;

		for( i = 0; allowedValuesInfo[ i ] != CRYPT_ERROR; i++ )
			{
			INV( i < 5 );
			if( value == allowedValuesInfo[ i ] )
				return( TRUE );
			}
		return( FALSE );
		}

	/* RANGEVAL_SUBRANGES contains a SUBRANGE [] of allowed subranges,
	   terminated by { CRYPT_ERROR, CRYPT_ERROR } */
	if( rangeType == RANGEVAL_SUBRANGES )
		{
		const RANGE_SUBRANGE_TYPE *allowedValuesInfo = rangeInfo;
		int i;

		for( i = 0; allowedValuesInfo[ i ].lowRange != CRYPT_ERROR; i++ )
			{
			INV( i < 5 );
			if( checkNumericRange( value, allowedValuesInfo[ i ].lowRange, 
								   allowedValuesInfo[ i ].highRange ) )
				return( TRUE );
			}
		return( FALSE );
		}

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

/* Check whether a string value falls within the given limits, with special
   handling for widechar strings.  This sort of thing really shouldn't be
   in the kernel, but not having it here makes correct string length range 
   checking difficult */

static BOOLEAN checkAttributeRangeWidechar( const void *value,
											const int valueLength,
											const int minLength,
											const int maxLength )
	{
#ifdef USE_WIDECHARS
	const wchar_t *wcString = value;

	/* If it's not a multiple of wchar_t in size or smaller than a
	   wchar_t, it can't be a widechar string */
	if( ( valueLength % WCSIZE ) || ( valueLength < WCSIZE ) )
		return( ( valueLength < minLength || valueLength > maxLength ) ? \
				FALSE : TRUE );

	/* If wchar_t is > 16 bits and the bits above 16 are all zero, it's
	   definitely a widechar string */
#if INT_MAX > 0xFFFFL
	if( WCSIZE > 2 && *wcString < 0xFFFF )
		return( ( valueLength < ( minLength * WCSIZE ) || \
				  valueLength > ( maxLength * WCSIZE ) ) ? \
				FALSE : TRUE );
#endif /* > 16-bit machines */

	/* Now it gets tricky.  The only thing that we can still safely check
	   for is something that's been bloated out into widechars from ASCII */
	if( ( valueLength > WCSIZE * 2 ) && \
		( wcString[ 0 ] < 0xFF && wcString[ 1 ] < 0xFF ) )
		return( ( valueLength < ( minLength * WCSIZE ) || \
				  valueLength > ( maxLength * WCSIZE ) ) ? \
				FALSE : TRUE );
#endif /* USE_WIDECHARS */

	/* It's not a widechar string or we can't handle these, perform a
	   straight range check */
	return( ( valueLength < minLength || valueLength > maxLength ) ? \
			FALSE : TRUE );
	}

/* Check whether a given action is permitted for an object */

static int checkActionPermitted( const OBJECT_INFO *objectInfoPtr,
								 const MESSAGE_TYPE message )
	{
	const MESSAGE_TYPE localMessage = message & MESSAGE_MASK;
	int requiredLevel, actualLevel;

	/* Determine the required level for access.  Like protection rings, the
	   lower the value, the higher the privilege level.  Level 3 is all-access,
	   level 2 is internal-access only, level 1 is no access, and level 0 is
	   not-available (e.g. encryption for hash contexts) */
	requiredLevel = objectInfoPtr->actionFlags & \
					MK_ACTION_PERM( localMessage, ACTION_PERM_MASK );

	/* Make sure that the action is enabled at the required level */
	if( message & MESSAGE_FLAG_INTERNAL )
		/* It's an internal message, the minimal permissions will do */
		actualLevel = MK_ACTION_PERM( localMessage, ACTION_PERM_NONE_EXTERNAL );
	else
		/* It's an external message, we need full permissions for access */
		actualLevel = MK_ACTION_PERM( localMessage, ACTION_PERM_ALL );
	if( requiredLevel < actualLevel )
		{
		/* The required level is less than the actual level (e.g. level 2 
		   access attempted from level 3), return more detailed information 
		   about the problem */
		return( ( ( requiredLevel >> ACTION_PERM_SHIFT( localMessage ) ) == ACTION_PERM_NOTAVAIL ) ? \
				CRYPT_ERROR_NOTAVAIL : CRYPT_ERROR_PERMISSION );
		}

	return( CRYPT_OK );
	}

/* Find the appropriate check ACL for a given message type */

static int findCheckACL( const int messageValue, 
						 const OBJECT_TYPE objectType, 
						 const CHECK_ACL **checkACLptr,
						 const CHECK_ALT_ACL **checkAltACLptr )
	{
	const CHECK_ACL *checkACL;
	const CHECK_ALT_ACL *checkAltACL;

	/* Precondition: It's a valid check message type */
	PRE( messageValue > MESSAGE_CHECK_NONE && \
		 messageValue < MESSAGE_CHECK_LAST );

	/* Clear return values */
	if( checkACLptr != NULL )
		*checkACLptr = NULL;
	if( checkAltACLptr != NULL )
		*checkAltACLptr = NULL;

	/* Find the appropriate ACL(s) for a given check type */
	if( messageValue > MESSAGE_CHECK_NONE && \
		messageValue < MESSAGE_CHECK_LAST )
		checkACL = &checkACLTbl[ messageValue - 1 ];
	if( checkACL == NULL )
		{
		assert( NOTREACHED );
		return( CRYPT_ARGERROR_VALUE );
		}

	/* Inner precondition: We have the correct ACL */
	PRE( checkACL->checkType == messageValue );

	/* If there's a sub-ACL present, find the correct ACL for this object
	   type */
	if( ( checkAltACL = checkACL->altACL ) != NULL )
		{
		int i;

		for( i = 0; checkAltACL[ i ].object != CRYPT_OBJECT_NONE && \
					checkAltACL[ i ].object != objectType; i++ );
		if( checkAltACL[ i ].object == CRYPT_OBJECT_NONE )
			return( CRYPT_ARGERROR_OBJECT );
		checkAltACL = &checkAltACL[ i ];
		if( checkAltACL->checkType > MESSAGE_CHECK_NONE && \
			checkAltACL->checkType < MESSAGE_CHECK_LAST )
			checkACL = &checkACLTbl[ checkAltACL->checkType - 1 ];
		if( checkACL == NULL )
			{
			assert( NOTREACHED );
			return( CRYPT_ARGERROR_VALUE );
			}
		}

	/* Postcondition: There's a valid ACL present */
	POST( isReadPtr( checkACL, sizeof( CHECK_ACL ) ) );
	POST( checkACL->altACL == NULL || \
		  isReadPtr( checkAltACL, sizeof( CHECK_ALT_ACL ) ) );
		
	if( checkACLptr != NULL )
		*checkACLptr = checkACL;
	if( checkAltACLptr != NULL )
		*checkAltACLptr = checkAltACL;

	return( CRYPT_OK );
	}

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

int initMessageACL( KERNEL_DATA *krnlDataPtr )
	{
	int i;

	/* Perform a consistency check on the compare ACL */
	for( i = 0; compareACLTbl[ i ].compareType != MESSAGE_COMPARE_NONE; i++ )
		{
		const COMPARE_ACL *compareACL = &compareACLTbl[ i ];

		if( compareACL->compareType <= MESSAGE_COMPARE_NONE || \
			compareACL->compareType >= MESSAGE_COMPARE_LAST || \
			compareACL->compareType != i + 1 )
			return( CRYPT_ERROR_FAILED );
		if( ( compareACL->objectACL.subTypeA & ~( SUBTYPE_CLASS_A | \
												  ST_CTX_ANY | ST_CERT_ANY ) ) || \
			compareACL->objectACL.subTypeB != ST_NONE )
			return( CRYPT_ERROR_FAILED );
		if( ( compareACL->objectACL.flags != 0 ) && \
			( compareACL->objectACL.flags != ACL_FLAG_HIGH_STATE ) )
			return( CRYPT_ERROR_FAILED );
		if( paramInfo( compareACL, 0 ).valueType == PARAM_VALUE_STRING )
			{
			if( paramInfo( compareACL, 0 ).lowRange < 2 || \
				paramInfo( compareACL, 0 ).lowRange > \
					paramInfo( compareACL, 0 ).highRange || \
				paramInfo( compareACL, 0 ).highRange > MAX_ATTRIBUTE_SIZE ) 
				return( CRYPT_ERROR_FAILED );
			}
		else
			{
			if( paramInfo( compareACL, 0 ).valueType != PARAM_VALUE_OBJECT )
				return( CRYPT_ERROR_FAILED );
			if( ( paramInfo( compareACL, 0 ).subTypeA & ~( SUBTYPE_CLASS_A | \
														   ST_CERT_ANY ) ) || \
				paramInfo( compareACL, 0 ).subTypeB != ST_NONE )
				return( CRYPT_ERROR_FAILED );
			}
		}

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

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

			if( checkAltACL->object != OBJECT_TYPE_CONTEXT && \
				checkAltACL->object != OBJECT_TYPE_CERTIFICATE )
				return( CRYPT_ERROR_FAILED );
			if( checkAltACL->checkType <= MESSAGE_CHECK_NONE || \
				checkAltACL->checkType >= MESSAGE_CHECK_LAST )
				return( CRYPT_ERROR_FAILED );
			if( checkAltACL->depObject != OBJECT_TYPE_CONTEXT && \
				checkAltACL->depObject != OBJECT_TYPE_CERTIFICATE )
				return( CRYPT_ERROR_FAILED );
			if( ( checkAltACL->depObjectACL.subTypeA & \
						~( SUBTYPE_CLASS_A | ST_CTX_ANY | ST_CERT_ANY ) ) || \
				checkAltACL->depObjectACL.subTypeB != ST_NONE )
				return( CRYPT_ERROR_FAILED );
			if( checkAltACL->depObjectACL.flags & ~ACL_FLAG_ANY_STATE )
				return( CRYPT_ERROR_FAILED );
			if( checkAltACL->fdCheckType <= MESSAGE_CHECK_NONE || \
				checkAltACL->fdCheckType >= MESSAGE_CHECK_LAST )
				return( CRYPT_ERROR_FAILED );
			}
		}

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

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

	/* 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,
									   const void *messageDataPtr,
									   const int messageValue,
									   const void *dummy )
	{
	OBJECT_INFO *objectInfoPtr = &krnlData->objectTable[ objectHandle ];

	/* Precondition */
	PRE( isValidObject( objectHandle ) && \
		 objectHandle >= NO_SYSTEM_OBJECTS );

	if( isValidObject( objectInfoPtr->dependentDevice ) )
		/* Velisurmaaja */
		decRefCount( objectInfoPtr->dependentDevice, 0, NULL, TRUE );
	if( isValidObject( objectInfoPtr->dependentObject ) )
		decRefCount( objectInfoPtr->dependentObject, 0, NULL, TRUE );
	objectInfoPtr->flags |= OBJECT_FLAG_SIGNALLED;

	/* Postcondition: The object is now in the destroyed state as far as
	   other objects are concerned */

⌨️ 快捷键说明

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