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

📄 cryptenv.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 5 页
字号:
					return( CRYPT_ARGERROR_VALUE );
				if( envelopeInfoPtr->usage != ACTION_NONE && \
					envelopeInfoPtr->usage != ACTION_SIGN )
					return( exitErrorInited( envelopeInfoPtr, 
											 CRYPT_ENVINFO_SIGNATURE_EXTRADATA ) );
				break;

			case CRYPT_ENVINFO_ORIGINATOR:
				checkType = MESSAGE_CHECK_PKC_KA_EXPORT;
				if( envelopeInfoPtr->usage != ACTION_NONE && \
					envelopeInfoPtr->usage != ACTION_CRYPT )
					return( exitErrorInited( envelopeInfoPtr, 
											 CRYPT_ENVINFO_ORIGINATOR ) );
				usage = ACTION_CRYPT;
				if( envelopeInfoPtr->iExtraCertChain != CRYPT_ERROR )
					return( exitErrorInited( envelopeInfoPtr, 
											 CRYPT_ENVINFO_ORIGINATOR ) );
				break;

			case CRYPT_ENVINFO_KEYSET_ENCRYPT:
				checkType = MESSAGE_CHECK_PKC_ENCRYPT_AVAIL;
				if( envelopeInfoPtr->iEncryptionKeyset != CRYPT_ERROR )
					return( exitErrorInited( envelopeInfoPtr, 
											 CRYPT_ENVINFO_KEYSET_ENCRYPT ) );
				break;

			case CRYPT_ENVINFO_KEYSET_DECRYPT:
				checkType = MESSAGE_CHECK_PKC_DECRYPT_AVAIL;
				if( envelopeInfoPtr->iDecryptionKeyset != CRYPT_ERROR )
					return( exitErrorInited( envelopeInfoPtr, 
											 CRYPT_ENVINFO_KEYSET_DECRYPT ) );
				break;

			case CRYPT_ENVINFO_KEYSET_SIGCHECK:
				checkType = MESSAGE_CHECK_PKC_SIGCHECK_AVAIL;
				if( envelopeInfoPtr->iSigCheckKeyset != CRYPT_ERROR )
					return( exitErrorInited( envelopeInfoPtr, 
											 CRYPT_ENVINFO_KEYSET_SIGCHECK ) );
				break;

			default:
				assert( NOTREACHED );
			}
		}
	if( checkType != MESSAGE_CHECK_NONE )
		{
		/* Check the object as appropriate.  A key agreement key can also act
		   as a public key because of the way KEA works, so if a check for a
		   straight public key fails we try again to see if it's a key
		   agreement key with import capabilities */
		status = krnlSendMessage( value, IMESSAGE_CHECK, NULL, checkType );
		if( status == CRYPT_ARGERROR_OBJECT && \
			messageValue == CRYPT_ENVINFO_PUBLICKEY )
			status = krnlSendMessage( value, IMESSAGE_CHECK, NULL,
									  MESSAGE_CHECK_PKC_KA_IMPORT );
		if( cryptStatusError( status ) )
			return( CRYPT_ARGERROR_NUM1 );

		/* Make sure that the object corresponds to a representable algorithm
		   type.  Note that this check isn't totally foolproof on de-
		   enveloping PGP data since the user can push the hash context 
		   before they push the signed data (to signifiy the use of a 
		   detached signature) so that it's checked using the default 
		   (CMS) algorithm values rather then PGP ones */
		if( checkType == MESSAGE_CHECK_CRYPT || \
			checkType == MESSAGE_CHECK_HASH || \
			checkType == MESSAGE_CHECK_MAC )
			{
			CRYPT_ALGO_TYPE algorithm;

			krnlSendMessage( value, IMESSAGE_GETATTRIBUTE, &algorithm,
							 CRYPT_CTXINFO_ALGO );
			if( checkType == MESSAGE_CHECK_CRYPT )
				{
				CRYPT_MODE_TYPE mode;

				krnlSendMessage( value, IMESSAGE_GETATTRIBUTE, &mode,
								 CRYPT_CTXINFO_MODE );
				status = envelopeInfoPtr->checkCryptAlgo( algorithm, mode );
				}
			else
				status = envelopeInfoPtr->checkHashAlgo( algorithm );
			if( cryptStatusError( status ) )
				return( CRYPT_ERROR_NOTAVAIL );
			}

		/* If we're using CMS enveloping, the object must have an initialised 
		   cert of the correct type associated with it.  Most of this will be 
		   caught by the kernel, but there are a couple of special cases (eg 
		   attribute cert where the main object is a PKC context) which are 
		   missed by the general kernel checks */
		if( ( messageValue == CRYPT_ENVINFO_SIGNATURE || \
			  messageValue == CRYPT_ENVINFO_PUBLICKEY || \
			  messageValue == CRYPT_ENVINFO_PRIVATEKEY || \
			  messageValue == CRYPT_ENVINFO_ORIGINATOR ) && 
			( envelopeInfoPtr->type == CRYPT_FORMAT_CMS || \
			  envelopeInfoPtr->type == CRYPT_FORMAT_SMIME ) )
			{
			int inited, certType;

			status = krnlSendMessage( value, IMESSAGE_GETATTRIBUTE, &inited, 
									  CRYPT_CERTINFO_IMMUTABLE );
			if( cryptStatusError( status ) || !inited )
				return( CRYPT_ARGERROR_NUM1 );
			status = krnlSendMessage( value, IMESSAGE_GETATTRIBUTE,
									  &certType, CRYPT_CERTINFO_CERTTYPE );
			if( cryptStatusError( status ) ||
				( certType != CRYPT_CERTTYPE_CERTIFICATE && \
				  certType != CRYPT_CERTTYPE_CERTCHAIN ) )
				return( CRYPT_ARGERROR_NUM1 );
			}
		}

	/* Add it to the envelope */
	status = envelopeInfoPtr->addInfo( envelopeInfoPtr, messageValue,
									   &value, 0 );
	if( cryptStatusError( status ) )
		{
		if( status == CRYPT_ERROR_INITED )
			return( exitErrorInited( envelopeInfoPtr, messageValue ) );
		return( status );
		}
	if( usage != ACTION_NONE )
		/* The action was successfully added, update the usage if 
		   necessary */
		envelopeInfoPtr->usage = usage;
	return( CRYPT_OK );
	}

