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

📄 pgppublickey.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	pgpPublicKey.c
	
	Copyright (C) 1997 Network Associates Inc. and affiliated companies.
	All rights reserved.

	$Id: pgpPublicKey.c,v 1.18 1999/03/10 02:54:43 heller Exp $
____________________________________________________________________________*/
#include "pgpConfig.h"
#include <string.h>

#include "pgpPublicKey.h"
#include "pgpHash.h"
#include "pgpMem.h"
#include "pgpErrors.h"
#include "pgpContext.h"
#include "pgpHashPriv.h"
#include "pgpUtilitiesPriv.h"
#include "pgpKDBInt.h"
#include "pgpPubKey.h"
#include "pgpKeyMisc.h"
#include "pgpOptionListPriv.h"

#define PGPValidatePublicKey( pkref )	\
	PGPValidateParam( pgpPublicKeyIsValid( pkref ) );
#define PGPValidatePrivateKey( pkref )	\
	PGPValidateParam( pgpPrivateKeyIsValid( pkref ) );
#define PGPValidateMessageFormat( messageFormat ) \
	PGPValidateParam( pgpMessageFormatIsValid( messageFormat ) );
	
#define elemsof(x) ((unsigned)(sizeof(x)/sizeof(*x)))

struct PGPPublicKeyContext
{
#define kPublicKeyMagic				0x58210770
	PGPUInt32						magic;
	PGPContextRef					context;
	PGPKeyRef						key;
	PGPPublicKeyMessageFormat		format;
	PGPPubKey						*enckey;
	PGPPubKey						*signkey;
};

struct PGPPrivateKeyContext
{
#define kPrivateKeyMagic			0x58249779
	PGPUInt32						magic;
	PGPContextRef					context;
	PGPKeyRef						key;
	PGPPublicKeyMessageFormat		format;
	PGPSecKey						*enckey;
	PGPSecKey						*signkey;
};


	static PGPBoolean
pgpPublicKeyIsValid( const PGPPublicKeyContext * ref)
{
	PGPBoolean	valid	= FALSE;
	
	valid	= IsntNull( ref ) && ref->magic	 == kPublicKeyMagic;
	
	return( valid );
}

	static PGPBoolean
pgpPrivateKeyIsValid( const PGPPrivateKeyContext * ref)
{
	PGPBoolean	valid	= FALSE;
	
	valid	= IsntNull( ref ) && ref->magic	 == kPrivateKeyMagic;
	
	return( valid );
}

	static PGPBoolean
pgpMessageFormatIsValid( PGPPublicKeyMessageFormat messageFormat )
{
	PGPBoolean	valid	= FALSE;
	
	valid = (messageFormat == kPGPPublicKeyMessageFormat_PGP) ||
			(messageFormat == kPGPPublicKeyMessageFormat_PKCS1) ||
		    (messageFormat == kPGPPublicKeyMessageFormat_IKE) ||
			(messageFormat == kPGPPublicKeyMessageFormat_X509);
	
	return( valid );
}


PGPError		sSetupPubkey( PGPPublicKeyContextRef ref );
PGPError		sSetupPrivkey( PGPPrivateKeyContextRef ref,
							   char const *passphrase,
							   PGPSize passphraseLength,
							   PGPBoolean hashedPhrase );



/*____________________________________________________________________________
	Exported routines, public key operations
____________________________________________________________________________*/

	PGPError
PGPNewPublicKeyContext(
	PGPKeyRef					publicKeyRef,
	PGPPublicKeyMessageFormat	messageFormat,
	PGPPublicKeyContextRef *	outRef )
{
	PGPPublicKeyContextRef		newRef	= NULL;
	PGPContextRef				context;
	PGPError					err	= kPGPError_NoErr;
	
	PGPValidatePtr( outRef );
	*outRef	= NULL;
	PGPValidateKey( publicKeyRef );
	PGPValidateMessageFormat( messageFormat );
	
	context = PGPGetKeyContext( publicKeyRef );

	newRef	= (PGPPublicKeyContextRef) pgpContextMemAlloc( context,
									sizeof( *newRef ),
									kPGPMemoryMgrFlags_Clear );
			
	if ( IsntNull( newRef ) )
	{
		newRef->magic						= kPublicKeyMagic;
		newRef->context						= context;
		newRef->key							= publicKeyRef;
		newRef->format						= messageFormat;

		err = sSetupPubkey( newRef );

		if( IsPGPError( err ) )
		{
			pgpContextMemFree( context, newRef );
			newRef = NULL;
		}
	}
	else
	{
		err	= kPGPError_OutOfMemory;
	}
	
	*outRef	= newRef;
	return( err );
}



