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

📄 cms_envpre.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
	return( CRYPT_OK );
	}

/****************************************************************************
*																			*
*						Signed Content Pre-processing						*
*																			*
****************************************************************************/

/* Process signing certificates and match the content-type in the 
   authenticated attributes with the signed content type if it's anything 
   other than 'data' (the data content-type is added automatically) */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int processSigningCerts( INOUT ENVELOPE_INFO *envelopeInfoPtr,
							    INOUT ACTION_LIST *actionListPtr )
	{
	int value, status;

	assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
	assert( isWritePtr( actionListPtr, sizeof( ACTION_LIST ) ) );

	/* If we're including signing certificates and there are multiple 
	   signing certificates present add the currently-selected one to the 
	   overall certificate collection */
	if( !( envelopeInfoPtr->flags & ENVELOPE_NOSIGNINGCERTS ) && \
		envelopeInfoPtr->iExtraCertChain != CRYPT_ERROR )
		{
		status = krnlSendMessage( envelopeInfoPtr->iExtraCertChain,
								  IMESSAGE_SETATTRIBUTE,
								  &actionListPtr->iCryptHandle,
								  CRYPT_IATTRIBUTE_CERTCOLLECTION );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* If there's no content-type present and the signed content type isn't 
	   'data' or it's an S/MIME envelope, create signing attributes to hold 
	   the content-type and smimeCapabilities */
	if( actionListPtr->iExtraData == CRYPT_ERROR && \
		( envelopeInfoPtr->contentType != CRYPT_CONTENT_DATA || \
		  envelopeInfoPtr->type == CRYPT_FORMAT_SMIME ) )
		{
		MESSAGE_CREATEOBJECT_INFO createInfo;

		setMessageCreateObjectInfo( &createInfo,
									CRYPT_CERTTYPE_CMS_ATTRIBUTES );
		status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
								  IMESSAGE_DEV_CREATEOBJECT,
								  &createInfo, OBJECT_TYPE_CERTIFICATE );
		if( cryptStatusError( status ) )
			return( status );
		actionListPtr->iExtraData = createInfo.cryptHandle;
		}

	/* If there are no signed attributes, we're done */
	if( actionListPtr->iExtraData == CRYPT_ERROR )
		return( CRYPT_OK );

	/* Make sure that the content-type in the attributes matches the actual 
	   content type by deleting any existing content-type if necessary and 
	   adding our one (quietly fixing things is easier than trying to report 
	   this error back to the caller) */
	if( krnlSendMessage( actionListPtr->iExtraData, IMESSAGE_GETATTRIBUTE, 
						 &value, CRYPT_CERTINFO_CMS_CONTENTTYPE ) != CRYPT_ERROR_NOTFOUND )
		{
		/* We ignore the return status from the deletion since the status 
		   from the add that follows will be more meaningful to the caller */
		( void ) krnlSendMessage( actionListPtr->iExtraData, 
								  IMESSAGE_DELETEATTRIBUTE, NULL, 
								  CRYPT_CERTINFO_CMS_CONTENTTYPE );
		}
	return( krnlSendMessage( actionListPtr->iExtraData, 
							 IMESSAGE_SETATTRIBUTE, 
							 &envelopeInfoPtr->contentType, 
							 CRYPT_CERTINFO_CMS_CONTENTTYPE ) );
	}

