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

📄 keyex_rw.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
static int writeCryptlibKeytrans( INOUT STREAM *stream,
								  IN_HANDLE const CRYPT_CONTEXT iCryptContext,
								  IN_BUFFER( encryptedKeyLength ) \
									const BYTE *encryptedKey, 
								  IN_LENGTH_SHORT_MIN( MIN_PKCSIZE ) \
									const int encryptedKeyLength,
								  STDC_UNUSED const void *auxInfo,
								  STDC_UNUSED const int auxInfoLength )
	{
	MESSAGE_DATA msgData;
	BYTE keyID[ CRYPT_MAX_HASHSIZE + 8 ];
	const int algoIdInfoSize = \
				sizeofContextAlgoID( iCryptContext, CRYPT_ALGO_NONE );
	int status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isReadPtr( encryptedKey, encryptedKeyLength ) );

	REQUIRES( isHandleRangeValid( iCryptContext ) );
	REQUIRES( encryptedKeyLength >= MIN_PKCSIZE && \
			  encryptedKeyLength < MAX_INTLENGTH_SHORT );
	REQUIRES( auxInfo == NULL && auxInfoLength == 0 );

	if( cryptStatusError( algoIdInfoSize ) )
		return( algoIdInfoSize  );

	setMessageData( &msgData, keyID, CRYPT_MAX_HASHSIZE );
	status = krnlSendMessage( iCryptContext, IMESSAGE_GETATTRIBUTE_S, &msgData,
							  CRYPT_IATTRIBUTE_KEYID );
	if( cryptStatusError( status ) )
		return( status );
	writeSequence( stream, sizeofShortInteger( KEYTRANS_EX_VERSION ) +
				   ( int ) sizeofObject( msgData.length ) + algoIdInfoSize + \
				   ( int ) sizeofObject( encryptedKeyLength ) );
	writeShortInteger( stream, KEYTRANS_EX_VERSION, DEFAULT_TAG );
	writeOctetString( stream, msgData.data, msgData.length, CTAG_KT_SKI );
	writeContextAlgoID( stream, iCryptContext, CRYPT_ALGO_NONE );
	return( writeOctetString( stream, encryptedKey, encryptedKeyLength, 
							  DEFAULT_TAG ) );
	}

#ifdef USE_PGP

/* Read/write PGP key transport data:

	PKE:
		byte	ctb = PGP_PACKET_PKE
		byte[]	length
		byte	version = PGP_VERSION_PGP2 or 3 (= OpenPGP, not the expected PGP3)
		byte[8]	keyID
		byte	PKC algo
		mpi(s)	encrypted session key */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int readPgpKeytrans( INOUT STREAM *stream, 
							INOUT QUERY_INFO *queryInfo )
	{
	const int startPos = stell( stream );
	int value, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( queryInfo, sizeof( QUERY_INFO ) ) );

	/* Make sure that the packet header is in order and check the packet
	   version.  For this packet type a version number of 3 denotes OpenPGP
	   whereas for signatures it denotes PGP 2.x, so we translate the value
	   that we return to the caller */
	status = getPgpPacketInfo( stream, queryInfo );
	if( cryptStatusError( status ) )
		return( status );
	value = sgetc( stream );
	if( value != PGP_VERSION_2 && value != 3 )
		return( CRYPT_ERROR_BADDATA );
	queryInfo->version = ( value == PGP_VERSION_2 ) ? \
						 PGP_VERSION_2 : PGP_VERSION_OPENPGP;

	/* Get the PGP key ID and algorithm */
	status = sread( stream, queryInfo->keyID, PGP_KEYID_SIZE );
	if( cryptStatusError( status ) )
		return( status );
	queryInfo->keyIDlength = PGP_KEYID_SIZE;
	status = readPgpAlgo( stream, &queryInfo->cryptAlgo, 
						  PGP_ALGOCLASS_PKCCRYPT );
	if( cryptStatusError( status ) )
		return( status );

	/* Read the RSA-encrypted key, recording the position and length of the 
	   raw RSA-encrypted integer value.  We have to be careful how we handle 
	   this because readInteger16Ubits() returns the canonicalised form of
	   the values (with leading zeroes truncated) so an stell() before the 
	   read doesn't necessarily represent the start of the payload:

		startPos	dataStart		 stell()
			|			|				|
			v			v <-- length -->v
		+---+-----------+---------------+
		|	|			|///////////////| Stream
		+---+-----------+---------------+ */
	if( queryInfo->cryptAlgo == CRYPT_ALGO_RSA )
		{
		status = readInteger16Ubits( stream, NULL, &queryInfo->dataLength,
									 MIN_PKCSIZE, CRYPT_MAX_PKCSIZE );
		if( cryptStatusError( status ) )
			return( status );
		queryInfo->dataStart = ( stell( stream ) - startPos ) - \
							   queryInfo->dataLength;
		}
	else
		{
		const int dataStartPos = stell( stream );
		int dummy;

		REQUIRES( queryInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL );

		/* Read the Elgamal-encrypted key, recording the position and
		   combined lengths of the MPI pair.  Again, we can't use the length
		   returned by readInteger16Ubits() to determine the overall size 
		   but have to calculate it from the position in the stream */
		status = readInteger16Ubits( stream, NULL, &dummy, MIN_PKCSIZE,
									 CRYPT_MAX_PKCSIZE );
		if( cryptStatusOK( status ) )
			status = readInteger16Ubits( stream, NULL, &dummy, MIN_PKCSIZE,
										 CRYPT_MAX_PKCSIZE );
		if( cryptStatusError( status ) )
			return( status );
		queryInfo->dataStart = dataStartPos - startPos;
		queryInfo->dataLength = stell( stream ) - dataStartPos;
		}

	return( CRYPT_OK );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
