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

📄 keyex_int.c

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

/****************************************************************************
*																			*
*							Low-level Key Import Functions					*
*																			*
****************************************************************************/

/* Import a conventionally encrypted session key */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int importConventionalKey( IN_BUFFER( encryptedKeyLength ) \
							const void *encryptedKey, 
						   IN_LENGTH_SHORT const int encryptedKeyLength,
						   IN_HANDLE const CRYPT_CONTEXT iSessionKeyContext,
						   IN_HANDLE const CRYPT_CONTEXT iImportContext,
						   IN_ENUM( KEYEX ) const KEYEX_TYPE keyexType )
	{
	CRYPT_ALGO_TYPE importAlgo;
	CRYPT_MODE_TYPE importMode = DUMMY_INIT;
	MECHANISM_WRAP_INFO mechanismInfo;
	const READKEK_FUNCTION readKeyexFunction = getReadKekFunction( keyexType );
	QUERY_INFO queryInfo;
	MESSAGE_DATA msgData;
	STREAM stream;
	int status;

	assert( isReadPtr( encryptedKey, encryptedKeyLength ) );

	REQUIRES( encryptedKeyLength > MIN_CRYPT_OBJECTSIZE && \
			  encryptedKeyLength < MAX_INTLENGTH_SHORT );
	REQUIRES( isHandleRangeValid( iSessionKeyContext ) );
	REQUIRES( isHandleRangeValid( iImportContext ) );
	REQUIRES( keyexType > KEYEX_NONE && keyexType < KEYEX_LAST );

	/* Make sure that the requested key exchange format is available */
	if( readKeyexFunction == NULL )
		return( CRYPT_ERROR_NOTAVAIL );

	/* Get the import parameters */
	status = krnlSendMessage( iImportContext, IMESSAGE_GETATTRIBUTE, 
							  &importAlgo, CRYPT_CTXINFO_ALGO );
	if( cryptStatusOK( status ) )
		status = krnlSendMessage( iImportContext, IMESSAGE_GETATTRIBUTE,
								  &importMode, CRYPT_CTXINFO_MODE );
	if( cryptStatusError( status ) )
		return( cryptArgError( status ) ? CRYPT_ARGERROR_NUM2 : status );

	/* Read and check the encrypted key record and make sure that we'll be 
	   using the correct type of encryption context to decrypt it */
	memset( &queryInfo, 0, sizeof( QUERY_INFO ) );
	sMemConnect( &stream, encryptedKey, encryptedKeyLength );
	status = readKeyexFunction( &stream, &queryInfo );
	sMemDisconnect( &stream );
	if( cryptStatusOK( status ) && \
		( importAlgo != queryInfo.cryptAlgo || \
		  importMode != queryInfo.cryptMode ) )
		status = CRYPT_ARGERROR_NUM1;
	if( cryptStatusError( status ) )
		{
		zeroise( &queryInfo, sizeof( QUERY_INFO ) );
		return( status );
		}

	/* Extract the encrypted key from the buffer and decrypt it.  Since we
	   don't want another thread changing the IV while we're using the import
	   context, we lock it for the duration */
	status = krnlSendMessage( iImportContext, IMESSAGE_SETATTRIBUTE,
							  MESSAGE_VALUE_TRUE, CRYPT_IATTRIBUTE_LOCKED );
	if( cryptStatusError( status ) )
		{
		zeroise( &queryInfo, sizeof( QUERY_INFO ) );
		return( status );
		}
	if( needsIV( importMode ) && importAlgo != CRYPT_ALGO_RC4 )
		{
		setMessageData( &msgData, queryInfo.iv, queryInfo.ivLength );
		status = krnlSendMessage( iImportContext, IMESSAGE_SETATTRIBUTE_S, 
								  &msgData, CRYPT_CTXINFO_IV );
		if( cryptStatusError( status ) )
			{
			( void ) krnlSendMessage( iImportContext, IMESSAGE_SETATTRIBUTE, 
									  MESSAGE_VALUE_FALSE, 
									  CRYPT_IATTRIBUTE_LOCKED );
			zeroise( &queryInfo, sizeof( QUERY_INFO ) );
			return( status );
			}
		}
	ENSURES( rangeCheck( queryInfo.dataStart, queryInfo.dataLength,
						 encryptedKeyLength ) );
	setMechanismWrapInfo( &mechanismInfo,
						  ( BYTE * ) encryptedKey + queryInfo.dataStart, 
						  queryInfo.dataLength, NULL, 0, 
						  iSessionKeyContext, iImportContext );
	status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_IMPORT,
							  &mechanismInfo, MECHANISM_ENC_CMS );
	( void ) krnlSendMessage( iImportContext, IMESSAGE_SETATTRIBUTE,
							  MESSAGE_VALUE_FALSE, 
							  CRYPT_IATTRIBUTE_LOCKED );
	clearMechanismInfo( &mechanismInfo );
	zeroise( &queryInfo, sizeof( QUERY_INFO ) );

	return( status );
	}

