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

📄 msg_acl.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
			   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:
			/* 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; \
				 attributeACL++ )
				if( isValidSubtype( attributeACL->subTypeA, subType ) || \
					isValidSubtype( attributeACL->subTypeB, subType ) )
					break;
			if( attributeACL->valueType == ATTRIBUTE_VALUE_NONE )
				{
				assert( NOTREACHED );
				return( CRYPT_ERROR_PERMISSION );
				}

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

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

	return( CRYPT_OK );
	}

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

int preDispatchCheckCompareParam( const int objectHandle,
								  const MESSAGE_TYPE message,
								  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( 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 ];
	if( compareACL == NULL )
		{
		assert( NOTREACHED );
		return( CRYPT_ARGERROR_VALUE );
		}

	/* 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 */
	if( !( isValidSubtype( compareACL->objectACL.subTypeA, \
						   objectInfoPtr->subType ) ) )
		{
		assert( NOTREACHED );
		return( CRYPT_ARGERROR_OBJECT );
		}
	if( ( compareACL->objectACL.flags & ACL_FLAG_STATE_MASK ) && \
		!checkObjectState( compareACL->objectACL.flags, objectHandle ) )
		{
		assert( NOTREACHED );
		return( CRYPT_ARGERROR_OBJECT );
		}

	/* 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 )
		{
		const CRYPT_HANDLE iCryptHandle = *( ( CRYPT_HANDLE * ) messageDataPtr );

		PRE( fullObjectCheck( iCryptHandle, message ) && \
			 isSameOwningObject( objectHandle, iCryptHandle ) );
		PRE( checkParamObject( paramInfo( compareACL, 0 ), iCryptHandle ) );
		}
	else
		{
		const RESOURCE_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( RESOURCE_DATA ) ) && \
			( ( RESOURCE_DATA * ) messageDataPtr )->length >= 2 && \
			isReadPtr( ( ( RESOURCE_DATA * ) messageDataPtr )->data, \
					   ( ( RESOURCE_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,
								const int messageValue,
								const void *dummy )
	{
	const OBJECT_INFO *objectTable = krnlData->objectTable;
	const OBJECT_INFO *objectInfoPtr = &objectTable[ objectHandle ];
	const CHECK_ACL *checkACL = NULL;
	int status;

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

	/* Find the ACL information for the message type */
	status = findCheckACL( messageValue, objectInfoPtr->type, 
						   &checkACL, NULL );
	if( cryptStatusError( status ) )
		return( status );

	/* 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 */
	if( !( isValidSubtype( checkACL->objectACL.subTypeA, \
						   objectInfoPtr->subType ) ) )
		return( CRYPT_ARGERROR_OBJECT );
	if( ( checkACL->objectACL.flags & ACL_FLAG_STATE_MASK ) && \
		!checkObjectState( checkACL->objectACL.flags, objectHandle ) )
		/* The object is in the wrong state, meaning that it's inited when
		   it shouldn't be or not inited when it should be, return a more
		   specific error message */
		return( isInHighState( objectHandle ) ? \
				CRYPT_ERROR_INITED : CRYPT_ERROR_NOTINITED );

	/* Make sure that the object's usage count is still valid.  The usage
	   count is a type of meta-capability that overrides all other
	   capabilities in that an object with an expired usage count isn't
	   valid for anything no matter what the available capabilities are */
	if( objectInfoPtr->usageCount != CRYPT_UNUSED && \
		objectInfoPtr->usageCount <= 0 )
		return( CRYPT_ARGERROR_OBJECT );

	/* If this is a context and there's an action associated with this 
	   check, make sure that the requested action is permitted for this 
	   object */
	if( objectInfoPtr->type == OBJECT_TYPE_CONTEXT && \
		checkACL->actionType != MESSAGE_NONE )
		{
		const BOOLEAN isInternalMessage = \
				( message & MESSAGE_FLAG_INTERNAL ) ? TRUE : FALSE;
		int status;

		/* Check that the action is permitted.  We convert the return status
		   to a CRYPT_ERROR_NOTAVAIL, which makes more sense than a generic
		   object error */
		status = checkActionPermitted( objectInfoPtr, 
							isInternalMessage ? \
								MKINTERNAL( checkACL->actionType ) : \
								checkACL->actionType );
		if( cryptStatusError( status ) )
			return( CRYPT_ERROR_NOTAVAIL );
		}

	/* Postconditions: The object being checked is valid */
	POST( fullObjectCheck( objectHandle, message ) && \
		  ( isValidSubtype( checkACL->objectACL.subTypeA, \
						    objectInfoPtr->subType ) ) );

	return( CRYPT_OK );
	}

/* It's a context action message, check the access conditions for the object */

