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

📄 lib_keyx.c

📁 提供了很多种加密算法和CA认证及相关服务如CMP、OCSP等的开发
💻 C
📖 第 1 页 / 共 3 页
字号:
					  C_IN CRYPT_CONTEXT sessionKeyContext )
	{
	/* cryptImportKey() and cryptImportKeyEx() do the same thing */
	return( cryptImportKeyEx( encryptedKey, importKey, sessionKeyContext ) );
	}

/* Export an extended encrypted key, either a cryptlib key or a CMS key */

C_RET cryptExportKeyEx( C_OUT void C_PTR encryptedKey, 
						C_OUT int C_PTR encryptedKeyLength,
						C_IN CRYPT_FORMAT_TYPE formatType,
						C_IN CRYPT_HANDLE exportKey,
						C_IN CRYPT_CONTEXT sessionKeyContext )
	{
	CRYPT_ALGO cryptAlgo;
	CRYPT_MODE sessionKeyMode;
	const RECIPIENT_TYPE recipientType = \
			( formatType == CRYPT_FORMAT_CRYPTLIB ) ? RECIPIENT_CRYPTLIB : \
			( formatType == CRYPT_FORMAT_CMS || \
			  formatType == CRYPT_FORMAT_SMIME ) ? RECIPIENT_CMS : RECIPIENT_NONE;
	BYTE auxDataBuffer[ 1024 ], *auxData = auxDataBuffer;
	RESOURCE_MESSAGE_CHECK_TYPE checkType;
	int auxDataLength = 1024, status;

	/* Perform basic error checking */
	if( encryptedKey != NULL )
		{
		if( checkBadPtrWrite( encryptedKey, MIN_CRYPT_OBJECTSIZE ) )
			return( CRYPT_ERROR_PARAM1 );
		memset( encryptedKey, 0, MIN_CRYPT_OBJECTSIZE );
		}
	if( checkBadPtrWrite( encryptedKeyLength, sizeof( int ) ) )
		return( CRYPT_ERROR_PARAM2 );
	*encryptedKeyLength = 0;
	if( formatType != CRYPT_FORMAT_CRYPTLIB && \
		formatType != CRYPT_FORMAT_CMS && formatType != CRYPT_FORMAT_SMIME )
		return( CRYPT_ERROR_PARAM3 );

	/* Check the exporting key */
	status = krnlSendMessage( exportKey, RESOURCE_MESSAGE_GETATTRIBUTE, 
							  &cryptAlgo, CRYPT_CTXINFO_ALGO );
	if( cryptStatusError( status ) )
		return( ( status == CRYPT_ARGERROR_OBJECT ) ? \
				CRYPT_ERROR_PARAM3 : status );
	if( cryptAlgo >= CRYPT_ALGO_FIRST_PKC && cryptAlgo <= CRYPT_ALGO_LAST_PKC )
		checkType = ( cryptAlgo == CRYPT_ALGO_DH ) ? \
					RESOURCE_MESSAGE_CHECK_PKC_KA_EXPORT : \
					RESOURCE_MESSAGE_CHECK_PKC_ENCRYPT;
	else
		checkType = RESOURCE_MESSAGE_CHECK_CRYPT;
	status = krnlSendMessage( exportKey, RESOURCE_MESSAGE_CHECK, NULL,
							  checkType );
	if( cryptStatusError( status ) )
		return( ( status == CRYPT_ARGERROR_OBJECT ) ? \
				CRYPT_ERROR_PARAM3 : status );
	if( cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL && \
		cryptStatusError( sizeofAlgoIDex( cryptAlgo,
										  ( CRYPT_ALGO ) CRYPT_MODE_CBC, 0 ) ) )
		/* Conventional key wrap requires the use of an CBC mode for the 
		   wrapping (which also implies the use of a block cipher).  CBC mode
		   isn't essential but it's a good safety check, the use of a block 
		   cipher is essential */
		return( CRYPT_ERROR_PARAM3 );

	/* Check the exported key */
	status = krnlSendMessage( sessionKeyContext, RESOURCE_MESSAGE_GETATTRIBUTE,
							  &sessionKeyMode, CRYPT_CTXINFO_MODE );
	if( status == CRYPT_ARGERROR_VALUE )
		{
		/* No encryption mode attribute present, it has to be a MAC 
		   context */
		checkType = RESOURCE_MESSAGE_CHECK_MAC;
		status = CRYPT_OK;
		}
	else
		checkType = RESOURCE_MESSAGE_CHECK_CRYPT;
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( sessionKeyContext, RESOURCE_MESSAGE_CHECK, 
								  NULL, checkType );
	if( cryptAlgo == CRYPT_ALGO_DH )
		{
		/* If we're using a key agreement algorithm it doesn't matter if the
		   session key context has a key attribute present or not, but the 
		   format has to be cryptlib */
		if( status == CRYPT_ERROR_NOTINITED )
			status = CRYPT_OK;
		if( formatType == CRYPT_FORMAT_CMS || \
			formatType == CRYPT_FORMAT_SMIME )
			status = CRYPT_ERROR_PARAM3;
		}
	if( cryptStatusError( status ) )
		return( ( status == CRYPT_ARGERROR_OBJECT ) ? \
				CRYPT_ERROR_PARAM4 : status );

	/* If we're exporting a key in CMS format using a public key we need to
	   obtain recipient information */
	if( ( formatType == CRYPT_FORMAT_CMS || \
		  formatType == CRYPT_FORMAT_SMIME ) && 
		( cryptAlgo >= CRYPT_ALGO_FIRST_PKC && \
		  cryptAlgo <= CRYPT_ALGO_LAST_PKC ) )
		{
		if( cryptAlgo == CRYPT_ALGO_DH || cryptAlgo == CRYPT_ALGO_KEA )
			{
			RESOURCE_DATA msgData;

			setResourceData( &msgData, auxDataBuffer, 1024 );
			status = krnlSendMessage( exportKey, 
								RESOURCE_MESSAGE_GETATTRIBUTE_S, &msgData, 
								CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER );
			if( cryptStatusError( status ) )
				status = CRYPT_ERROR_PARAM4;
			auxDataLength = msgData.length;
			}
		else
			status = getIssuerAndSerialNumber( exportKey, &auxData,
											   &auxDataLength );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Export it as appropriate */
	if( cryptAlgo >= CRYPT_ALGO_FIRST_PKC && cryptAlgo <= CRYPT_ALGO_LAST_PKC )
		{
		if( cryptAlgo == CRYPT_ALGO_DH || cryptAlgo == CRYPT_ALGO_KEA )
			status = exportKeyAgreeKey( encryptedKey, encryptedKeyLength,
										sessionKeyContext, exportKey, 
										CRYPT_UNUSED, auxData, auxDataLength );
		else
			status = exportPublicKey( encryptedKey, encryptedKeyLength,
									  sessionKeyContext, exportKey, auxData, 
									  auxDataLength, recipientType );
		}
	else
		status = exportConventionalKey( encryptedKey, encryptedKeyLength,
										sessionKeyContext, exportKey );

	/* Clean up */
	if( auxData != auxDataBuffer )
		free( auxData );
	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 );
	}

