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

📄 keyex.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 2 页
字号:
		/* The importing key is owned, set the imported key's owner if it's
		   present */
		if( sessionKeyContext != CRYPT_UNUSED )
			{
			status = krnlSendMessage( sessionKeyContext, MESSAGE_SETATTRIBUTE, 
									  &owner, CRYPT_PROPERTY_OWNER );
			if( cryptStatusError( status ) )
				return( status );
			}
		}
	else
		{
		/* Don't try and change the session key ownership */
		originalOwner = CRYPT_ERROR;
		}

	/* Import it as appropriate */
	status = iCryptImportKey( encryptedKey, encryptedKeyLength, formatType,
							  importKey, sessionKeyContext, 
							  ( formatType == CRYPT_FORMAT_PGP ) ? \
								&iReturnedContext : NULL );
	if( cryptStatusError( status ) )
		{
		/* The import failed, return the session key context to its
		   original owner.  If this fails there's not much that we can do
		   to recover so we don't do anything with the return value */
		if( originalOwner != CRYPT_ERROR )
			{
			( void ) krnlSendMessage( sessionKeyContext, 
									  MESSAGE_SETATTRIBUTE,
									  &originalOwner, CRYPT_PROPERTY_OWNER );
			}
		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 );
		}

#ifdef USE_PGP
	/* If it's a PGP key import then the session key was recreated from 
	   information stored with the wrapped key so we have to make it 
	   externally visible before it can be used by the caller */
	if( formatType == CRYPT_FORMAT_PGP && \
		importAlgo >= CRYPT_ALGO_FIRST_PKC && importAlgo <= CRYPT_ALGO_LAST_PKC )
		{
		/* If the importing key is owned, set the imported key's owner */
		if( originalOwner != CRYPT_ERROR )
			{
			status = krnlSendMessage( iReturnedContext, 
									  IMESSAGE_SETATTRIBUTE, 
									  &owner, CRYPT_PROPERTY_OWNER );
			if( cryptStatusError( status ) )
				{
				krnlSendNotifier( iReturnedContext, IMESSAGE_DECREFCOUNT );
				return( status );
				}
			}

		/* Make the newly-created context externally visible */
		status = krnlSendMessage( iReturnedContext, IMESSAGE_SETATTRIBUTE, 
								  MESSAGE_VALUE_FALSE, 
								  CRYPT_IATTRIBUTE_INTERNAL );
		if( cryptStatusError( status ) )
			{
			krnlSendNotifier( iReturnedContext, IMESSAGE_DECREFCOUNT );
			return( status );
			}
		*returnedContext = iReturnedContext;
		}
#endif /* USE_PGP */
	
	return( CRYPT_OK );
	}

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 a Session Key						*
*																			*
****************************************************************************/

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

