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

📄 cryptapi.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************
*																			*
*						 cryptlib External API Interface					*
*						Copyright Peter Gutmann 1997-2007					*
*																			*
****************************************************************************/

/* NSA motto: In God we trust... all others we monitor.
														-- Stanley Miller */
#include "crypt.h"
#if defined( INC_ALL )
  #include "rpc.h"
#else
  #include "misc/rpc.h"
#endif /* Compiler-specific includes */

/* Handlers for the various commands */

static int cmdCertCheck( void *stateInfo, COMMAND_INFO *cmd )
	{
	assert( cmd->type == COMMAND_CERTCHECK );
	assert( cmd->flags == COMMAND_FLAG_NONE );
	assert( cmd->noArgs == 2 );
	assert( cmd->noStrArgs == 0 );

	UNUSED_ARG( stateInfo );

	/* Perform basic server-side error checking */
	if( !isHandleRangeValid( cmd->arg[ 0 ] ) )
		return( CRYPT_ARGERROR_OBJECT );
	if( !isHandleRangeValid( cmd->arg[ 1 ] ) && \
		( cmd->arg[ 1 ] != CRYPT_UNUSED ) )
		return( CRYPT_ARGERROR_NUM1 );

	return( krnlSendMessage( cmd->arg[ 0 ], MESSAGE_CRT_SIGCHECK, NULL,
							 cmd->arg[ 1 ] ) );
	}

static int cmdCertMgmt( void *stateInfo, COMMAND_INFO *cmd )
	{
	MESSAGE_CERTMGMT_INFO certMgmtInfo;
	int status;

	assert( cmd->type == COMMAND_CERTMGMT );
	assert( cmd->flags == COMMAND_FLAG_NONE || \
			cmd->flags == COMMAND_FLAG_RET_NONE );
	assert( cmd->noArgs == 4 );
	assert( cmd->noStrArgs == 0 );

	UNUSED_ARG( stateInfo );

	/* Perform basic server-side error checking */
	if( !isHandleRangeValid( cmd->arg[ 0 ] ) )
		return( CRYPT_ARGERROR_OBJECT );
	if( cmd->arg[ 1 ] < CRYPT_CERTACTION_FIRST_USER || \
		cmd->arg[ 1 ] > CRYPT_CERTACTION_LAST_USER )
		return( CRYPT_ARGERROR_VALUE );
	if( !isHandleRangeValid( cmd->arg[ 2 ] ) && \
		!( ( cmd->arg[ 1 ] == CRYPT_CERTACTION_EXPIRE_CERT || \
			 cmd->arg[ 1 ] == CRYPT_CERTACTION_CLEANUP ) && \
		   cmd->arg[ 2 ] == CRYPT_UNUSED ) )
		return( CRYPT_ARGERROR_NUM1 );
	if( !isHandleRangeValid( cmd->arg[ 3 ] ) && \
		!( ( cmd->arg[ 1 ] == CRYPT_CERTACTION_ISSUE_CRL || \
			 cmd->arg[ 1 ] == CRYPT_CERTACTION_EXPIRE_CERT || \
			 cmd->arg[ 1 ] == CRYPT_CERTACTION_CLEANUP ) && \
		   cmd->arg[ 3 ] == CRYPT_UNUSED ) )
		return( CRYPT_ARGERROR_NUM2 );

	setMessageCertMgmtInfo( &certMgmtInfo, cmd->arg[ 2 ], cmd->arg[ 3 ] );
	if( cmd->flags == COMMAND_FLAG_RET_NONE )
		/* If we aren't interested in the return value, set the crypt handle
		   to CRYPT_UNUSED to indicate that there's no need to return the
		   created cert object */
		certMgmtInfo.cryptCert = CRYPT_UNUSED;
	status = krnlSendMessage( cmd->arg[ 0 ], MESSAGE_KEY_CERTMGMT,
							  &certMgmtInfo, cmd->arg[ 1 ] );
	if( cryptStatusOK( status ) && cmd->flags != COMMAND_FLAG_RET_NONE )
		cmd->arg[ 0 ] = certMgmtInfo.cryptCert;
	return( status );
	}

