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

📄 msg_acl.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
				if( !isWritePtr( ( void * ) messageDataPtr, sizeof( int ) ) )
					return( CRYPT_ARGERROR_STR1 );
				break;
				}

			/* Inner precondition: We're sending data to the object */
			PRE( localMessage == MESSAGE_SETATTRIBUTE );

			/* If it's a standard range check, make sure that the attribute
			   value is within the allowed range */
			if( !isSpecialRange( attributeACL ) )
				{
				if( !checkNumericRange( *valuePtr, attributeACL->lowRange,
										attributeACL->highRange ) )
					return( CRYPT_ARGERROR_NUM1 );
				break;
				}

			/* It's a special-case range check */
			assert( isSpecialRange( attributeACL ) );
			switch( getSpecialRangeType( attributeACL ) )
				{
				case RANGEVAL_ANY:
					break;

				case RANGEVAL_SELECTVALUE:
					if( *valuePtr != CRYPT_UNUSED )
						return( CRYPT_ARGERROR_NUM1 );
					break;

				case RANGEVAL_ALLOWEDVALUES:
					if( !checkAttributeRangeSpecial( RANGEVAL_ALLOWEDVALUES,
											getSpecialRangeInfo( attributeACL ),
											*valuePtr ) )
						return( CRYPT_ARGERROR_NUM1 );
					break;

				case RANGEVAL_SUBRANGES:
					if( !checkAttributeRangeSpecial( RANGEVAL_SUBRANGES,
											getSpecialRangeInfo( attributeACL ),
											*valuePtr ) )
						return( CRYPT_ARGERROR_NUM1 );
					break;

				default:
					retIntError();
				}
			break;
			}

		case ATTRIBUTE_VALUE_OBJECT:
			{
			const OBJECT_ACL *objectACL = attributeACL->extendedInfo;
			const int *valuePtr = messageDataPtr;
			int objectParamHandle, objectParamSubType;

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

			/* Inner precondition: We're sending data to the object */
			PRE( localMessage == MESSAGE_SETATTRIBUTE );

			/* Must contain a valid object handle */
			if( !fullObjectCheck( *valuePtr, message ) || \
				!isSameOwningObject( objectHandle, *valuePtr ) )
				return( CRYPT_ARGERROR_NUM1 );

			/* Object must be of the correct type */
			if( objectACL->flags & ACL_FLAG_ROUTE_TO_CTX )
				objectParamHandle = findTargetType( *valuePtr,
													OBJECT_TYPE_CONTEXT );
			else
				{
				if( objectACL->flags & ACL_FLAG_ROUTE_TO_CERT )
					objectParamHandle = findTargetType( *valuePtr,
														OBJECT_TYPE_CERTIFICATE );
				else
					objectParamHandle = *valuePtr;
				}
			if( cryptStatusError( objectParamHandle ) )
				return( CRYPT_ARGERROR_NUM1 );
			objectParamSubType = objectTable[ objectParamHandle ].subType;
			if( !isValidSubtype( objectACL->subTypeA, objectParamSubType ) && \
				!isValidSubtype( objectACL->subTypeB, objectParamSubType ) )
				return( CRYPT_ARGERROR_NUM1 );
			if( ( objectACL->flags & ACL_FLAG_STATE_MASK ) && \
				!checkObjectState( objectACL->flags, objectParamHandle ) )
				return( CRYPT_ARGERROR_NUM1 );

			/* Postcondition: Object parameter is valid and accessible,
			   object is of the correct type and state */
			POST( fullObjectCheck( *valuePtr, message ) && \
				  isSameOwningObject( objectHandle, *valuePtr ) );
			POST( isValidSubtype( objectACL->subTypeA, objectParamSubType ) || \
				  isValidSubtype( objectACL->subTypeB, objectParamSubType ) );
			POST( !( objectACL->flags & ACL_FLAG_STATE_MASK ) || \
				  checkObjectState( objectACL->flags, objectParamHandle ) );
			break;
			}

		case ATTRIBUTE_VALUE_STRING:
		case ATTRIBUTE_VALUE_WCSTRING:
			{
			const MESSAGE_DATA *msgData = messageDataPtr;

			/* Inner precondition: If it's an internal message, it must be
			   a valid string value or a null value if we're obtaining a
			   length.  Polled entropy data can be arbitrarily large so we
			   don't check its length */
			PRE( isReadPtr( messageDataPtr, sizeof( MESSAGE_DATA ) ) );
			PRE( !isInternalMessage || \
				 ( ( localMessage == MESSAGE_GETATTRIBUTE_S && \
					 ( ( msgData->data == NULL && msgData->length == 0 ) || \
					   ( msgData->length >= 1 && \
					     msgData->length < MAX_INTLENGTH && \
						 isWritePtr( msgData->data, msgData->length ) ) ) ) || \
				   ( localMessage == MESSAGE_SETATTRIBUTE_S && \
					 isReadPtr( msgData->data, msgData->length ) && \
					 ( msgData->length > 0 && \
					   msgData->length < MAX_INTLENGTH_SHORT || \
					   messageValue == CRYPT_IATTRIBUTE_ENTROPY ) ) ) );

			/* Must be a string value */
			if( localMessage != MESSAGE_GETATTRIBUTE_S && \
				localMessage != MESSAGE_SETATTRIBUTE_S )
				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.  We return a string arg error for both the buffer and
			   length, since the length isn't explicitly specified by an
			   external caller */
			if( localMessage == MESSAGE_GETATTRIBUTE_S )
				{
				if( !( ( msgData->data == NULL && msgData->length == 0 ) || \
					   ( msgData->length > 0 && \
						 isWritePtr( msgData->data, msgData->length ) ) ) )
					return( CRYPT_ARGERROR_STR1 );
				break;
				}

			/* Inner precondition: We're sending data to the object */
			PRE( localMessage == MESSAGE_SETATTRIBUTE_S );

			/* Make sure that the string length is within the allowed
			   range */
			if( isSpecialRange( attributeACL ) )
				{
				if( !checkAttributeRangeSpecial( \
									getSpecialRangeType( attributeACL ),
									getSpecialRangeInfo( attributeACL ),
									msgData->length ) )
					return( CRYPT_ARGERROR_NUM1 );
				}
			else
				{
				if( attributeACL->valueType == ATTRIBUTE_VALUE_WCSTRING )
					{
					if( !checkAttributeRangeWidechar( msgData->data,
													  msgData->length,
													  attributeACL->lowRange,
													  attributeACL->highRange ) )
						return( CRYPT_ARGERROR_NUM1 );
					}
				else
					{
					if( msgData->length < attributeACL->lowRange || \
						msgData->length > attributeACL->highRange )
						return( CRYPT_ARGERROR_NUM1 );
					}
				}
			if( msgData->length > 0 && \
				!isReadPtr( msgData->data, msgData->length ) )
				return( CRYPT_ARGERROR_STR1 );
			break;
			}

		case ATTRIBUTE_VALUE_TIME:
			{
			const MESSAGE_DATA *msgData = messageDataPtr;

			/* Inner precondition: If it's an internal message, it must be
			   a string value corresponding to a time_t */
			PRE( isReadPtr( messageDataPtr, sizeof( MESSAGE_DATA ) ) );
			PRE( !isInternalMessage || \
				 ( ( localMessage == MESSAGE_GETATTRIBUTE_S || \
					 localMessage == MESSAGE_SETATTRIBUTE_S ) && \
				   isReadPtr( msgData->data, msgData->length ) && \
				   msgData->length == sizeof( time_t ) ) );

			/* Must be a string value */
			if( localMessage != MESSAGE_GETATTRIBUTE_S && \
				localMessage != MESSAGE_SETATTRIBUTE_S )
				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.  We return a string arg error for both the buffer and
			   length, since the length isn't explicitly specified by an
			   external caller */
			if( localMessage == MESSAGE_GETATTRIBUTE_S )
				{
				if( !( ( msgData->data == NULL && msgData->length == 0 ) || \
					   ( msgData->length > 0 && \
						 isWritePtr( msgData->data, msgData->length ) ) ) )
					return( CRYPT_ARGERROR_STR1 );
				break;
				}

			/* If we're sending the data back to the caller, we can't check
			   it yet */
			if( localMessage == MESSAGE_GETATTRIBUTE_S )
				break;

			/* Inner precondition: We're sending data to the object */
			PRE( localMessage == MESSAGE_SETATTRIBUTE_S );

			/* Must contain a time_t in a sensible range */
			if( !isReadPtr( msgData->data, sizeof( time_t ) ) || \
				*( ( time_t * ) msgData->data ) <= MIN_TIME_VALUE )
				return( CRYPT_ARGERROR_STR1 );
			if( msgData->length != sizeof( time_t ) )
				return( CRYPT_ARGERROR_NUM1 );
			break;
			}

		case ATTRIBUTE_VALUE_SPECIAL:
			{
			int iterationCount = 0;
			
			/* It's an ACL with an object-subtype-specific sub-ACL, find the
			   precise ACL for this object subtype */
			for( attributeACL = getSpecialRangeInfo( attributeACL ); 
				 attributeACL->valueType != ATTRIBUTE_VALUE_NONE && \
					iterationCount++ < FAILSAFE_ITERATIONS_MED;  
				 attributeACL++ )
				{
				if( isValidSubtype( attributeACL->subTypeA, subType ) || \
					isValidSubtype( attributeACL->subTypeB, subType ) )
					break;
				}
			ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
			ENSURES( attributeACL->valueType != ATTRIBUTE_VALUE_NONE );

			/* Recursively check the message against the sub-ACL */
			return( preDispatchCheckAttributeAccess( objectHandle, message,
							messageDataPtr, messageValue, attributeACL ) );
			}

		default:
			retIntError();
		}

	return( CRYPT_OK );
	}

