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

📄 msg_acl.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
	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( fullObjectCheck( objectHandle, message ) );
	PRE( isReadPtr( messageACL, sizeof( MESSAGE_ACL ) ) && \
		 messageACL->type == ( message & MESSAGE_MASK ) );

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

	/* 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 is in the low state so a state change message
	   is valid and the object parameter is valid, accessible, and of the
	   correct type */
	POST( !isInHighState( objectHandle ) );
	POST( fullObjectCheck( messageValue, message ) && \
		  isSameOwningObject( objectHandle, messageValue ) );
	POST( isValidSubtype( objectACL->subTypeA, subType ) || \
		  isValidSubtype( objectACL->subTypeB, subType ) );

	return( CRYPT_OK );
	}

/* We're exporting a certificate, make sure that the format is valid for
   this cert type */

int preDispatchCheckExportAccess( const int objectHandle,
								  const MESSAGE_TYPE message,
								  const void *messageDataPtr,
								  const int messageValue,
								  const void *dummy )
	{
	const ATTRIBUTE_ACL *formatACL;
	int i;

	/* Precondition */
	PRE( isValidObject( objectHandle ) );
	PRE( messageDataPtr != NULL );
	PRE( messageValue > CRYPT_CERTFORMAT_NONE && \
		 messageValue < CRYPT_CERTFORMAT_LAST );

	/* Make sure that the export format is valid */
	if( messageValue <= CRYPT_CERTFORMAT_NONE || \
		messageValue >= CRYPT_CERTFORMAT_LAST )
		return( CRYPT_ARGERROR_VALUE );

	/* Find the appropriate ACL for this export type */
	for( i = 0; formatPseudoACL[ i ].attribute != messageValue && \
				formatPseudoACL[ i ].attribute != CRYPT_CERTFORMAT_NONE; \
		 i++ );
	if( formatPseudoACL[ i ].attribute == CRYPT_CERTFORMAT_NONE )
		{
		assert( NOTREACHED );
		return( CRYPT_ARGERROR_VALUE );
		}
	formatACL = ( ATTRIBUTE_ACL * ) &formatPseudoACL[ i ];

	/* The easiest way to handle this check is to use an ACL, treating the
	   format type as a pseudo-attribute type */
	POST( formatACL->attribute == messageValue );

	return( preDispatchCheckAttributeAccess( objectHandle,
							( message & MESSAGE_FLAG_INTERNAL ) ? \
							IMESSAGE_GETATTRIBUTE_S : MESSAGE_GETATTRIBUTE_S,
							messageDataPtr, messageValue, formatACL ) );
	}

/* It's data being pushed or popped, make sure that it's a valid data
   quantity */

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

	/* Precondition */
	PRE( isValidObject( objectHandle ) );
	PRE( isReadPtr( messageDataPtr, sizeof( RESOURCE_DATA ) ) );
	PRE( messageValue == 0 );

	/* Make sure that it's either a flush (buffer = NULL, length = 0)
	   or valid data */
	if( msgData->data == NULL )
		{
		if( localMessage != MESSAGE_ENV_PUSHDATA )
			return( CRYPT_ARGERROR_STR1 );
		if( msgData->length != 0 )
			return( CRYPT_ARGERROR_NUM1 );
		}
	else
		{
		if( msgData->length <= 0 )
			return( CRYPT_ARGERROR_NUM1 );
		if( !isReadPtr( msgData->data, msgData->length ) )
			return( CRYPT_ARGERROR_STR1 );
		}

	/* Postcondition: It's a flush or it's valid data */
	POST( ( localMessage == MESSAGE_ENV_PUSHDATA && \
			msgData->data == NULL && msgData->length == 0 ) || \
		  ( msgData->data != NULL && msgData->length > 0 ) );

	return( CRYPT_OK );
	}

/* We're creating a new object, set its owner to the owner of the object 
   that it's being created through */