static int cmdCertSign( void *stateInfo, COMMAND_INFO *cmd )
	{
	assert( cmd->type == COMMAND_CERTSIGN );
	assert( cmd->flags == COMMAND_FLAG_NONE );
	assert( cmd->noArgs == 2 );
	assert( cmd->noStrArgs == 0 );

	UNUSED_ARG( stateInfo );

	/* Perform basic server-side error checking */
	if( !isHandleRangeValid( cmd->arg[ 0 ] ) )
		return( CRYPT_ARGERROR_OBJECT );
	if( !isHandleRangeValid( cmd->arg[ 1 ] ) )
		return( CRYPT_ARGERROR_NUM1 );

	return( krnlSendMessage( cmd->arg[ 0 ], MESSAGE_CRT_SIGN, NULL,
							 cmd->arg[ 1 ] ) );
	}

static int cmdCreateObject( void *stateInfo, COMMAND_INFO *cmd )
	{
	MESSAGE_CREATEOBJECT_INFO createInfo;
	BOOLEAN bindToOwner = FALSE, hasStrArg = FALSE;
	int owner = DUMMY_INIT, status;

	assert( cmd->type == COMMAND_CREATEOBJECT );
	assert( cmd->flags == COMMAND_FLAG_NONE );
	assert( cmd->noArgs >= 2 && cmd->noArgs <= 4 );
	assert( cmd->noStrArgs >= 0 && cmd->noStrArgs <= 2 );

	UNUSED_ARG( stateInfo );

	/* Perform basic server-side error checking */
	if( !isHandleRangeValid( cmd->arg[ 0 ] ) && \
		cmd->arg[ 0 ] != SYSTEM_OBJECT_HANDLE )
		return( CRYPT_ARGERROR_OBJECT );
	if( cmd->arg[ 1 ] <= OBJECT_TYPE_NONE || \
		cmd->arg[ 1 ] >= OBJECT_TYPE_LAST )
		return( CRYPT_ERROR_FAILED );	/* Internal error */
	switch( cmd->arg[ 1 ] )
		{
		case OBJECT_TYPE_CONTEXT:
			assert( cmd->noArgs == 3 );
			assert( cmd->noStrArgs == 0 );
			if( ( cmd->arg[ 2 ] <= CRYPT_ALGO_NONE || \
				  cmd->arg[ 2 ] >= CRYPT_ALGO_LAST ) && \
				cmd->arg[ 2 ] != CRYPT_USE_DEFAULT )
				return( CRYPT_ARGERROR_NUM1 );
			break;

		case OBJECT_TYPE_CERTIFICATE:
			assert( cmd->noArgs == 3 );
			assert( cmd->noStrArgs == 0 );
			if( cmd->arg[ 2 ] <= CRYPT_CERTTYPE_NONE || \
				cmd->arg[ 2 ] >= CRYPT_CERTTYPE_LAST_EXTERNAL )
				return( CRYPT_ARGERROR_NUM1 );
			break;

		case OBJECT_TYPE_DEVICE:
			assert( cmd->noArgs == 3 );
			assert( cmd->noStrArgs == 1 );
			if( cmd->arg[ 2 ] <= CRYPT_DEVICE_NONE || \
				cmd->arg[ 2 ] >= CRYPT_DEVICE_LAST )
				return( CRYPT_ARGERROR_NUM1 );
			if( cmd->arg[ 2 ] == CRYPT_DEVICE_PKCS11 || \
				cmd->arg[ 2 ] == CRYPT_DEVICE_CRYPTOAPI )
				{
				if( cmd->strArgLen[ 0 ] < MIN_NAME_LENGTH || \
					cmd->strArgLen[ 0 ] >= MAX_ATTRIBUTE_SIZE )
					return( CRYPT_ARGERROR_STR1 );
				hasStrArg = TRUE;
				}
			break;

		case OBJECT_TYPE_KEYSET:
			assert( cmd->noArgs == 4 );
			assert( cmd->noStrArgs >= 0 && cmd->noStrArgs <= 1 );
			if( cmd->arg[ 2 ] <= CRYPT_KEYSET_NONE || \
				cmd->arg[ 2 ] >= CRYPT_KEYSET_LAST )
				return( CRYPT_ARGERROR_NUM1 );
			if( cmd->strArgLen[ 0 ] < MIN_NAME_LENGTH || \
				cmd->strArgLen[ 0 ] >= MAX_ATTRIBUTE_SIZE )
				return( CRYPT_ARGERROR_STR1 );
			if( cmd->arg[ 3 ] < CRYPT_KEYOPT_NONE || \
				cmd->arg[ 3 ] >= CRYPT_KEYOPT_LAST_EXTERNAL )
				{
				/* CRYPT_KEYOPT_NONE is a valid setting for this parameter */
				return( CRYPT_ARGERROR_NUM2 );
				}
			hasStrArg = TRUE;
			break;

		case OBJECT_TYPE_ENVELOPE:
			assert( cmd->noArgs == 3 );
			assert( cmd->noStrArgs == 0 );
			if( cmd->arg[ 2 ] <= CRYPT_FORMAT_NONE || \
				cmd->arg[ 2 ] >= CRYPT_FORMAT_LAST_EXTERNAL )
				return( CRYPT_ARGERROR_NUM1 );
			break;

		case OBJECT_TYPE_SESSION:
			assert( cmd->noArgs == 3 );
			assert( cmd->noStrArgs == 0 );
			if( cmd->arg[ 2 ] <= CRYPT_SESSION_NONE || \
				cmd->arg[ 2 ] >= CRYPT_SESSION_LAST )
				return( CRYPT_ARGERROR_NUM1 );
			break;

		case OBJECT_TYPE_USER:
			assert( cmd->noArgs == 2 );
			assert( cmd->noStrArgs == 2 );
			if( cmd->strArgLen[ 0 ] < MIN_NAME_LENGTH || \
				cmd->strArgLen[ 0 ] >= CRYPT_MAX_TEXTSIZE )
				return( CRYPT_ARGERROR_STR1 );
			if( cmd->strArgLen[ 1 ] < MIN_NAME_LENGTH || \
				cmd->strArgLen[ 1 ] >= CRYPT_MAX_TEXTSIZE )
				return( CRYPT_ARGERROR_STR2 );
			hasStrArg = TRUE;
			break;

		default:
			retIntError();
		}

	/* If we're creating the object via a device, we should set the new
	   object owner to the device owner */
	if( cmd->arg[ 0 ] != SYSTEM_OBJECT_HANDLE )
		{
		bindToOwner = TRUE;
		owner = cmd->arg[ 0 ];
		}

	/* Create the object via the device.  Since we're usually doing this via
	   the system object which is invisible to the user, we have to use an
	   internal message for this one case */
	setMessageCreateObjectInfo( &createInfo, cmd->arg[ 2 ] );
	if( cmd->noArgs == 4 )
		createInfo.arg2 = cmd->arg[ 3 ];
	if( hasStrArg )
		{
		createInfo.strArg1 = cmd->strArg[ 0 ];
		createInfo.strArgLen1 = cmd->strArgLen[ 0 ];
		if( cmd->noStrArgs > 1 )
			{
			createInfo.strArg2 = cmd->strArg[ 1 ];
			createInfo.strArgLen2 = cmd->strArgLen[ 1 ];
			}
		}
	if( cmd->arg[ 0 ] == SYSTEM_OBJECT_HANDLE )
		{
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
								  IMESSAGE_DEV_CREATEOBJECT, &createInfo,
								  cmd->arg[ 1 ] );
		}
	else
		{
		status = krnlSendMessage( cmd->arg[ 0 ], MESSAGE_DEV_CREATEOBJECT,
								  &createInfo, cmd->arg[ 1 ] );
		}
	if( cryptStatusError( status ) )
		return( status );

	/* If the device used to create the object is bound to a thread, bind the
	   created object to the thread as well.  If this fails, we don't return
	   the object to the caller since it would be returned in a potentially
	   unbound state */
	if( bindToOwner )
		{
		int ownerID;

		status = krnlSendMessage( owner, IMESSAGE_GETATTRIBUTE, &ownerID,
								  CRYPT_PROPERTY_OWNER );
		if( cryptStatusOK( status ) )
			status = krnlSendMessage( createInfo.cryptHandle,
									  IMESSAGE_SETATTRIBUTE, &ownerID,
									  CRYPT_PROPERTY_OWNER );
		if( cryptStatusError( status ) && status != CRYPT_ERROR_NOTINITED )
			{
			krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
			return( status );
			}
		}

	/* Make the newly-created object externally visible if necessary.  This
	   is only required when we're creating the object via the system
	   handle, which requires an internal message that leaves the object
	   internal */
	if( cmd->arg[ 0 ] == SYSTEM_OBJECT_HANDLE )
		{
		krnlSendMessage( createInfo.cryptHandle, IMESSAGE_SETATTRIBUTE,
						 MESSAGE_VALUE_FALSE, CRYPT_IATTRIBUTE_INTERNAL );
		}
	cmd->arg[ 0 ] = createInfo.cryptHandle;
	return( CRYPT_OK );
	}

