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

📄 resource.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 5 页
字号:
			if( envelopeInfoPtr->preActionList != NULL )
				return( FALSE );
			}
		else
			if( actionListPtr != NULL )
				/* A standalone action can only be (session-key based) 
				   encryption except for de-enveloping a signed envelope,
				   where we can have standalone hash actions before we get 
				   to the signature data and add post-actions */
				if( !( ( actionListPtr->action == ACTION_CRYPT ) || \
					   ( ( envelopeInfoPtr->flags & ENVELOPE_ISDEENVELOPE ) && \
					     actionListPtr->action == ACTION_HASH ) ) )
					return( FALSE );

	/* Pre-actions can only be key exchange actions, and have to be sorted
	   by action group */
	if( envelopeInfoPtr->preActionList != NULL )
		{
		actionListPtr = envelopeInfoPtr->preActionList;

		while( actionListPtr != NULL && \
			   actionListPtr->action == ACTION_KEYEXCHANGE_PKC )
			actionListPtr = actionListPtr->next;
		while( actionListPtr != NULL && \
			   actionListPtr->action == ACTION_KEYEXCHANGE )
			actionListPtr = actionListPtr->next;

		return( ( actionListPtr == NULL ) ? TRUE : FALSE );
		}

	/* Post-actions can only be signature actions */
	if( envelopeInfoPtr->postActionList != NULL )
		{
		for( actionListPtr = envelopeInfoPtr->postActionList;
			 actionListPtr != NULL; actionListPtr = actionListPtr->next )
			if( actionListPtr->action != ACTION_SIGN )
				return( FALSE );

		return( TRUE );
		}

	/* A standalone action can be either a single crypt, one or more hashes,
	   or nothing */
	if( envelopeInfoPtr->actionList == NULL )
		return( TRUE );
	if( envelopeInfoPtr->actionList->action == ACTION_CRYPT )
		return( envelopeInfoPtr->actionList->next == NULL ? TRUE : FALSE );
	for( actionListPtr = envelopeInfoPtr->preActionList;
		 actionListPtr != NULL; actionListPtr = actionListPtr->next )
		if( actionListPtr->action != ACTION_HASH )
			return( FALSE );

	return( TRUE );
	}
#endif /* !NDEBUG */

/****************************************************************************
*																			*
*						Content List Management Functions					*
*																			*
****************************************************************************/

/* Create a content list item */

CONTENT_LIST *createContentListItem( MEMPOOL_STATE memPoolState, 
									 const CRYPT_FORMAT_TYPE formatType,
									 const void *object, const int objectSize,
									 const BOOLEAN isSigObject )
	{
	CONTENT_LIST *contentListItem;

	if( ( contentListItem = getMemPool( memPoolState,
										sizeof( CONTENT_LIST ) ) ) == NULL )
		return( NULL );
	memset( contentListItem, 0, sizeof( CONTENT_LIST ) );
	contentListItem->formatType = formatType;
	contentListItem->object = ( void * ) object;
	contentListItem->objectSize = objectSize;
	if( isSigObject )
		{
		contentListItem->flags = CONTENTLIST_ISSIGOBJ;
		contentListItem->clSigInfo.iSigCheckKey = CRYPT_ERROR;
		contentListItem->clSigInfo.iExtraData = CRYPT_ERROR;
		}

	return( contentListItem );
	}

/* Add an item to the content list */

void appendContentListItem( ENVELOPE_INFO *envelopeInfoPtr,
							const CONTENT_LIST *contentListItem )
	{
	CONTENT_LIST *contentListPtr = envelopeInfoPtr->contentList;

	if( envelopeInfoPtr->contentList == NULL )
		{
		envelopeInfoPtr->contentList = ( CONTENT_LIST * ) contentListItem;
		return;
		}

	/* Find the end of the list and add the new item */
	while( contentListPtr->next != NULL )
		contentListPtr = contentListPtr->next;
	contentListPtr->next = ( CONTENT_LIST * ) contentListItem;
	}

/* Delete a content list */

