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

📄 cryptapi.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
		status = krnlSendMessage( cmd->arg[ 0 ], MESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_CTXINFO_IV );
		if( cryptStatusError( status ) )
			return( status );
		}

	status = krnlSendMessage( cmd->arg[ 0 ],
							  ( cryptAlgo >= CRYPT_ALGO_FIRST_HASH ) ? \
								MESSAGE_CTX_HASH : MESSAGE_CTX_DECRYPT,
							  cmd->strArgLen[ 0 ] ? cmd->strArg[ 0 ] : "",
							  cmd->strArgLen[ 0 ] );
	if( cryptAlgo >= CRYPT_ALGO_FIRST_HASH )
		{
		/* There's no data to return since the hashing doesn't change it */
		cmd->strArgLen[ 0 ] = 0;
		}
	return( status );
	}

static int cmdDeleteAttribute( void *stateInfo, COMMAND_INFO *cmd )
	{
	assert( cmd->type == COMMAND_DELETEATTRIBUTE );
	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 ] ) && \
		cmd->arg[ 0 ] != DEFAULTUSER_OBJECT_HANDLE )
		return( CRYPT_ARGERROR_OBJECT );
	if( cmd->arg[ 0 ] == DEFAULTUSER_OBJECT_HANDLE )
		{
		if( cmd->arg[ 1 ] <= CRYPT_OPTION_FIRST || \
			cmd->arg[ 1 ] >= CRYPT_OPTION_LAST )
			return( CRYPT_ARGERROR_NUM1 );
		}
	else
		{
		if( cmd->arg[ 1 ] <= CRYPT_ATTRIBUTE_NONE || \
			cmd->arg[ 1 ] >= CRYPT_ATTRIBUTE_LAST )
			return( CRYPT_ARGERROR_NUM1 );
		}

	/* Delete the attribute.  Since we're usually doing this via the default
	   user object which is invisible to the user, we have to use an internal
	   message for this one case */
	if( cmd->arg[ 0 ] == DEFAULTUSER_OBJECT_HANDLE )
		{
		return( krnlSendMessage( DEFAULTUSER_OBJECT_HANDLE,
								 IMESSAGE_DELETEATTRIBUTE, NULL,
								 cmd->arg[ 1 ] ) );
		}
	return( krnlSendMessage( cmd->arg[ 0 ], MESSAGE_DELETEATTRIBUTE, NULL,
							 cmd->arg[ 1 ] ) );
	}

static int cmdDeleteKey( void *stateInfo, COMMAND_INFO *cmd )
	{
	MESSAGE_KEYMGMT_INFO deletekeyInfo;
	int itemType = KEYMGMT_ITEM_PUBLICKEY;

	assert( cmd->type == COMMAND_DELETEKEY );
	assert( cmd->flags == COMMAND_FLAG_NONE );
	assert( cmd->noArgs >= 2 && cmd->noArgs <= 3 );
	assert( cmd->noStrArgs == 1 );

	UNUSED_ARG( stateInfo );

	/* Perform basic server-side error checking */
	if( !isHandleRangeValid( cmd->arg[ 0 ] ) )
		return( CRYPT_ARGERROR_OBJECT );
	if( cmd->arg[ 1 ] <= CRYPT_KEYID_NONE || \
		cmd->arg[ 1 ] >= CRYPT_KEYID_LAST_EXTERNAL )
		return( CRYPT_ARGERROR_NUM1 );
	if( cmd->arg[ 2 ] )
		{
		/* It's a special-case object being fetched from a CA store */
		if( cmd->arg[ 2 ] == CRYPT_CERTTYPE_REQUEST_CERT )
			itemType = KEYMGMT_ITEM_REQUEST;
		else
			{
			if( cmd->arg[ 2 ] == CRYPT_CERTTYPE_PKIUSER )
				itemType = KEYMGMT_ITEM_PKIUSER;
			else
				return( CRYPT_ARGERROR_NUM2 );
			}
		}
	if( cmd->strArgLen[ 0 ] < MIN_NAME_LENGTH || \
		cmd->strArgLen[ 0 ] >= MAX_ATTRIBUTE_SIZE )
		return( CRYPT_ARGERROR_STR1 );

	/* Delete the key from the keyset.  Unless the user has explicitly
	   specified a CA item to delete, we set the item type to delete to
	   public-key since private-key keysets will interpret this correctly
	   to mean they should also delete the associated private key */
	setMessageKeymgmtInfo( &deletekeyInfo, cmd->arg[ 1 ], cmd->strArg[ 0 ],
						   cmd->strArgLen[ 0 ], NULL, 0, KEYMGMT_FLAG_NONE );
	return( krnlSendMessage( cmd->arg[ 0 ], MESSAGE_KEY_DELETEKEY,
							 &deletekeyInfo, itemType ) );
	}

