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

📄 obj_acc.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 2 页
字号:
		return( CRYPT_ERROR_PERMISSION );
		}

	/* It's a valid object, get its info */
	objectInfoPtr = &objectTable[ objectHandle ];
	STORE_ORIGINAL_INT( lockCount, objectInfoPtr->lockCount );

	objectInfoPtr->lockCount--;

	/* Postcondition: The object's lock count has been decremented and is
	   non-negative */
	POST( objectInfoPtr->lockCount == \
							ORIGINAL_VALUE( lockCount ) - 1 );
	POST( objectInfoPtr->lockCount >= 0 );

	MUTEX_UNLOCK( objectTable );
	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*							Init/Shutdown Functions							*
*																			*
****************************************************************************/

int initObjectAltAccess( KERNEL_DATA *krnlDataPtr )
	{
	/* Set up the reference to the kernel data block */
	krnlData = krnlDataPtr;

	return( CRYPT_OK );
	}

void endObjectAltAccess( void )
	{
	krnlData = NULL;
	}

/****************************************************************************
*																			*
*						Direct Object Access Functions						*
*																			*
****************************************************************************/

/* Acquire/release an object */

int krnlAcquireObject( const int objectHandle, const OBJECT_TYPE type,
					   void **objectPtr, const int errorCode )
	{
	return( getObject( objectHandle, type, ACCESS_CHECK_EXTERNAL, 
					   objectPtr, errorCode ) );
	}

int krnlReleaseObject( const int objectHandle )
	{
	return( releaseObject( objectHandle, ACCESS_CHECK_EXTERNAL_RELEASE ) );
	}

/* Relinquish ownership of the system object to another thread.  This
   procedure is needed to allow a background polling thread to add entropy
   to the system device.  The way it works is that the calling thread hands
   ownership over to the polling thread and suspends itself until the
   polling thread completes.  When the polling thread has completed, it
   terminates, whereupon the original thread wakes up and reacquires
   ownership.  The value passed to the release call is actually a thread ID,
   but since this type isn't visible outside the kernel we just us a generic
   int */

int krnlRelinquishSystemObject( const int /* THREAD_HANDLE */ objectOwner )
	{
	OBJECT_INFO *objectTable = krnlData->objectTable;
#ifdef USE_THREADS
	OBJECT_INFO *objectInfoPtr = &objectTable[ SYSTEM_OBJECT_HANDLE ];
#endif /* USE_THREADS */

	/* Preconditions: The object is valid and in use */
	PRE( isValidObject( SYSTEM_OBJECT_HANDLE ) );
	PRE( isInUse( SYSTEM_OBJECT_HANDLE ) );

	MUTEX_LOCK( objectTable );

	/* Precondition: We're relinquishing ownership, we must currently be
	   the owner */
	PRE( isObjectOwner( SYSTEM_OBJECT_HANDLE ) );

	/* Check that the access is valid */
	if( !isValidObject( SYSTEM_OBJECT_HANDLE ) || \
		!isInUse( SYSTEM_OBJECT_HANDLE ) || \
		!checkObjectOwnership( objectTable[ SYSTEM_OBJECT_HANDLE ] ) )
		{
		MUTEX_UNLOCK( objectTable );
		assert( NOTREACHED );
		return( CRYPT_ERROR_PERMISSION );
		}

#ifdef USE_THREADS
	objectInfoPtr->lockOwner = ( THREAD_HANDLE ) objectOwner;
#endif /* USE_THREADS */

	MUTEX_UNLOCK( objectTable );
	return( CRYPT_OK );
	}