static int writePgpKeytrans( INOUT STREAM *stream,
							 IN_HANDLE const CRYPT_CONTEXT iCryptContext,
							 IN_BUFFER( encryptedKeyLength ) \
								const BYTE *encryptedKey, 
							 IN_LENGTH_SHORT_MIN( MIN_PKCSIZE ) \
								const int encryptedKeyLength,
							 STDC_UNUSED const void *auxInfo, 
							 STDC_UNUSED const int auxInfoLength )
	{
	CRYPT_ALGO_TYPE cryptAlgo;
	BYTE keyID[ PGP_KEYID_SIZE + 8 ];
	int pgpAlgo, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isReadPtr( encryptedKey, encryptedKeyLength ) );

	REQUIRES( isHandleRangeValid( iCryptContext ) );
	REQUIRES( encryptedKeyLength >= MIN_PKCSIZE && \
			  encryptedKeyLength < MAX_INTLENGTH_SHORT );
	REQUIRES( auxInfo == NULL && auxInfoLength == 0 );

	/* Get the key information */
	status = krnlSendMessage( iCryptContext, IMESSAGE_GETATTRIBUTE,
							  &cryptAlgo, CRYPT_CTXINFO_ALGO );
	if( cryptStatusOK( status ) )
		{
		MESSAGE_DATA msgData;

		setMessageData( &msgData, keyID, PGP_KEYID_SIZE );
		status = krnlSendMessage( iCryptContext, IMESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_IATTRIBUTE_KEYID_OPENPGP );
		}
	if( cryptStatusError( status ) )
		return( status );
	status = cryptlibToPgpAlgo( cryptAlgo, &pgpAlgo );
	ENSURES( cryptStatusOK( status ) );

	/* Write the PKE packet */
	pgpWritePacketHeader( stream, PGP_PACKET_PKE,
						  PGP_VERSION_SIZE + PGP_KEYID_SIZE + PGP_ALGOID_SIZE + \
						  ( ( cryptAlgo == CRYPT_ALGO_RSA ) ? \
							sizeofInteger16U( encryptedKeyLength ) : \
							encryptedKeyLength ) );
	sputc( stream, 3 );		/* Version = 3 (OpenPGP) */
	swrite( stream, keyID, PGP_KEYID_SIZE );
	sputc( stream, pgpAlgo );
	return( ( cryptAlgo == CRYPT_ALGO_RSA ) ? \
			writeInteger16Ubits( stream, encryptedKey, encryptedKeyLength ) :
			swrite( stream, encryptedKey, encryptedKeyLength ) );
	}
#endif /* USE_PGP */

/****************************************************************************
*																			*
*					Key Exchange Read/Write Access Function					*
*																			*
****************************************************************************/

typedef struct {
	const KEYEX_TYPE type;
	const READKEYTRANS_FUNCTION function;
	} KEYTRANS_READ_INFO;
static const KEYTRANS_READ_INFO keytransReadTable[] = {
	{ KEYEX_CMS, readCmsKeytrans },
	{ KEYEX_CRYPTLIB, readCryptlibKeytrans },
#ifdef USE_PGP
	{ KEYEX_PGP, readPgpKeytrans },
#endif /* USE_PGP */
	{ KEYEX_NONE, NULL }, { KEYEX_NONE, NULL }
	};

typedef struct {
	const KEYEX_TYPE type;
	const WRITEKEYTRANS_FUNCTION function;
	} KEYTRANS_WRITE_INFO;