int preDispatchSetObjectOwner( const int objectHandle,
							   const MESSAGE_TYPE message,
							   const void *messageDataPtr,
							   const int messageValue,
							   const void *dummy )
	{
	const OBJECT_INFO *objectTable = krnlData->objectTable;
	MESSAGE_CREATEOBJECT_INFO *createInfo = \
					( MESSAGE_CREATEOBJECT_INFO * ) messageDataPtr;

	/* Precondition */
	PRE( fullObjectCheck( objectHandle, message ) && \
		 objectTable[ objectHandle ].type == OBJECT_TYPE_DEVICE );
	PRE( messageDataPtr != NULL );
	PRE( isValidType( messageValue ) );
	PRE( createInfo->cryptOwner == CRYPT_ERROR );

	/* Set the new object's owner to the owner of the object that it's being
	   created through.  If it's being created through the system device
	   object (which has no owner), we set the owner to the default user
	   object */
	if( objectHandle == SYSTEM_OBJECT_HANDLE )
		createInfo->cryptOwner = DEFAULTUSER_OBJECT_HANDLE;
	else
		{
		const int ownerObject = objectTable[ objectHandle ].owner;

		/* Inner precondition: The owner is a valid user object */
		PRE( isValidObject( ownerObject ) && \
			 objectTable[ ownerObject ].type == OBJECT_TYPE_USER );

		createInfo->cryptOwner = ownerObject;
		}

	/* Postcondition: The new object's owner will be the user object it's
	   being created through or the default user if it's being done via the
	   system object */
	POST( ( objectHandle == SYSTEM_OBJECT_HANDLE && \
			createInfo->cryptOwner == DEFAULTUSER_OBJECT_HANDLE ) || \
		  ( objectHandle != SYSTEM_OBJECT_HANDLE && \
			createInfo->cryptOwner == objectTable[ objectHandle ].owner ) );

	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*							Message Post-Dispatch Handlers					*
*																			*
****************************************************************************/

/* If we're fetching or creating an object, it won't be visible to an
   outside caller.  If it's an external message, we have to make the object
   externally visible before we return it */

int postDispatchMakeObjectExternal( const int dummy,
									const MESSAGE_TYPE message,
									const void *messageDataPtr,
									const int messageValue,
									const void *auxInfo )
	{
	const MESSAGE_TYPE localMessage = message & MESSAGE_MASK;
	const BOOLEAN isInternalMessage = \
					( message & MESSAGE_FLAG_INTERNAL ) ? TRUE : FALSE;
	CRYPT_HANDLE objectHandle;
	int status;

	/* Preconditions */
	PRE( localMessage == MESSAGE_GETATTRIBUTE || \
		 localMessage == MESSAGE_DEV_CREATEOBJECT || \
		 localMessage == MESSAGE_DEV_CREATEOBJECT_INDIRECT || \
		 localMessage == MESSAGE_KEY_GETKEY || \
		 localMessage == MESSAGE_KEY_GETNEXTCERT || \
		 localMessage == MESSAGE_KEY_CERTMGMT );
	PRE( messageDataPtr != NULL );

	/* If it's an internal message, there are no problems with object
	   visibility.  In addition most messages are internal, so performing
	   this check before anything else quickly weeds out the majority of
	   cases */
	if( isInternalMessage )
		return( CRYPT_OK );

	switch( localMessage )
		{
		case MESSAGE_GETATTRIBUTE:
			{
			const ATTRIBUTE_ACL *attributeACL = ( ATTRIBUTE_ACL * ) auxInfo;

			/* Inner precondition: Since it's an external message, we must
			   be reading a standard attribute */
			PRE( isAttribute( messageValue ) );
			PRE( isReadPtr( attributeACL, sizeof( ATTRIBUTE_ACL ) ) || \
				 attributeACL->attribute == messageValue );

			/* If it's not an object attribute read, we're done */
			if( attributeACL->valueType == ATTRIBUTE_VALUE_SPECIAL )
				{
				attributeACL = getSpecialRangeInfo( attributeACL );
				POST( isReadPtr( attributeACL, sizeof( ATTRIBUTE_ACL ) ) );
				}
			if( attributeACL->valueType != ATTRIBUTE_VALUE_OBJECT )
				return( CRYPT_OK );

			/* Inner precondition: We're reading an object attribute and
			   sending the response to an external caller */
			PRE( attributeACL->valueType == ATTRIBUTE_VALUE_OBJECT );
			PRE( isValidObject( *( ( int * ) messageDataPtr ) ) );
			PRE( !isInternalMessage );

			objectHandle = *( ( int * ) messageDataPtr );
			break;
			}

		case MESSAGE_DEV_CREATEOBJECT:
		case MESSAGE_DEV_CREATEOBJECT_INDIRECT:
			{
			MESSAGE_CREATEOBJECT_INFO *createInfo = \
							( MESSAGE_CREATEOBJECT_INFO * ) messageDataPtr;

			PRE( isReadPtr( createInfo, sizeof( MESSAGE_CREATEOBJECT_INFO ) ) );

			objectHandle = createInfo->cryptHandle;
			break;
			}

		case MESSAGE_KEY_GETKEY:
		case MESSAGE_KEY_GETNEXTCERT:
			{
			MESSAGE_KEYMGMT_INFO *getkeyInfo = \
							( MESSAGE_KEYMGMT_INFO * ) messageDataPtr;

			PRE( isReadPtr( getkeyInfo, sizeof( MESSAGE_KEYMGMT_INFO ) ) );

			objectHandle = getkeyInfo->cryptHandle;
			break;
			}

		case MESSAGE_KEY_CERTMGMT:
			{
			MESSAGE_CERTMGMT_INFO *certMgmtInfo = \
							( MESSAGE_CERTMGMT_INFO * ) messageDataPtr;

			PRE( isReadPtr( certMgmtInfo, sizeof( MESSAGE_CERTMGMT_INFO ) ) );

			/* If it's not a cert management action that can return an
			   object, there's no object to make visible */
			if( messageValue != CRYPT_CERTACTION_ISSUE_CERT && \
				messageValue != CRYPT_CERTACTION_CERT_CREATION && \
				messageValue != CRYPT_CERTACTION_ISSUE_CRL )
				return( CRYPT_OK );

			/* If the caller has indicated that they're not interested in the
			   newly-created object, it won't be present so we can't make it
			   externally visible */
			if( certMgmtInfo->cryptCert == CRYPT_UNUSED )
				return( CRYPT_OK );

			/* Inner precondition: It's an action that can return an object,
			   and there's an object present */
			PRE( messageValue == CRYPT_CERTACTION_ISSUE_CERT || \
				 messageValue == CRYPT_CERTACTION_CERT_CREATION || \
				 messageValue == CRYPT_CERTACTION_ISSUE_CRL );
			PRE( certMgmtInfo->cryptCert != CRYPT_UNUSED );

			objectHandle = certMgmtInfo->cryptCert;
			break;
			}

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

	/* Postcondition: We've got a valid internal object to make externally
	   visible */
	POST( isValidObject( objectHandle ) && \
		  isInternalObject( objectHandle ) );

	/* Make the object externally visible.  In theory we should make this 
	   attribute read-only, but it's currently still needed in init.c (the
	   kernel self-test, which checks for internal vs. external 
	   accessibility), keyex.c (to make PGP imported contexts visible), 
	   sign.c (to make CMS signing attributes externally visible), and
	   cryptapi.c when creating objects (to make them externally visible) 
	   and destroying objects (to make the appear destroyed if a dec-
	   refcount leaves it still active) */
	status = krnlSendMessage( objectHandle, IMESSAGE_SETATTRIBUTE,
							  MESSAGE_VALUE_FALSE,
							  CRYPT_IATTRIBUTE_INTERNAL );
	if( cryptStatusError( status ) )
		return( status );

	/* Postcondition: The object is now externally visible */
	POST( isValidObject( objectHandle ) && \
		  !isInternalObject( objectHandle ) );

	return( CRYPT_OK );
	}

/* If there's a dependent object with a given relationship to the controlling
   object, forward the message.  In practice the only dependencies are those
   of PKC contexts paired with certs, for which a message sent to one (e.g. a
   check message such as "is this suitable for signing?") needs to be
   forwarded to the other */

int postDispatchForwardToDependentObject( const int objectHandle,
										  const MESSAGE_TYPE message,
										  const void *dummy1,
										  const int messageValue,
										  const void *dummy2 )
	{
	const OBJECT_INFO *objectInfoPtr = &krnlData->objectTable[ objectHandle ];
	const int dependentObject = objectInfoPtr->dependentObject;
	const OBJECT_TYPE objectType = objectInfoPtr->type;
	const OBJECT_TYPE dependentType = isValidObject( dependentObject ) ? \
					krnlData->objectTable[ dependentObject ].type : CRYPT_ERROR;
	const CHECK_ALT_ACL *checkAltACL;
	MESSAGE_CHECK_TYPE localMessageValue = messageValue;
	int status;
	TEMP_VAR( const MESSAGE_TYPE localMessage = message & MESSAGE_MASK );

	/* Precondition: It's an appropriate message type being forwarded to a
	   dependent object */
	PRE( isValidObject( objectHandle ) );
	PRE( localMessage == MESSAGE_CHECK );
	PRE( messageValue > MESSAGE_CHECK_NONE && \
		 messageValue < MESSAGE_CHECK_LAST );
	PRE( isValidObject( dependentObject ) || dependentObject == CRYPT_ERROR );

	/* Find the ACL information for the message type */
	status = findCheckACL( messageValue, objectInfoPtr->type, NU

⌨️ 快捷键说明

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