static int cmdDestroyObject( void *stateInfo, COMMAND_INFO *cmd )
	{
	assert( cmd->type == COMMAND_DESTROYOBJECT );
	assert( cmd->flags == COMMAND_FLAG_NONE );
	assert( cmd->noArgs == 1 );
	assert( cmd->noStrArgs == 0 );

	UNUSED_ARG( stateInfo );

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

	/* Decrement the object's reference count, which may or may not actually
	   destroy it (the kernel marks it as internal so it appears destroyed
	   to the caller) */
	return( krnlSendNotifier( cmd->arg[ 0 ], MESSAGE_DECREFCOUNT ) );
	}

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

	assert( cmd->type == COMMAND_ENCRYPT );
	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( cryptAlgo >= CRYPT_ALGO_FIRST_HASH )
		{
		/* For hash and MAC operations a length of zero is valid since this
		   is an indication to wrap up the hash operation */
		if( cmd->strArgLen[ 0 ] < 0 )
			return( CRYPT_ARGERROR_NUM1 );
		}
	else
		{
		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 );
		}

	/* If there's no IV set, generate one ourselves */
	if( needsIV( cryptMode ) && !isStreamCipher( cryptAlgo ) )
		{
		MESSAGE_DATA msgData;

		setMessageData( &msgData, NULL, 0 );
		status = krnlSendMessage( cmd->arg[ 0 ], MESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_CTXINFO_IV );
		if( cryptStatusError( status ) )
			{
			if( status == CRYPT_ERROR_NOTINITED )
				krnlSendNotifier( cmd->arg[ 0 ], MESSAGE_CTX_GENIV );
			else
				return( status );
			}
		}

	status = krnlSendMessage( cmd->arg[ 0 ],
							  ( cryptAlgo >= CRYPT_ALGO_FIRST_HASH ) ? \
								MESSAGE_CTX_HASH : MESSAGE_CTX_ENCRYPT,
							  cmd->strArgLen[ 0 ] ? cmd->strArg[ 0 ] : "",
							  cmd->strArgLen[ 0 ] );
	if( cryptAlgo >= CRYPT_ALGO_FIRST_HASH )
		{
		/* There's no data to return since the hashing doesn't change it */
		cmd->strArgLen[ 0 ] = 0;
		}
	return( status );
	}

static int cmdExportObject( void *stateInfo, COMMAND_INFO *cmd )
	{
	MESSAGE_DATA msgData;
	int status;

	assert( cmd->type == COMMAND_EXPORTOBJECT );
	assert( cmd->flags == COMMAND_FLAG_NONE || \
			cmd->flags == COMMAND_FLAG_RET_LENGTH );
	assert( cmd->noArgs == 2 );
	assert( ( cmd->flags == COMMAND_FLAG_NONE && cmd->noStrArgs == 1 ) || \
			( cmd->flags == COMMAND_FLAG_RET_LENGTH && cmd->noStrArgs == 0 ) );
	assert( cmd->flags == COMMAND_FLAG_RET_LENGTH || \
			cmd->strArg[ 0 ] != NULL );

	UNUSED_ARG( stateInfo );

	/* Perform basic server-side error checking */
	if( !isHandleRangeValid( cmd->arg[ 0 ] ) )
		return( CRYPT_ARGERROR_OBJECT );
	if( cmd->arg[ 1 ] <= CRYPT_CERTFORMAT_NONE || \
		cmd->arg[ 1 ] >= CRYPT_CERTFORMAT_LAST_EXTERNAL )
		{
		/* At the moment the only object that we can export is a cert, so we
		   make sure that the format type is valid for this */
		return( CRYPT_ARGERROR_NUM1 );
		}

	/* Export the cert */
	if( cmd->flags == COMMAND_FLAG_RET_LENGTH )
		{
		setMessageData( &msgData, NULL, 0 );
		status = krnlSendMessage( cmd->arg[ 0 ], MESSAGE_CRT_EXPORT,
								  &msgData, cmd->arg[ 1 ] );
		if( cryptStatusOK( status ) )
			cmd->arg[ 0 ] = msgData.length;
		}
	else
		{
		setMessageData( &msgData, cmd->strArg[ 0 ], cmd->strArgLen[ 0 ] );
		status = krnlSendMessage( cmd->arg[ 0 ], MESSAGE_CRT_EXPORT,
								  &msgData, cmd->arg[ 1 ] );
		if( cryptStatusOK( status ) )
			cmd->strArgLen[ 0 ] = msgData.length;
		}

	/* If we try and export using a disallowed format (e.g. a
	   CRYPT_CERTFORMAT_CERTCHAIN from a cert request) we'll get an argument
	   value error that we need to convert into something more sensible.
	   The error type to report is somewhat debatable since either the
	   format type or the object can be regarded as being wrong, for example
	   when exporting a cert request as a cert chain the format is wrong but
	   when exporting a data-only object as anything the object is wrong.
	   To handle this, we report an argument value error as a numeric
	   parameter error for cases where the format is incorrect for the
	   object type, and a permission error for cases where the object can't
	   be exported externally */
	if( status == CRYPT_ARGERROR_VALUE )
		{
		int type;

		status = krnlSendMessage( cmd->arg[ 0 ], MESSAGE_GETATTRIBUTE, &type,
								  CRYPT_CERTINFO_CERTTYPE );
		if( cryptStatusError( status ) )
			return( CRYPT_ARGERROR_OBJECT );
		status = ( type == CRYPT_CERTTYPE_CERTIFICATE || \
				   type == CRYPT_CERTTYPE_ATTRIBUTE_CERT || \
				   type == CRYPT_CERTTYPE_CERTCHAIN || \
				   type == CRYPT_CERTTYPE_CERTREQUEST || \
				   type == CRYPT_CERTTYPE_CRL ) ? \
				 CRYPT_ARGERROR_NUM1 : CRYPT_ERROR_PERMISSION;
		}

	return( status );
	}