static const KEYTRANS_WRITE_INFO keytransWriteTable[] = {
	{ KEYEX_CMS, writeCmsKeytrans },
	{ KEYEX_CRYPTLIB, writeCryptlibKeytrans },
#ifdef USE_PGP
	{ KEYEX_PGP, writePgpKeytrans },
#endif /* USE_PGP */
	{ KEYEX_NONE, NULL }, { KEYEX_NONE, NULL }
	};

typedef struct {
	const KEYEX_TYPE type;
	const READKEK_FUNCTION function;
	} KEK_READ_INFO;
static const KEK_READ_INFO kekReadTable[] = {
	{ KEYEX_CMS, readCryptlibKek },
	{ KEYEX_CRYPTLIB, readCryptlibKek },
#ifdef USE_PGP
	{ KEYEX_PGP, readPgpKek },
#endif /* USE_PGP */
	{ KEYEX_NONE, NULL }, { KEYEX_NONE, NULL }
	};

typedef struct {
	const KEYEX_TYPE type;
	const WRITEKEK_FUNCTION function;
	} KEK_WRITE_INFO;
static const KEK_WRITE_INFO kekWriteTable[] = {
	{ KEYEX_CMS, writeCryptlibKek },
	{ KEYEX_CRYPTLIB, writeCryptlibKek },
#ifdef USE_PGP
	{ KEYEX_PGP, writePgpKek },
#endif /* USE_PGP */
	{ KEYEX_NONE, NULL }, { KEYEX_NONE, NULL }
	};

CHECK_RETVAL_PTR \
READKEYTRANS_FUNCTION getReadKeytransFunction( IN_ENUM( KEYEX ) \
												const KEYEX_TYPE keyexType )
	{
	int i;

	REQUIRES_N( keyexType > KEYEX_NONE && keyexType < KEYEX_LAST );

	for( i = 0; 
		 keytransReadTable[ i ].type != KEYEX_NONE && \
			i < FAILSAFE_ARRAYSIZE( keytransReadTable, KEYTRANS_READ_INFO ); 
		 i++ )
		{
		if( keytransReadTable[ i ].type == keyexType )
			return( keytransReadTable[ i ].function );
		}
	ENSURES_N( i < FAILSAFE_ARRAYSIZE( keytransReadTable, KEYTRANS_READ_INFO ) );

	return( NULL );
	}
CHECK_RETVAL_PTR \
WRITEKEYTRANS_FUNCTION getWriteKeytransFunction( IN_ENUM( KEYEX ) \
													const KEYEX_TYPE keyexType )
	{
	int i;

	REQUIRES_N( keyexType > KEYEX_NONE && keyexType < KEYEX_LAST );

	for( i = 0; 
		 keytransWriteTable[ i ].type != KEYEX_NONE && \
			i < FAILSAFE_ARRAYSIZE( keytransWriteTable, KEYTRANS_WRITE_INFO ); 
		 i++ )
		{
		if( keytransWriteTable[ i ].type == keyexType )
			return( keytransWriteTable[ i ].function );
		}
	ENSURES_N( i < FAILSAFE_ARRAYSIZE( keytransWriteTable, KEYTRANS_WRITE_INFO ) );

	return( NULL );
	}
CHECK_RETVAL_PTR \
READKEK_FUNCTION getReadKekFunction( IN_ENUM( KEYEX ) \
										const KEYEX_TYPE keyexType )
	{
	int i;

	REQUIRES_N( keyexType > KEYEX_NONE && keyexType < KEYEX_LAST );

	for( i = 0; 
		 kekReadTable[ i ].type != KEYEX_NONE && \
			i < FAILSAFE_ARRAYSIZE( kekReadTable, KEK_READ_INFO ); 
		 i++ )
		{
		if( kekReadTable[ i ].type == keyexType )
			return( kekReadTable[ i ].function );
		}
	ENSURES_N( i < FAILSAFE_ARRAYSIZE( kekReadTable, KEK_READ_INFO ) );
		
	return( NULL );
	}
CHECK_RETVAL_PTR \
WRITEKEK_FUNCTION getWriteKekFunction( IN_ENUM( KEYEX ) \
										const KEYEX_TYPE keyexType )
	{
	int i;

	REQUIRES_N( keyexType > KEYEX_NONE && keyexType < KEYEX_LAST );

	for( i = 0; 
		 kekWriteTable[ i ].type != KEYEX_NONE && \
			i < FAILSAFE_ARRAYSIZE( kekWriteTable, KEK_WRITE_INFO ); 
		 i++ )
		{
		if( kekWriteTable[ i ].type == keyexType )
			return( kekWriteTable[ i ].function );
		}
	ENSURES_N( i < FAILSAFE_ARRAYSIZE( kekWriteTable, KEK_WRITE_INFO ) );

	return( NULL );
	}

⌨️ 快捷键说明

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