/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError 
PGPFreePublicKeyContext( PGPPublicKeyContextRef ref )
{
	PGPError		err	= kPGPError_NoErr;
	PGPContextRef	context	= NULL;
	
	PGPValidatePublicKey( ref );

	context	= ref->context;
	
	if( IsntNull( ref->enckey ) )
		pgpPubKeyDestroy( ref->enckey );
	if( IsntNull( ref->signkey ) )
		pgpPubKeyDestroy( ref->signkey );
	
	pgpClearMemory( ref, sizeof( *ref ) );
	pgpContextMemFree( context, ref );
	
	return( err );
}



/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError
PGPPublicKeyEncrypt(
	PGPPublicKeyContextRef	ref,
	const void *			in,
	PGPSize					inSize,
	void *					out,
	PGPSize *				outSize)
{
	PGPRandomContext *			randomContext;
	PGPSize						lOutSize;
	PGPError					err	= kPGPError_NoErr;
	
	if( IsntNull( outSize ) )
	{
		PGPValidatePtr( outSize );
		*outSize = 0;
	}
	PGPValidatePtr( out );
	PGPValidatePublicKey( ref );
	PGPValidatePtr( in );
	PGPValidateParam( inSize != 0 );

	if( IsNull( ref->enckey ) )
		return kPGPError_FeatureNotAvailable;

	randomContext = pgpContextGetX9_17RandomContext( ref->context );

	err = pgpPubKeyEncrypt( ref->enckey, (const PGPByte *) in, inSize,
							(PGPByte *) out, &lOutSize, randomContext,
							ref->format );

	if( IsntPGPError( err )  && IsntNull( outSize ) )
	{
		*outSize = lOutSize;
	}

	return( err );
}


/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError
PGPPublicKeyVerifySignature(
	PGPPublicKeyContextRef		ref,
	PGPHashContextRef			hashContext,
	const void *				signature,
	PGPSize						signatureSize)
{
	PGPError					err	= kPGPError_NoErr;
	PGPHashVTBL const *			hashVTBL;
	PGPSize						hashSize;
	PGPByte						hashData[100];
	PGPInt32					rslt;
	
	PGPValidatePublicKey( ref );
	PGPValidatePtr( hashContext );
	PGPValidatePtr( signature );
	PGPValidateParam( signatureSize != 0 );

	if( IsNull( ref->signkey ) )
		return kPGPError_FeatureNotAvailable;

	/* Hash too big for our array? */
	PGPGetHashSize( hashContext, &hashSize );
	if( hashSize > sizeof(hashData) )
	{
		PGPFreeHashContext( hashContext );
		return kPGPError_BadParams;
	}

	hashVTBL = pgpHashGetVTBL( hashContext );
	PGPFinalizeHash( hashContext, hashData );

	/* Do the verification */
	rslt = pgpPubKeyVerify( ref->signkey, (const PGPByte *) signature,
							signatureSize, hashVTBL, hashData, ref->format );

	PGPFreeHashContext( hashContext );

	if( rslt != 1 )
	{
		err = kPGPError_BadSignature;
	}

	return( err );
}


/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError
PGPPublicKeyVerifyRaw(
	PGPPublicKeyContextRef		ref,
	const void *				signedData,
	PGPSize						signedDataSize,
	const void *				signature,
	PGPSize						signatureSize)
{
	PGPError					err	= kPGPError_NoErr;
	PGPHashVTBL					dummyVTBL;
	PGPInt32					rslt;
	
	PGPValidatePublicKey( ref );
	PGPValidatePtr( signedData );
	PGPValidateParam( signedDataSize != 0 );
	/* Raw mode supported only for PKCS sigs */
	if( ref->format != 	kPGPPublicKeyMessageFormat_PKCS1 &&
		ref->format != 	kPGPPublicKeyMessageFormat_X509 &&
		ref->format != 	kPGPPublicKeyMessageFormat_IKE ) {
		return kPGPError_BadParams;
	}
	PGPValidatePtr( signature );
	PGPValidateParam( signatureSize != 0 );

	if( IsNull( ref->signkey ) )
		return kPGPError_FeatureNotAvailable;

	/* Set up value for hash size used by signature function */
	pgpClearMemory( &dummyVTBL, sizeof(dummyVTBL) );
	dummyVTBL.hashsize = signedDataSize;

	/* Do the verification */
	rslt = pgpPubKeyVerify( ref->signkey, (const PGPByte *) signature,
							signatureSize, &dummyVTBL,
							(const PGPByte *)signedData, ref->format );

	if( rslt != 1 )
	{
		err = kPGPError_BadSignature;
	}

	return( err );
}


