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

📄 lib_sign.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 4 页
字号:
		krnlSendMessage( createInfo.cryptHandle, RESOURCE_IMESSAGE_CTX_HASH, 
						 ( ( BYTE * ) queryInfo.attributeStart ) + 1, 
						 queryInfo.attributeLength - 1 );
		krnlSendMessage( createInfo.cryptHandle, RESOURCE_IMESSAGE_CTX_HASH, 
						 "", 0 );
		iCmsHashContext = createInfo.cryptHandle;
		}

	/* Check the signature */
	status = checkSignature( signature, signatureLength, sigCheckContext, 
							 iCmsHashContext, SIGNATURE_CMS );
	if( queryInfo.attributeStart == NULL )
		/* No signed attributes, we're done */
		return( status );
	krnlSendNotifier( iCmsHashContext, RESOURCE_IMESSAGE_DECREFCOUNT );
	if( cryptStatusError( status ) )
		return( status );

	/* Import the attributes and make sure the data hash value given in the
	   signed attributes matches the user-supplied hash */
	setMessageCreateObjectIndirectInfo( &createInfo, 
					queryInfo.attributeStart, queryInfo.attributeLength );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, 
							  RESOURCE_IMESSAGE_DEV_CREATEOBJECT_INDIRECT,
							  &createInfo, OBJECT_TYPE_CERTIFICATE );
	if( cryptStatusError( status ) )
		return( status );
	setResourceData( &msgData, hashValue, CRYPT_MAX_HASHSIZE );
	status = krnlSendMessage( createInfo.cryptHandle, 
							  RESOURCE_IMESSAGE_GETATTRIBUTE_S, &msgData, 
							  CRYPT_CERTINFO_CMS_MESSAGEDIGEST );
	if( cryptStatusOK( status ) )
		{
		status = krnlSendMessage( iHashContext, RESOURCE_IMESSAGE_COMPARE,
								  &msgData, RESOURCE_MESSAGE_COMPARE_HASH );
		if( cryptStatusError( status ) )
			status = CRYPT_ERROR_SIGNATURE;
		}
	if( cryptStatusError( status ) )
		{
		krnlSendNotifier( createInfo.cryptHandle, 
						  RESOURCE_IMESSAGE_DECREFCOUNT );
		return( status );
		}

	/* If the user wants to look at the attributes, make them externally
	   visible, otherwise delete them */
	if( iExtraData != NULL )
		*iExtraData = createInfo.cryptHandle;
	else
		krnlSendNotifier( createInfo.cryptHandle, 
						  RESOURCE_IMESSAGE_DECREFCOUNT );

	return( status );
	}

/* Create/check an extended signature type, either a cryptlib signature or a
   CMS-style signature */

C_RET cryptCreateSignatureEx( C_OUT void C_PTR signature, 
							  C_OUT int C_PTR signatureLength,
							  C_IN CRYPT_FORMAT_TYPE formatType,
							  C_IN CRYPT_CONTEXT signContext,
							  C_IN CRYPT_CONTEXT hashContext,
							  C_IN CRYPT_HANDLE extraData )
	{
	int status;

	/* Perform basic error checking */
	if( signature != NULL )
		{
		if( checkBadPtrWrite( signature, MIN_CRYPT_OBJECTSIZE ) )
			return( CRYPT_ERROR_PARAM1 );
		memset( signature, 0, MIN_CRYPT_OBJECTSIZE );
		}
	if( checkBadPtrWrite( signatureLength, sizeof( int ) ) )
		return( CRYPT_ERROR_PARAM2 );
	*signatureLength = 0;
	if( formatType <= CRYPT_FORMAT_NONE || formatType >= CRYPT_FORMAT_LAST )
		return( CRYPT_ERROR_PARAM3 );
	if( formatType == CRYPT_FORMAT_PGP )
		return( CRYPT_ERROR_NOTAVAIL );	/* Not supported yet */
	status = krnlSendMessage( signContext, RESOURCE_MESSAGE_CHECK, NULL,
							  RESOURCE_MESSAGE_CHECK_PKC_SIGN );
	if( cryptStatusError( status ) )
		return( ( status == CRYPT_ARGERROR_OBJECT ) ? \
				CRYPT_ERROR_PARAM4 : status );
	if( formatType == CRYPT_FORMAT_CMS || \
		formatType == CRYPT_FORMAT_SMIME )
		{
		int certType;

		/* Make sure the signing context has a cert attached to it */
		status = krnlSendMessage( signContext, RESOURCE_MESSAGE_GETATTRIBUTE,
								  &certType, CRYPT_CERTINFO_CERTTYPE );
		if( cryptStatusError( status ) ||
			( certType != CRYPT_CERTTYPE_CERTIFICATE && \
			  certType != CRYPT_CERTTYPE_CERTCHAIN ) )
			return( CRYPT_ERROR_PARAM4 );

		/* Make sure the extra data object is in order */
		if( extraData != CRYPT_USE_DEFAULT )
			{
			status = krnlSendMessage( extraData, RESOURCE_MESSAGE_GETATTRIBUTE,
									  &certType, CRYPT_CERTINFO_CERTTYPE );
			if( cryptStatusError( status ) || \
				certType != CRYPT_CERTTYPE_CMS_ATTRIBUTES )
				return( CRYPT_ERROR_PARAM6 );
			}
		}
	status = krnlSendMessage( hashContext, RESOURCE_MESSAGE_CHECK, NULL,
							  RESOURCE_MESSAGE_CHECK_HASH );
	if( cryptStatusError( status ) )
		return( ( status == CRYPT_ARGERROR_OBJECT ) ? \
				CRYPT_ERROR_PARAM5 : status );
	if( formatType == CRYPT_FORMAT_CRYPTLIB && extraData != CRYPT_USE_DEFAULT )
		return( CRYPT_ERROR_PARAM6 );

	/* Call the low-level signature create function to create the signature */
	if( formatType == CRYPT_FORMAT_CRYPTLIB )
		return( createSignature( signature, signatureLength, signContext,
								 hashContext, SIGNATURE_CRYPTLIB ) );
	status = createSignatureCMS( signature, signatureLength,
								 signContext, hashContext, extraData,
								 CRYPT_UNUSED );
	if( cryptArgError( status ) )
		/* If we get an argument error from the mechanism-level code, map the
		   mechanism parameter number to the function argument number */
		status = ( status == CRYPT_ARGERROR_NUM1 ) ? \
				 CRYPT_ERROR_PARAM5 : CRYPT_ERROR_PARAM4;
	return( status );
	}