static int cmdCreateObjectIndirect( void *stateInfo, COMMAND_INFO *cmd )
	{
	MESSAGE_CREATEOBJECT_INFO createInfo;
	int status;

	assert( cmd->type == COMMAND_CREATEOBJECT_INDIRECT );
	assert( cmd->flags == COMMAND_FLAG_NONE );
	assert( cmd->noArgs == 2 );
	assert( cmd->noStrArgs == 1 );

	UNUSED_ARG( stateInfo );

	/* Perform basic server-side error checking */
	if( cmd->arg[ 0 ] != SYSTEM_OBJECT_HANDLE )
		return( CRYPT_ERROR_FAILED );	/* Internal error */
	if( cmd->arg[ 1 ] != OBJECT_TYPE_CERTIFICATE )
		return( CRYPT_ERROR_FAILED );	/* Internal error */
	if( cmd->strArgLen[ 0 ] < MIN_CERTSIZE || \
		cmd->strArgLen[ 0 ] >= MAX_INTLENGTH )
		return( CRYPT_ARGERROR_STR1 );

	/* Create the object via the device.  Since we're usually doing this via
	   the system object which is invisible to the user, we have to use an
	   internal message for this one case */
	setMessageCreateObjectIndirectInfo( &createInfo, cmd->strArg[ 0 ],
										cmd->strArgLen[ 0 ],
										CRYPT_CERTTYPE_NONE );
	if( cmd->arg[ 0 ] == SYSTEM_OBJECT_HANDLE )
		{
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
								  IMESSAGE_DEV_CREATEOBJECT_INDIRECT,
								  &createInfo, OBJECT_TYPE_CERTIFICATE );
		}
	else
		{
		status = krnlSendMessage( cmd->arg[ 0 ],
								  MESSAGE_DEV_CREATEOBJECT_INDIRECT,
								  &createInfo, OBJECT_TYPE_CERTIFICATE );
		}
	if( cryptStatusError( status ) )
		return( status );

	/* Make the newly-created object externally visible */
	krnlSendMessage( createInfo.cryptHandle, IMESSAGE_SETATTRIBUTE,
					 MESSAGE_VALUE_FALSE, CRYPT_IATTRIBUTE_INTERNAL );
	cmd->arg[ 0 ] = createInfo.cryptHandle;
	return( status );
	}

