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

📄 int_msg.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 3 页
字号:
			   scalar thread IDs, which we can't easily handle when all we
			   have is an integer handle.  However, the need to bind threads
			   to objects only exists because of Win32 security holes
			   arising from the ability to perform thread injection, so this
			   isn't a big issue */
			return( CRYPT_ERROR_FAILED );
  #else
			*valuePtr = ( int ) objectInfoPtr->objectOwner;
  #endif /* Non-scalar threading environments */
#else
			*valuePtr = 0;
#endif /* USE_THREADS */
			break;

		case CRYPT_PROPERTY_FORWARDCOUNT:
			if( objectInfoPtr->flags & OBJECT_FLAG_ATTRLOCKED )
				return( CRYPT_ERROR_PERMISSION );
			*valuePtr = objectInfoPtr->forwardCount;
			break;

		case CRYPT_PROPERTY_LOCKED:
			/* We allow this to be read since its value can be determined
			   anyway with a trial write */
			*( ( BOOLEAN * ) messageDataPtr ) = \
						( objectInfoPtr->flags & OBJECT_FLAG_ATTRLOCKED ) ? \
						TRUE : FALSE;
			break;

		case CRYPT_PROPERTY_USAGECOUNT:
			*valuePtr = objectInfoPtr->usageCount;
			break;

		/* Internal properties */
		case CRYPT_IATTRIBUTE_TYPE :
			*valuePtr = objectInfoPtr->type;
			break;

		case CRYPT_IATTRIBUTE_SUBTYPE :
			*valuePtr = objectInfoPtr->subType;
			break;

		case CRYPT_IATTRIBUTE_STATUS:
			*valuePtr = objectInfoPtr->flags & OBJECT_FLAGMASK_STATUS;
			break;

		case CRYPT_IATTRIBUTE_INTERNAL:
			*( ( BOOLEAN * ) messageDataPtr ) = \
					( objectInfoPtr->flags & OBJECT_FLAG_INTERNAL ) ? \
					TRUE : FALSE;
			break;

		case CRYPT_IATTRIBUTE_ACTIONPERMS:
			*valuePtr = objectInfoPtr->actionFlags;
			break;

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

	return( CRYPT_OK );
	}