static CRYPT_FORMAT_TYPE getFormatType( const void *data )
	{
	CRYPT_FORMAT_TYPE formatType = CRYPT_FORMAT_NONE;
	STREAM stream;
	int status;

	/* Figure out what we've got.  A cryptlib signature begins:
		cryptlibSignature ::= SEQUENCE {
			version		INTEGER (3),
			keyID [ 0 ]	OCTET STRING
	   while a CMS signature begins:
		cmsSignature ::= SEQUENCE {
			version		INTEGER (1),
			digestAlgo	SET OF {
	   which allows us to determine which type of object we have */
	sMemConnect( &stream, data, 16 );
	status = readSequence( &stream, NULL );
	if( !cryptStatusError( status ) )
		{
		long version;

		if( !cryptStatusError( readShortInteger( &stream, &version ) ) )
			formatType = ( version == 1 ) ? CRYPT_FORMAT_CMS : \
						 ( version == 3 ) ? CRYPT_FORMAT_CRYPTLIB : \
						 CRYPT_FORMAT_NONE;
		}
	sMemDisconnect( &stream );

	/* If we couldn't find anything recognisable as ASN.1, see if it's a
	   PGP signature */
	if( formatType == CRYPT_FORMAT_NONE )
		{
		int value;

		/* If it looks like the start of a PGP MPI for a DSA or RSA 
		   signature, treat it as a PGP-format sig */
		sMemConnect( &stream, data, 16 );
		value = ( sgetc( &stream ) << 8 ) | sgetc( &stream );
		if( ( value >= 120 && value <= 160 ) || \
			( value >= 504 && value <= 4096 ) )
			formatType = CRYPT_FORMAT_PGP;
		sMemDisconnect( &stream );
		}

	return( formatType );
	}