int preDispatchCheckActionAccess( const int objectHandle,
								  const MESSAGE_TYPE message,
								  const void *messageDataPtr,
								  const int messageValue,
								  const void *dummy )
	{
	const OBJECT_INFO *objectInfoPtr = &krnlData->objectTable[ objectHandle ];
	const MESSAGE_TYPE localMessage = message & MESSAGE_MASK;
	int status;

	/* Precondition: It's a valid access */
	PRE( isValidObject( objectHandle ) );
	PRE( isActionMessage( localMessage ) );

	/* If the object is in the low state, it can't be used for any action */
	if( !isInHighState( objectHandle ) )
		return( CRYPT_ERROR_NOTINITED );

	/* If the object is in the high state, it can't receive another message
	   of the kind that causes the state change */
	if( localMessage == MESSAGE_CTX_GENKEY )
		return( CRYPT_ERROR_INITED );

	/* If there's a usage count set for the object and it's gone to zero, it
	   can't be used any more */
	if( objectInfoPtr->usageCount != CRYPT_UNUSED && \
		objectInfoPtr->usageCount <= 0 )
		return( CRYPT_ERROR_PERMISSION );

	/* Inner precondition: Object is in the high state and can process the
	   action message */
	PRE( isInHighState( objectHandle ) );
	POST( objectInfoPtr->usageCount == CRYPT_UNUSED || \
		  objectInfoPtr->usageCount > 0 );

	/* Check that the requested action is permitted for this object */
	status = checkActionPermitted( objectInfoPtr, message );
	if( cryptStatusError( status ) )
		return( status );

	/* Postcondition */
	POST( localMessage != MESSAGE_CTX_GENKEY );
	POST( isInHighState( objectHandle ) );
	POST( objectInfoPtr->usageCount == CRYPT_UNUSED || \
		  objectInfoPtr->usageCount > 0 );
	POST( cryptStatusOK( checkActionPermitted( objectInfoPtr, message ) ) );

	return( CRYPT_OK );
	}

/* If it's a state change trigger message, make sure that the object isn't
   already in the high state */

int preDispatchCheckState( const int objectHandle,
						   const MESSAGE_TYPE message,
						   const void *messageDataPtr,
						   const int messageValue, const void *dummy )
	{
	const MESSAGE_TYPE localMessage = message & MESSAGE_MASK;

	/* Precondition: It's a valid access */
	PRE( isValidObject( objectHandle ) );

	if( isInHighState( objectHandle ) )
		return( CRYPT_ERROR_PERMISSION );

	/* If it's a keygen message, perform a secondary check to ensure that key
	   generation is permitted for this object */
	if( localMessage == MESSAGE_CTX_GENKEY )
		{
		int status;

		/* Check that the requested action is permitted for this object */
		status = checkActionPermitted( &krnlData->objectTable[ objectHandle ], 
									   message );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Postcondition: Object is in the low state so a state change message
	   is valid */
	POST( !isInHighState( objectHandle ) );

	return( CRYPT_OK );
	}

/* Check the access conditions for a message containing an optional handle
   as the message parameter */

int preDispatchCheckParamHandleOpt( const int objectHandle,
									const MESSAGE_TYPE message,
									const void *messageDataPtr,
									const int messageValue,
									const void *auxInfo )
	{
	const MESSAGE_ACL *messageACL = ( MESSAGE_ACL * ) auxInfo;
	const OBJECT_ACL *objectACL = &messageACL->objectACL;
	const OBJECT_INFO *objectTable = krnlData->objectTable;
	int subType;

	/* Preconditions: The access is valid and we've been supplied a valid 
	   check ACL */
	PRE( isValidObject( objectHandle ) );
	PRE( isReadPtr( messageACL, sizeof( MESSAGE_ACL ) ) && \
		 messageACL->type == ( message & MESSAGE_MASK ) );

	/* If the object parameter is CRYPT_UNUSED (for example for a self-signed
	   cert), we're OK */
	if( messageValue == CRYPT_UNUSED )
		return( CRYPT_OK );

	/* Make sure that the object parameter is valid and accessible */
	if( !fullObjectCheck( messageValue, message ) || \
		!isSameOwningObject( objectHandle, messageValue ) )
		return( CRYPT_ARGERROR_VALUE );

	/* Make sure that the object parameter subtype is correct */
	subType = objectTable[ messageValue ].subType;
	if( !isValidSubtype( objectACL->subTypeA, subType ) && \
		!isValidSubtype( objectACL->subTypeB, subType ) )
		return( CRYPT_ARGERROR_VALUE );

	/* Postcondition: Object parameter is valid, accessible, and of the
	   correct type */
	POST( fullObjectCheck( messageValue, message ) && \
		  isSameOwningObject( objectHandle, messageValue ) );
	POST( isValidSubtype( objectACL->subTypeA, subType ) || \
		  isValidSubtype( objectACL->subTypeB, subType ) );

	return( CRYPT_OK );
	}

/* Perform a combined check of the object and the handle */

int preDispatchCheckStateParamHandle( const int objectHandle,
									  const MESSAGE_TYPE message,
									  const void *messageDataPtr,
									  const int messageValue,
									  const void *auxInfo )
	{
	const MESSAGE_ACL *messageACL = ( MESSAGE_ACL * ) auxInfo;

⌨️ 快捷键说明

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