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

📄 resource.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 4 页
字号:

		envelopeInfoPtr->flags |= ENVELOPE_NOSIGNINGCERTS;
		return( CRYPT_OK );
		}

	/* If it's keyset information, just keep a record of it for later use */
	if( envInfo == CRYPT_ENVINFO_KEYSET_SIGCHECK || \
		envInfo == CRYPT_ENVINFO_KEYSET_ENCRYPT || \
		envInfo == CRYPT_ENVINFO_KEYSET_DECRYPT )
		return( addKeyset( envelopeInfoPtr, envInfo, cryptHandle ) );

	/* If it's extra data for the signature, record it with the signature
	   action */
	if( envInfo == CRYPT_ENVINFO_SIGNATURE_EXTRADATA )
		{
		/* Find the last signature action which was added and make sure 
		   it doesn't already have extra data attached to it */
		actionListPtr = envelopeInfoPtr->postActionList;
		if( actionListPtr == NULL )
			return( CRYPT_ERROR_NOTINITED );
		while( actionListPtr->next != NULL && \
			   actionListPtr->next->action == ACTION_SIGN )
			actionListPtr = actionListPtr->next;
		if( actionListPtr->iExtraData != CRYPT_ERROR )
			return( CRYPT_ERROR_INITED );

		/* Increment its reference count and add it to the action */
		status = krnlSendNotifier( cryptHandle, 
								   RESOURCE_IMESSAGE_INCREFCOUNT );
		if( cryptStatusOK( status ) )
			actionListPtr->iExtraData = cryptHandle;
		return( status );
		}
	if( envInfo == CRYPT_ENVINFO_TIMESTAMP_AUTHORITY )
		{
		MESSAGE_CREATEOBJECT_INFO createInfo;
		RESOURCE_DATA msgData;

		/* Find the last signature action which was added and make sure 
		   it doesn't already have a TSP session object attached to it */
		actionListPtr = envelopeInfoPtr->postActionList;
		if( actionListPtr == NULL )
			return( CRYPT_ERROR_NOTINITED );
		while( actionListPtr->next != NULL && \
			   actionListPtr->next->action == ACTION_SIGN )
			actionListPtr = actionListPtr->next;
		if( actionListPtr->iTspSession != CRYPT_ERROR )
			return( CRYPT_ERROR_INITED );

		/* Create the TSP session object necessary for timestamping the
		   enveloped data */
		setMessageCreateObjectInfo( &createInfo, CRYPT_SESSION_TSP );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, 
								  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
								  &createInfo, OBJECT_TYPE_SESSION );
		if( cryptStatusError( status ) )
			return( status );
		setResourceData( &msgData, ( void * ) value, valueLength );
		status = krnlSendMessage( createInfo.cryptHandle, 
								  RESOURCE_IMESSAGE_SETATTRIBUTE_S,
								  &msgData, CRYPT_SESSINFO_SERVER_NAME );
		if( cryptStatusError( status ) )
			{
			krnlSendNotifier( createInfo.cryptHandle, 
							  RESOURCE_IMESSAGE_DECREFCOUNT );
			return( status );
			}
		actionListPtr->iTspSession = createInfo.cryptHandle;

		return( CRYPT_OK );
		}

	/* If it's originator information, record it for the enveloped data 
	   header */
	if( envInfo == CRYPT_ENVINFO_ORIGINATOR )
		{
		/* If there's a session key present, make sure it's consistent with
		   the originator info */
		if( envelopeInfoPtr->iCryptContext != CRYPT_ERROR )
			{
			status = checkFortezzaUsage( cryptHandle, envelopeInfoPtr, 
										 CRYPT_ENVINFO_ORIGINATOR );
			if( cryptStatusError( status ) )
				return( status );
			}

		/* Increment its reference count and add it to the action */
		status = krnlSendNotifier( cryptHandle, 
								   RESOURCE_IMESSAGE_INCREFCOUNT );
		if( cryptStatusError( status ) )
			return( status );
		envelopeInfoPtr->iOriginatorChain = cryptHandle;

		/* Since we're using Fortezza key management, we have to use Skipjack 
		   as the data encryption algorithm */
		envelopeInfoPtr->defaultAlgo = CRYPT_ALGO_SKIPJACK;

		return( CRYPT_OK );
		}