/*____________________________________________________________________________
If we have an encrypt-only or sign only key, we return zeros for the
one(s) which we don't support.
____________________________________________________________________________*/
	PGPError
PGPGetPublicKeyOperationSizes(
	PGPPublicKeyContextRef	ref,
	PGPSize *				maxDecryptedBufferSize,
	PGPSize *				maxEncryptedBufferSize,
	PGPSize *				maxSignatureSize )
{
	PGPValidatePublicKey( ref );
	if( IsntNull( maxDecryptedBufferSize ) )
		PGPValidatePtr( maxDecryptedBufferSize );
	if( IsntNull( maxEncryptedBufferSize ) )
		PGPValidatePtr( maxEncryptedBufferSize );
	if( IsntNull( maxSignatureSize ) )
		PGPValidatePtr( maxSignatureSize );
	
	if( IsntNull( maxEncryptedBufferSize ) )
	{
		if( IsntNull( ref->enckey ) ) {
			*maxEncryptedBufferSize = pgpPubKeyMaxesk( ref->enckey,
													   ref->format );
		} else {
			*maxEncryptedBufferSize = 0;
		}
	}

	if( IsntNull( maxDecryptedBufferSize ) )
	{
		if( IsntNull( ref->enckey ) )
			*maxDecryptedBufferSize = pgpPubKeyMaxdecrypted( ref->enckey,
															 ref->format );
		else
			*maxDecryptedBufferSize = 0;
	}

	if( IsntNull( maxSignatureSize ) )
	{
		if( IsntNull( ref->signkey ) )
			*maxSignatureSize = pgpPubKeyMaxsig( ref->signkey, ref->format );
		else
			*maxSignatureSize = 0;
	}
	return kPGPError_NoErr;
}



/*____________________________________________________________________________
	Exported routines, private key operations
____________________________________________________________________________*/


/* Internal function to create a new private key context */
	static PGPError
sNewPrivateKeyContext (
	PGPKeyRef					privateKeyRef,
	PGPPublicKeyMessageFormat	messageFormat,
	char const *				passphrase,
	PGPSize						passphraseLength,
	PGPBoolean					hashedPhrase,
	PGPPrivateKeyContextRef *	outRef )
	
{
	PGPPrivateKeyContextRef		newRef	= NULL;
	PGPContextRef				context;
	PGPError					err	= kPGPError_NoErr;
	
	context = PGPGetKeyContext( privateKeyRef );

	newRef	= (PGPPrivateKeyContextRef) pgpContextMemAlloc( context,
									sizeof( *newRef ),
									kPGPMemoryMgrFlags_Clear );
			
	if ( IsntNull( newRef ) )
	{
		newRef->magic						= kPrivateKeyMagic;
		newRef->context						= context;
		newRef->key							= privateKeyRef;
		newRef->format						= messageFormat;

		err = sSetupPrivkey( newRef, passphrase, passphraseLength,
							 hashedPhrase );

		if( IsPGPError( err ) )
		{
			pgpContextMemFree( context, newRef );
			newRef = NULL;
		}
	}
	else
	{
		err	= kPGPError_OutOfMemory;
	}
	
	*outRef	= newRef;
	return( err );
}



static const PGPOptionType privctxOptionSet[] = {
	 kPGPOptionType_Passphrase,
	 kPGPOptionType_Passkey,
};


	static PGPError
pgpNewPrivateKeyContextInternal (
	PGPKeyRef					privateKeyRef,
	PGPPublicKeyMessageFormat	messageFormat,
	PGPPrivateKeyContextRef *	outRef,
	PGPOptionListRef			optionList
	)
{
	char *						passphrase;
	PGPSize						passphraseLength;
	PGPBoolean					hashedPhrase = FALSE;
	PGPError					err = kPGPError_NoErr;

	if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
					privctxOptionSet, elemsof( privctxOptionSet ) ) ) )
		return err;

	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						 kPGPOptionType_Passphrase, FALSE,
						 "%p%l", &passphrase, &passphraseLength ) ) )
		goto error;
	if (IsNull( passphrase )) {
		hashedPhrase = TRUE;
		if( IsPGPError( err = pgpFindOptionArgs( optionList,
							kPGPOptionType_Passkey, FALSE,
							"%p%l", &passphrase, &passphraseLength ) ) )
			goto error;
	}

	err = sNewPrivateKeyContext( privateKeyRef, messageFormat, passphrase,

⌨️ 快捷键说明

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