C_RET cryptExportKeyEx( C_OUT_OPT 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 exportAlgo, sessionKeyAlgo;
	int status;

	/* Perform basic error checking */
	if( encryptedKey != NULL )
		{
		if( encryptedKeyMaxLength <= MIN_CRYPT_OBJECTSIZE || \
			encryptedKeyMaxLength >= MAX_INTLENGTH )
			return( CRYPT_ERROR_PARAM2 );
		if( !isWritePtr( encryptedKey, encryptedKeyMaxLength ) )
			return( CRYPT_ERROR_PARAM1 );
		memset( encryptedKey, 0, MIN_CRYPT_OBJECTSIZE );
		}
	else
		{
		if( encryptedKeyMaxLength != 0 )
			return( CRYPT_ERROR_PARAM2 );
		}
	if( !isWritePtr( encryptedKeyLength, sizeof( int ) ) )
		return( CRYPT_ERROR_PARAM3 );
	*encryptedKeyLength = 0;
	if( formatType != CRYPT_FORMAT_CRYPTLIB && \
		formatType != CRYPT_FORMAT_CMS && \
		formatType != CRYPT_FORMAT_SMIME && \
		formatType != CRYPT_FORMAT_PGP )
		return( CRYPT_ERROR_PARAM4 );
	if( !isHandleRangeValid( exportKey ) )
		return( CRYPT_ERROR_PARAM5 );
	if( !isHandleRangeValid( sessionKeyContext ) )
		return( CRYPT_ERROR_PARAM6 );

	/* Check the exporting key */
	status = checkWrapKey( exportKey, &exportAlgo, FALSE );
	if( cryptStatusError( status ) )
		return( cryptArgError( status ) ? CRYPT_ERROR_PARAM5 : status );
	status = checkContextsEncodable( exportKey, exportAlgo, 
									 sessionKeyContext, formatType );
	if( cryptStatusError( status ) )
		{
		return( ( status == CRYPT_ERROR_PARAM1 ) ? CRYPT_ERROR_PARAM5 : \
				( status == CRYPT_ERROR_PARAM3 ) ? CRYPT_ERROR_PARAM6 : \
				CRYPT_ERROR_PARAM4 );
		}

	/* Check the exported key */
	status = krnlSendMessage( sessionKeyContext, MESSAGE_GETATTRIBUTE,
							  &sessionKeyAlgo, CRYPT_CTXINFO_ALGO );
	if( cryptStatusError( status ) )
		return( CRYPT_ERROR_PARAM6 );
	status = krnlSendMessage( sessionKeyContext, MESSAGE_CHECK, NULL,
							  ( sessionKeyAlgo >= CRYPT_ALGO_FIRST_MAC && \
								sessionKeyAlgo <= CRYPT_ALGO_LAST_MAC ) ? \
							  MESSAGE_CHECK_MAC : MESSAGE_CHECK_CRYPT );
	if( cryptStatusError( status ) )
		return( cryptArgError( status ) ? CRYPT_ERROR_PARAM6 : status );

	/* Export the key via the shared export function */
	status = iCryptExportKey( encryptedKey, encryptedKeyMaxLength, 
							  encryptedKeyLength, formatType,
							  sessionKeyContext, exportKey );
	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_OPT 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 explicit 
   checking done by the external versions (e.g. "Is this value really a 
   handle to a valid PKC context?") since they're only called by cryptlib 
   internal functions rather than being passed untrusted user data */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int iCryptImportKey( IN_BUFFER( encryptedKeyLength ) const void *encryptedKey, 
					 IN_LENGTH_SHORT const int encryptedKeyLength,
					 IN_ENUM( CRYPT_FORMAT ) const CRYPT_FORMAT_TYPE formatType,
					 IN_HANDLE const CRYPT_CONTEXT iImportKey,
					 IN_HANDLE_OPT const CRYPT_CONTEXT iSessionKeyContext,
					 OUT_OPT_HANDLE_OPT CRYPT_CONTEXT *iReturnedContext )
	{
	CRYPT_ALGO_TYPE importAlgo;
	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_PGP && \
			  isWritePtr( iReturnedContext, sizeof( CRYPT_CONTEXT ) ) ) || \
			( formatType != CRYPT_FORMAT_PGP && \
			  iReturnedContext == NULL ) );

	REQUIRES( encryptedKeyLength > MIN_CRYPT_OBJECTSIZE && \
			  encryptedKeyLength < MAX_INTLENGTH_SHORT );
	REQUIRES( formatType > CRYPT_FORMAT_NONE && \
			  formatType < CRYPT_FORMAT_LAST );
	REQUIRES( isHandleRangeValid( iImportKey ) );
	REQUIRES( ( formatType == CRYPT_FORMAT_PGP && \
				iSessionKeyContext == CRYPT_UNUSED ) || \
			  ( formatType != CRYPT_FORMAT_PGP && \
				isHandleRangeValid( iSessionKeyContext ) ) );
	REQUIRES( ( 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 since it's a protocol-specific mechanism used by SSH and SSL,
	   which are internal-only formats */
	status = krnlSendMessage( iImportKey, IMESSAGE_GETATTRIBUTE, &importAlgo,
							  CRYPT_CTXINFO_ALGO );
	if( cryptStatusError( status ) )
		return( status );
	if( importAlgo >= CRYPT_ALGO_FIRST_CONVENTIONAL && \
		importAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL )
		{
		return( importConventionalKey( encryptedKey, encryptedKeyLength,
									   iSessionKeyContext, iImportKey,
									   keyexType ) );
		}
	return( importPublicKey( encryptedKey, encryptedKeyLength,
							 iSessionKeyContext, iImportKey,
							 iReturnedContext, keyexType ) );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \
int iCryptExportKey( OUT_BUFFER_OPT( encryptedKeyMaxLength, *encryptedKeyLength ) \
						void *encryptedKey, 
					 IN_LENGTH_Z const int encryptedKeyMaxLength,
					 OUT_LENGTH_Z int *encryptedKeyLength,
					 IN_ENUM( CRYPT_FORMAT ) const CRYPT_FORMAT_TYPE formatType,
					 IN_HANDLE_OPT const CRYPT_CONTEXT iSessionKeyContext,
					 IN_HANDLE const CRYPT_CONTEXT iExportKey )
	{
	CRYPT_ALGO_TYPE exportAlgo;
	const KEYEX_TYPE keyexType = \
			( formatType == CRYPT_FORMAT_CRYPTLIB ) ? KEYEX_CRYPTLIB : \
			( formatType == CRYPT_FORMAT_PGP ) ? KEYEX_PGP : KEYEX_CMS;
	DYNBUF auxDB;
	const int encKeyMaxLength = ( encryptedKey == NULL ) ? \
								0 : encryptedKeyMaxLength;
	int status;

	assert( ( encryptedKey == NULL && encryptedKeyMaxLength == 0 ) || \
			( encryptedKeyMaxLength >= MIN_CRYPT_OBJECTSIZE && \
			  isWritePtr( encryptedKey, encryptedKeyMaxLength ) ) );
	assert( isWritePtr( encryptedKeyLength, sizeof( int ) ) );

	REQUIRES( ( encryptedKey == NULL && encryptedKeyMaxLength == 0 ) || \
			  ( encryptedKeyMaxLength > MIN_CRYPT_OBJECTSIZE && \
				encryptedKeyMaxLength < MAX_INTLENGTH ) );
	REQUIRES( formatType > CRYPT_FORMAT_NONE && \
			  formatType < CRYPT_FORMAT_LAST );
	REQUIRES( ( formatType == CRYPT_FORMAT_PGP && \
				iSessionKeyContext == CRYPT_UNUSED ) || \
			  isHandleRangeValid( iSessionKeyContext ) );
	REQUIRES( isHandleRangeValid( iExportKey ) );

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

	/* Perform simplified error checking */
	status = krnlSendMessage( iExportKey, IMESSAGE_GETATTRIBUTE, &exportAlgo,
							  CRYPT_CTXINFO_ALGO );
	if( cryptStatusError( status ) )
		return( cryptArgError( status ) ? CRYPT_ARGERROR_NUM2 : status );

	/* If it's a non-PKC export, pass the call down to the low-level export
	   function */
	if( exportAlgo < CRYPT_ALGO_FIRST_PKC || exportAlgo > CRYPT_ALGO_LAST_PKC )
		{
		return( exportConventionalKey( encryptedKey, encKeyMaxLength, 
									   encryptedKeyLength, iSessionKeyContext, 
									   iExportKey, keyexType ) );
		}

	REQUIRES( isHandleRangeValid( iSessionKeyContext ) );

	/* If it's a non-CMS/SMIME PKC export, pass the call down to the low-
	   level export function */
	if( formatType != CRYPT_FORMAT_CMS && formatType != CRYPT_FORMAT_SMIME )
		{
		return( exportPublicKey( encryptedKey, encKeyMaxLength, 
								 encryptedKeyLength, iSessionKeyContext, 
								 iExportKey, NULL, 0, keyexType ) );
		}

	/* We're exporting a key in CMS format we need to obtain recipient 
	   information from the certificate associated with the export context.
	   First we 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 );
	status = krnlSendMessage( iExportKey, IMESSAGE_SETATTRIBUTE,
							  MESSAGE_VALUE_CURSORFIRST, 
							  CRYPT_CERTINFO_CURRENT_CERTIFICATE );
	if( cryptStatusError( status ) )
		{
		/* Unlock the chain before we exit.  If this fails there's not much 
		   that we can do to recover so we don't do anything with the return 
		   value */
		( void ) krnlSendMessage( iExportKey, IMESSAGE_SETATTRIBUTE,
								  MESSAGE_VALUE_FALSE, 
								  CRYPT_IATTRIBUTE_LOCKED );
		return( CRYPT_ERROR_PARAM5 );
		}

	/* Next we get the recipient information from the cert into a dynbuf */
	status = dynCreate( &auxDB, iExportKey,
						( exportAlgo == CRYPT_ALGO_KEA ) ? \
							CRYPT_CERTINFO_SUBJECTKEYIDENTIFIER : \
							CRYPT_IATTRIBUTE_ISSUERANDSERIALNUMBER );
	if( cryptStatusError( status ) )
		{
		( void ) krnlSendMessage( iExportKey, IMESSAGE_SETATTRIBUTE,
								  MESSAGE_VALUE_FALSE, 
								  CRYPT_IATTRIBUTE_LOCKED );
		return( CRYPT_ERROR_PARAM5 );
		}

	/* We're ready to export the key alongside the key ID as auxiliary 
	   data */
	status = exportPublicKey( encryptedKey, encKeyMaxLength, 
							  encryptedKeyLength, iSessionKeyContext, 
							  iExportKey, dynData( auxDB ), 
							  dynLength( auxDB ), keyexType );

	/* Clean up.  If the unlock fails there's not much that we can do to 
	   recover so we don't do anything with the return value */
	( void ) krnlSendMessage( iExportKey, IMESSAGE_SETATTRIBUTE, 
							  MESSAGE_VALUE_FALSE, CRYPT_IATTRIBUTE_LOCKED );
	dynDestroy( &auxDB );

	return( status );
	}

⌨️ 快捷键说明

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