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

📄 keyex.c

📁 cryptlib是功能强大的安全工具集。允许开发人员快速在自己的软件中集成加密和认证服务。
💻 C
📖 第 1 页 / 共 3 页
字号:

		status = krnlSendMessage( sessionKeyContext, MESSAGE_GETATTRIBUTE, 
								  &sessionKeyAlgo, CRYPT_CTXINFO_ALGO );
		if( cryptStatusOK( status ) )
			status = krnlSendMessage( sessionKeyContext, MESSAGE_CHECK, NULL, 
							( sessionKeyAlgo >= CRYPT_ALGO_FIRST_MAC ) ? \
								MESSAGE_CHECK_MAC_READY : \
								MESSAGE_CHECK_CRYPT_READY );
		if( cryptStatusError( status ) )
			return( ( status == CRYPT_ARGERROR_OBJECT ) ? \
					CRYPT_ERROR_PARAM4 : status );
		if( returnedContext != NULL )
			return( CRYPT_ERROR_PARAM5 );
		}

	/* If the importing key is owned, bind the session key context to the same 
	   owner before we load a key into it.  We also need to save the original 
	   owner so we can undo the binding later if things fail */
	status = krnlSendMessage( sessionKeyContext, MESSAGE_GETATTRIBUTE, 
							  &originalOwner, CRYPT_PROPERTY_OWNER );
	if( cryptStatusError( status ) )
		originalOwner = CRYPT_ERROR;	/* Unowned object */
	status = krnlSendMessage( importKey, MESSAGE_GETATTRIBUTE, &owner, 
							  CRYPT_PROPERTY_OWNER );
	if( cryptStatusOK( status ) )
		krnlSendMessage( sessionKeyContext, MESSAGE_SETATTRIBUTE, &owner, 
						 CRYPT_PROPERTY_OWNER );

	/* Import it as appropriate */
	if( cryptAlgo >= CRYPT_ALGO_FIRST_PKC && cryptAlgo <= CRYPT_ALGO_LAST_PKC )
		{
		if( formatType == CRYPT_FORMAT_PGP )
			{
			status = importPublicKey( encryptedKey, encryptedKeyLength,
									  CRYPT_UNUSED, importKey, 
									  &iReturnedContext, KEYEX_PGP );
			if( cryptStatusOK( status ) )
				/* Make the newly-created context externally visible */
				krnlSendMessage( iReturnedContext, IMESSAGE_SETATTRIBUTE,
								 MESSAGE_VALUE_FALSE, 
								 CRYPT_IATTRIBUTE_INTERNAL );
			}
		else
			status = importPublicKey( encryptedKey, encryptedKeyLength,
									  sessionKeyContext, importKey, NULL,
									  ( formatType == CRYPT_FORMAT_CMS ) ? \
										KEYEX_CMS : KEYEX_CRYPTLIB );
		}
	else
		status = importConventionalKey( encryptedKey, encryptedKeyLength,
							sessionKeyContext, importKey,
							( formatType == CRYPT_FORMAT_CRYPTLIB ) ? \
								KEYEX_CRYPTLIB : KEYEX_PGP );

	/* If the import failed, return the session key context to its
	   original owner */
	if( cryptStatusError( status ) )
		{
		if( originalOwner != CRYPT_ERROR )
			krnlSendMessage( sessionKeyContext, MESSAGE_SETATTRIBUTE,
							 &originalOwner, CRYPT_PROPERTY_OWNER );
		}
	else
		/* If we created the session key as part of the import operation,
		   return it to the caller */
		if( formatType == CRYPT_FORMAT_PGP )
			*returnedContext = iReturnedContext;

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

C_RET cryptImportKey( C_IN void C_PTR encryptedKey,
					  C_IN int encryptedKeyLength,
					  C_IN CRYPT_CONTEXT importKey,
					  C_IN CRYPT_CONTEXT sessionKeyContext )
	{
	return( cryptImportKeyEx( encryptedKey, encryptedKeyLength, importKey, 
							  sessionKeyContext, NULL ) );
	}

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