void deleteContentList( MEMPOOL_STATE memPoolState,
						CONTENT_LIST *contentListPtr )
	{
	while( contentListPtr != NULL )
		{
		CONTENT_LIST *contentListItem = contentListPtr;

		/* Destroy any attached objects if necessary */
		if( contentListItem->flags & CONTENTLIST_ISSIGOBJ )
			{
			CONTENT_SIG_INFO *sigInfo = &contentListItem->clSigInfo;

			if( sigInfo->iSigCheckKey != CRYPT_ERROR )
				krnlSendNotifier( sigInfo->iSigCheckKey, IMESSAGE_DECREFCOUNT );
			if( sigInfo->iExtraData != CRYPT_ERROR )
				krnlSendNotifier( sigInfo->iExtraData, IMESSAGE_DECREFCOUNT );
			}

		/* Erase and free the object buffer if necessary */
		contentListPtr = contentListPtr->next;
		if( contentListItem->object != NULL )
			{
			zeroise( contentListItem->object, contentListItem->objectSize );
			clFree( "deleteContentList", contentListItem->object );
			}
		zeroise( contentListItem, sizeof( CONTENT_LIST ) );
		freeMemPool( memPoolState, contentListItem );
		}
	}

/****************************************************************************
*																			*
*						Misc.Enveloping Info Management Functions			*
*																			*
****************************************************************************/

/* Set up the encryption for an envelope */

int initEnvelopeEncryption( ENVELOPE_INFO *envelopeInfoPtr,
							const CRYPT_CONTEXT cryptContext,
							const CRYPT_ALGO_TYPE algorithm, 
							const CRYPT_MODE_TYPE mode,
							const BYTE *iv, const int ivLength,
							const BOOLEAN copyContext )
	{
	CRYPT_CONTEXT iCryptContext = cryptContext;
	CRYPT_ALGO_TYPE cryptAlgo;
	CRYPT_MODE_TYPE cryptMode;
	RESOURCE_DATA msgData;
	int blockSize, status;

	/* Extract the information we need to process data */
	status = krnlSendMessage( cryptContext, IMESSAGE_GETATTRIBUTE, 
							  &cryptAlgo, CRYPT_CTXINFO_ALGO );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( cryptContext, IMESSAGE_GETATTRIBUTE, 
								  &cryptMode, CRYPT_CTXINFO_MODE );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( cryptContext, IMESSAGE_GETATTRIBUTE, 
								  &blockSize, CRYPT_CTXINFO_BLOCKSIZE );
	if( cryptStatusError( status ) )
		return( status );

	/* Make sure that the context is what's required */
	if( algorithm != CRYPT_UNUSED && \
		( cryptAlgo != algorithm || cryptMode != mode ) )
		/* This can only happen on deenveloping if the data is corrupted or 
		   if the user is asked for a KEK and tries to supply a session key 
		   instead */
		return( CRYPT_ERROR_WRONGKEY );

	/* If it's a user-supplied context, take a copy for our own use.  This is
	   only done for non-idempotent user-supplied contexts, for everything 
	   else we either use cryptlib's object management to handle things for 
	   us or the context is a internal one created specifically for our own 
	   use */
	if( copyContext )
		{
		MESSAGE_CREATEOBJECT_INFO createInfo;

		setMessageCreateObjectInfo( &createInfo, cryptAlgo );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, 
								  IMESSAGE_DEV_CREATEOBJECT, &createInfo, 
								  OBJECT_TYPE_CONTEXT );
		if( cryptStatusError( status ) )
			return( status );
		status = krnlSendMessage( iCryptContext, IMESSAGE_CLONE, NULL, 
								  createInfo.cryptHandle );
		if( cryptStatusError( status ) )
			{
			krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
			return( status );
			}
		iCryptContext = createInfo.cryptHandle;
		}

	/* Load the IV into the context and set up the encryption information for
	   the envelope */
	if( !isStreamCipher( cryptAlgo ) )
		{
		if( iv != NULL )
			{
			int ivSize;

			status = krnlSendMessage( cryptContext, IMESSAGE_GETATTRIBUTE, 
									  &ivSize, CRYPT_CTXINFO_IVSIZE );
			setMessageData( &msgData, ( void * ) iv, min( ivLength, ivSize ) );
			if( cryptStatusOK( status ) )
				status = krnlSendMessage( iCryptContext, IMESSAGE_SETATTRIBUTE_S,
										  &msgData, CRYPT_CTXINFO_IV );
			}
		else
			/* There's no IV specified, generate a new one */
			status = krnlSendNotifier( iCryptContext, IMESSAGE_CTX_GENIV );
		if( cryptStatusError( status ) )
			{
			if( copyContext )
				/* Destroy the copy we created earlier */
				krnlSendNotifier( iCryptContext, IMESSAGE_DECREFCOUNT );
			return( status );
			}
		}
	envelopeInfoPtr->iCryptContext = iCryptContext;
	envelopeInfoPtr->blockSize = blockSize;
	envelopeInfoPtr->blockSizeMask = ~( blockSize - 1 );

	return( CRYPT_OK );
	}

