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

📄 cryptkrn.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 5 页
字号:
			*( ( 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_OK );
	}

static int setPropertyAttribute( const int objectHandle,
								 const CRYPT_ATTRIBUTE_TYPE attribute,
								 void *messageDataPtr )
	{
	OBJECT_INFO *objectInfoPtr = &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( messageDataPtr != NULL );
	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 */
			objectInfoPtr->objectOwner = THREAD_SELF();
			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( __MVS__ ) || ( defined( __UNIX__ ) && defined( _MPRAS ) ) )
				objectInfoPtr->objectOwner = ( THREAD_HANDLE ) value;
				objectInfoPtr->flags |= OBJECT_FLAG_OWNED;
#endif /* Non-scalar threading environments */
				}
			break;

		case CRYPT_PROPERTY_FORWARDCOUNT:
			if( objectInfoPtr->flags & OBJECT_FLAG_ATTRLOCKED )
				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 ) )
				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,
									CRYPT_IATTRIBUTE_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 the 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 )
				objectInfoPtr->flags |= OBJECT_FLAG_INTERNAL;
			else
				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++;
				objectInfoPtr->lockOwner = THREAD_SELF();
				}
			else
				{
				/* Precondition: The lock count is positive */
				PRE( objectInfoPtr->lockCount > 0 );

				objectInfoPtr->lockCount--;
				}

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

		default:
			assert( NOTREACHED );
		}

	return( CRYPT_OK );
	}

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

static int incRefCount( const int objectHandle, const int dummy1,
						const void *dummy2 )
	{
	ORIGINAL_INT_VAR( refCt, objectTable[ objectHandle ].referenceCount );

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

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

static int decRefCount( const int objectHandle, const int dummy1,
						const void *dummy2 )
	{
	int status;
	ORIGINAL_INT_VAR( refCt, objectTable[ objectHandle ].referenceCount );

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

	/* Decrement an object's reference count */
	if( objectTable[ objectHandle ].referenceCount > 0 )
		{
		objectTable[ objectHandle ].referenceCount--;

		/* Postconditions: We decremented the reference count and it's
		   greater than or equal to zero (the ground state) */
		POST( objectTable[ objectHandle ].referenceCount >= 0 );
		POST( objectTable[ objectHandle ].referenceCount == \
			  ORIGINAL_VALUE( refCt ) - 1 );

#if 0
	if( objectInfoPtr->dependentDevice != CRYPT_ERROR )
		/* Velisurmaaja */
		decRefCount( objectInfoPtr->dependentDevice, 0, NULL );
	if( objectInfoPtr->dependentObject != CRYPT_ERROR )
		decRefCount( objectInfoPtr->dependentObject, 0, NULL );
#endif

		return( CRYPT_OK );
		}

	/* We're already at a single reference, destroy the object.  Since this
	   may take some time, we unlock the object table around the call */
	unlockResource( objectTable );
	status = krnlSendNotifier( objectHandle, IMESSAGE_DESTROY );
	lockResource( objectTable );

	/* Postconditions - none.  We can't be sure that the object has been
	   destroyed at this point since the message will have been enqueued */

	return( status );
	}

/* Get/set dependent objects for an object */

static int getDependentObject( const int objectHandle,
							   const int targetType,
							   const void *messageDataPtr )
	{
	int *valuePtr = ( int * ) messageDataPtr, localObjectHandle;

	/* Preconditions */
	PRE( isValidObject( objectHandle ) );
	PRE( isValidType( targetType ) );
	PRE( messageDataPtr != NULL );

	/* Clear return value */
	*valuePtr = CRYPT_ERROR;

	localObjectHandle = findTargetType( objectHandle, targetType );
	if( cryptStatusError( localObjectHandle ) )
		{
		/* Postconditions: No dependent object found */
		POST( *valuePtr == CRYPT_ERROR );

		return( CRYPT_ARGERROR_OBJECT );
		}
	*valuePtr = localObjectHandle;

	/* Postconditions: We found a dependent object */
	POST( isValidObject( *valuePtr ) && \
		  isSameOwningObject( objectHandle, *valuePtr ) );

	return( CRYPT_OK );
	}

static int setDependentObject( const int objectHandle,
							   const int incReferenceCount,
							   const void *messageDataPtr )
	{
	const int dependentObject = *( ( int * ) messageDataPtr );
	int *objectHandlePtr, status = CRYPT_OK;

	/* Preconditions */
	PRE( isValidObject( objectHandle ) );
	PRE( incReferenceCount == TRUE || incReferenceCount == FALSE );
	PRE( isValidHandle( dependentObject ) );

	/* Determine which dependent object value to update based on its type */
	if( !isValidObject( dependentObject ) )
		/* The object was signalled after the message was

⌨️ 快捷键说明

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