C_RET cryptExportKey( C_OUT void C_PTR encryptedKey, 
					  C_OUT int C_PTR encryptedKeyLength,
					  C_IN CRYPT_HANDLE exportKey,
					  C_IN CRYPT_CONTEXT sessionKeyContext )
	{
	int status;

	status = cryptExportKeyEx( encryptedKey, encryptedKeyLength, 
							   CRYPT_FORMAT_CRYPTLIB, exportKey, 
							   sessionKeyContext );
	return( ( status == CRYPT_ERROR_PARAM4 ) ? CRYPT_ERROR_PARAM3 : \
			( status == CRYPT_ERROR_PARAM5 ) ? CRYPT_ERROR_PARAM4 : status );
	}

/****************************************************************************
*																			*
*						Internal Import/Export Functions					*
*																			*
****************************************************************************/

/* 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 */

int iCryptImportKeyEx( const void *encryptedKey, const int encryptedKeyLength,
					   const CRYPT_CONTEXT iImportKey,
					   const CRYPT_CONTEXT iSessionKeyContext )
	{
	CRYPT_ALGO cryptAlgo;
	int status;

	/* Import it as appropriate.  We don't handle key agreement at this
	   level */
	status = krnlSendMessage( iImportKey, RESOURCE_IMESSAGE_GETATTRIBUTE, 
							  &cryptAlgo, CRYPT_CTXINFO_ALGO );
	if( cryptStatusError( status ) )
		return( status );
	if( cryptAlgo >= CRYPT_ALGO_FIRST_CONVENTIONAL && \
		cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL )
		return( importConventionalKey( encryptedKey, encryptedKeyLength,
									   iSessionKeyContext, iImportKey ) );
	return( importPublicKey( encryptedKey, encryptedKeyLength,
							 iSessionKeyContext, iImportKey ) );
	}

