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

📄 pgppublickey.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 2 页
字号:
	PGPSize						passphraseLength;
	PGPBoolean					hashedPhrase = FALSE;
	PGPUInt32					cacheTimeOut;
	PGPBoolean					cacheGlobal;
	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;
	}
	if( IsPGPError( err = pgpFindOptionArgs( optionList,
						kPGPOptionType_CachePassphrase, FALSE,
						"%d%b", &cacheTimeOut, &cacheGlobal ) ) )
		goto error;

	err = sNewPrivateKeyContext( privateKeyRef, messageFormat, passphrase,
								 passphraseLength, hashedPhrase, cacheTimeOut,
								 cacheGlobal, outRef );

error:

	return err;
}

/* Version of NewPrivateKeyContext which takes passphrase options */
	PGPError
PGPNewPrivateKeyContext(
	PGPKeyDBObjRef				privateKeyRef,
	PGPPublicKeyMessageFormat	messageFormat,
	PGPPrivateKeyContextRef *	outRef,
	PGPOptionListRef			firstOption,
	...
	)
{
	PGPError	error	= kPGPError_NoErr;
	
	PGPValidatePtr( outRef );
	*outRef	= NULL;
	if( !OBJISKEY( privateKeyRef ) )
		return kPGPError_BadParams;
	PGPValidateMessageFormat( messageFormat );

	pgpEnterPGPErrorFunction();

	{
		va_list				args;
		PGPContextRef		context;
		PGPOptionListRef	optionList;

		context = PGPPeekKeyDBObjContext( privateKeyRef );

		va_start( args, firstOption );
		optionList = pgpBuildOptionListArgs( context,
			FALSE, firstOption, args );

		error = pgpGetOptionListError( optionList );
		if( IsntPGPError( error ) )
		{
			error = pgpNewPrivateKeyContextInternal( privateKeyRef,
										messageFormat, outRef, optionList );
		}
		va_end( args );

		PGPFreeOptionList( optionList );
	}
	
	return( error );
}




/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError 
PGPFreePrivateKeyContext( PGPPrivateKeyContextRef ref )
{
	PGPError		err	= kPGPError_NoErr;
	PGPContextRef	context	= NULL;
	
	PGPValidatePrivateKey( ref );

	pgpEnterPGPErrorFunction();

	context	= ref->context;
	
	if( IsntNull( ref->passphrase ) )
	{
		pgpClearMemory( ref->passphrase, ref->passphraseLength );
		PGPFreeData( ref->passphrase );
	}
	
	pgpClearMemory( ref, sizeof( *ref ) );
	pgpContextMemFree( context, ref );
	
	return( err );
}



