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

📄 int_env.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************
*																			*
*					cryptlib Internal Enveloping API						*
*					Copyright Peter Gutmann 1992-2008						*
*																			*
****************************************************************************/

#include "crypt.h"
#ifndef NDEBUG		/* For assert( checkObjectEncoding() ) */
  #if defined( INC_ALL )
	#include "asn1.h"
  #else
	#include "misc/asn1.h"
  #endif /* Compiler-specific includes */
#endif /* NDEBUG */

/****************************************************************************
*																			*
*							Data Wrap/Unwrap Functions						*
*																			*
****************************************************************************/

/* General-purpose enveloping functions, used by various high-level
   protocols */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 5 ) ) \
int envelopeWrap( IN_BUFFER( inDataLength ) const void *inData, 
				  IN_LENGTH_MIN( 16 ) const int inDataLength, 
				  OUT_BUFFER( outDataMaxLength, \
							  *outDataLength ) void *outData, 
				  IN_LENGTH_MIN( 16 ) const int outDataMaxLength, 
				  OUT_LENGTH_Z int *outDataLength, 
				  IN_ENUM( CRYPT_FORMAT ) const CRYPT_FORMAT_TYPE formatType,
				  IN_ENUM_OPT( CRYPT_CONTENT ) \
					const CRYPT_CONTENT_TYPE contentType,
				  IN_HANDLE_OPT const CRYPT_HANDLE iPublicKey )
	{
	CRYPT_ENVELOPE iCryptEnvelope;
	MESSAGE_CREATEOBJECT_INFO createInfo;
	MESSAGE_DATA msgData;
	const int minBufferSize = max( MIN_BUFFER_SIZE, inDataLength + 512 );
	int status;

	assert( isReadPtr( inData, inDataLength ) );
	assert( isWritePtr( outData, outDataMaxLength ) );
	assert( isWritePtr( outDataLength, sizeof( int ) ) );

	REQUIRES( inDataLength > 16 && inDataLength < MAX_INTLENGTH );
	REQUIRES( outDataMaxLength > 16 && \
			  outDataMaxLength >= inDataLength + 512 && \
			  outDataMaxLength < MAX_INTLENGTH );
	REQUIRES( formatType == CRYPT_FORMAT_CRYPTLIB || \
			  formatType == CRYPT_FORMAT_CMS );
	REQUIRES( contentType >= CRYPT_CONTENT_NONE && \
			  contentType < CRYPT_CONTENT_LAST );
	REQUIRES( ( iPublicKey == CRYPT_UNUSED ) || \
			  isHandleRangeValid( iPublicKey ) );

	/* Clear return values.  Note that we can't clear the output buffer 
	   at this point since this function is frequently used for in-place 
	   processing, so we clear it after we've pushed the input data */
	*outDataLength = 0;

	/* Create an envelope to wrap the data, add the encryption key if
	   necessary, and pop the wrapped result */
	setMessageCreateObjectInfo( &createInfo, formatType );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
							  IMESSAGE_DEV_CREATEOBJECT, &createInfo,
							  OBJECT_TYPE_ENVELOPE );
	if( cryptStatusError( status ) )
		{
		memset( outData, 0, min( 16, outDataMaxLength ) );
		return( status );
		}
	iCryptEnvelope = createInfo.cryptHandle;
	( void ) krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
							  ( void * ) &minBufferSize, 
							  CRYPT_ATTRIBUTE_BUFFERSIZE );
	status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
							  ( void * ) &inDataLength,
							  CRYPT_ENVINFO_DATASIZE );
	if( cryptStatusOK( status ) && contentType != CRYPT_CONTENT_NONE )
		status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
								  ( void * ) &contentType,
								  CRYPT_ENVINFO_CONTENTTYPE );
	if( cryptStatusOK( status ) && iPublicKey != CRYPT_UNUSED )
		status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
								  ( void * ) &iPublicKey,
								  CRYPT_ENVINFO_PUBLICKEY );
	if( cryptStatusOK( status ) )
		{
		setMessageData( &msgData, ( void * ) inData, inDataLength );
		status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_PUSHDATA,
								  &msgData, 0 );
		if( cryptStatusOK( status ) )
			{
			ENSURES( msgData.length >= inDataLength );
			}
		}
	memset( outData, 0, min( 16, outDataMaxLength ) );
	if( cryptStatusOK( status ) )
		{
		setMessageData( &msgData, NULL, 0 );
		status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_PUSHDATA,
								  &msgData, 0 );
		}
	if( cryptStatusOK( status ) )
		{
		setMessageData( &msgData, outData, outDataMaxLength );
		status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_POPDATA,
								  &msgData, 0 );
		if( cryptStatusOK( status ) )
			{
			ENSURES( msgData.length > inDataLength && \
					 msgData.length < outDataMaxLength );
			}
		if( cryptStatusOK( status ) )
			*outDataLength = msgData.length;
		}
	krnlSendNotifier( iCryptEnvelope, IMESSAGE_DECREFCOUNT );

	assert( cryptStatusError( status ) || \
			!cryptStatusError( checkObjectEncoding( outData, \
													*outDataLength ) ) );
	assert( !cryptArgError( status ) );
	return( cryptArgError( status ) ? CRYPT_ERROR_BADDATA : status );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 5 ) ) \
