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