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

📄 pgppublickey.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	$Id: pgpPublicKey.c,v 1.20 2002/08/06 20:11:04 dallen Exp $
____________________________________________________________________________*/
#include "pgpConfig.h"
#include <string.h>

#include "pgpPublicKey.h"
#include "pgpHash.h"
#include "pgpMem.h"
#include "pgpPFLPriv.h"
#include "pgpErrors.h"
#include "pgpContext.h"
#include "pgpKeyPriv.h"
#include "pgpHashPriv.h"
#include "pgpUtilitiesPriv.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;
	PGPPublicKeyMessageFormat		format;
	PGPKeyDBObjRef					key;
	PGPBoolean						keyIsSubkey;
	PGPBoolean						canVerify;
	PGPBoolean						canEncrypt;
};

struct PGPPrivateKeyContext
{
#define kPrivateKeyMagic			0x58249779
	PGPUInt32						magic;
	PGPContextRef					context;
	PGPKeyDBObjRef					key;
	PGPPublicKeyMessageFormat		format;
	PGPBoolean						keyIsSubkey;
	PGPBoolean						canSign;
	PGPBoolean						canDecrypt;
	PGPByte *						passphrase;
	PGPSize							passphraseLength;
	PGPBoolean						hashedPhrase;
};


	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,
							   PGPUInt32 cacheTimeOut, PGPBoolean cacheGlobal);



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

	PGPError
PGPNewPublicKeyContext(
	PGPKeyDBObjRef				publicKeyRef,
	PGPPublicKeyMessageFormat	messageFormat,
	PGPPublicKeyContextRef *	outRef )
{
	PGPPublicKeyContextRef		newRef	= NULL;
	PGPContextRef				context;
	PGPError					err	= kPGPError_NoErr;
	
	PGPValidatePtr( outRef );
	*outRef	= NULL;
	if( !OBJISKEY( publicKeyRef ) )
		return kPGPError_BadParams;
	PGPValidateMessageFormat( messageFormat );
	
	pgpEnterPGPErrorFunction();

	context = PGPPeekKeyDBObjContext( 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 );

	pgpEnterPGPErrorFunction();

	context	= ref->context;
	
	pgpClearMemory( ref, sizeof( *ref ) );
	pgpContextMemFree( context, ref );
	
	return( err );
}



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

	pgpEnterPGPErrorFunction();

	if( !ref->canEncrypt )
		return kPGPError_FeatureNotAvailable;

	err = pgpKeyEncrypt( ref->key, (const PGPByte *) in, inSize,
							ref->format, &outbuf, &lOutSize );

	if( IsntPGPError( err ) )
	{
		pgpCopyMemory( outbuf, (PGPByte *)out, lOutSize );
		PGPFreeData( outbuf );
		if( 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 );

	pgpEnterPGPErrorFunction();

	if( !ref->canVerify )
		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 = pgpKeyVerify( ref->key, (const PGPByte *) signature,
						 signatureSize, hashVTBL->algorithm,
						 hashData, hashVTBL->hashsize, 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;
	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 );

	pgpEnterPGPErrorFunction();

	if( !ref->canVerify )
		return kPGPError_FeatureNotAvailable;

	/* Do the verification */
	rslt = pgpKeyVerify( ref->key, (const PGPByte *) signature,
						 signatureSize, (PGPHashAlgorithm)0,
						 (const PGPByte *)signedData, signedDataSize,
						 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 )
{
	PGPUInt32				maxenc;
	PGPUInt32				maxdec;
	PGPUInt32				maxsig;

	PGPValidatePublicKey( ref );

	if( IsntNull( maxDecryptedBufferSize ) )
		PGPValidatePtr( maxDecryptedBufferSize );
	if( IsntNull( maxEncryptedBufferSize ) )
		PGPValidatePtr( maxEncryptedBufferSize );
	if( IsntNull( maxSignatureSize ) )
		PGPValidatePtr( maxSignatureSize );
	
	pgpEnterPGPErrorFunction();

	if( IsntNull( maxEncryptedBufferSize ) )
		*maxEncryptedBufferSize = 0;
	if( IsntNull( maxDecryptedBufferSize ) )
		*maxDecryptedBufferSize = 0;
	if( IsntNull( maxSignatureSize ) )
		*maxSignatureSize = 0;

	if( IsntNull( maxEncryptedBufferSize ) ||
		IsntNull( maxDecryptedBufferSize ) ||
		IsntNull( maxSignatureSize ) )
	{
		pgpKeyMaxSizes( ref->key,
						(IsntNull(maxEncryptedBufferSize) ? &maxenc : NULL),
						(IsntNull(maxDecryptedBufferSize) ? &maxdec : NULL),
						(IsntNull(maxSignatureSize) ? &maxsig : NULL),
						ref->format );
		if( IsntNull( maxEncryptedBufferSize ) )
			*maxEncryptedBufferSize = maxenc;
		if( IsntNull( maxDecryptedBufferSize ) )
			*maxDecryptedBufferSize = maxdec;
		if( IsntNull( maxSignatureSize ) )
			*maxSignatureSize = maxsig;
	}

	return kPGPError_NoErr;
}



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


/* Internal function to create a new private key context */
	static PGPError
sNewPrivateKeyContext (
	PGPKeyDBObjRef				privateKeyRef,
	PGPPublicKeyMessageFormat	messageFormat,
	char const *				passphrase,
	PGPSize						passphraseLength,
	PGPBoolean					hashedPhrase,
	PGPUInt32					cacheTimeOut,
	PGPBoolean					cacheGlobal,
	PGPPrivateKeyContextRef *	outRef )
	
{
	PGPPrivateKeyContextRef		newRef	= NULL;
	PGPContextRef				context;
	PGPError					err	= kPGPError_NoErr;
	
	context = PGPPeekKeyDBObjContext( 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, cacheTimeOut, cacheGlobal );

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



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


	static PGPError
pgpNewPrivateKeyContextInternal (
	PGPKeyDBObjRef				privateKeyRef,
	PGPPublicKeyMessageFormat	messageFormat,
	PGPPrivateKeyContextRef *	outRef,
	PGPOptionListRef			optionList
	)
{
	char *						passphrase;

⌨️ 快捷键说明

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