static int processSetAttributeS( ENVELOPE_INFO *envelopeInfoPtr,
								 void *messageDataPtr, const int messageValue )
	{
	RESOURCE_DATA *msgData = ( RESOURCE_DATA * ) messageDataPtr;
	ACTION_TYPE usage = ACTION_NONE;
	int status;

	/* Handle the various information types */
	switch( messageValue )
		{
		case CRYPT_ENVINFO_PASSWORD:
			/* Set the envelope usage type based on the fact that we've been
			   fed a password */
			if( envelopeInfoPtr->usage == ACTION_NONE )
				usage = ACTION_CRYPT;
			else		
				if( envelopeInfoPtr->usage != ACTION_CRYPT && \
					envelopeInfoPtr->usage != ACTION_MAC )
					return( exitErrorInited( envelopeInfoPtr, 
											 CRYPT_ENVINFO_PASSWORD ) );

			/* In general we can't add new enveloping information once we've
			   started processing data */
			if( envelopeInfoPtr->state != STATE_PREDATA && \
				!( envelopeInfoPtr->flags & ENVELOPE_ISDEENVELOPE ) )
				/* We can't add new information once we've started enveloping */
				return( exitErrorInited( envelopeInfoPtr, 
										 CRYPT_ENVINFO_PASSWORD ) );

			/* Add it to the envelope */
			status = envelopeInfoPtr->addInfo( envelopeInfoPtr,
						CRYPT_ENVINFO_PASSWORD, msgData->data, msgData->length );
			break;

		case CRYPT_ENVINFO_RECIPIENT:
			{
			MESSAGE_KEYMGMT_INFO getkeyInfo;

			/* Set the envelope usage type based on the fact that we've been
			   fed a recipient email address */
			if( envelopeInfoPtr->usage != ACTION_NONE && \
				envelopeInfoPtr->usage != ACTION_CRYPT )
				return( CRYPT_ARGERROR_VALUE );
			usage = ACTION_CRYPT;

			/* Make sure that there's a keyset available to pull the 
			   recipient's key from */
			if( envelopeInfoPtr->iEncryptionKeyset == CRYPT_ERROR )
				return( exitErrorNotInited( envelopeInfoPtr, 
											CRYPT_ENVINFO_KEYSET_ENCRYPT ) );

			/* Try and read the recipient's key from the keyset.  Some 
			   keysets (particularly PKCS #11 devices, for which apps set 
			   the usage flags more or less at random) may not be able to 
			   differentiate between encryption and signature keys based on 
			   the information they have.  This isn't a problem when matching 
			   a key based on a unique ID, but with the use of the recipient 
			   name as the ID there could be multiple possible matches.  
			   Before we try and use the key we therefore perform an extra 
			   check here to make sure that it really is an encryption-
			   capable key */
			setMessageKeymgmtInfo( &getkeyInfo, CRYPT_KEYID_URI, 
								   msgData->data, msgData->length, NULL, 0, 
								   KEYMGMT_FLAG_USAGE_CRYPT );
			status = krnlSendMessage( envelopeInfoPtr->iEncryptionKeyset,
									  IMESSAGE_KEY_GETKEY, &getkeyInfo, 
									  KEYMGMT_ITEM_PUBLICKEY );
			if( cryptStatusOK( status ) && \
				cryptStatusError( \
					krnlSendMessage( getkeyInfo.cryptHandle, IMESSAGE_CHECK, 
									 NULL, MESSAGE_CHECK_PKC_ENCRYPT ) ) )
				{
				krnlSendNotifier( getkeyInfo.cryptHandle,
								  IMESSAGE_DECREFCOUNT );
				status = CRYPT_ERROR_NOTFOUND;
				}
			if( cryptStatusOK( status ) )
				{
				/* We got the key, add it to the envelope */
				status = envelopeInfoPtr->addInfo( envelopeInfoPtr,
												   CRYPT_ENVINFO_PUBLICKEY,
												   &getkeyInfo.cryptHandle, 0 );
				krnlSendNotifier( getkeyInfo.cryptHandle,
								  IMESSAGE_DECREFCOUNT );
				}
			break;
			}

		default:
			assert( NOTREACHED );
		}

	if( cryptStatusError( status ) )
		{
		if( status == CRYPT_ERROR_INITED )
			return( exitErrorInited( envelopeInfoPtr, messageValue ) );
		return( status );
		}
	if( usage != ACTION_NONE )
		/* The action was successfully added, update the usage if 
		   necessary */
		envelopeInfoPtr->usage = usage;
	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*							Envelope Data Handling Functions				*
*																			*
****************************************************************************/

/* Push data into an envelope */

static int envelopePush( ENVELOPE_INFO *envelopeInfoPtr, void *buffer,
						 const int length, int *bytesCopied )
	{
	int status;

	/* Clear return value */
	*bytesCopied = 0;

	/* If we haven't started processing data yet, handle the initial data
	   specially */
	if( envelopeInfoPtr->state == STATE_PREDATA )
		{
		CRYPT_ATTRIBUTE_TYPE missingInfo;

		/* Make sure that all the information we need to proceed is 
		   present */
		assert( envelopeInfoPtr->checkMissingInfo != NULL );
		missingInfo = envelopeInfoPtr->checkMissingInfo( envelopeInfoPtr );
		if( missingInfo != CRYPT_ATTRIBUTE_NONE )
			return( exitErrorNotInited( envelopeInfoPtr, missingInfo ) );

		/* If the envelope buffer hasn't been allocated yet, allocate it now */
		if( envelopeInfoPtr->buffer == NULL )
			{
			if( ( envelopeInfoPtr->buffer = \
							clAlloc( "envelopePush", \
									 envelopeInfoPtr->bufSize ) ) == NULL )
				return( CRYPT_ERROR_MEMORY );
			memset( envelopeInfoPtr->buffer, 0, envelopeInfoPtr->bufSize );
			}

		/* Emit the header information into the envelope */
		status = envelopeInfoPtr->processPreambleFunction( envelopeInfoPtr );
		if( cryptStatusError( status ) )
			{
			if( !isRecoverableError( status ) )
				envelopeInfoPtr->errorState = status;
			return( status );
			}

		/* The envelope is ready to process data, move it into the high
		   state */
		krnlSendMessage( envelopeInfoPtr->objectHandle, IMESSAGE_SETATTRIBUTE,
						 MESSAGE_VALUE_UNUSED, CRYPT_IATTRIBUTE_INITIALISED );
		envelopeInfoPtr->state = STATE_DATA;
		}

	/* If we're in the main data processing state, add the data and perform
	   any necessary actions on it */
	if( envelopeInfoPtr->state == STATE_DATA )
		{
		if( length )
			{
			/* Copy the data to the envelope */
			status = envelopeInfoPtr->copyToEnvelopeFunction( envelopeInfoPtr,
															  buffer, length );
			if( cryptStatusError( status ) )
				{
				if( !isRecoverableError( status ) )
					envelopeInfoPtr->errorState = status;
				return( status );
				}
			*bytesCopied = status;

			return( ( *bytesCopied < length ) ? \
					CRYPT_ERROR_OVERFLOW : CRYPT_OK );
			}

		/* This was a flush, move on to the postdata state */
		envelopeInfoPtr->state = STATE_POSTDATA;
		envelopeInfoPtr->envState = ENVSTATE_NONE;
		}

	assert( envelopeInfoPtr->state == STATE_POSTDATA );

	/* We're past the main data-processing state, emit the postamble */
	status = envelopeInfoPtr->processPostambleFunction( envelopeInfoPtr );
	if( cryptStatusError( status ) )
		{
		if( !isRecoverableError( status ) )
			envelopeInfoPtr->errorState = status;
		return( status );
		}
	envelopeInfoPtr->state = STATE_FINISHED;

	return( CRYPT_OK );
	}

static int deenvelopePush( ENVELOPE_INFO *envelopeInfoPtr, void *buffer,
						   const int length, int *bytesCopied )
	{
	BYTE *bufPtr = ( BYTE * ) buffer;
	int bytesIn = length, status = CRYPT_OK;

	/* Clear return value */
	*bytesCopied = 0;

	/* If we haven't started processing data yet, handle the initial data
	   specially */
	if( envelopeInfoPtr->state == STATE_PREDATA )
		{
		/* Perform any initialisation actions */

⌨️ 快捷键说明

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