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