int krnlReacquireSystemObject( void )
	{
#ifdef USE_THREADS
	OBJECT_INFO *objectInfoPtr = &krnlData->objectTable[ SYSTEM_OBJECT_HANDLE ];
#endif /* USE_THREADS */

	/* Preconditions: The object is valid and in use */
	PRE( isValidObject( SYSTEM_OBJECT_HANDLE ) );
	PRE( isInUse( SYSTEM_OBJECT_HANDLE ) );

	MUTEX_LOCK( objectTable );

	/* Precondition: Since we're reacquiring ownership, we're not currently 
	   the owner  */
	PRE( !isObjectOwner( SYSTEM_OBJECT_HANDLE ) );

	/* Check that the access is valid */
	if( !isValidObject( SYSTEM_OBJECT_HANDLE ) || \
		!isInUse( SYSTEM_OBJECT_HANDLE ) )
		{
		MUTEX_UNLOCK( objectTable );
		assert( NOTREACHED );
		return( CRYPT_ERROR_PERMISSION );
		}

#ifdef USE_THREADS
	objectInfoPtr->lockOwner = THREAD_SELF();
#endif /* USE_THREADS */

	MUTEX_UNLOCK( objectTable );
	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*							Key Extract Functions							*
*																			*
****************************************************************************/

/* The cryptlib equivalent of trusted downgraders in other security models:
   Functions that extract a key from a context.  These functions need to
   bypass the kernel's security checking in order to allow key export and
   are the only ones that can do this.  This is an unavoidable requirement
   in the complete-isolation model - some bypass mechanism needs to be
   present in order to allow a key to be exported from an encryption action
   object.  The three functions that perform the necessary operations are:

	extractKeyData: Extract a session key from a conventional/MAC context
					prior to encryption with a KEK.
	exportPrivateKey: Write private key data to a stream prior to encryption
					  with a KEK.
	importPrivateKey: Read private key data from a stream after decryption
					  with a KEK */

#define PKC_CONTEXT		/* Indicate that we're working with PKC context */
#if defined( INC_ALL )
  #include "context.h"
#elif defined( INC_CHILD )
  #include "../context/context.h"
#else
  #include "context/context.h"
#endif /* Compiler-specific includes */

int extractKeyData( const CRYPT_CONTEXT iCryptContext, void *keyData )
	{
	CONTEXT_INFO *contextInfoPtr;
	int status;

	/* Clear return value */
	memset( keyData, 0, bitsToBytes( MIN_KEYSIZE_BITS ) );

	/* Make sure that we've been given a conventional encryption or MAC 
	   context with a key loaded.  This has already been checked at a higher 
	   level, but we perform a sanity check here to be safe */
	status = getObject( iCryptContext, OBJECT_TYPE_CONTEXT,
						ACCESS_CHECK_KEYACCESS,
						( void ** ) &contextInfoPtr, CRYPT_ARGERROR_OBJECT );
	if( cryptStatusError( status ) )
		return( status );
	if( ( contextInfoPtr->type != CONTEXT_CONV && \
		  contextInfoPtr->type != CONTEXT_MAC ) || \
		!( contextInfoPtr->flags & CONTEXT_KEY_SET ) )
		{
		releaseObject( iCryptContext, ACCESS_CHECK_KEYACCESS );
		return( CRYPT_ARGERROR_OBJECT );
		}

	/* Export the key data from the context */
	switch( contextInfoPtr->type )
		{
		case CONTEXT_CONV:
			memcpy( keyData, contextInfoPtr->ctxConv->userKey,
					contextInfoPtr->ctxConv->userKeyLength );
			break;

		case CONTEXT_MAC:
			memcpy( keyData, contextInfoPtr->ctxMAC->userKey,
					contextInfoPtr->ctxMAC->userKeyLength );
			break;

		default:
			assert( NOTREACHED );
			status = CRYPT_ARGERROR_OBJECT;
		}
	releaseObject( iCryptContext, ACCESS_CHECK_KEYACCESS );
	return( status );
	}

int exportPrivateKeyData( STREAM *stream, const CRYPT_CONTEXT iCryptContext,
						  const KEYFORMAT_TYPE formatType )
	{
	CONTEXT_INFO *contextInfoPtr;
	int status;

	/* Make sure that we've been given a PKC context with a private key
	   loaded.  This has already been checked at a higher level, but we
	   perform a sanity check here to be safe */
	status = getObject( iCryptContext, OBJECT_TYPE_CONTEXT, 
						ACCESS_CHECK_KEYACCESS,
						( void ** ) &contextInfoPtr, CRYPT_ARGERROR_OBJECT );
	if( cryptStatusError( status ) )
		return( status );
	if( contextInfoPtr->type != CONTEXT_PKC ||
		!( contextInfoPtr->flags & CONTEXT_KEY_SET ) || \
		( contextInfoPtr->flags & CONTEXT_ISPUBLICKEY ) )
		{
		releaseObject( iCryptContext, ACCESS_CHECK_KEYACCESS );
		return( CRYPT_ARGERROR_OBJECT );
		}

	/* Export the key data from the context */
	status = contextInfoPtr->ctxPKC->writePrivateKeyFunction( stream, 
										contextInfoPtr, formatType, "private" );
	releaseObject( iCryptContext, ACCESS_CHECK_KEYACCESS );
	return( status );
	}

int importPrivateKeyData( STREAM *stream, const CRYPT_CONTEXT iCryptContext,
						  const KEYFORMAT_TYPE formatType )
	{
	CONTEXT_INFO *contextInfoPtr;
	int status;

	/* Make sure that we've been given a PKC context with no private key
	   loaded.  This has already been checked at a higher level, but we
	   perform a sanity check here to be safe */
	status = getObject( iCryptContext, OBJECT_TYPE_CONTEXT, 
						ACCESS_CHECK_KEYACCESS,
						( void ** ) &contextInfoPtr, CRYPT_ARGERROR_OBJECT );
	if( cryptStatusError( status ) )
		return( status );
	if( contextInfoPtr->type != CONTEXT_PKC ||
		( contextInfoPtr->flags & CONTEXT_KEY_SET ) || \
		( contextInfoPtr->flags & CONTEXT_ISPUBLICKEY ) )
		{
		releaseObject( iCryptContext, ACCESS_CHECK_KEYACCESS );
		return( CRYPT_ARGERROR_OBJECT );
		}

	/* Import the key data into the context */
	status = contextInfoPtr->ctxPKC->readPrivateKeyFunction( stream, 
										contextInfoPtr, formatType );
	if( cryptStatusOK( status ) )
		{
		/* If everything went OK, perform an internal load that uses the
		   values already present in the context */
		status = contextInfoPtr->loadKeyFunction( contextInfoPtr, NULL, 0 );
		if( cryptStatusOK( status ) )
			{
			krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE, 
							 MESSAGE_VALUE_UNUSED, 
							 CRYPT_IATTRIBUTE_INITIALISED );
			contextInfoPtr->flags |= CONTEXT_KEY_SET;
			}
		else
			if( cryptArgError( status ) )
				/* Map the status to a more appropriate code */
				status = CRYPT_ERROR_BADDATA;
		}
	releaseObject( iCryptContext, ACCESS_CHECK_KEYACCESS );
	return( status );
	}

⌨️ 快捷键说明

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