static int cmdDecrypt( void *stateInfo, COMMAND_INFO *cmd )
	{
	CRYPT_ALGO_TYPE cryptAlgo;
	CRYPT_MODE_TYPE cryptMode = CRYPT_MODE_NONE;
	int status;

	assert( cmd->type == COMMAND_DECRYPT );
	assert( cmd->flags == COMMAND_FLAG_NONE );
	assert( cmd->noArgs == 1 );
	assert( cmd->noStrArgs == 1 );

	UNUSED_ARG( stateInfo );

	/* Perform basic server-side error checking */
	status = krnlSendMessage( cmd->arg[ 0 ], MESSAGE_GETATTRIBUTE,
							  &cryptAlgo, CRYPT_CTXINFO_ALGO );
	if( cryptStatusError( status ) )
		return( status );
	if( cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL )
		{
		status = krnlSendMessage( cmd->arg[ 0 ], MESSAGE_GETATTRIBUTE,
								  &cryptMode, CRYPT_CTXINFO_MODE );
		if( cryptStatusError( status ) )
				return( status );
		}
	else
		{
		if( cryptAlgo <= CRYPT_ALGO_LAST_PKC )
			{
			int blockSize;

			status = krnlSendMessage( cmd->arg[ 0 ], MESSAGE_GETATTRIBUTE,
									  &blockSize, CRYPT_CTXINFO_KEYSIZE );
			if( cryptStatusOK( status ) && cmd->strArgLen[ 0 ] != blockSize )
				status = CRYPT_ARGERROR_NUM1;
			if( cryptStatusError( status ) )
				return( status );
			}
		}
	if( cmd->strArgLen[ 0 ] < 0 )
		return( CRYPT_ARGERROR_NUM1 );
	if( cryptMode == CRYPT_MODE_ECB || cryptMode == CRYPT_MODE_CBC )
		{
		int blockSize;

		status = krnlSendMessage( cmd->arg[ 0 ], MESSAGE_GETATTRIBUTE,
								  &blockSize, CRYPT_CTXINFO_BLOCKSIZE );
		if( cryptStatusOK( status ) && cmd->strArgLen[ 0 ] % blockSize )
			status = CRYPT_ARGERROR_NUM1;
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Make sure the IV has been set */
	if( needsIV( cryptMode ) && !isStreamCipher( cryptAlgo ) )
		{
		MESSAGE_DATA msgData;

		setMessageData( &msgData, NULL, 0 );

⌨️ 快捷键说明

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