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

📄 cryptapi.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 5 页
字号:

	/* 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 ) )
		{
		RESOURCE_DATA msgData;

		setMessageData( &msgData, NULL, 0 );
		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( stateInfo );

	/* Perform basic server-side error checking */
	if( !checkHandleRange( 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;

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

	UNUSED( stateInfo );

	/* Perform basic server-side error checking */
	if( !checkHandleRange( 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->strArgLen[ 0 ] < MIN_NAME_LENGTH || \
		cmd->strArgLen[ 0 ] >= MAX_ATTRIBUTE_SIZE )
		return( CRYPT_ARGERROR_STR1 );

	/* Delete the key from the keyset.  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, KEYMGMT_ITEM_PUBLICKEY ) );
	}

static int cmdDestroyObject( void *stateInfo, COMMAND_INFO *cmd )
	{
	int dummy, status;

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

	UNUSED( stateInfo );

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

	/* Since we're about to access an internal attribute which can only be
	   done through an internal message, we have to explicitly make sure the
	   object is externally visible.  We do this by reading it's locked
	   property (which is valid for all objects) */
	status = krnlSendMessage( cmd->arg[ 0 ], MESSAGE_GETATTRIBUTE, &dummy,
							  CRYPT_PROPERTY_LOCKED );
	if( cryptStatusError( status ) )
		return( status );

	/* Make the object internal, which marks it as invalid for any external
	   access (to the caller, it looks like it's been destroyed).  After
	   this, decrement its reference count (which may or may not actually
	   destroy it) */
	krnlSendMessage( cmd->arg[ 0 ], IMESSAGE_SETATTRIBUTE,
					 MESSAGE_VALUE_TRUE, CRYPT_IATTRIBUTE_INTERNAL );
	return( krnlSendNotifier( cmd->arg[ 0 ], IMESSAGE_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( 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 );
		}

	/* If there's no IV set, generate one ourselves */
	if( needsIV( cryptMode ) && !isStreamCipher( cryptAlgo ) )
		{
		RESOURCE_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 )
	{
	RESOURCE_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( stateInfo );

	/* Perform basic server-side error checking */
	if( !checkHandleRange( 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 we can export is a cert, so we
		   make sure the format type is valid for this */
		return( CRYPT_ARGERROR_NUM1 );

	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 )
	{
	RESOURCE_DATA msgData;
	int status;

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

	UNUSED( stateInfo );

	/* Perform basic server-side error checking */
	if( !checkHandleRange( 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 && cmd->noArgs <= 2 );
	assert( cmd->noStrArgs == 0 );

	UNUSED( stateInfo );

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

	return( krnlSendMessage( cmd->arg[ 0 ], MESSAGE_CTX_GENKEY, NULL,
							 ( cmd->noArgs > 1 ) ? \
								( cmd->arg[ 1 ] ? TRUE : FALSE ) : FALSE ) );
	}

static int cmdGetAttribute( void *stateInfo, COMMAND_INFO *cmd )
	{
	RESOURCE_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( stateInfo );

	/* Perform basic server-side error checking */
	if( !checkHandleRange( cmd->arg[ 0 ] ) && \
		cmd->arg[ 0 ] != DEFAULTUSER_OBJECT_HANDLE )
		return( CRYPT_ARGERROR_OBJECT );
	if( cmd->arg[ 0 ] == DEFAULTUSER_OBJECT_HANDLE )
		{

⌨️ 快捷键说明

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