int setPropertyAttribute( const int objectHandle,
						  const CRYPT_ATTRIBUTE_TYPE attribute,
						  void *messageDataPtr )
	{
	OBJECT_INFO *objectInfoPtr = &krnlData->objectTable[ objectHandle ];
	const int value = *( ( int * ) messageDataPtr );

	/* Preconditions */
	PRE( isValidObject( objectHandle ) );
	PRE( attribute == CRYPT_PROPERTY_HIGHSECURITY || \
		 attribute == CRYPT_PROPERTY_OWNER || \
		 attribute == CRYPT_PROPERTY_FORWARDCOUNT || \
		 attribute == CRYPT_PROPERTY_LOCKED || \
		 attribute == CRYPT_PROPERTY_USAGECOUNT || \
		 attribute == CRYPT_IATTRIBUTE_STATUS || \
		 attribute == CRYPT_IATTRIBUTE_INTERNAL || \
		 attribute == CRYPT_IATTRIBUTE_ACTIONPERMS || \
		 attribute == CRYPT_IATTRIBUTE_LOCKED );
	PRE( isReadPtr( messageDataPtr, sizeof( int ) ) );
	PRE( objectHandle >= NO_SYSTEM_OBJECTS || \
		 attribute == CRYPT_IATTRIBUTE_STATUS );

	switch( attribute )
		{
		/* User-accessible properties */
		case CRYPT_PROPERTY_HIGHSECURITY:
			/* This is a combination property that makes an object owned,
			   non-forwardable, and locked */
			if( objectInfoPtr->flags & OBJECT_FLAG_ATTRLOCKED )
				return( CRYPT_ERROR_PERMISSION );
#ifdef USE_THREADS
			objectInfoPtr->objectOwner = THREAD_SELF();
#endif /* USE_THREADS */
			objectInfoPtr->forwardCount = 0;
			objectInfoPtr->flags |= OBJECT_FLAG_ATTRLOCKED | OBJECT_FLAG_OWNED;
			break;

		case CRYPT_PROPERTY_OWNER:
			/* This property can still be changed (even if the object is
			   locked) until the forwarding count drops to zero, otherwise
			   locking the object would prevent any forwarding */
			if( objectInfoPtr->forwardCount != CRYPT_UNUSED )
				{
				if( objectInfoPtr->forwardCount <= 0 )
					return( CRYPT_ERROR_PERMISSION );
				objectInfoPtr->forwardCount--;
				}
			if( value == CRYPT_UNUSED )
				objectInfoPtr->flags &= ~OBJECT_FLAG_OWNED;
			else
				{
#if defined( USE_THREADS ) && !defined( NONSCALAR_THREADS )
				objectInfoPtr->objectOwner = ( THREAD_HANDLE ) value;
				objectInfoPtr->flags |= OBJECT_FLAG_OWNED;
#endif /* USE_THREADS && scalar threading environments */
				}
			break;

		case CRYPT_PROPERTY_FORWARDCOUNT:
			if( objectInfoPtr->flags & OBJECT_FLAG_ATTRLOCKED )
				return( CRYPT_ERROR_PERMISSION );
			if( objectInfoPtr->forwardCount != CRYPT_UNUSED && \
				objectInfoPtr->forwardCount < value )
				/* Once set the forward count can only be decreased, never
				   increased */
				return( CRYPT_ERROR_PERMISSION );
			objectInfoPtr->forwardCount = value;
			break;

		case CRYPT_PROPERTY_LOCKED:
			/* Precondition: This property can only be set to true */
			PRE( value );

			objectInfoPtr->flags |= OBJECT_FLAG_ATTRLOCKED;
			break;

		case CRYPT_PROPERTY_USAGECOUNT:
			if( objectInfoPtr->flags & OBJECT_FLAG_ATTRLOCKED || \
				( objectInfoPtr->usageCount != CRYPT_UNUSED && \
				  objectInfoPtr->usageCount < value ) )
				/* Once set the usage count can only be decreased, never
				   increased */
				return( CRYPT_ERROR_PERMISSION );
			objectInfoPtr->usageCount = value;
			break;

		/* Internal properties */
		case CRYPT_IATTRIBUTE_STATUS:
			/* We're clearing an error/abnormal state or setting the object
			   to the busy state */
			PRE( value == CRYPT_OK || value == CRYPT_ERROR_TIMEOUT );

			if( isInvalidObjectState( objectHandle ) )
				{
				/* If the object is in an abnormal state, we can only (try to)
				   return it back to the normal state after the problem is
				   resolved */
				PRE( value == CRYPT_OK );

				/* If we're resetting the object status from busy to OK,
				   notify the object in case there's any extra processing to
				   be done */
				if( objectInfoPtr->flags & OBJECT_FLAG_BUSY )
					{
					/* Precondition: Only contexts can be busy */
					PRE( objectInfoPtr->type == OBJECT_TYPE_CONTEXT );

					/* If the notification returns an error, the object is
					   still performing some sort of processing (e.g. cleanup/
					   shutdown), don't reset the status (it'll be done later
					   when the object is ready) */
					if( objectInfoPtr->messageFunction( objectInfoPtr->objectPtr,
									MESSAGE_CHANGENOTIFY, messageDataPtr,
									MESSAGE_CHANGENOTIFY_STATUS ) == CRYPT_OK )
						objectInfoPtr->flags &= ~OBJECT_FLAG_BUSY;
					break;
					}

				/* If we're processing a notification from the caller that
				   the object init is complete and the object was destroyed
				   while it was being created (which sets its state to
				   CRYPT_ERROR_SIGNALLED), tell the caller to convert the
				   message to a destroy object message unless it's a system
				   object, which can't be explicitly destroyed.  In this case
				   we just return an error so the cryptlib init fails */
				if( objectInfoPtr->flags & OBJECT_FLAG_SIGNALLED )
					return( ( objectHandle < NO_SYSTEM_OBJECTS ) ?
							CRYPT_ERROR_SIGNALLED : OK_SPECIAL );

				/* We're transitioning the object to the initialised state */
				PRE( objectInfoPtr->flags & OBJECT_FLAG_NOTINITED );
				objectInfoPtr->flags &= ~OBJECT_FLAG_NOTINITED;
				POST( !( objectInfoPtr->flags & OBJECT_FLAG_NOTINITED ) );
				break;
				}

			/* Inner precondition: The object is in a valid state */
			PRE( !isInvalidObjectState( objectHandle ) );

			/* We're setting the object's busy flag because it's about to
			   perform an async op */
			if( value == CRYPT_ERROR_TIMEOUT )
				objectInfoPtr->flags |= OBJECT_FLAG_BUSY;
			break;

		case CRYPT_IATTRIBUTE_INTERNAL:
			if( value )
				{
				PRE( !( objectInfoPtr->flags & OBJECT_FLAG_INTERNAL ) );

				objectInfoPtr->flags |= OBJECT_FLAG_INTERNAL;
				}
			else
				{
				PRE( objectInfoPtr->flags & OBJECT_FLAG_INTERNAL );

				objectInfoPtr->flags &= ~OBJECT_FLAG_INTERNAL;
				}
			break;

		case CRYPT_IATTRIBUTE_ACTIONPERMS:
			objectInfoPtr->actionFlags = \
					updateActionPerms( objectInfoPtr->actionFlags, value );
			break;

		case CRYPT_IATTRIBUTE_LOCKED:
			/* Incremement or decrement the object's lock count depending on
			   whether we're locking or unlocking it */
			if( value )
				{
				objectInfoPtr->lockCount++;
#ifdef USE_THREADS
				objectInfoPtr->lockOwner = THREAD_SELF();
#endif /* USE_THREADS */
				}
			else
				{
				/* Precondition: The lock count is positive */
				PRE( objectInfoPtr->lockCount > 0 );

				if( objectInfoPtr->lockCount <= 0 )
					{
					assert( NOTREACHED );
					return( CRYPT_ERROR_PERMISSION );
					}
				objectInfoPtr->lockCount--;
				}

			/* If it's a certificate, notify it that it should save/restore 
			   its internal state */
			if( objectInfoPtr->type == OBJECT_TYPE_CERTIFICATE )
				objectInfoPtr->messageFunction( objectInfoPtr->objectPtr,
									MESSAGE_CHANGENOTIFY, messageDataPtr,
									MESSAGE_CHANGENOTIFY_STATE );
			break;

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

	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*							Update Internal Properties						*
*																			*
****************************************************************************/

/* Increment/decrement the reference count for an object.  This adjusts the
   reference count as appropriate and sends destroy messages if the reference
   count goes negative */

int incRefCount( const int objectHandle, const int dummy1,
				 const void *dummy2, const BOOLEAN dummy3 )
	{
	OBJECT_INFO *objectTable = krnlData->objectTable;
	ORIGINAL_INT_VAR( refCt, objectTable[ objectHandle ].referenceCount );

	/* Preconditions */
	PRE( isValidObject( objectHandle ) );
	POST( objectTable[ objectHandle ].referenceCount >= 0 );

	/* Increment an object's reference count */
	objectTable[ objectHandle ].referenceCount++;

	/* Postcondition: We incremented the reference count and it's now greater
	   than zero (the ground state) */
	POST( objectTable[ objectHandle ].referenceCount >= 1 );
	POST( objectTable[ objectHandle ].referenceCount == \
		  ORIGINAL_VALUE( refCt ) + 1 );

	return( CRYPT_OK );
	}

int decRefCount( const int objectHandle, const int dummy1,
				 const void *dummy2, const BOOLEAN isInternal )
	{
	OBJECT_INFO *objectTable = krnlData->objectTable;
	int status;
	ORIGINAL_INT_VAR( refCt, objectTable[ objectHandle ].referenceCount );

	/* Preconditions */
	PRE( isValidObject( objectHandle ) );

	/* If the message is coming from an external source (in other words if
	   it's an external caller destroying the object), make the object 
	   internal.  This marks it as invalid for any external access, so that
	   to the caller it looks like it's been destroyed even if its reference 
	   count keeps it active */
	if( !isInternal )
		{
		PRE( !isInternalObject( objectHandle ) );

		objectTable[ objectHandle ].flags |= OBJECT_FLAG_INTERNAL;

⌨️ 快捷键说明

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