C_RET cryptExportKeyEx( C_OUT void C_PTR encryptedKey, 
						C_IN int encryptedKeyMaxLength,
						C_OUT int C_PTR encryptedKeyLength,
						C_IN CRYPT_FORMAT_TYPE formatType,
						C_IN CRYPT_HANDLE exportKey,
						C_IN CRYPT_CONTEXT sessionKeyContext )
	{
	CRYPT_ALGO_TYPE cryptAlgo;
	CRYPT_MODE_TYPE sessionKeyMode;
	MESSAGE_CHECK_TYPE checkType;
	int status;

	/* Perform basic error checking */
	if( encryptedKey != NULL )
		{
		if( encryptedKeyMaxLength < MIN_CRYPT_OBJECTSIZE )
			return( CRYPT_ERROR_PARAM2 );
		if( !isWritePtr( encryptedKey, encryptedKeyMaxLength ) )
			return( CRYPT_ERROR_PARAM1 );
		memset( encryptedKey, 0, MIN_CRYPT_OBJECTSIZE );
		}
	if( !isWritePtr( encryptedKeyLength, sizeof( int ) ) )
		return( CRYPT_ERROR_PARAM3 );
	*encryptedKeyLength = 0;
	if( formatType <= CRYPT_FORMAT_NONE || \
		formatType >= CRYPT_FORMAT_LAST_EXTERNAL )
		return( CRYPT_ERROR_PARAM4 );

	/* Check the exporting key */
	status = krnlSendMessage( exportKey, MESSAGE_GETATTRIBUTE, &cryptAlgo, 
							  CRYPT_CTXINFO_ALGO );
	if( cryptStatusError( status ) )
		return( ( status == CRYPT_ARGERROR_OBJECT ) ? \
				CRYPT_ERROR_PARAM5 : status );
	if( cryptAlgo >= CRYPT_ALGO_FIRST_PKC && cryptAlgo <= CRYPT_ALGO_LAST_PKC )
		checkType = ( cryptAlgo == CRYPT_ALGO_DH ) ? \
					MESSAGE_CHECK_PKC_KA_EXPORT : MESSAGE_CHECK_PKC_ENCRYPT;
	else
		checkType = MESSAGE_CHECK_CRYPT;
	if( isDlpAlgo( cryptAlgo ) )
		/* The DLP algorithms have specialised data-formatting requirements 
		   and can't normally be directly accessed via external messages, 
		   however if we're performing a key export this is OK since they're
		   being used from cryptlib-internal routines.  Doing the check via
		   an internal message is safe since we've already checked its 
		   external accessibility when we got the algorithm info */
		status = krnlSendMessage( exportKey, IMESSAGE_CHECK, NULL, 
								  checkType );
	else
		status = krnlSendMessage( exportKey, MESSAGE_CHECK, NULL, 
								  checkType );
	if( cryptStatusError( status ) )
		return( ( status == CRYPT_ARGERROR_OBJECT ) ? \
				CRYPT_ERROR_PARAM5 : status );
	if( cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL && \
		cryptStatusError( sizeofAlgoIDex( cryptAlgo,
								( CRYPT_ALGO_TYPE ) 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_PARAM5 );

	/* Check the exported key */
	status = krnlSendMessage( sessionKeyContext, MESSAGE_GETATTRIBUTE,
							  &sessionKeyMode, CRYPT_CTXINFO_MODE );
	if( status == CRYPT_ARGERROR_VALUE )
		{
		/* No encryption mode attribute present, it has to be a MAC 
		   context */
		checkType = MESSAGE_CHECK_MAC;
		status = CRYPT_OK;
		}
	else
		checkType = MESSAGE_CHECK_CRYPT;
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( sessionKeyContext, MESSAGE_CHECK, NULL, 
								  checkType );
#ifdef USE_PGP
	if( formatType == CRYPT_FORMAT_PGP )
		{
		CRYPT_ALGO_TYPE sessionKeyAlgo;

		/* PGP can only handle a limited subset of algorithms, make sure this
		   is an algorithm type which can be represented in the PGP format */
		status = krnlSendMessage( sessionKeyContext, MESSAGE_GETATTRIBUTE, 
								  &sessionKeyAlgo, CRYPT_CTXINFO_ALGO );
		if( cryptStatusError( status ) )
			return( ( status == CRYPT_ARGERROR_OBJECT ) ? \
					CRYPT_ERROR_PARAM6 : status );
		if( cryptlibToPgpAlgo( sessionKeyAlgo ) == PGP_ALGO_NONE )
			return( CRYPT_ERROR_PARAM6 );
		}
#endif /* USE_PGP */
	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_PARAM4;
		}
	if( cryptStatusError( status ) )
		return( ( status == CRYPT_ARGERROR_OBJECT ) ? \
				CRYPT_ERROR_PARAM6 : status );

	/* Export the key via the shared export function */
	status = iCryptExportKeyEx( encryptedKey, encryptedKeyLength,
								encryptedKeyMaxLength, formatType,
								sessionKeyContext, exportKey,
								CRYPT_UNUSED );
	if( cryptArgError( status ) )
		/* If we get an argument error from the lower-level code, map the
		   parameter number to the function argument number */
		status = ( status == CRYPT_ARGERROR_NUM1 ) ? \
				 CRYPT_ERROR_PARAM6 : CRYPT_ERROR_PARAM5;
	return( status );
	}

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

	status = cryptExportKeyEx( encryptedKey, encryptedKeyMaxLength, 
							   encryptedKeyLength, CRYPT_FORMAT_CRYPTLIB, 
							   exportKey, sessionKeyContext );
	return( ( status == CRYPT_ERROR_PARAM5 ) ? CRYPT_ERROR_PARAM4 : \
			( status == CRYPT_ERROR_PARAM6 ) ? CRYPT_ERROR_PARAM5 : 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_FORMAT_TYPE formatType,
					   const CRYPT_CONTEXT iImportKey,
					   const CRYPT_CONTEXT iSessionKeyContext,
					   CRYPT_CONTEXT *iReturnedContext )
	{
	CRYPT_ALGO_TYPE cryptAlgo;
	const KEYEX_TYPE keyexType = \
			( formatType == CRYPT_FORMAT_AUTO || \
			  formatType == CRYPT_FORMAT_CRYPTLIB ) ? KEYEX_CRYPTLIB : \
			( formatType == CRYPT_FORMAT_PGP ) ? KEYEX_PGP : KEYEX_CMS;
	int status;

	assert( isReadPtr( encryptedKey, encryptedKeyLength ) );
	assert( formatType > CRYPT_FORMAT_NONE && \
			formatType < CRYPT_FORMAT_LAST );
	assert( isHandleRangeValid( iImportKey ) );
	assert( ( formatType == CRYPT_FORMAT_PGP && \
			  iSessionKeyContext == CRYPT_UNUSED ) || \
			( formatType != CRYPT_FORMAT_PGP && \
			  isHandleRangeValid( iSessionKeyContext ) ) );
	assert( ( formatType == CRYPT_FORMAT_PGP && \
			  iReturnedContext != NULL ) || \
			( formatType != CRYPT_FORMAT_PGP && \
			  iReturnedContext == NULL ) );

	/* Import it as appropriate.  We don't handle key agreement at this
	   level */
	status = krnlSendMessage( iImportKey, 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, 
									   keyexType ) );
	return( importPublicKey( encryptedKey, encryptedKeyLength,
							 iSessionKeyContext, iImportKey, 
							 iReturnedContext, keyexType ) );
	}