#ifndef NO_COMPRESSION
	/* If it's compression information, set up the compression structures */
	if( envInfo == CRYPT_ENVINFO_COMPRESSION )
		{
		assert( !envelopeInfoPtr->zStreamInited );

		/* Initialize the compression */
		if( deflateInit( &envelopeInfoPtr->zStream, \
						 Z_DEFAULT_COMPRESSION ) != Z_OK )
			return( CRYPT_ERROR_MEMORY );
		envelopeInfoPtr->zStreamInited = TRUE;

		return( CRYPT_OK );
		}
#endif /* NO_COMPRESSION */

	/* If it's a password, derive a session key encryption context from it */
	if( envInfo == CRYPT_ENVINFO_PASSWORD )
		{
		MESSAGE_CREATEOBJECT_INFO createInfo;
		CRYPT_ALGO cryptAlgo = envelopeInfoPtr->defaultAlgo;

		/* PGP doesn't support both PKC and conventional key exchange 
		   actions or multiple conventional key exchange actions in the same 
		   envelope since the session key is encrypted for the PKC action 
		   but derived from the password for the conventional action */
		if( envelopeInfoPtr->type == CRYPT_FORMAT_PGP && \
			( findAction( envelopeInfoPtr->preActionList,
						  ACTION_KEYEXCHANGE_PKC ) != NULL ) || \
			  envelopeInfoPtr->actionList != NULL )
			  return( CRYPT_ERROR_INITED );

		/* Create the appropriate encryption context.  We have to be careful 
		   to ensure we use an algorithm which is compatible with the 
		   wrapping mechanism.  We don't have to perform this check if the
		   format type is PGP since PGP wrapping always uses CFB mode (so
		   there are no modes which need to be avoided) and the higher-level
		   code has constrained the algorithm type to something which is 
		   encodable using the PGP data format */
		if( envelopeInfoPtr->type != CRYPT_FORMAT_PGP && \
			( isStreamCipher( cryptAlgo ) || \
			  cryptStatusError( sizeofAlgoIDex( cryptAlgo,
									( CRYPT_ALGO ) CRYPT_MODE_CBC, 0 ) ) ) )
			cryptAlgo = CRYPT_ALGO_3DES;
		setMessageCreateObjectInfo( &createInfo, cryptAlgo );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, 
								  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
								  &createInfo, OBJECT_TYPE_CONTEXT );
		if( cryptStatusError( status ) )
			return( status );

		/* Derive the key into the context and add it to the action list */
#ifndef NO_PGP
		if( envelopeInfoPtr->type == CRYPT_FORMAT_PGP )
			{
			BYTE salt[ PGP_SALTSIZE ];
			static const CRYPT_MODE mode = CRYPT_MODE_CFB;

			/* PGP uses CFB mode for everything so we change the mode from 
			   the default of CBC to CFB */
			krnlSendMessage( createInfo.cryptHandle, 
							 RESOURCE_IMESSAGE_SETATTRIBUTE, 
							 ( void * ) &mode, CRYPT_CTXINFO_MODE );

			/* Generate a salt, derive the key into the context, and insert 
			   it into the action list.  Since PGP doesn't perform a key 
			   exchange of a session key, we insert the password-derived 
			   context directly into the main action list */
			getNonce( salt, PGP_SALTSIZE );
			status = pgpPasswordToKey( createInfo.cryptHandle, value, 
									   valueLength, envelopeInfoPtr->defaultHash,
									   salt, PGP_ITERATIONS );
			if( cryptStatusOK( status ) && \
				addAction( &envelopeInfoPtr->actionList, ACTION_CRYPT, 
						   createInfo.cryptHandle ) == NULL )
				status = CRYPT_ERROR_MEMORY;
			}
		else