/* Import a public-key encrypted session key */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int importPublicKey( IN_BUFFER( encryptedKeyLength ) const void *encryptedKey, 
					 IN_LENGTH_SHORT const int encryptedKeyLength,
					 IN_HANDLE_OPT const CRYPT_CONTEXT iSessionKeyContext,
					 IN_HANDLE const CRYPT_CONTEXT iImportContext,
					 OUT_OPT_HANDLE_OPT CRYPT_CONTEXT *iReturnedContext, 
					 IN_ENUM( KEYEX ) const KEYEX_TYPE keyexType )
	{
	MECHANISM_WRAP_INFO mechanismInfo;
	const READKEYTRANS_FUNCTION readKetransFunction = getReadKeytransFunction( keyexType );
	QUERY_INFO queryInfo;
	MESSAGE_DATA msgData;
	STREAM stream;
	int compareType, status;

	assert( isReadPtr( encryptedKey, encryptedKeyLength ) );
	assert( ( keyexType == KEYEX_PGP && \
			  isWritePtr( iReturnedContext, sizeof( CRYPT_CONTEXT ) ) ) || \
			( keyexType != KEYEX_PGP && iReturnedContext == NULL ) );

	REQUIRES( encryptedKeyLength > MIN_CRYPT_OBJECTSIZE && \
			  encryptedKeyLength < MAX_INTLENGTH );
	REQUIRES( ( keyexType == KEYEX_PGP && \
				iSessionKeyContext == CRYPT_UNUSED ) || \
			  ( keyexType != KEYEX_PGP && \
				isHandleRangeValid( iSessionKeyContext ) ) );
	REQUIRES( isHandleRangeValid( iImportContext ) );
	REQUIRES( ( keyexType == KEYEX_PGP && iReturnedContext != NULL ) || \
			  ( keyexType != KEYEX_PGP && iReturnedContext == NULL ) );
	REQUIRES( keyexType > KEYEX_NONE && keyexType < KEYEX_LAST );

	/* Clear return value */
	if( iReturnedContext != NULL )
		*iReturnedContext = CRYPT_ERROR;

	/* Make sure that the requested key exchange format is available */
	if( readKetransFunction == NULL )
		return( CRYPT_ERROR_NOTAVAIL );

	/* Read and check the encrypted key record */
	memset( &queryInfo, 0, sizeof( QUERY_INFO ) );
	sMemConnect( &stream, encryptedKey, encryptedKeyLength );
	status = readKetransFunction( &stream, &queryInfo );
	sMemDisconnect( &stream );
	if( cryptStatusError( status ) )
		{
		zeroise( &queryInfo, sizeof( QUERY_INFO ) );
		return( status );
		}

	/* Make sure that we've been given the correct key */
	setMessageData( &msgData, queryInfo.keyID, queryInfo.keyIDlength );
	switch( keyexType )
		{
		case KEYEX_CMS:
			setMessageData( &msgData, \
					( BYTE * ) encryptedKey + queryInfo.iAndSStart, \
					queryInfo.iAndSLength );
			compareType = MESSAGE_COMPARE_ISSUERANDSERIALNUMBER;
			break;

		case KEYEX_CRYPTLIB:
			compareType = MESSAGE_COMPARE_KEYID;
			break;

		case KEYEX_PGP:
			compareType = ( queryInfo.version == PGP_VERSION_2 ) ? \
						  MESSAGE_COMPARE_KEYID_PGP : \
						  MESSAGE_COMPARE_KEYID_OPENPGP;
			break;

		default:
			retIntError();
		}
	status = krnlSendMessage( iImportContext, IMESSAGE_COMPARE, &msgData, 
							  compareType );
	if( cryptStatusError( status ) && \
		compareType == MESSAGE_COMPARE_KEYID_OPENPGP )
		{
		/* Some broken PGP implementations put PGP 2.x IDs in packets marked 
		   as OpenPGP packets so if we were doing a check for an OpenPGP ID 
		   and it failed, fall back to a PGP 2.x one */
		status = krnlSendMessage( iImportContext, IMESSAGE_COMPARE, 
								  &msgData, MESSAGE_COMPARE_KEYID_PGP );
		}
	if( cryptStatusError( status ) )
		{
		/* A failed comparison is reported as a generic CRYPT_ERROR, convert 
		   it into a wrong-key error */
		zeroise( &queryInfo, sizeof( QUERY_INFO ) );
		return( CRYPT_ERROR_WRONGKEY );
		}

	/* Decrypt the encrypted key and load it into the context */
	if( keyexType != KEYEX_PGP )
		{
		setMechanismWrapInfo( &mechanismInfo,
							  ( BYTE * ) encryptedKey + queryInfo.dataStart, 
							  queryInfo.dataLength, NULL, 0, 
							  iSessionKeyContext, iImportContext );
		status = krnlSendMessage( iImportContext, IMESSAGE_DEV_IMPORT,
								  &mechanismInfo, MECHANISM_ENC_PKCS1 );
		}
	else
		{
		/* PGP doesn't provide separate session key information with the
		   encrypted data but wraps it up alongside the encrypted key, so we
		   can't import the wrapped key into a context via the standard key
		   import functions but instead have to create the context as part
		   of the unwrap process */
		setMechanismWrapInfo( &mechanismInfo, 
							  ( BYTE * ) encryptedKey + queryInfo.dataStart,
							  queryInfo.dataLength, NULL, 0, 
							  CRYPT_UNUSED, iImportContext );
		status = krnlSendMessage( iImportContext, IMESSAGE_DEV_IMPORT,
								  &mechanismInfo, MECHANISM_ENC_PKCS1_PGP );
		if( cryptStatusOK( status ) )
			*iReturnedContext = mechanismInfo.keyContext;
		}
	clearMechanismInfo( &mechanismInfo );
	zeroise( &queryInfo, sizeof( QUERY_INFO ) );

	return( status );
	}

⌨️ 快捷键说明

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