/* Add keyset information */

static int addKeyset( ENVELOPE_INFO *envelopeInfoPtr,
					  const CRYPT_ATTRIBUTE_TYPE keysetFunction,
					  const CRYPT_KEYSET keyset )
	{
	CRYPT_KEYSET *iKeysetPtr;

	/* Figure out which keyset we want to set */
	switch( keysetFunction )
		{
		case CRYPT_ENVINFO_KEYSET_ENCRYPT:
			iKeysetPtr = &envelopeInfoPtr->iEncryptionKeyset;
			break;

		case CRYPT_ENVINFO_KEYSET_DECRYPT:
			iKeysetPtr = &envelopeInfoPtr->iDecryptionKeyset;
			break;

		case CRYPT_ENVINFO_KEYSET_SIGCHECK:
			iKeysetPtr = &envelopeInfoPtr->iSigCheckKeyset;
			break;

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

	/* Make sure that the keyset hasn't already been set */
	if( *iKeysetPtr != CRYPT_ERROR )
		return( CRYPT_ERROR_INITED );

	/* Remember the new keyset and increment its reference count */
	*iKeysetPtr = keyset;
	return( krnlSendNotifier( keyset, IMESSAGE_INCREFCOUNT ) );
	}

/****************************************************************************
*																			*
*					Deenveloping Information Management Functions			*
*																			*
****************************************************************************/

/* Process CMS unauthenticated attributes.  We can't handle these as 
   standard CMS attributes since the only thing we're likely to see here is 
   a countersignature, which isn't an attribute in the normal sense */

static int processUnauthAttributes( CONTENT_LIST *contentListPtr,
									const void *unauthAttr, 
									const int unauthAttrLength )
	{
	STREAM stream;
	int status;

	UNUSED( contentListPtr );

	/* Make sure that the unauthenticated attributes are OK.  Normally this 
	   is done when we import the attributes, but since we can't import 
	   them we have to perform the check explicitly here */
	status = checkObjectEncoding( unauthAttr, unauthAttrLength );
	if( cryptStatusError( status ) )
		return( status );

	/* Process each attribute */
	sMemConnect( &stream, unauthAttr, unauthAttrLength );
	status = readConstructed( &stream, NULL, 1 );
	while( cryptStatusOK( status ) && \
		   sMemDataLeft( &stream ) > MIN_CRYPT_OBJECTSIZE )
		{
		BYTE oid[ MAX_OID_SIZE ];
		int oidLength;

		/* See what we've got */
		readSequence( &stream, NULL );
		status = readRawObject( &stream, oid, &oidLength, MAX_OID_SIZE, 
								BER_OBJECT_IDENTIFIER );
		if( cryptStatusOK( status ) )
			status = readSet( &stream, NULL );
		if( cryptStatusError( status ) )
			break;
		if( oidLength != sizeofOID( OID_TSP_TSTOKEN ) || \
			memcmp( oid, OID_TSP_TSTOKEN, oidLength ) )
			{
			/* It's not a timestamp, skip it and continue */
			readUniversal( &stream );
			continue;
			}

		/* We've got a timestamp.  We can't really do much with this at the 
		   moment since although it quacks like a countersignature, in the 
		   PKIX tradition it's subtly (and gratuitously) incompatible in 
		   various ways, so it can't be verified as a standard 
		   countersignature.  Amusingly, the RFC actually states that this 
		   is a stupid way to do things.  Specifically, instead of using the 
		   normal MUST/SHOULD it first states that the sensible solution to 
		   the problem is to use a countersignature, and then goes on to 
		   describe something that isn't a countersignature.  Since this 
		   isn't the sensible solution, it's obviously the stupid one.  QED */
#if 1
		readUniversal( &stream );
#else	/* Alternatively, if we're being asked to return the timestamp data,
		   we could proceed as follows */
		{
		MESSAGE_CREATEOBJECT_INFO createInfo;
		RESOURCE_DATA msgData;
		int dataSize, bufSize;

		/* Find out how much data we've got */
		dataSize = getStreamObjectLength( &stream );
		if( cryptStatusError( dataSize ) )
			return( dataSize );
		if( dataSize > sMemDataLeft( &stream ) )
			return( CRYPT_ERROR_OVERFLOW );
		bufSize = max( dataSize + 128, MIN_BUFFER_SIZE );

⌨️ 快捷键说明

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