/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError
PGPPrivateKeyDecrypt(
	PGPPrivateKeyContextRef		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 );
	PGPValidatePrivateKey( ref );
	PGPValidatePtr( in );
	PGPValidateParam( inSize != 0 );

	pgpEnterPGPErrorFunction();

	if( !ref->canDecrypt )
		return kPGPError_FeatureNotAvailable;

	err = pgpKeyDecrypt( ref->key, ref->passphrase, ref->passphraseLength,
						 ref->hashedPhrase, 0, FALSE, (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
PGPPrivateKeySign(
	PGPPrivateKeyContextRef		ref,
	PGPHashContextRef			hashContext,
	void *						signature,
	PGPSize *					signatureSize)
{
	PGPHashVTBL const *			hashVTBL;
	PGPSize						hashSize;
	PGPByte						hashData[100];
	PGPByte *					sigbuf;
	PGPSize						lSignatureSize;
	PGPError					err	= kPGPError_NoErr;
	
	if( IsntNull( signatureSize ) )
	{
		PGPValidatePtr( signatureSize );
		*signatureSize = 0;
	}
	PGPValidatePrivateKey( ref );
	PGPValidatePtr( hashContext );
	PGPValidatePtr( signature );

	pgpEnterPGPErrorFunction();

	if( !ref->canSign )
		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 signature */
	err = pgpKeySign( ref->key, ref->passphrase, ref->passphraseLength,
					  ref->hashedPhrase, 0, FALSE, hashVTBL->algorithm,
					  hashData, hashVTBL->hashsize, ref->format, &sigbuf,
					  &lSignatureSize );

	PGPFreeHashContext( hashContext );

	if( IsntPGPError( err ) )
	{
		pgpCopyMemory( sigbuf, signature, lSignatureSize );
		PGPFreeData( sigbuf );
		if( IsntNull( signatureSize ) )
			*signatureSize = lSignatureSize;
	}

	return( err );
}


/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError
PGPPrivateKeySignRaw(
	PGPPrivateKeyContextRef		ref,
	const void *				signedData,
	PGPSize						signedDataSize,
	void *						signature,
	PGPSize *					signatureSize)
{
	PGPByte *					sigbuf;
	PGPSize						lSignatureSize;
	PGPError					err	= kPGPError_NoErr;
	
	if( IsntNull( signatureSize ) )
	{
		PGPValidatePtr( signatureSize );
		*signatureSize = 0;
	}
	PGPValidatePrivateKey( 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 );

	pgpEnterPGPErrorFunction();

	if( !ref->canSign )
		return kPGPError_FeatureNotAvailable;

	/* Do the signature */
	err = pgpKeySign( ref->key, ref->passphrase, ref->passphraseLength,
					  ref->hashedPhrase, 0, FALSE, (PGPHashAlgorithm)0,
					  (const PGPByte *) signedData, signedDataSize,
					  ref->format, &sigbuf, &lSignatureSize );

	if( IsntPGPError( err ) )
	{
		pgpCopyMemory( sigbuf, signature, lSignatureSize );
		PGPFreeData( sigbuf );
		if( IsntNull( signatureSize ) )
			*signatureSize = lSignatureSize;
	}

	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
PGPGetPrivateKeyOperationSizes(
	PGPPrivateKeyContextRef	ref,
	PGPSize *				maxDecryptedBufferSize,
	PGPSize *				maxEncryptedBufferSize,
	PGPSize *				maxSignatureSize )
{
	PGPUInt32				maxenc = 0;
	PGPUInt32				maxdec = 0;
	PGPUInt32				maxsig = 0;

	PGPValidatePrivateKey( ref );

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

	if( IsntNull( maxDecryptedBufferSize ) )
		*maxDecryptedBufferSize = 0;
	if( IsntNull( maxEncryptedBufferSize ) )
		*maxEncryptedBufferSize = 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;
}



/*____________________________________________________________________________
Given the size of a prime modulus in bits, this returns an appropriate
size for an exponent in bits, such that the work factor to find a
discrete log modulo the modulus is approximately equal to half the
length of the exponent.  This makes the exponent an appropriate size
for a subgroup in a discrete log signature scheme.  For encryption
schemes, where decryption attacks can be stealthy and undetected, we
use 3/2 times the returned exponent size.
____________________________________________________________________________*/

	PGPError
PGPDiscreteLogExponentBits(
	PGPUInt32				modulusBits,
	PGPUInt32			   *exponentBits )
{
	PGPValidatePtr( exponentBits );

	pgpEnterPGPErrorFunction();

	*exponentBits = pgpDiscreteLogExponentBits( modulusBits );

	return kPGPError_NoErr;
}


#if PRAGMA_MARK_SUPPORTED
#pragma mark --- Internal Routines ---
#endif






/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError
sSetupPubkey( PGPPublicKeyContextRef ref )
{
	PGPKeyDBObjRef		topkey;
	PGPInt32			keytype;
	PGPError			err = kPGPError_NoErr;

	pgpGetKeyDBObjNumber( ref->key, kPGPKeyDBObjProperty_ObjectType,
						  &keytype );
	ref->keyIsSubkey = keytype == kPGPKeyDBObjType_SubKey;
	topkey = PGPPeekKeyDBObjKey( ref->key );
	pgpGetKeyBoolean( topkey, kPGPKeyProperty_CanEncrypt, &ref->canEncrypt );
	pgpGetKeyBoolean( topkey, kPGPKeyProperty_CanVerify, &ref->canVerify );

	if( !ref->canEncrypt && !ref->canVerify )
		err = kPGPError_BadParams;

	return err;
}

/*____________________________________________________________________________
____________________________________________________________________________*/
	PGPError
sSetupPrivkey( PGPPrivateKeyContextRef ref, char const *passphrase,
	PGPSize passphraseLength, PGPBoolean hashedPhrase, PGPUInt32 cacheTimeOut,
	PGPBoolean cacheGlobal )
{
	PGPKeyDBObjRef		topkey;
	PGPInt32			keytype;
	PGPError			err = kPGPError_NoErr;

	pgpGetKeyDBObjNumber( ref->key, kPGPKeyDBObjProperty_ObjectType,
						  &keytype );
	ref->keyIsSubkey = keytype == kPGPKeyDBObjType_SubKey;
	topkey = PGPPeekKeyDBObjKey( ref->key );
	pgpGetKeyBoolean( topkey, kPGPKeyProperty_CanDecrypt, &ref->canDecrypt );
	pgpGetKeyBoolean( topkey, kPGPKeyProperty_CanSign, &ref->canSign );

	if( !ref->canDecrypt && !ref->canSign )
	{
		err = kPGPError_BadParams;
		goto error;
	}

	if( !pgpSecPassphraseOK( ref->key, (PGPByte *) passphrase,
							 passphraseLength, hashedPhrase, cacheTimeOut,
							 cacheGlobal ) )
	{
		err = kPGPError_BadPassphrase;
		goto error;
	}

	if( passphraseLength != 0 )
	{
		ref->passphrase = pgpContextMemAlloc( ref->context, passphraseLength,
											  0 );
		if( IsNull( ref->passphrase ) )
			return kPGPError_OutOfMemory;

		pgpCopyMemory( passphrase, ref->passphrase, passphraseLength );
		ref->passphraseLength = passphraseLength;
		ref->hashedPhrase = hashedPhrase;
	}

error:

	return err;
}




/*__Editor_settings____

	Local Variables:
	tab-width: 4
	End:
	vi: ts=4 sw=4
	vim: si
_____________________*/

⌨️ 快捷键说明

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