int iCryptExportKeyEx( void *encryptedKey, int *encryptedKeyLength,
					   const int encryptedKeyMaxLength,
					   const CRYPT_FORMAT_TYPE formatType,
					   const CRYPT_CONTEXT iSessionKeyContext,
					   const CRYPT_CONTEXT iExportKey,
					   const CRYPT_CONTEXT iAuxContext )
	{
	CRYPT_ALGO_TYPE cryptAlgo;
	const KEYEX_TYPE keyexType = \
			( formatType == CRYPT_FORMAT_CRYPTLIB ) ? KEYEX_CRYPTLIB : \
			( formatType == CRYPT_FORMAT_PGP ) ? KEYEX_PGP : KEYEX_CMS;
	DYNBUF auxDB;
	BOOLEAN lockObject = FALSE;
	int status;

	assert( encryptedKey == NULL || \
			isWritePtr( encryptedKey, MIN_CRYPT_OBJECTSIZE ) );
	assert( isWritePtr( encryptedKeyLength, sizeof( int ) ) );
	assert( formatType > CRYPT_FORMAT_NONE && \
			formatType < CRYPT_FORMAT_LAST );
	assert( isHandleRangeValid( iExportKey ) );

	/* Clear return value */
	*encryptedKeyLength = 0;

	/* Perform simplified error checking */
	status = krnlSendMessage( iExportKey, IMESSAGE_GETATTRIBUTE, &cryptAlgo, 
							  CRYPT_CTXINFO_ALGO );
	if( cryptStatusError( status ) )
		return( ( status == CRYPT_ARGERROR_OBJECT ) ? \
				CRYPT_ARGERROR_NUM2 : 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 ) )
		{
		/* Lock the cert for our exclusive use, and in case it's a cert 
		   chain, select the first cert in the chain */
		status = krnlSendMessage( iExportKey, IMESSAGE_SETATTRIBUTE,
								  MESSAGE_VALUE_TRUE, 
								  CRYPT_IATTRIBUTE_LOCKED );
		if( cryptStatusError( status ) )
			return( CRYPT_ERROR_PARAM5 );
		krnlSendMessage( iExportKey, IMESSAGE_SETATTRIBUTE, 
						 MESSAGE_VALUE_CURSORFIRST, 
						 CRYPT_CERTINFO_CURRENT_CERTIFICATE );

		/* Get the recipient information from the cert */
		status = dynCreate( &auxDB, iExportKey, 
							( cryptAlgo == CRYPT_ALGO_DH || \
							  cryptAlgo == CRYPT_ALGO_KEA ) ? \
								CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER : \
								CRYPT_IATTRIBUTE_ISSUERANDSERIALNUMBER );
		if( cryptStatusError( status ) )
			{
			krnlSendMessage( iExportKey, IMESSAGE_SETATTRIBUTE,
							 MESSAGE_VALUE_FALSE, CRYPT_IATTRIBUTE_LOCKED );
			return( CRYPT_ERROR_PARAM5 );
			}
		lockObject = TRUE;
		}
	else
		dynCreate( &auxDB, CRYPT_UNUSED, CRYPT_UNUSED );

	/* Export it as appropriate */
	if( cryptAlgo >= CRYPT_ALGO_FIRST_PKC && cryptAlgo <= CRYPT_ALGO_LAST_PKC )
		status = exportPublicKey( encryptedKey, encryptedKeyLength,
								  ( encryptedKey == NULL ) ? \
										0 : encryptedKeyMaxLength,
								  iSessionKeyContext, iExportKey, 
								  dynData( auxDB ), dynLength( auxDB ), 
								  keyexType );
	else
		status = exportConventionalKey( encryptedKey, encryptedKeyLength,
										( encryptedKey == NULL ) ? \
											0 : encryptedKeyMaxLength,
										iSessionKeyContext, iExportKey,
										keyexType );

	/* Clean up */
	if( lockObject )
		krnlSendMessage( iExportKey, IMESSAGE_SETATTRIBUTE,
						 MESSAGE_VALUE_FALSE, CRYPT_IATTRIBUTE_LOCKED );
	dynDestroy( &auxDB );
	return( status );
	}

⌨️ 快捷键说明

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