/* It's a compare message, make sure that the parameters are OK */

int preDispatchCheckCompareParam( const int objectHandle,
								  const MESSAGE_TYPE message,		/* Unused */
								  const void *messageDataPtr,
								  const int messageValue,
								  const void *dummy )
	{
	const OBJECT_INFO *objectTable = krnlData->objectTable;
	const OBJECT_INFO *objectInfoPtr = &objectTable[ objectHandle ];
	const COMPARE_ACL *compareACL = NULL;

	/* Precondition: It's a valid compare message type */
	PRE( isValidMessage( message & MESSAGE_MASK ) );
	PRE( fullObjectCheck( objectHandle, message ) );
	PRE( messageValue > MESSAGE_COMPARE_NONE && \
		 messageValue < MESSAGE_COMPARE_LAST );

	/* Find the appropriate ACL for this compare type */
	if( messageValue > MESSAGE_COMPARE_NONE && \
		messageValue < MESSAGE_COMPARE_LAST )
		compareACL = &compareACLTbl[ messageValue - 1 ];
	ENSURES( compareACL != NULL );

	/* Inner precondition: We have the correct ACL, and the full object
	   check has been performed by the kernel */
	PRE( compareACL->compareType == messageValue );

	/* Check the message target.  The full object check has already been
	   performed by the message dispatcher so all we need to check is the
	   compare-specific subtype.  We throw an exception if we find an
	   invalid parameter, both because this is an internal message and this
	   situation shouldn't occur, and because an error return from a compare
	   message is perfectly valid (it denotes a non-match) so parameter
	   errors won't otherwise be caught by the caller */
	ENSURES( isValidSubtype( compareACL->objectACL.subTypeA, \
							 objectInfoPtr->subType ) );
	if( ( compareACL->objectACL.flags & ACL_FLAG_STATE_MASK ) && \
		!checkObjectState( compareACL->objectACL.flags, objectHandle ) )
		retIntError();

	/* Check the message parameters.  We throw an exception if we find an
	   invalid parameter for the reason given above */
	if( paramInfo( compareACL, 0 ).valueType == PARAM_VALUE_OBJECT )
		{
		STDC_UNUSED \
		const CRYPT_HANDLE iCryptHandle = *( ( CRYPT_HANDLE * ) messageDataPtr );

		PRE( fullObjectCheck( iCryptHandle, message ) && \
			 isSameOwningObject( objectHandle, iCryptHandle ) );
		PRE( checkParamObject( paramInfo( compareACL, 0 ), iCryptHandle ) );
		}
	else
		{
		STDC_UNUSED \
		const MESSAGE_DATA *msgData = messageDataPtr;

		PRE( checkParamString( paramInfo( compareACL, 0 ),
							   msgData->data, msgData->length ) );
		}

	/* Postconditions: The compare parameters are valid, either an object
	   handle or a string value at least as big as a minimal-length DN */
	POST( ( messageValue == MESSAGE_COMPARE_CERTOBJ && \
			isValidHandle( *( ( CRYPT_HANDLE * ) messageDataPtr ) ) ) || \
		  ( messageValue != MESSAGE_COMPARE_CERTOBJ && \
			isReadPtr( messageDataPtr, sizeof( MESSAGE_DATA ) ) && \
			( ( MESSAGE_DATA * ) messageDataPtr )->length >= 2 && \
			isReadPtr( ( ( MESSAGE_DATA * ) messageDataPtr )->data, \
					   ( ( MESSAGE_DATA * ) messageDataPtr )->length ) ) );

	return( CRYPT_OK );
	}

/* It's a check message, make sure that the parameters are OK */

int preDispatchCheckCheckParam( const int objectHandle,
								const MESSAGE_TYPE message,
								const void *messageDataPtr,			/* Unused */
								const int messageValue,

⌨️ 快捷键说明

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