int envelopeUnwrap( IN_BUFFER( inDataLength ) const void *inData, 
					IN_LENGTH_MIN( 16 ) const int inDataLength,
					OUT_BUFFER( outDataMaxLength, \
								*outDataLength ) void *outData, 
					IN_LENGTH_MIN( 16 ) const int outDataMaxLength,
					OUT_LENGTH_Z int *outDataLength, 
					IN_HANDLE_OPT const CRYPT_CONTEXT iPrivKey )
	{
	CRYPT_ENVELOPE iCryptEnvelope;
	MESSAGE_CREATEOBJECT_INFO createInfo;
	MESSAGE_DATA msgData;
	const int minBufferSize = max( MIN_BUFFER_SIZE, inDataLength );
	int status;

	assert( isReadPtr( inData, inDataLength ) );
	assert( isWritePtr( outData, outDataMaxLength ) );
	assert( isWritePtr( outDataLength, sizeof( int ) ) );

	REQUIRES( inDataLength > 16 && inDataLength < MAX_INTLENGTH );
	REQUIRES( outDataMaxLength > 16 && \
			  outDataMaxLength >= inDataLength && \
			  outDataMaxLength < MAX_INTLENGTH );
	REQUIRES( ( iPrivKey == CRYPT_UNUSED ) || \
			  isHandleRangeValid( iPrivKey ) );

	/* Clear return values.  Note that we can't clear the output buffer 
	   at this point since this function is frequently used for in-place 
	   processing, so we clear it after we've pushed the input data */
	*outDataLength = 0;

	/* Create an envelope to unwrap the data, add the decryption key if
	   necessary, and pop the unwrapped result.  In theory we could use 
	   checkASN1() here to perform a safety check of the envelope data
	   prior to processing but this has already been done by the calling
	   code when the datagram containing the enveloped data was read so
	   we don't need to repeat the (rather heavyweight) operation here */
	setMessageCreateObjectInfo( &createInfo, CRYPT_FORMAT_AUTO );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
							  IMESSAGE_DEV_CREATEOBJECT, &createInfo,
							  OBJECT_TYPE_ENVELOPE );
	if( cryptStatusError( status ) )
		{
		memset( outData, 0, min( 16, outDataMaxLength ) );
		return( status );
		}
	iCryptEnvelope = createInfo.cryptHandle;
	( void ) krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
							  ( void * ) &minBufferSize, 
							  CRYPT_ATTRIBUTE_BUFFERSIZE );
	setMessageData( &msgData, ( void * ) inData, inDataLength );
	status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_PUSHDATA,
							  &msgData, 0 );
	if( cryptStatusOK( status ) )
		{
		ENSURES( msgData.length >= inDataLength );
		}
	memset( outData, 0, min( 16, outDataMaxLength ) );
	if( status == CRYPT_ENVELOPE_RESOURCE )
		{
		/* If the caller wasn't expecting encrypted data, let them know */
		if( iPrivKey == CRYPT_UNUSED )
			status = CRYPT_ERROR_WRONGKEY;
		else
			{
			status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
									  ( void * ) &iPrivKey,
									  CRYPT_ENVINFO_PRIVATEKEY );
			}
		}
	if( cryptStatusOK( status ) )
		{
		setMessageData( &msgData, NULL, 0 );
		status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_PUSHDATA,
								  &msgData, 0 );
		}
	if( cryptStatusOK( status ) )
		{
		setMessageData( &msgData, outData, outDataMaxLength );
		status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_POPDATA,
								  &msgData, 0 );
		if( cryptStatusOK( status ) )
			{
			ENSURES( msgData.length < inDataLength && \
					 msgData.length < outDataMaxLength );
			}
		}
	krnlSendNotifier( iCryptEnvelope, IMESSAGE_DECREFCOUNT );
	if( cryptStatusOK( status ) )
		*outDataLength = msgData.length;

	assert( !cryptArgError( status ) );
	return( cryptArgError( status ) ? CRYPT_ERROR_BADDATA : status );
	}

/****************************************************************************
*																			*
*							Data Sign/Verify Functions						*
*																			*
****************************************************************************/

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 5 ) ) \
int envelopeSign( IN_BUFFER( inDataLength ) const void *inData, 
				  IN_LENGTH_MIN( 16 ) const int inDataLength,
				  OUT_BUFFER( outDataMaxLength, \
							  *outDataLength ) void *outData, 
				  IN_LENGTH_MIN( 16 ) const int outDataMaxLength,
				  OUT_LENGTH_Z int *outDataLength, 
				  IN_ENUM_OPT( CRYPT_CONTENT ) \
					const CRYPT_CONTENT_TYPE contentType,
				  IN_HANDLE const CRYPT_CONTEXT iSigKey,

⌨️ 快捷键说明

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