static int cmdFlushData( void *stateInfo, COMMAND_INFO *cmd )
	{
	MESSAGE_DATA msgData;
	int status;

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

	UNUSED_ARG( stateInfo );

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

	/* Send the flush data command to the object */
	setMessageData( &msgData, NULL, 0 );
	status = krnlSendMessage( cmd->arg[ 0 ], MESSAGE_ENV_PUSHDATA,
							  &msgData, 0 );
	return( status );
	}

static int cmdGenKey( void *stateInfo, COMMAND_INFO *cmd )
	{
	assert( cmd->type == COMMAND_GENKEY );
	assert( cmd->flags == COMMAND_FLAG_NONE );
	assert( cmd->noArgs == 1 );
	assert( cmd->noStrArgs == 0 );

	UNUSED_ARG( stateInfo );

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

	return( krnlSendNotifier( cmd->arg[ 0 ], MESSAGE_CTX_GENKEY ) );
	}

static int cmdGetAttribute( void *stateInfo, COMMAND_INFO *cmd )
	{
	MESSAGE_DATA msgData;
	int status;

	assert( cmd->type == COMMAND_GETATTRIBUTE );
	assert( cmd->flags == COMMAND_FLAG_NONE || \
			cmd->flags == COMMAND_FLAG_RET_LENGTH );
	assert( cmd->noArgs >= 2 && cmd->noArgs <= 3 );
	assert( ( cmd->flags == COMMAND_FLAG_NONE && cmd->noStrArgs == 1 ) || \
			( ( cmd->noArgs == 2 || cmd->flags == COMMAND_FLAG_RET_LENGTH ) && \
				cmd->noStrArgs == 0 ) );

	UNUSED_ARG( stateInfo );

	/* Perform basic server-side error checking */
	if( !isHandleRangeValid( cmd->arg[ 0 ] ) && \
		cmd->arg[ 0 ] != DEFAULTUSER_OBJECT_HANDLE )
		return( CRYPT_ARGERROR_OBJECT );
	if( cmd->arg[ 0 ] == DEFAULTUSER_OBJECT_HANDLE )
		{
		if( cmd->arg[ 1 ] <= CRYPT_OPTION_FIRST || \
			cmd->arg[ 1 ] >= CRYPT_OPTION_LAST )
			return( CRYPT_ARGERROR_NUM1 );
		}
	else
		{
		if( cmd->arg[ 1 ] <= CRYPT_ATTRIBUTE_NONE || \
			cmd->arg[ 1 ] >= CRYPT_ATTRIBUTE_LAST )
			return( CRYPT_ARGERROR_NUM1 );
		}

	/* Get the attribute data from the object.  If it's a config option,
	   we're usually doing this via the default user object which is
	   invisible to the user, so we have to use an internal message for this
	   one case.

	   This is further complicated by the fact that the kernel checks that
	   the destination memory is writeable and either returns an error (for
	   an external message) or throws an exception (for the internal message
	   required to access the user object) if it isn't.  Since the external
	   API doesn't allow the specification of the returned data length, it
	   uses a worst-case estimate which may be much larger than the actual
	   buffer size, which the kernel will refuse to write to.  To handle
	   this we first read the actual length and then ask for only that much
	   data, which the caller should have made available for the output */
	if( cmd->noArgs == 2 )
		{
		if( cmd->arg[ 0 ] == DEFAULTUSER_OBJECT_HANDLE )
			{
			return( krnlSendMessage( DEFAULTUSER_OBJECT_HANDLE,
									 IMESSAGE_GETATTRIBUTE, &cmd->arg[ 0 ],
									 cmd->arg[ 1 ] ) );
			}
		return( krnlSendMessage( cmd->arg[ 0 ], MESSAGE_GETATTRIBUTE,
								 &cmd->arg[ 0 ], cmd->arg[ 1 ] ) );
		}

⌨️ 快捷键说明

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