📄 pgpencode.c
字号:
bestalg = ( algInfo->oldkeys ? kPGPCipherAlgorithm_IDEA : kPGPCipherAlgorithm_3DES );
/* IDEA and 3DES must always be present */
pgpAssert (IsntNull( pgpCipherGetVTBL ( (PGPCipherAlgorithm)bestalg ) ) );
}
pgpAssert (algsOK != 0);
pgpAssert (IsntNull( pgpCipherGetVTBL ( (PGPCipherAlgorithm)bestalg ) ) );
/* Have choice in bestalg */
pgpenvSetInt (env, PGPENV_CIPHER, bestalg, PGPENV_PRI_FORCE);
error:
return err;
}
static PGPError
pgpCleanupPreferredAlgorithms (
PGPContextRef context,
PGPPreferredAlgs *algInfo
)
{
pgpContextMemFree (context, algInfo->votes);
pgpContextMemFree (context, algInfo->algok);
return kPGPError_NoErr;
}
/*********** Functions to set up data structures for pipeline *************/
/* Extract conventional encryption info from optionList */
static PGPError
pgpSetupConventionalEncryption(
PGPContextRef context,
PGPOptionListRef optionList,
PGPEventHandlerProcPtr func,
PGPUserValue userValue,
PGPConvKey **convkey
)
{
PGPOption op; /* Selected option from list */
PGPError err; /* Error return code */
PGPByte *passPhrase; /* Pass phrase for conv encr */
PGPSize passLength; /* Length of passPhrase */
(void)func;
(void)userValue;
/* Init return pointer */
pgpa( pgpaAddrValid( convkey, PGPConvKey * ) );
*convkey = NULL;
if( IsPGPError( err = pgpSearchOptionSingle( optionList,
kPGPOptionType_ConventionalEncrypt, &op ) ) )
goto error;
if( IsOp( op ) ) {
/* Conventional encryption */
if( IsPGPError( err = pgpSearchOptionSingle( op.subOptions,
kPGPOptionType_Passphrase, &op ) ) )
{
goto error;
}
if( IsntOp( op ) ) {
pgpDebugMsg( "no passphrase specified for conventional encrypt" );
err = kPGPError_MissingPassphrase;
goto error;
} else {
if( IsPGPError( err = pgpOptionPtrLength( &op,
( void ** )&passPhrase, &passLength ) ) )
goto error;
if ( passLength == 0 ) {
pgpDebugMsg( "passphrases of length 0 are "\
"illegal for conventional encryption" );
err = kPGPError_BadParams;
goto error;
}
}
if( IsNull( ( *convkey = (PGPConvKey *)pgpContextMemAlloc(
context, sizeof( PGPConvKey ),
0 ) ) ) ) {
err = kPGPError_OutOfMemory;
goto error;
}
(*convkey)->pass = NULL;
(*convkey)->next = NULL;
(*convkey)->stringToKey = 0;
(*convkey)->pass = (char *)pgpContextMemAlloc( context, passLength,
0 );
if( IsNull( (*convkey)->pass ) ) {
err = kPGPError_OutOfMemory;
goto error;
}
pgpCopyMemory( passPhrase, (char *)(*convkey)->pass, passLength );
(*convkey)->passlen = passLength;
}
return kPGPError_NoErr;
error:
if( IsntNull( *convkey ) ) {
pgpClearMemory( (*convkey)->pass, (*convkey)->passlen );
pgpContextMemFree( context, (char *)(*convkey)->pass );
pgpContextMemFree( context, *convkey );
}
return err;
}
/* Service routine for pgpSetupPublicKeyEncryption, to do checks for a
* single key, and append it to encryption key set */
static PGPError
pgpSetupEncryptionKeySet(
PGPContextRef context,
PGPOptionListRef optionList,
PGPKeyDBObj *key,
PGPValidity failValidity,
PGPValidity warnValidity,
PGPPreferredAlgs *preferredAlgs,
PGPKeySetRef *pubkeys,
PGPKeySetRef *warnKeys
)
{
PGPBoolean canEncrypt; /* Can key encrypt? */
PGPError err; /* Error return code */
if( IsNull( *warnKeys ) )
{
if( IsPGPError( err = PGPNewEmptyKeySet( PGPPeekKeyDBObjKeyDB(key),
warnKeys ) ) )
goto error;
}
if( IsPGPError( err = pgpCheckKeyValidity( context, optionList,
key, failValidity, warnValidity, *warnKeys,
NULL ) ) )
goto error;
if( IsPGPError( err = pgpCheckPreferredAlgorithms( preferredAlgs, key ) ) )
goto error;
if( IsPGPError( err = pgpGetKeyBoolean( key, kPGPKeyProperty_CanEncrypt,
&canEncrypt ) ) )
goto error;
if( !canEncrypt )
{
err = kPGPError_KeyUnusableForEncryption;
goto error;
}
if( IsNull( *pubkeys ) )
{
if( IsPGPError( err = PGPNewOneKeySet( key, pubkeys ) ) )
goto error;
} else {
if( IsPGPError( err = PGPAddKey( key, *pubkeys ) ) )
goto error;
}
return kPGPError_NoErr;
error:
return err;
}
/* Extract public key encryption info from optionList */
static PGPError
pgpSetupPublicKeyEncryption(
PGPContextRef context,
PGPOptionListRef optionList,
PGPEnv *env,
PGPKeySetRef *pubkeys
)
{
PGPOption op; /* Selected option from list */
PGPError err; /* Error return code */
PGPInt32 keyCount; /* Number of key we are doing */
PGPKeyDBObj *key; /* Key to encrypt to */
PGPKeyDBObj *obj; /* Child obj to encrypt to */
PGPKeySet *keySet; /* Keyset to encrypt to */
PGPKeyIter *keyIter; /* Iterator over keySet */
PGPValidity failValidity, /* Fail on keys less valid */
warnValidity; /* Warn on keys less valid */
PGPPreferredAlgs preferredAlgs; /* Preferred algorithm data */
PGPKeySet *warnKeys; /* Keys with warnable trusts */
/* Init return pointer */
pgpa( pgpaAddrValid( pubkeys, PGPKeySetRef ) );
*pubkeys = NULL;
warnKeys = NULL;
keyIter = NULL;
/* Initialize for loops below */
if( IsPGPError( err = pgpInitPreferredAlgorithms( context,
&preferredAlgs ) ) )
goto error;
if( IsPGPError( err = pgpGetMinValidity( optionList,
&failValidity, &warnValidity ) ) )
goto error;
/* Find any encryption KeyDBObjs */
keyCount = 0;
if( IsPGPError( err = pgpSearchOption( optionList,
kPGPOptionType_EncryptToKeyDBObj, keyCount, &op )))
goto error;
while( IsOp( op ) ) {
if( IsPGPError( err = pgpOptionPtr( &op, (void **)&obj ) ) )
goto error;
pgpa(pgpaPGPKeyDBObjValid(obj));
if( !pgpKeyDBObjIsValid(obj) ) {
pgpDebugMsg( "Error: invalid EncryptToKeyDBObj" );
err = kPGPError_BadParams;
goto error;
}
/* Move up to find nearest key or subkey */
key = obj;
while( pgpObjectType( key ) != RINGTYPE_KEY &&
pgpObjectType( key ) != RINGTYPE_SUBKEY )
key = key->up;
if( IsPGPError( err = pgpSetupEncryptionKeySet( context, optionList,
key, failValidity, warnValidity,
&preferredAlgs, pubkeys,
&warnKeys ) ) )
goto error;
if( IsPGPError( err = pgpSearchOption( optionList,
kPGPOptionType_EncryptToKeyDBObj, ++keyCount, &op )))
goto error;
}
/* Find any encryption keys specified as keysets */
keyCount = 0;
if( IsPGPError( err = pgpSearchOption( optionList,
kPGPOptionType_EncryptToKeySet, keyCount, &op ) ) )
goto error;
while( IsOp( op ) ) {
PGPUInt32 keySetCount;
if( IsPGPError( err = pgpOptionPtr( &op, (void **)&keySet ) ) )
goto error;
pgpa(pgpaPGPKeySetValid(keySet));
if( !pgpKeySetIsValid(keySet) ) {
pgpDebugMsg( "Error: invalid EncryptToKeySet keyset" );
err = kPGPError_BadParams;
goto error;
}
if( IsPGPError( err = PGPCountKeys( keySet, &keySetCount ) ) )
goto error;
if ( keySetCount < 1 ) {
pgpDebugMsg( "Error: empty EncryptToKeySet keyset" );
err = kPGPError_BadParams;
goto error;
}
if( IsPGPError( err = PGPNewKeyIterFromKeySet ( keySet, &keyIter ) ) )
goto error;
while( IsntPGPError( err = PGPKeyIterNextKeyDBObj( keyIter,
kPGPKeyDBObjType_Key, &key ) ) ) {
if( IsPGPError( err = pgpSetupEncryptionKeySet( context,
optionList, key,
failValidity, warnValidity,
&preferredAlgs, pubkeys,
&warnKeys ) ) )
goto error;
}
PGPFreeKeyIter( keyIter );
keyIter = NULL;
if( IsPGPError( err = pgpSearchOption( optionList,
kPGPOptionType_EncryptToKeySet, ++keyCount, &op ) ) )
goto error;
}
if( IsntNull( warnKeys ) ) {
PGPUInt32 numKeys;
if ( IsPGPError( PGPCountKeys( warnKeys, &numKeys ) ) )
goto error;
if( numKeys > 0 ) {
if( IsPGPError( pgpWarnUser( context, optionList,
kPGPError_KeyInvalid, warnKeys ) ) )
goto error;
}
PGPFreeKeySet( warnKeys );
warnKeys = NULL;
}
if( IsntNull( *pubkeys ) ) {
if( IsPGPError( err = pgpSetPreferredAlgorithm( optionList,
&preferredAlgs, env ) ) )
goto error;
}
pgpCleanupPreferredAlgorithms( context, &preferredAlgs );
return kPGPError_NoErr;
error:
pgpCleanupPreferredAlgorithms( context, &preferredAlgs );
if( IsntNull( *pubkeys ) ) {
PGPFreeKeySet( *pubkeys );
*pubkeys = NULL;
}
if( IsntNull( warnKeys ) )
PGPFreeKeySet( warnKeys );
if( IsntNull( keyIter ) )
PGPFreeKeyIter( keyIter );
return err;
}
/* Extract public key signature info from optionList */
/* Currently only allows a single signing key */
static PGPError
pgpSetupSigning(
PGPContextRef context,
PGPOptionListRef optionList,
PGPBoolean fHaveEncryption,
PGPEnv *env,
PGPEventHandlerProcPtr func,
PGPUserValue userValue,
PGPBoolean knownBinaryInput,
PGPBoolean sepsig,
PGPSigSpec **sigspec
)
{
PGPOption op; /* Selected option from list */
PGPError err; /* Error return code */
PGPKeyDBObj *signKey; /* keydbobj for signing key */
PGPByte signMode; /* Text vs binary mode for sig */
PGPByte *passPhrase; /* Signing key pass phrase */
PGPSize passLength; /* Length of passPhrase */
PGPBoolean hashedPhrase = FALSE; /* True if passkey given */
PGPUInt32 cacheTimeOut; /* Passphrase cache timeout */
PGPBoolean cacheGlobal; /* Passphrase cache global */
PGPBoolean canSign; /* Can key sign? */
PGPBoolean needsPassphrase;/* Does signing key need p.p.? */
PGPValidity failValidity, /* Fail on keys less valid */
warnValidity; /* Warn on keys less valid */
(void)func;
(void)userValue;
/* Init return pointers */
pgpa( pgpaAddrValid( sigspec, PGPSigSpec * ) );
*sigspec = NULL;
/* See if signature requested. Only one signing key allowed. */
if( IsPGPError( err = pgpSearchOptionSingle( optionList,
kPGPOptionType_SignWithKey, &op ) ) )
goto error;
if( IsOp( op ) ) {
/* Get signing key and data */
if( IsPGPError( err = pgpOptionPtr( &op, (void **)&signKey ) ) )
goto error;
pgpa(pgpaPGPKeyValid(signKey));
if( !pgpKeyIsValid(signKey) ) {
pgpDebugMsg( "Error: invalid SignWithKey keyref" );
err = kPGPError_BadParams;
goto error;
}
pgpGetKeyBoolean( signKey, kPGPKeyProperty_CanSign, &canSign );
if( !canSign ) {
err = kPGPError_KeyUnusableForSignature;
goto error;
}
if( IsPGPError( err = pgpGetMinValidity( optionList,
&failValidity, &warnValidity ) ) )
goto error;
if( IsPGPError( err = pgpCheckKeyValidity( context, optionList,
signKey, failValidity, warnValidity, NULL, NULL ) ) )
goto error;
pgpGetKeyBoolean( signKey, kPGPKeyProperty_NeedsPassphrase,
&needsPassphrase );
if( needsPassphrase )
{
/* See if we have a valid passphrase for secret key */
if( IsPGPError( err = pgpFindOptionArgs( op.subOptions,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -