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

📄 cryptmis.c

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

void *getMemPool( void *statePtr, const int size )
	{
	MEMPOOL_INFO *state = ( MEMPOOL_INFO * ) statePtr;
	BYTE *allocPtr = state->storage;
	const int allocSize = roundUp( size, sizeof( int ) );

	assert( isWritePtr( state, sizeof( MEMPOOL_INFO ) ) );
	assert( isWritePtr( state->storage, state->storageSize ) );

	/* If we can't satisfy the request from the memory pool, we have to 
	   allocate it dynamically */
	if( state->storageSize - state->storagePos < allocSize )
		return( clDynAlloc( "getMemPool", size ) );
	
	/* We can satisfy the request from the pool */
	allocPtr += state->storagePos;
	state->storagePos += size;
	return( allocPtr );
	}

void freeMemPool( void *statePtr, void *memblock )
	{
	MEMPOOL_INFO *state = ( MEMPOOL_INFO * ) statePtr;

	assert( isWritePtr( state, sizeof( MEMPOOL_INFO ) ) );
	assert( isWritePtr( state->storage, state->storageSize ) );

	/* If the memory block is within the pool, there's nothing to do */
	if( memblock >= state->storage && \
		memblock <= ( void * ) ( ( BYTE * ) state->storage + \
											state->storageSize ) )
		return;

	/* It's outside the pool and therefore dynamically allocated, free it */
	clFree( "freeMemPool", memblock );
	}

/* Export attribute or certificate data to a stream.  In theory we would
   have to export this via a dynbuf and then write it to the stream, however
   we can save some overhead by writing it directly to the stream's buffer */

int exportAttributeToStream( void *streamPtr, const CRYPT_HANDLE cryptHandle,
							 const CRYPT_ATTRIBUTE_TYPE attributeType )
	{
	RESOURCE_DATA msgData;
	STREAM *stream = streamPtr;
	int status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( sStatusOK( stream ) );
	assert( checkHandleRange( cryptHandle ) );
	assert( isAttribute( attributeType ) || \
			isInternalAttribute( attributeType ) );

	/* Before we try the export, make sure that everything is OK with the
	   stream */
	if( !sStatusOK( stream ) )
		return( sGetStatus( stream ) );
	if( sMemDataLeft( stream ) < 2 )
		return( CRYPT_ERROR_UNDERFLOW );

	/* Export the attribute to the stream */
	setMessageData( &msgData, sMemBufPtr( stream ), sMemDataLeft( stream ) );
	status = krnlSendMessage( cryptHandle, IMESSAGE_GETATTRIBUTE_S,
							  &msgData, attributeType );
	if( cryptStatusOK( status ) )
		status = sSkip( stream, msgData.length );
	return( status );
	}

int exportCertToStream( void *streamPtr,
						const CRYPT_CERTIFICATE cryptCertificate,
						const CRYPT_CERTTYPE_TYPE certType )
	{
	RESOURCE_DATA msgData;
	STREAM *stream = streamPtr;
	int status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( sStatusOK( stream ) );
	assert( checkHandleRange( cryptCertificate ) );
	assert( certType > CRYPT_CERTTYPE_NONE && \
			certType < CRYPT_CERTTYPE_LAST );

	/* Before we try the export, make sure that everything is OK with the
	   stream */
	if( !sStatusOK( stream ) )
		return( sGetStatus( stream ) );
	if( sMemDataLeft( stream ) < MIN_CRYPT_OBJECTSIZE )
		return( CRYPT_ERROR_UNDERFLOW );

	/* Export the cert to the stream */
	setMessageData( &msgData, sMemBufPtr( stream ), sMemDataLeft( stream ) );
	status = krnlSendMessage( cryptCertificate, IMESSAGE_CRT_EXPORT,
							  &msgData, certType );
	if( cryptStatusOK( status ) )
		status = sSkip( stream, msgData.length );
	return( status );
	}

/****************************************************************************
*																			*
*							Enveloping Functions							*
*																			*
****************************************************************************/

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