int iCryptExportKeyEx( void *encryptedKey, int *encryptedKeyLength,
					   const CRYPT_FORMAT_TYPE formatType,
					   const CRYPT_CONTEXT iSessionKeyContext,
					   const CRYPT_CONTEXT iExportKey,
					   const CRYPT_CONTEXT iAuxContext )
	{
	CRYPT_ALGO cryptAlgo;
	const RECIPIENT_TYPE recipientType = \
			( formatType == CRYPT_FORMAT_CRYPTLIB ) ? RECIPIENT_CRYPTLIB : \
			( formatType == CRYPT_FORMAT_CMS || \
			  formatType == CRYPT_FORMAT_SMIME ) ? RECIPIENT_CMS : RECIPIENT_NONE;
	BYTE auxDataBuffer[ 1024 ], *auxData = auxDataBuffer;
	int auxDataLength = 1024, status;

	*encryptedKeyLength = 0;

	/* Perform simplified error checking */
	status = krnlSendMessage( iExportKey, RESOURCE_IMESSAGE_GETATTRIBUTE, 
							  &cryptAlgo, CRYPT_CTXINFO_ALGO );
	if( cryptStatusError( status ) )
		return( status );

	/* If we're exporting a key in CMS format using a public key we need to
	   obtain recipient information */
	if( ( formatType == CRYPT_FORMAT_CMS || \
		  formatType == CRYPT_FORMAT_SMIME ) && \
		( cryptAlgo >= CRYPT_ALGO_FIRST_PKC && \
		  cryptAlgo <= CRYPT_ALGO_LAST_PKC ) )
		{
		if( cryptAlgo == CRYPT_ALGO_DH || cryptAlgo == CRYPT_ALGO_KEA )
			{
			RESOURCE_DATA msgData;

			setResourceData( &msgData, auxDataBuffer, 1024 );
			status = krnlSendMessage( iExportKey, 
								RESOURCE_IMESSAGE_GETATTRIBUTE_S, &msgData, 
								CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER );
			if( cryptStatusError( status ) )
				status = CRYPT_ARGERROR_OBJECT;
			auxDataLength = msgData.length;
			}
		else
			status = getIssuerAndSerialNumber( iExportKey, &auxData,
											   &auxDataLength );
		if( cryptStatusError( status ) )
			return( status );
		}

	/* Export it as appropriate.  We don't handle key agreement at this
	   level */
	if( cryptAlgo >= CRYPT_ALGO_FIRST_PKC && cryptAlgo <= CRYPT_ALGO_LAST_PKC )
		{
		if( cryptAlgo == CRYPT_ALGO_DH || cryptAlgo == CRYPT_ALGO_KEA )
			status = exportKeyAgreeKey( encryptedKey, encryptedKeyLength,
										iSessionKeyContext, iExportKey, 
										iAuxContext, auxData, auxDataLength );
		else
			status = exportPublicKey( encryptedKey, encryptedKeyLength,
									  iSessionKeyContext, iExportKey, 
									  auxData, auxDataLength, recipientType );
		}
	else
		status = exportConventionalKey( encryptedKey, encryptedKeyLength,
										iSessionKeyContext, iExportKey );

	/* Clean up */
	if( auxData != auxDataBuffer )
		free( auxData );
	return( status );
	}

/****************************************************************************
*																			*
*								Object Query Function						*
*																			*
****************************************************************************/

/* Query an object.  This is just a wrapper which provides an external
   interface for queryObject() */

C_RET cryptQueryObject( C_IN void C_PTR objectData,
						C_OUT CRYPT_OBJECT_INFO C_PTR cryptObjectInfo )
	{
	QUERY_INFO queryInfo;
	STREAM stream;
	int status;

	/* Perform basic error checking */
	if( checkBadPtrRead( objectData, MIN_CRYPT_OBJECTSIZE ) )
		return( CRYPT_ERROR_PARAM1 );
	if( checkBadPtrWrite( cryptObjectInfo, sizeof( CRYPT_OBJECT_INFO ) ) )
		return( CRYPT_ERROR_PARAM2 );
	memset( cryptObjectInfo, 0, sizeof( CRYPT_OBJECT_INFO ) );

	/* Query the object.  This is just a wrapper for the lower-level
	   queryObject() function.  The length 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 */
	sMemConnect( &stream, ( void * ) objectData, 2048 );
	status = queryObject( &stream, &queryInfo );
	sMemDisconnect( &stream );

	/* Copy the externally-visible fields across */
	if( cryptStatusOK( status ) )
		{
		cryptObjectInfo->objectType = queryInfo.type;
		cryptObjectInfo->cryptAlgo = queryInfo.cryptAlgo;
		cryptObjectInfo->cryptMode = queryInfo.cryptMode;
		if( queryInfo.type == CRYPT_OBJECT_SIGNATURE )
			cryptObjectInfo->hashAlgo = queryInfo.hashAlgo;
		if( queryInfo.type == CRYPT_OBJECT_ENCRYPTED_KEY && \
			queryInfo.saltLength )
			{
			memcpy( cryptObjectInfo->salt, queryInfo.salt, 
					queryInfo.saltLength );
			cryptObjectInfo->saltSize = queryInfo.saltLength;
			}
		}

	return( status );
	}

⌨️ 快捷键说明

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