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

📄 int_msg.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 3 页
字号:
		POST( isInternalObject( 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 );

		return( CRYPT_OK );
		}

	/* We're already at a single reference, destroy the object.  Since this
	   can entail arbitrary amounts of processing during the object shutdown
	   phase, we have to unlock the object table around the call */
	MUTEX_UNLOCK( objectTable );
	status = krnlSendNotifier( objectHandle, IMESSAGE_DESTROY );
	MUTEX_LOCK( objectTable );

	return( status );
	}

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

int getDependentObject( const int objectHandle, const int targetType,
						const void *messageDataPtr, const BOOLEAN dummy )
	{
	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 );
	}

int setDependentObject( const int objectHandle, const int incReferenceCount,
						const void *messageDataPtr, const BOOLEAN dummy )
	{
	OBJECT_INFO *objectTable = krnlData->objectTable;
	OBJECT_INFO *objectInfoPtr = &objectTable[ objectHandle ];
	const OBJECT_INFO *dependentObjectInfoPtr = &objectTable[ objectHandle ];
	const int dependentObject = *( ( int * ) messageDataPtr );
	const DEPENDENCY_ACL *dependencyACL = NULL;
	int *objectHandlePtr, i, status;

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

	/* Make sure that the object is valid, it may have been signalled after 
	   the message was sent */
	if( !isValidObject( dependentObject ) )
		return( CRYPT_ERROR_SIGNALLED );
	dependentObjectInfoPtr = &objectTable[ dependentObject ];
	objectHandlePtr = ( dependentObjectInfoPtr->type == OBJECT_TYPE_DEVICE ) ? \
			&objectInfoPtr->dependentDevice : &objectInfoPtr->dependentObject;

	/* Basic validity checks: There can't already be a dependent object set */
	if( *objectHandlePtr != CRYPT_ERROR )
		{
		/* There's already a dependent object present and we're trying to
		   overwrite it with a new one, something is seriously wrong */
		assert( NOTREACHED );
		return( CRYPT_ARGERROR_VALUE );
		}
	
	/* More complex validity checks to ensure that the object table is 
	   consistent: The object isn't already dependent on the dependent object 
	   (making the dependent object then dependent on the object would 
	   create a loop), and the object won't be dependent on its own object 
	   type unless it's a device dependent on the system device */
	if( ( ( ( objectInfoPtr->type == OBJECT_TYPE_DEVICE ) ? \
			  dependentObjectInfoPtr->dependentDevice : \
			  dependentObjectInfoPtr->dependentObject ) == objectHandle ) || \
		( objectInfoPtr->type == dependentObjectInfoPtr->type && \
		  dependentObject != SYSTEM_OBJECT_HANDLE ) )
		{
		assert( NOTREACHED );
		return( CRYPT_ARGERROR_VALUE );
		}

	/* Find the dependency ACL entry for this object/dependent object 
	   combination.  Since there can be more than one dependent object
	   type for an object, we check subtypes as well */
	for( i = 0; dependencyACLTbl[ i ].type != OBJECT_TYPE_NONE; i++ )
		if( dependencyACLTbl[ i ].type == objectInfoPtr->type && \
			dependencyACLTbl[ i ].dType == dependentObjectInfoPtr->type && \
			( isValidSubtype( dependencyACLTbl[ i ].dSubTypeA, \
							  dependentObjectInfoPtr->subType ) || \
			  isValidSubtype( dependencyACLTbl[ i ].dSubTypeB, \
							  dependentObjectInfoPtr->subType ) ) )
			{
			dependencyACL = &dependencyACLTbl[ i ];
			break;
			}
	if( dependencyACL == NULL )
		{
		assert( NOTREACHED );
		return( CRYPT_ARGERROR_VALUE );
		}

	/* Inner precondition: We have the appropriate ACL for this combination 
	   of object and dependent object */
	PRE( dependencyACL->type == objectInfoPtr->type && \
		 dependencyACL->dType == dependentObjectInfoPtr->type && \
		 ( isValidSubtype( dependencyACL->dSubTypeA, \
						   dependentObjectInfoPtr->subType ) || \
		   isValidSubtype( dependencyACL->dSubTypeB, \
						   dependentObjectInfoPtr->subType ) ) );

	/* Type-specific checks.  For PKC context -> cert and cert -> PKC context
	   attaches we should also check that the primary PKC object is a 
	   private-key object and the dependent PKC object is a public-key object
	   to catch things like a private key depending on a (public-key) cert,
	   however this requires unlocking the object table in order to send the
	   context a check message.  Since this requires additional precautions,
	   we leave it for updateDependentObjectPerms(), which has to unlock the
	   table for its own update operations */
	if( !isValidSubtype( dependencyACL->subTypeA, \
						 objectInfoPtr->subType ) && \
		!isValidSubtype( dependencyACL->subTypeB, \
						 objectInfoPtr->subType ) )
		{
		assert( NOTREACHED );
		return( CRYPT_ARGERROR_VALUE );
		}
	if( !isValidSubtype( dependencyACL->dSubTypeA, \
						 dependentObjectInfoPtr->subType ) && \
		!isValidSubtype( dependencyACL->dSubTypeB, \
						 dependentObjectInfoPtr->subType ) )
		{
		assert( NOTREACHED );
		return( CRYPT_ARGERROR_VALUE );
		}

	/* Inner precondition */
	PRE( *objectHandlePtr == CRYPT_ERROR );
	PRE( isSameOwningObject( objectHandle, dependentObject ) );

	/* Certs and contexts have special relationships in that the cert can
	   constrain the use of the context beyond its normal level.  If we're
	   performing this type of object attachment, we have to adjust one
	   object's behaviour based on the permissions of the other one.  We do
	   this before we increment the reference count because the latter can 
	   never fail so we don't have to worry about undoing the update */
	if( dependencyACL->flags & DEP_FLAG_UPDATEDEP )
		{
		status = updateDependentObjectPerms( objectHandle, dependentObject );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Update the dependent object's reference count if required and record
	   the new status in the object table.  Dependent objects can be
	   established in one of two ways, by taking an existing object and
	   attaching it to another object (which increments its reference count,
	   since it's now being referred to by the original owner and by the
	   object it's  attached to), or by creating a new object and attaching
	   it to another object (which doesn't increment the reference count
	   since it's only referred to by the controlling object).  An example of
	   the former operation is adding a context from a cert request to a cert
	   (the cert request is referenced by both the caller and the cert), an
	   example of the latter operation is attaching a data-only cert to a
	   context (the cert is only referenced by the context) */
	if( incReferenceCount )
		{
		status = incRefCount( dependentObject, 0, NULL, TRUE );
		if( cryptStatusError( status ) )
			return( status );
		}
	*objectHandlePtr = dependentObject;

	/* Postconditions */
	POST( isValidObject( *objectHandlePtr ) && \
		  isSameOwningObject( objectHandle, *objectHandlePtr ) );

	return( CRYPT_OK );
	}

/* Clone an object.  The older copy-on-write implementation didn't actually 
   do anything at this point except check that the access was valid and set 
   the aliased and cloned flags to indicate that the object needed to be 
   handled specially if a write access was made to it, but with the kernel
   tracking instance data we can do a copy immediately to create two 
   distinct objects */

int cloneObject( const int objectHandle, const int clonedObject,
				 const void *dummy1, const BOOLEAN dummy2 )
	{
	OBJECT_INFO *objectInfoPtr = &krnlData->objectTable[ objectHandle ];
	OBJECT_INFO *clonedObjectInfoPtr = &krnlData->objectTable[ clonedObject ];
	int actionFlags, status;

	/* Preconditions */
	PRE( isValidObject( objectHandle ) && \
		 objectHandle >= NO_SYSTEM_OBJECTS );
	PRE( !isClonedObject( objectHandle ) && \
		 !isAliasedObject( objectHandle ) );
	PRE( objectInfoPtr->type == OBJECT_TYPE_CONTEXT );
	PRE( isValidObject( clonedObject ) && \
		 clonedObject >= NO_SYSTEM_OBJECTS );
	PRE( !isClonedObject( clonedObject ) && \
		 !isAliasedObject( clonedObject ) );
	PRE( clonedObjectInfoPtr->type == OBJECT_TYPE_CONTEXT );
	PRE( objectHandle != clonedObject );

	/* Make sure that the original object is in the high state.  This will
	   have been checked by the caller anyway, but we check again here to
	   make sure */
	if( !isInHighState( objectHandle ) )
		return( CRYPT_ERROR_NOTINITED );

	/* Cloning of non-native contexts is somewhat complex because we usually
	   can't clone a device object, so we have to detect requests to clone
	   these objects and increment their reference count instead.  This
	   isn't a major problem because cryptlib always creates native contexts
	   for clonable algorithms, if the user explicitly overrides this by
	   using their own device-specific context then the usage will usually
	   be create, add to envelope, destroy, so there's no need to clone the
	   context anyway.  The only that time there's a potential problem is if
	   they override the use of native contexts by adding device contexts to
	   multiple envelopes, but in that case it's assumed that they'll be
	   aware of potential problems with this approach */
	if( objectInfoPtr->dependentDevice != SYSTEM_OBJECT_HANDLE )
		return( incRefCount( objectHandle, 0, NULL, TRUE ) );

	/* Since this is an internal-use-only object, lock down the action
	   permissions so that only encryption and hash actions from internal
	   sources are allowed (assuming they were allowed to begin with).
	   Keygen is disabled entirely (there should already be a key loaded),
	   and signing isn't possible with a non-PKC object anyway.  This takes
	   advantage of the ratchet enforced for the action permissions, which
	   can only make them more restrictive than the existing permissions, to 
	   avoid having to read and modify each permission individually */
	actionFlags = \
		MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, ACTION_PERM_NONE_EXTERNAL ) | \
		MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, ACTION_PERM_NONE_EXTERNAL ) | \
		MK_ACTION_PERM( MESSAGE_CTX_HASH, ACTION_PERM_NONE_EXTERNAL );
	status = setPropertyAttribute( clonedObject, CRYPT_IATTRIBUTE_ACTIONPERMS,
								   &actionFlags );
	if( cryptStatusError( status ) )
		return( status );

	/* Postcondition: The cloned object can only be used internally */
	POST( ( clonedObjectInfoPtr->actionFlags & ~ACTION_PERM_NONE_EXTERNAL_ALL ) == 0 );

	/* Inner precondition: The instance data is valid and ready to be 
	   copied */
	PRE( isWritePtr( objectInfoPtr->objectPtr, objectInfoPtr->objectSize ) );
	PRE( isWritePtr( clonedObjectInfoPtr->objectPtr, 
					 clonedObjectInfoPtr->objectSize ) );
	PRE( objectInfoPtr->objectSize == clonedObjectInfoPtr->objectSize );

#if 0	/* 18/2/04 No need for copy-on-write any more since we can just copy 
				   across the instance data referenced in the object table */
	/* Mark the two objects as being aliases, and the (incomplete) clone as
	   a cloned object */
	objectInfoPtr->flags |= OBJECT_FLAG_ALIASED;
	objectInfoPtr->clonedObject = clonedObject;
	clonedObjectInfoPtr->flags |= OBJECT_FLAG_ALIASED | OBJECT_FLAG_CLONE;
	clonedObjectInfoPtr->clonedObject = objectHandle;

	/* Postconditions: The objects are marked as aliased objects and the
	   cloned object as a clone */
	POST( isAliasedObject( objectHandle ) && !isClonedObject( objectHandle ) );
	POST( isAliasedObject( clonedObject ) && isClonedObject( clonedObject ) );
	POST( !isClonedObject( clonedObjectInfoPtr->clonedObject ) );
	POST( isClonedObject( objectInfoPtr->clonedObject ) );
	POST( objectHandle != clonedObject );
#else
	/* Copy across the object contents and reset any instance-specific 
	   information.  We only update the owning object if required, in
	   almost all cases this will be the system device so there's no need
	   to perform the update */
	memcpy( clonedObjectInfoPtr->objectPtr, objectInfoPtr->objectPtr,
			objectInfoPtr->objectSize );
	objectInfoPtr->messageFunction( clonedObjectInfoPtr->objectPtr,
									MESSAGE_CHANGENOTIFY, 
									( void * ) &clonedObject,
									MESSAGE_CHANGENOTIFY_OBJHANDLE );
	if( objectInfoPtr->owner != clonedObjectInfoPtr->owner )
		objectInfoPtr->messageFunction( clonedObjectInfoPtr->objectPtr,
										MESSAGE_CHANGENOTIFY, 
										&clonedObjectInfoPtr->owner,
										MESSAGE_CHANGENOTIFY_OWNERHANDLE );

	/* We've copied across the object's state, the cloned object is now
	   initialised ready for use */
	clonedObjectInfoPtr->flags |= OBJECT_FLAG_HIGH;
#endif /* 0 */

	return( CRYPT_OK );
	}

⌨️ 快捷键说明

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