int envelopeWrap( const void *inData, const int inDataLength, void *outData,
				  int *outDataLength, const int outDataMaxLength,
				  const CRYPT_FORMAT_TYPE formatType,
				  const CRYPT_CONTENT_TYPE contentType,
				  const CRYPT_HANDLE iCryptKey )
	{
	CRYPT_ENVELOPE iCryptEnvelope;
	MESSAGE_CREATEOBJECT_INFO createInfo;
	RESOURCE_DATA msgData;
	const int minBufferSize = max( MIN_BUFFER_SIZE, inDataLength + 512 );
	int status;

	assert( isReadPtr( inData, inDataLength ) );
	assert( inDataLength > 16 );
	assert( isWritePtr( outData, outDataMaxLength ) );
	assert( outDataMaxLength > 16 );
	assert( isWritePtr( outDataLength, sizeof( int ) ) );
	assert( contentType == CRYPT_UNUSED || \
			( contentType > CRYPT_CONTENT_NONE && \
			  contentType < CRYPT_CONTENT_LAST ) );
	assert( ( iCryptKey == CRYPT_UNUSED ) || \
			checkHandleRange( iCryptKey ) );

	*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 ) )
		return( status );
	iCryptEnvelope = createInfo.cryptHandle;
	krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
					 ( void * ) &minBufferSize, CRYPT_ATTRIBUTE_BUFFERSIZE );
	status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
							  ( void * ) &inDataLength,
							  CRYPT_ENVINFO_DATASIZE );
	if( cryptStatusOK( status ) && contentType != CRYPT_UNUSED )
		status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
								  ( void * ) &contentType,
								  CRYPT_ENVINFO_CONTENTTYPE );
	if( cryptStatusOK( status ) && iCryptKey != CRYPT_UNUSED )
		status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
								  ( void * ) &iCryptKey,
								  CRYPT_ENVINFO_PUBLICKEY );
	if( cryptStatusOK( status ) )
		{
		setMessageData( &msgData, ( void * ) inData, inDataLength );
		status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_PUSHDATA,
								  &msgData, 0 );
		}
	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 );
		}
	krnlSendNotifier( iCryptEnvelope, IMESSAGE_DECREFCOUNT );
	if( cryptStatusOK( status ) )
		*outDataLength = msgData.length;
	return( status );
	}

int envelopeUnwrap( const void *inData, const int inDataLength,
					void *outData, int *outDataLength,
					const int outDataMaxLength,
					const CRYPT_CONTEXT iDecryptKey )
	{
	CRYPT_ENVELOPE iCryptEnvelope;
	MESSAGE_CREATEOBJECT_INFO createInfo;
	RESOURCE_DATA msgData;
	const int minBufferSize = max( MIN_BUFFER_SIZE, inDataLength );
	int status;

	assert( isReadPtr( inData, inDataLength ) );
	assert( inDataLength > 16 );
	assert( isWritePtr( outData, outDataMaxLength ) );
	assert( outDataMaxLength > 16 );
	assert( isWritePtr( outDataLength, sizeof( int ) ) );
	assert( ( iDecryptKey == CRYPT_UNUSED ) || \
			checkHandleRange( iDecryptKey ) );

	*outDataLength = 0;

	/* Create an envelope to unwrap the data, add the decryption key if
	   necessary, and pop the unwrapped result */
	setMessageCreateObjectInfo( &createInfo, CRYPT_FORMAT_AUTO );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
							  IMESSAGE_DEV_CREATEOBJECT, &createInfo,
							  OBJECT_TYPE_ENVELOPE );
	if( cryptStatusError( status ) )
		return( status );
	iCryptEnvelope = createInfo.cryptHandle;
	krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
					 ( void * ) &minBufferSize, CRYPT_ATTRIBUTE_BUFFERSIZE );
	setMessageData( &msgData, ( void * ) inData, inDataLength );
	status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_PUSHDATA,
							  &msgData, 0 );
	if( status == CRYPT_ENVELOPE_RESOURCE )
		{
		/* If the caller wasn't expecting encrypted data, let them know */
		if( iDecryptKey == CRYPT_UNUSED )
			status = CRYPT_ERROR_WRONGKEY;
		else
			status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
									  ( void * ) &iDecryptKey,
									  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 );
		}

	krnlSendNotifier( iCryptEnvelope, IMESSAGE_DECREFCOUNT );
	if( cryptStatusOK( status ) )
		*outDataLength = msgData.length;
	return( status );
	}