/* Pre-process information for signed enveloping */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int processSignatureAction( INOUT ENVELOPE_INFO *envelopeInfoPtr,
								   INOUT ACTION_LIST *actionListPtr )
	{
	CRYPT_ALGO_TYPE cryptAlgo = DUMMY_INIT;
	int signatureSize, signingAttributes, status;

	assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );
	assert( isWritePtr( actionListPtr, sizeof( ACTION_LIST ) ) );

	REQUIRES( actionListPtr->action == ACTION_SIGN && \
			  actionListPtr->associatedAction != NULL );

	/* Process signing certificates and fix up the content-type in the 
	   authenticated attributes if necessary */
	if( envelopeInfoPtr->type == CRYPT_FORMAT_CMS || \
		envelopeInfoPtr->type == CRYPT_FORMAT_SMIME )
		{
		status = processSigningCerts( envelopeInfoPtr, actionListPtr );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Determine the type of signing attributes to use.  If none are
	   specified (which can only happen if the signed content is data),
	   either get the signing code to add the default ones for us or use
	   none at all if the use of default attributes is disabled */
	signingAttributes = actionListPtr->iExtraData;
	if( signingAttributes == CRYPT_ERROR )
		{
		/* If it's a raw signature there are no signing attributes */
		if( envelopeInfoPtr->type == CRYPT_FORMAT_CRYPTLIB )
			signingAttributes = CRYPT_UNUSED;
		else
			{
			int useDefaultAttributes;

			/* It's a CMS/SMIME signature, use whatever the default is */
			status = krnlSendMessage( envelopeInfoPtr->ownerHandle, 
									  IMESSAGE_GETATTRIBUTE,
									  &useDefaultAttributes,
									  CRYPT_OPTION_CMS_DEFAULTATTRIBUTES );
			if( cryptStatusError( status ) )
				return( status );
			signingAttributes = useDefaultAttributes ? \
								CRYPT_USE_DEFAULT : CRYPT_UNUSED;
			}
		}

	/* Evaluate the size of the exported action */
	status = iCryptCreateSignature( NULL, 0, &signatureSize, 
						envelopeInfoPtr->type, actionListPtr->iCryptHandle,
						actionListPtr->associatedAction->iCryptHandle,
						signingAttributes,
						( actionListPtr->iTspSession != CRYPT_ERROR ) ? \
							actionListPtr->iTspSession : CRYPT_UNUSED );
	if( cryptStatusOK( status ) )
		{
		status = krnlSendMessage( actionListPtr->iCryptHandle,
								  IMESSAGE_GETATTRIBUTE, &cryptAlgo,
								  CRYPT_CTXINFO_ALGO );
		}
	if( cryptStatusError( status ) )
		return( status );
	if( isDlpAlgo( cryptAlgo ) || actionListPtr->iTspSession != CRYPT_ERROR )
		{
		/* If there are any signature actions that will result in indefinite-
		   length encodings present we can't use a definite-length encoding
		   for the signature */
		envelopeInfoPtr->dataFlags |= ENVDATA_HASINDEFTRAILER;
		actionListPtr->encodedSize = CRYPT_UNUSED;
		}
	else
		{
		actionListPtr->encodedSize = signatureSize;
		envelopeInfoPtr->signActionSize += signatureSize;
		}
	if( envelopeInfoPtr->dataFlags & ENVDATA_HASINDEFTRAILER )
		envelopeInfoPtr->signActionSize = CRYPT_UNUSED;
	ENSURES( ( envelopeInfoPtr->signActionSize == CRYPT_UNUSED ) || \
			 ( envelopeInfoPtr->signActionSize > 0 && \
			   envelopeInfoPtr->signActionSize < MAX_INTLENGTH ) );

	return( CRYPT_OK );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int cmsPreEnvelopeSign( INOUT ENVELOPE_INFO *envelopeInfoPtr )
	{
	ACTION_LIST *actionListPtr = envelopeInfoPtr->postActionList;
	int iterationCount, status;

	assert( isWritePtr( envelopeInfoPtr, sizeof( ENVELOPE_INFO ) ) );

	REQUIRES( envelopeInfoPtr->usage == ACTION_SIGN );

	/* Make sure that there's at least one signing action present */
	if( actionListPtr == NULL )
		return( CRYPT_ERROR_NOTINITED );

	assert( isWritePtr( actionListPtr, sizeof( ACTION_LIST ) ) );

	REQUIRES( actionListPtr->associatedAction != NULL );

	/* If we're generating a detached signature the content is supplied
	   externally and has zero size */
	if( envelopeInfoPtr->flags & ENVELOPE_DETACHED_SIG )
		envelopeInfoPtr->payloadSize = 0;

	/* If it's an attributes-only message it must be zero-length CMS signed
	   data with signing attributes present */
	if( envelopeInfoPtr->flags & ENVELOPE_ATTRONLY )
		{
		if( envelopeInfoPtr->type != CRYPT_FORMAT_CMS || \
			actionListPtr->iExtraData == CRYPT_ERROR )
			{
			setErrorInfo( envelopeInfoPtr, CRYPT_ENVINFO_SIGNATURE_EXTRADATA,
						  CRYPT_ERRTYPE_ATTR_ABSENT );
			return( CRYPT_ERROR_NOTINITED );
			}
		if( envelopeInfoPtr->payloadSize > 0 )
			{
			setErrorInfo( envelopeInfoPtr, CRYPT_ENVINFO_DATASIZE,
						  CRYPT_ERRTYPE_ATTR_VALUE );
			return( CRYPT_ERROR_INITED );
			}
		}

	/* If it's a CMS envelope we have to write the signing certificate chain
	   alongside the signatures as extra data unless it's explicitly 
	   excluded so we record how large the info will be for later */
	if( ( envelopeInfoPtr->type == CRYPT_FORMAT_CMS || \
		  envelopeInfoPtr->type == CRYPT_FORMAT_SMIME ) && \
		!( envelopeInfoPtr->flags & ENVELOPE_NOSIGNINGCERTS ) )
		{
		if( actionListPtr->next != NULL )
			{
			MESSAGE_CREATEOBJECT_INFO createInfo;

			/* There are multiple sets of signing certificates present, 
			   create a signing-certificate meta-object to hold the overall 
			   set of certificates */
			setMessageCreateObjectInfo( &createInfo,
										CRYPT_CERTTYPE_CERTCHAIN );
			status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
									  IMESSAGE_DEV_CREATEOBJECT,
									  &createInfo, OBJECT_TYPE_CERTIFICATE );
			if( cryptStatusError( status ) )
				return( status );
			envelopeInfoPtr->iExtraCertChain = createInfo.cryptHandle;
			}
		else
			{
			MESSAGE_DATA msgData;

			/* There's a single signing certificate present, determine its 
			   size */
			setMessageData( &msgData, NULL, 0 );
			status = krnlSendMessage( actionListPtr->iCryptHandle,
									  IMESSAGE_CRT_EXPORT, &msgData,
									  CRYPT_ICERTFORMAT_CERTSET );
			if( cryptStatusError( status ) )
				return( status );
			envelopeInfoPtr->extraDataSize = msgData.length;
			}
		}

	/* Evaluate the size of each signature action */
	for( actionListPtr = envelopeInfoPtr->postActionList, iterationCount = 0; 
		 actionListPtr != NULL && iterationCount < FAILSAFE_ITERATIONS_MED;
		 actionListPtr = actionListPtr->next, iterationCount++ )
		{
		status = processSignatureAction( envelopeInfoPtr, actionListPtr );
		if( cryptStatusError( status ) )
			return( status );
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
	if( envelopeInfoPtr->iExtraCertChain != CRYPT_ERROR )
		{
		MESSAGE_DATA msgData;

		/* We're writing the signing certificate chain and there are 
		   multiple signing certificates present, get the size of the 
		   overall certificate collection */
		setMessageData( &msgData, NULL, 0 );
		status = krnlSendMessage( envelopeInfoPtr->iExtraCertChain,
								  IMESSAGE_CRT_EXPORT, &msgData,
								  CRYPT_ICERTFORMAT_CERTSET );
		if( cryptStatusError( status ) )
			return( status );
		envelopeInfoPtr->extraDataSize = msgData.length;
		}
	ENSURES( envelopeInfoPtr->extraDataSize >= 0 && \
			 envelopeInfoPtr->extraDataSize < MAX_INTLENGTH );

	/* Hashing is now active (you have no chance to survive make your 
	   time) */
	envelopeInfoPtr->dataFlags |= ENVDATA_HASHACTIONSACTIVE;

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

⌨️ 快捷键说明

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