#endif /* NO_PGP */
			{
			RESOURCE_DATA msgData;

			setResourceData( &msgData, ( void * ) value, valueLength );
			status = krnlSendMessage( createInfo.cryptHandle, 
								RESOURCE_IMESSAGE_SETATTRIBUTE_S, &msgData,
								CRYPT_CTXINFO_KEYING_VALUE );
			if( cryptStatusOK( status ) )
				/* Make sure this key exchange action isn't already present 
				   and insert it into the list */
				if( checkAction( envelopeInfoPtr->preActionList, 
								 ACTION_KEYEXCHANGE, 
								 createInfo.cryptHandle ) == ACTION_RESULT_INITED )
					status = CRYPT_ERROR_INITED;
				else
					if( addAction( &envelopeInfoPtr->preActionList, 
								   ACTION_KEYEXCHANGE, 
								   createInfo.cryptHandle ) == NULL )
						status = CRYPT_ERROR_MEMORY;
			}
		if( cryptStatusError( status ) )
			krnlSendNotifier( createInfo.cryptHandle, 
							  RESOURCE_IMESSAGE_DECREFCOUNT );
		return( status );
		}

	/* It's a generic "add a context" action, check that everything is valid.  
	   This is necessary because the PGP format doesn't support the full 
	   range of enveloping capabilities */
	if( envelopeInfoPtr->type == CRYPT_FORMAT_PGP )
		{
		/* PGP doesn't support both PKC and conventional key exchange 
		   actions in the same envelope since the session key is encrypted
		   for the PKC action but derived from the password for the 
		   conventional action */
		if( findAction( envelopeInfoPtr->preActionList,
						ACTION_KEYEXCHANGE ) != NULL )
			return( CRYPT_ERROR_INITED );

		/* PGP handles multiple signers by nesting signed data rather than
		   attaching multiple signatures, so we can only apply a single
		   signature per envelope */
		if( envInfo == CRYPT_ENVINFO_SIGNATURE && \
			envelopeInfoPtr->postActionList != NULL )
			return( CRYPT_ERROR_INITED );

		/* PGP doesn't allow multiple hash algorithms to be used when signing
		   data (a follow-on from the way nested sigs are handled) */
		if( envInfo == CRYPT_ENVINFO_HASH && \
			envelopeInfoPtr->actionList != NULL )
			return( CRYPT_ERROR_INITED );
		}
	switch( envInfo )
		{
		case CRYPT_ENVINFO_PUBLICKEY:
		case CRYPT_ENVINFO_PRIVATEKEY:
			actionListHeadPtrPtr = &envelopeInfoPtr->preActionList;
			actionType = ACTION_KEYEXCHANGE_PKC;
			break;

		case CRYPT_ENVINFO_KEY:
			if( envelopeInfoPtr->actionList != NULL )
				/* We can't add more than one general encryption action */
				return( CRYPT_ERROR_INITED );
			actionListHeadPtrPtr = &envelopeInfoPtr->actionList;
			actionType = ACTION_CRYPT;
			break;

		case CRYPT_ENVINFO_SESSIONKEY:
			/* We can't add more than one session key */
			if( envelopeInfoPtr->actionList != NULL )
				return( CRYPT_ERROR_INITED );
			actionListHeadPtrPtr = &envelopeInfoPtr->actionList;
			actionType = ACTION_CRYPT;

			/* If there's originator info present, make sure it's consistent 
			   with the new session key */
			if( envelopeInfoPtr->iOriginatorChain != CRYPT_ERROR )
				{
				status = checkFortezzaUsage( cryptHandle, envelopeInfoPtr, 
											 CRYPT_ENVINFO_SESSIONKEY );
				if( cryptStatusError( status ) )
					return( status );
				}
			break;

		case CRYPT_ENVINFO_HASH:
			actionListHeadPtrPtr = &envelopeInfoPtr->actionList;
			actionType = ACTION_HASH;
			break;

		case CRYPT_ENVINFO_SIGNATURE:
			actionListHeadPtrPtr = &envelopeInfoPtr->postActionList;
			actionType = ACTION_SIGN;
			break;

		default:
			assert( NOTREACHED );
			return( CRYPT_ARGERROR_NUM1 );
		}

	/* Find the insertion point for this action and make sure it isn't
	   already present.  The difference between an inited and present return
	   code is that an inited response indicates that the user explicitly 
	   added the action and can't add it again while a present response
	   indicates that the action was added automatically by cryptlib in
	   response to the user adding some other action and shouldn't be 
	   reported as an error, to the user it doesn't make any difference
	   whether the same action was added automatically by cryptlib or
	   explicitly */
	actionResult = checkAction( *actionListHeadPtrPtr, actionType, cryptHandle );
	if( actionResult == ACTION_RESULT_INITED )
		return( CRYPT_ERROR_INITED );
	if( actionResult == ACTION_RESULT_PRESENT )
		return( CRYPT_OK );

	/* Insert the action into the list.  If it's a non-PKC context (ie one 
	   whose state can change based on user action), we clone it for our own 
	   use, otherwise we just increment its reference count */
	if( actionType == ACTION_HASH || actionType == ACTION_CRYPT )
		{
		CRYPT_CONTEXT iNewContext;

		status = krnlSendMessage( cryptHandle, RESOURCE_IMESSAGE_CLONE,
								  &iNewContext, 0 );
		if( cryptStatusError( status ) )
			return( status );
		cryptHandle = iNewContext;
		}
	else
		status = krnlSendNotifier( cryptHandle, RESOURCE_IMESSAGE_INCREFCOUNT );
	actionListPtr = addAction( actionListHeadPtrPtr, actionType, cryptHandle );
	if( actionListPtr == NULL )
		{
		krnlSendNotifier( cryptHandle, RESOURCE_IMESSAGE_DECREFCOUNT );
		return( CRYPT_ERROR_MEMORY );
		}
	if( actionType == ACTION_HASH )
		/* Remember that we need to hook the hash action up to a signature
		   action before we start enveloping data */
		actionListPtr->needsController = TRUE;

	/* If the newly-inserted action isn't a controlling action, we're done */
	if( actionType != ACTION_SIGN )
		return( status );

	/* If there's no subject hash action available, create one so we can 
	   connect it to the signature action */
	if( envelopeInfoPtr->actionList == NULL )
		{
		MESSAGE_CREATEOBJECT_INFO createInfo;

		/* Create a default hash action */
		setMessageCreateObjectInfo( &createInfo, envelopeInfoPtr->defaultHash );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, 
								  RESOURCE_IMESSAGE_DEV_CREATEOBJECT,
								  &createInfo, OBJECT_TYPE_CONTEXT );
		if( cryptStatusError( status ) )
			return( status );

		/* Add the hash action to the list */
		hashActionPtr = addAction( &envelopeInfoPtr->actionList, ACTION_HASH, 
								   createInfo.cryptHandle );
		if( hashActionPtr == NULL )
			{
			krnlSendNotifier( createInfo.cryptHandle, 
							  RESOURCE_IMESSAGE_DECREFCOUNT );
			return( CRYPT_ERROR_MEMORY );
			}

		/* Remember that the action was added invisibly to the caller so we
		   don't return an error if they add it as well */
		hashActionPtr->addedAutomatically = TRUE;
		}
	else
		/* Find the last hash action which was added */
		hashActionPtr = findLastAction( envelopeInfoPtr->actionList, 
										ACTION_HASH );

	/* Connect the signature action to the last hash action which was added 
	   and remember that this action now has a controlling action */
	actionListPtr->associatedAction = hashActionPtr;
	hashActionPtr->needsController = FALSE;

	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*							Envelope Access Routines						*
*																			*
****************************************************************************/

void initResourceHandling( ENVELOPE_INFO *envelopeInfoPtr )
	{
	/* Set the access method pointers */
	envelopeInfoPtr->addInfo = \
				( envelopeInfoPtr->flags & ENVELOPE_ISDEENVELOPE ) ? \
				addDeenvelopeInfo : addEnvelopeInfo;
	}

⌨️ 快捷键说明

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