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

📄 pgp.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 3 页
字号:
	BYTE iD[ CRYPT_MAX_HASHSIZE + 8 ];
	BOOLEAN privkeyPresent;
	char label[ CRYPT_MAX_TEXTSIZE + 1 + 8 ];
	int iDsize = DUMMY_INIT, status;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );
	assert( ( itemType == KEYMGMT_ITEM_PUBLICKEY && \
			  password == NULL && passwordLength == 0 ) || \
			( itemType == KEYMGMT_ITEM_PRIVATEKEY && \
			  isReadPtr( password, passwordLength ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_FILE && \
			  ( keysetInfoPtr->subType == KEYSET_SUBTYPE_PGP_PUBLIC || 
				keysetInfoPtr->subType == KEYSET_SUBTYPE_PGP_PRIVATE ) );
	REQUIRES( isHandleRangeValid( cryptHandle ) );
	REQUIRES( itemType == KEYMGMT_ITEM_PUBLICKEY || \
			  itemType == KEYMGMT_ITEM_PRIVATEKEY );
	REQUIRES( ( password == NULL && passwordLength == 0 ) || \
			  ( password != NULL && \
				passwordLength >= MIN_NAME_LENGTH && \
				passwordLength < MAX_ATTRIBUTE_SIZE ) );
	REQUIRES( ( itemType == KEYMGMT_ITEM_PUBLICKEY && \
				password == NULL && passwordLength == 0 ) || \
			  ( itemType == KEYMGMT_ITEM_PRIVATEKEY && \
				password != NULL && passwordLength != 0 ) );
	REQUIRES( flags == KEYMGMT_FLAG_NONE );

	/* Check the object and extract ID information from it */
	status = krnlSendMessage( cryptHandle, IMESSAGE_CHECK, NULL,
							  MESSAGE_CHECK_PKC );
	if( cryptStatusOK( status ) )
		{
		status = krnlSendMessage( cryptHandle, IMESSAGE_GETATTRIBUTE,
								  &cryptAlgo, CRYPT_CTXINFO_ALGO );
		if( cryptStatusOK( status ) && cryptAlgo != CRYPT_ALGO_RSA )
			{
			/* For now we can only store RSA keys because of the peculiar
			   properties of PGP DLP keys, which are actually two keys
			   with entirely different semantics and attributes but are
			   nevertheless occasionally treated as a single key by PGP */
			status = CRYPT_ARGERROR_NUM1;
			}
		}
	if( cryptStatusOK( status ) )
		{
		setMessageData( &msgData, iD, CRYPT_MAX_HASHSIZE );
		status = krnlSendMessage( cryptHandle, IMESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_IATTRIBUTE_KEYID );
		if( cryptStatusOK( status ) )
			iDsize = msgData.length;
		}
	if( cryptStatusError( status ) )
		{
		return( ( status == CRYPT_ARGERROR_OBJECT ) ? \
				CRYPT_ARGERROR_NUM1 : status );
		}
	privkeyPresent = cryptStatusOK( \
			krnlSendMessage( cryptHandle, IMESSAGE_CHECK, NULL,
							 MESSAGE_CHECK_PKC_PRIVATE ) ) ? TRUE : FALSE;

	/* If we're adding a private key make sure that there's a context and a
	   password present.  Conversely if we're adding a public key make sure 
	   that there's no password present.  The password-check has already 
	   been performed by the kernel but we perform a second check here just 
	   to be safe.  The private-key check can't be performed by the kernel 
	   since it doesn't know the difference between public- and private-key 
	   contexts */
	switch( itemType )
		{
		case KEYMGMT_ITEM_PUBLICKEY:
			if( password != NULL )
				return( CRYPT_ARGERROR_STR1 );
			break;

		case KEYMGMT_ITEM_PRIVATEKEY:
			if( !privkeyPresent )
				{
				retExtArg( CRYPT_ARGERROR_NUM1, 
						   ( CRYPT_ARGERROR_NUM1, KEYSET_ERRINFO, 
							 "Item being added doesn't contain a private "
							 "key" ) );
				}
			if( password == NULL )
				return( CRYPT_ARGERROR_STR1 );
			break;
		
		default:
			retIntError();
		}

	/* Find out where we can add data and what needs to be added.  At the 
	   moment we only allow atomic adds since the semantics of PGP's dual 
	   keys, with assorted optional attributes attached to one or both keys 
	   can't easily be handled using a straightforward add */
	pgpInfoPtr = findEntry( keysetInfoPtr->keyData, MAX_PGP_OBJECTS, 
							CRYPT_IKEYID_KEYID, iD,  iDsize, 
							KEYMGMT_FLAG_NONE, NULL );
	if( pgpInfoPtr != NULL )
		{
		retExt( CRYPT_ERROR_DUPLICATE, 
				( CRYPT_ERROR_DUPLICATE, KEYSET_ERRINFO, 
				  "Item is already present in keyset" ) );
		}

	/* Make sure that the label of what we're adding doesn't duplicate the 
	   label of an existing object */
	if( privkeyPresent )
		{
		setMessageData( &msgData, label, CRYPT_MAX_TEXTSIZE );
		status = krnlSendMessage( cryptHandle, IMESSAGE_GETATTRIBUTE_S,
								  &msgData, CRYPT_CTXINFO_LABEL );
		if( cryptStatusError( status ) )
			return( status );
		if( findEntry( keysetInfoPtr->keyData, MAX_PGP_OBJECTS, 
					   CRYPT_KEYID_NAME, msgData.data, msgData.length, 
					   KEYMGMT_FLAG_NONE, NULL ) != NULL )
			{
			retExt( CRYPT_ERROR_DUPLICATE, 
					( CRYPT_ERROR_DUPLICATE, KEYSET_ERRINFO, 
					  "Item with this label is already present" ) );
			}
		}

	/* Find out where we can add the new key data */
	pgpInfoPtr = findFreeEntry( pgpInfo, MAX_PGP_OBJECTS );
	if( pgpInfoPtr == NULL )
		{
		retExt( CRYPT_ERROR_OVERFLOW, 
				( CRYPT_ERROR_OVERFLOW, KEYSET_ERRINFO, 
				  "No more room in keyset to add this item" ) );
		}

	/* Not implemented yet */
	return( CRYPT_ERROR_NOTAVAIL );
	}

/****************************************************************************
*																			*
*								Init/Shutdown Functions						*
*																			*
****************************************************************************/

/* Shutdown functions */

RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int shutdownFunction( INOUT KEYSET_INFO *keysetInfoPtr )
	{
	PGP_INFO *pgpInfo = ( PGP_INFO * ) keysetInfoPtr->keyData;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_FILE && \
			  ( keysetInfoPtr->subType == KEYSET_SUBTYPE_PGP_PUBLIC || 
				keysetInfoPtr->subType == KEYSET_SUBTYPE_PGP_PRIVATE ) );

	/* If there's no PGP information data cached, we're done */
	if( pgpInfo == NULL )
		return( CRYPT_OK );

	/* Free the cached key information */
	if( keysetInfoPtr->subType == KEYSET_SUBTYPE_PGP_PRIVATE )
		{
		int i;

		for( i = 0; i < MAX_PGP_OBJECTS; i++ )
			pgpFreeEntry( &pgpInfo[ i ] );
		}
	else
		pgpFreeEntry( pgpInfo );
	clFree( "shutdownFunction", pgpInfo );
	keysetInfoPtr->keyData = NULL;
	keysetInfoPtr->keyDataSize = 0;

	return( CRYPT_OK );
	}