int envelopeSign( const void *inData, const int inDataLength,
				  void *outData, int *outDataLength,
				  const int outDataMaxLength,
				  const CRYPT_CONTENT_TYPE contentType,
				  const CRYPT_CONTEXT iSigKey,
				  const CRYPT_CERTIFICATE iCmsAttributes )
	{
	CRYPT_ENVELOPE iCryptEnvelope;
	MESSAGE_CREATEOBJECT_INFO createInfo;
	RESOURCE_DATA msgData;
	const int minBufferSize = max( MIN_BUFFER_SIZE, inDataLength + 1024 );
	int status;

	assert( isReadPtr( inData, inDataLength ) );
	assert( inDataLength > 16 || \
			( contentType == CRYPT_CONTENT_NONE && \
			  checkHandleRange( iCmsAttributes ) && \
			  inDataLength == 0 ) );
	assert( isWritePtr( outData, outDataMaxLength ) );
	assert( outDataMaxLength > 16 );
	assert( isWritePtr( outDataLength, sizeof( int ) ) );
	assert( contentType >= CRYPT_CONTENT_NONE && \
			contentType < CRYPT_CONTENT_LAST );
	assert( checkHandleRange( iSigKey ) );
	assert( iCmsAttributes == CRYPT_UNUSED || \
			checkHandleRange( iCmsAttributes ) );

	*outDataLength = 0;

	/* Create an envelope to sign the data, add the signature key and
	   optional signing attributes, and pop the signed result */
	setMessageCreateObjectInfo( &createInfo, CRYPT_FORMAT_CMS );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
							  IMESSAGE_DEV_CREATEOBJECT, &createInfo,
							  OBJECT_TYPE_ENVELOPE );
	if( cryptStatusError( status ) )
		return( status );
	iCryptEnvelope = createInfo.cryptHandle;
	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 ) )
		status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
								  ( void * ) &iSigKey,
								  CRYPT_ENVINFO_SIGNATURE );
	if( cryptStatusOK( status ) && iCmsAttributes != CRYPT_UNUSED )
		status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
								  ( void * ) &iCmsAttributes,
								  CRYPT_ENVINFO_SIGNATURE_EXTRADATA );
	if( cryptStatusOK( status ) )
		{
		/* If there's no data supplied, it's an attributes-only message
		   containing only authenticated attributes */
		if( inDataLength <= 0 )
			status = krnlSendMessage( iCryptEnvelope, IMESSAGE_SETATTRIBUTE,
									  MESSAGE_VALUE_TRUE,
									  CRYPT_IATTRIBUTE_ATTRONLY );
		else
			{
			setMessageData( &msgData, ( void * ) inData, inDataLength );
			status = krnlSendMessage( iCryptEnvelope, IMESSAGE_ENV_PUSHDATA,
									  &msgData, 0 );
			}
		}
	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 );
		}
	krnlSendNotifier( iCryptEnvelope, IMESSAGE_DECREFCOUNT );
	if( cryptStatusOK( status ) )
		*outDataLength = msgData.length;
	return( status );
	}

int envelopeSigCheck( const void *inData, const int inDataLength,
					  void *outData, int *outDataLength,
					  const int outDataMaxLength,
					  const CRYPT_CONTEXT iSigCheckKey,
					  int *sigResult, CRYPT_CERTIFICATE *iSigningCert,
					  CRYPT_CERTIFICATE *iCmsAttributes )
	{
	CRYPT_ENVELOPE iCryptEnvelope;
	MESSAGE_CREATEOBJECT_INFO createInfo;
	RESOURCE_DATA msgData;
	const int minBufferSize = max( MIN_BUFFER_SIZE, inDataLength );
	int status;

	assert( isReadPtr( inData, inDataLength ) );
	assert( inDataLength > 16 );
	assert( isWritePtr( outData, outDataMaxLength ) );
	assert( outDataMaxLength > 16 );
	assert( isWritePtr( outDataLength, sizeof( int ) ) );
	assert( iSigCheckKey == CRYPT_UNUSED || \
			checkHandleRange( iSigCheckKey ) );
	assert( isWritePtr( sigResult, sizeof( int ) ) );

	/* Clear return values */
	*outDataLength = 0;
	*sigResult = CRYPT_ERROR;
	if( iSigningCert != NULL )
		*iSigningCert = CRYPT_ERROR;
	if( iCmsAttributes != NULL )
		*iCmsAttributes = CRYPT_ERROR;

	/* Create an envelope to sig.check the data, push in the signed data and
	   sig.check key, and pop the result.  We also speculatively set the
	   attributes-only flag to let the enveloping code know that a signed
	   message with no content is a zero-data-length message rather than a
	   detached signature, which is what this type of message would normally
	   be */

⌨️ 快捷键说明

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