📄 pgppublickey.c
字号:
/*____________________________________________________________________________
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 + -