/* PGP public keyrings can be arbitrarily large so we don't try to do any
   preprocessing, all we do at this point is allocate the key information */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int initPublicFunction( INOUT KEYSET_INFO *keysetInfoPtr, 
							   STDC_UNUSED const char *name,
							   STDC_UNUSED const int nameLength,
							   IN_ENUM( CRYPT_KEYOPT ) \
								const CRYPT_KEYOPT_TYPE options )
	{
	PGP_INFO *pgpInfo;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_FILE && \
			  keysetInfoPtr->subType == KEYSET_SUBTYPE_PGP_PUBLIC );
	REQUIRES( name == NULL && nameLength == 0 );
	REQUIRES( options >= CRYPT_KEYOPT_NONE && options < CRYPT_KEYOPT_LAST );

	/* Allocate memory for the key information */
	if( ( pgpInfo = clAlloc( "initPublicFunction", \
							 sizeof( PGP_INFO ) ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	memset( pgpInfo, 0, sizeof( PGP_INFO ) );
	if( ( pgpInfo->keyData = clAlloc( "initPublicFunction", \
									  KEYRING_BUFSIZE ) ) == NULL )
		{
		clFree( "initPublicFunction", pgpInfo );
		return( CRYPT_ERROR_MEMORY );
		}
	pgpInfo->keyDataLen = KEYRING_BUFSIZE;
	keysetInfoPtr->keyData = pgpInfo;
	keysetInfoPtr->keyDataSize = sizeof( PGP_INFO );

	return( CRYPT_OK );
	}

/* A PGP private keyring can contain multiple keys and whatnot so when we
   open it we scan it and record various pieces of information about it that 
   we can use later when we need to access it */

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static int initPrivateFunction( INOUT KEYSET_INFO *keysetInfoPtr, 
								STDC_UNUSED const char *name,
								STDC_UNUSED const int nameLength,
								IN_ENUM( CRYPT_KEYOPT ) \
									const CRYPT_KEYOPT_TYPE options )
	{
	PGP_INFO *pgpInfo;
	int status;

	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_FILE && \
			  keysetInfoPtr->subType == KEYSET_SUBTYPE_PGP_PRIVATE );
	REQUIRES( name == NULL && nameLength == 0 );
	REQUIRES( options >= CRYPT_KEYOPT_NONE && options < CRYPT_KEYOPT_LAST );

	/* Allocate the PGP object information */
	if( ( pgpInfo = clAlloc( "initPrivateFunction", \
							 sizeof( PGP_INFO ) * MAX_PGP_OBJECTS ) ) == NULL )
		return( CRYPT_ERROR_MEMORY );
	memset( pgpInfo, 0, sizeof( PGP_INFO ) * MAX_PGP_OBJECTS );
	keysetInfoPtr->keyData = pgpInfo;
	keysetInfoPtr->keyDataSize = sizeof( PGP_INFO ) * MAX_PGP_OBJECTS;

	/* If this is a newly-created keyset, there's nothing left to do */
	if( options == CRYPT_KEYOPT_CREATE )
		return( CRYPT_OK );

	/* Read all of the keys in the keyring */
	status = pgpReadKeyring( &keysetInfoPtr->keysetFile->stream, pgpInfo, 
							 MAX_PGP_OBJECTS, NULL, NULL, KEYSET_ERRINFO );
	if( status == OK_SPECIAL )
		{
		/* We couldn't process one or more packets, make the keyset read-
		   only to ensure that the incomplete key data isn't written to 
		   disk */
		keysetInfoPtr->options = CRYPT_KEYOPT_READONLY;
		status = CRYPT_OK;
		}
	if( cryptStatusError( status ) )
		keysetInfoPtr->shutdownFunction( keysetInfoPtr );
	return( status );
	}

/****************************************************************************
*																			*
*							Keyset Access Routines							*
*																			*
****************************************************************************/

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int setAccessMethodPGPPublic( INOUT KEYSET_INFO *keysetInfoPtr )
	{
	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_FILE && \
			  ( keysetInfoPtr->subType == KEYSET_SUBTYPE_PGP_PUBLIC || 
				keysetInfoPtr->subType == KEYSET_SUBTYPE_PGP_PRIVATE ) );

	/* Set the access method pointers */
	keysetInfoPtr->initFunction = initPublicFunction;
	keysetInfoPtr->shutdownFunction = shutdownFunction;
	keysetInfoPtr->getItemFunction = getItemFunction;
	keysetInfoPtr->setItemFunction = setItemFunction;

	return( CRYPT_OK );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
int setAccessMethodPGPPrivate( INOUT KEYSET_INFO *keysetInfoPtr )
	{
	assert( isWritePtr( keysetInfoPtr, sizeof( KEYSET_INFO ) ) );

	REQUIRES( keysetInfoPtr->type == KEYSET_FILE && \
			  ( keysetInfoPtr->subType == KEYSET_SUBTYPE_PGP_PUBLIC || 
				keysetInfoPtr->subType == KEYSET_SUBTYPE_PGP_PRIVATE ) );

	/* Set the access method pointers */
	keysetInfoPtr->initFunction = initPrivateFunction;
	keysetInfoPtr->shutdownFunction = shutdownFunction;
	keysetInfoPtr->getItemFunction = getItemFunction;
	keysetInfoPtr->setItemFunction = setItemFunction;

	return( CRYPT_OK );
	}
#endif /* USE_PGPKEYS */

⌨️ 快捷键说明

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