C_RET cryptCheckSignatureEx( C_IN void C_PTR signature,
							 C_IN CRYPT_HANDLE sigCheckKey,
							 C_IN CRYPT_CONTEXT hashContext,
							 C_OUT CRYPT_HANDLE C_PTR extraData )
	{
	CRYPT_FORMAT_TYPE formatType;
	CRYPT_CONTEXT sigCheckContext;
	int signatureLength, status;

	/* Perform basic error checking */
	if( signature != NULL && checkBadPtrRead( signature, MIN_CRYPT_OBJECTSIZE ) )
		return( CRYPT_ERROR_PARAM1 );
	if( ( formatType = getFormatType( signature ) ) == CRYPT_FORMAT_NONE || \
		( formatType == CRYPT_FORMAT_PGP ) )
		return( CRYPT_ERROR_BADDATA );
	status = krnlSendMessage( sigCheckKey, RESOURCE_MESSAGE_GETDEPENDENT,
							  &sigCheckContext, OBJECT_TYPE_CONTEXT );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( sigCheckContext, RESOURCE_IMESSAGE_CHECK, 
								  NULL, RESOURCE_MESSAGE_CHECK_PKC_SIGCHECK );
	if( cryptStatusOK( status ) )
		{
		status = krnlSendMessage( hashContext, RESOURCE_MESSAGE_CHECK, NULL,
								  RESOURCE_MESSAGE_CHECK_HASH );
		if( status == CRYPT_ARGERROR_OBJECT )
			status = CRYPT_ERROR_PARAM3;
		}
	else
		if( status == CRYPT_ARGERROR_OBJECT )
			status = CRYPT_ERROR_PARAM2;
	if( cryptStatusError( status ) )
		return( status );
	if( formatType == CRYPT_FORMAT_CMS )
		{
		int certType;

		/* Make sure the sig check key includes a cert */
		status = krnlSendMessage( sigCheckKey, RESOURCE_MESSAGE_GETATTRIBUTE,
								  &certType, CRYPT_CERTINFO_CERTTYPE );
		if( cryptStatusError( status ) ||
			( certType != CRYPT_CERTTYPE_CERTIFICATE && \
			  certType != CRYPT_CERTTYPE_CERTCHAIN ) )
			return( CRYPT_ERROR_PARAM2 );
		}

	/* Try and determine the length of the signature data.  This should be 
	   specified as a user parameter, unfortunately the early cryptlib API 
	   didn't take length parameters when it wasn't absolutely necessary so
	   we have to take a guess at a safe size limit and hope that the data
	   isn't all done with an indefinite encoding */
	signatureLength = getObjectLength( signature, 512 );
	if( cryptStatusError( signatureLength ) )
		return( CRYPT_ERROR_PARAM1 );

	/* Call the low-level signature check function to check the signature */
	if( formatType == CRYPT_FORMAT_CRYPTLIB )
		{
		if( extraData != NULL )
			return( CRYPT_ERROR_PARAM4 );
		return( checkSignature( signature, signatureLength, sigCheckContext, 
								hashContext, SIGNATURE_CRYPTLIB ) );
		}
	if( extraData != NULL )
		{
		if( checkBadPtrWrite( extraData, sizeof( int ) ) )
			return( CRYPT_ERROR_PARAM5 );
		*extraData = CRYPT_ERROR;
		}
	status = checkSignatureCMS( signature, signatureLength, sigCheckContext, 
								hashContext, extraData, sigCheckKey );
	if( cryptStatusOK( status ) && extraData != NULL )
		/* Make the recovered signing attributes externally visible */
		krnlSendMessage( *extraData, RESOURCE_IMESSAGE_SETATTRIBUTE,
						 MESSAGE_VALUE_FALSE, CRYPT_IATTRIBUTE_INTERNAL );

	if( cryptArgError( status ) )
		/* If we get an argument error from the mechanism-level code, map the
		   mechanism parameter number to the function argument number */
		status = ( status == CRYPT_ARGERROR_NUM1 ) ? \
				 CRYPT_ERROR_PARAM3 : CRYPT_ERROR_PARAM2;
	return( status );
	}

/* Internal versions of the above.  These skip a lot of the checking done by
   the external versions since they're only called by cryptlib internal
   functions which have already checked the parameters for validity.  In
   addition the iExtraData value can take two out-of-band values,
   CRYPT_USE_DEFAULT (generate the default signing attributes for the caller)
   or CRYPT_UNUSED (don't use any signing attributes, valid only when signing
   raw data) */

int iCryptCreateSignatureEx( void *signature, int *signatureLength,
							 const CRYPT_FORMAT_TYPE formatType,
							 const CRYPT_CONTEXT iSignContext,
							 const CRYPT_CONTEXT iHashContext,
							 const CRYPT_HANDLE iExtraData,
							 const CRYPT_SESSION iTspSession )
	{
	/* Clear return value */
	*signatureLength = 0;

	/* Call the low-level signature create function to create the signature */
	if( formatType == CRYPT_FORMAT_CRYPTLIB )
		return( createSignature( signature, signatureLength, iSignContext,
								 iHashContext, SIGNATURE_CRYPTLIB ) );
	if( formatType == CRYPT_FORMAT_PGP )
		return( createSignature( signature, signatureLength, iSignContext,
								 iHashContext, SIGNATURE_PGP ) );
	return( createSignatureCMS( signature, signatureLength,
								iSignContext, iHashContext, iExtraData,
								iTspSession ) );
	}

int iCryptCheckSignatureEx( const void *signature, const int signatureLength,
							const CRYPT_HANDLE iSigCheckKey,
							const CRYPT_CONTEXT iHashContext,
							CRYPT_HANDLE *extraData )
	{
	CRYPT_FORMAT_TYPE formatType;
	CRYPT_CONTEXT sigCheckContext;
	int status;

	/* Perform basic error checking */
	if( ( formatType = getFormatType( signature ) ) == CRYPT_FORMAT_NONE )
		return( CRYPT_ERROR_BADDATA );
	status = krnlSendMessage( iSigCheckKey, RESOURCE_IMESSAGE_GETDEPENDENT,
							  &sigCheckContext, OBJECT_TYPE_CONTEXT );
	if( cryptStatusError( status ) )
		return( status );

	/* Call the low-level signature check function to check the signature */
	if( formatType == CRYPT_FORMAT_CRYPTLIB )
		return( checkSignature( signature, signatureLength, sigCheckContext, 
								iHashContext, SIGNATURE_CRYPTLIB ) );
	if( formatType == CRYPT_FORMAT_PGP )
		return( checkSignature( signature, signatureLength, sigCheckContext, 
								iHashContext, SIGNATURE_PGP ) );
	if( extraData != NULL )
		*extraData = CRYPT_ERROR;
	return( checkSignatureCMS( signature, signatureLength, sigCheckContext, 
							   iHashContext, extraData, iSigCheckKey ) );
	}

⌨️ 快捷键说明

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