📄 pgpencode.c
字号:
if (algsOK == 0) {
/* Choose an algorithm which we support and most people accept */
for( i=0; i<algInfo->n; ++i ) {
if( IsNull( pgpCipherGetVTBL( (PGPCipherAlgorithm)(i+1) ) ) )
continue;
algsOK += 1;
if ( bestalg == 0 || algInfo->algok[i] > bestvote ) {
/* First acceptable, or best one so far */
bestvote = algInfo->algok[i];
bestalg = i+1;
}
}
}
if (algsOK == 0) {
/* None of the algs we support are acceptable to anyone */
/* Just choose the first algorithm we support */
for (i=0; i<kPGPCipherAlgorithm_Last; ++i) {
if( IsNull( pgpCipherGetVTBL( (PGPCipherAlgorithm)(i+1) ) ) )
continue;
algsOK += 1;
bestalg = i;
break;
}
}
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 pubkeys list */
static PGPError
pgpSetupPubkey(
PGPContextRef context,
PGPOptionListRef optionList,
PGPKey *key,
PGPValidity failValidity,
PGPValidity warnValidity,
PGPPreferredAlgs *preferredAlgs,
PGPPubKey **pubkeys,
PGPKeySetRef warnKeySet
)
{
PGPError err; /* Error return code */
RingObject *ringKey; /* Keyring obj for encryption key */
RingSet const *ringSet; /* Lowlevel keyring set for enc key */
PGPPubKey *pubkey; /* Internal struct for current key */
if( IsPGPError( err = pgpGetKeyRingObject( key, FALSE, &ringKey ) ) )
goto error;
if( IsPGPError( err = pgpGetKeyRingSet( key, FALSE, &ringSet ) ) )
goto error;
if( IsPGPError( err = pgpCheckKeyValidity( context, optionList,
key, ringSet, failValidity, warnValidity, warnKeySet,
NULL ) ) )
goto error;
if( IsPGPError( err = pgpCheckPreferredAlgorithms( preferredAlgs, key,
ringSet ) ) )
goto error;
pubkey = ringKeyPubKey( ringSet, ringKey, PGP_PKUSE_ENCRYPT );
if( IsNull( pubkey ) ) {
/* err = kPGPError_KeyUnusableForEncryption; */
err = ringSetError( ringSet ) -> error;
goto error;
}
pubkey->next = *pubkeys;
*pubkeys = pubkey;
return kPGPError_NoErr;
error:
return err;
}
/* Extract public key encryption info from optionList */
static PGPError
pgpSetupPublicKeyEncryption(
PGPContextRef context,
PGPOptionListRef optionList,
PGPEnv *env,
PGPPubKey **pubkeys,
PGPKeyRef *enckeyref
)
{
PGPOption op; /* Selected option from list */
PGPError err; /* Error return code */
PGPInt32 keyCount; /* Number of key we are doing */
PGPKey *key; /* PGPKey structure for current key */
PGPUserID *userid; /* UserID to encrypt to */
PGPKeySet *keySet; /* Keyset to encrypt to */
PGPKeyList *keyList; /* Sorted version of keySet */
PGPKeyIter *keyIter; /* Iterator over keyList */
PGPValidity failValidity, /* Fail on keys less valid */
warnValidity; /* Warn on keys less valid */
PGPPreferredAlgs preferredAlgs; /* Preferred algorithm data */
PGPKeySet *warnKeySet; /* Keys with warnable trusts */
/* Init return pointer */
pgpa( pgpaAddrValid( pubkeys, PGPPubKey * ) );
pgpa( pgpaAddrValid( enckeyref, PGPKeyRef ) );
*pubkeys = NULL;
*enckeyref = kInvalidPGPKeyRef;
warnKeySet = NULL;
keyList = NULL;
keyIter = NULL;
/* Initialize for loops below */
if( IsPGPError( err = pgpInitPreferredAlgorithms( context,
&preferredAlgs ) ) )
goto error;
if( IsPGPError( err = pgpGetMinValidity( optionList,
&failValidity, &warnValidity ) ) )
goto error;
/* Accumulate warning keys here */
if( IsPGPError( err = PGPNewKeySet( context, &warnKeySet ) ) )
goto error;
/* Find any encryption keys specified as keys */
keyCount = 0;
if( IsPGPError( err = pgpSearchOption( optionList,
kPGPOptionType_EncryptToKey, keyCount, &op ) ) )
goto error;
while( IsOp( op ) ) {
if( IsPGPError( err = pgpOptionPtr( &op, (void **)&key ) ) )
goto error;
pgpa(pgpaPGPKeyValid(key));
if( !pgpKeyIsValid(key) ) {
pgpDebugMsg( "Error: invalid EncryptToKey keyref" );
err = kPGPError_BadParams;
goto error;
}
if( *enckeyref == kInvalidPGPKeyRef )
*enckeyref = key;
if( IsPGPError( err = pgpSetupPubkey( context, optionList, key,
failValidity, warnValidity,
&preferredAlgs, pubkeys,
warnKeySet ) ) )
goto error;
if( IsPGPError( err = pgpSearchOption( optionList,
kPGPOptionType_EncryptToKey, ++keyCount, &op ) ) )
goto error;
}
/* Find any encryption keys specified as userids */
keyCount = 0;
if( IsPGPError( err = pgpSearchOption( optionList,
kPGPOptionType_EncryptToUserID, keyCount, &op ) ) )
goto error;
while( IsOp( op ) ) {
if( IsPGPError( err = pgpOptionPtr( &op, (void **)&userid ) ) )
goto error;
pgpa(pgpaPGPUserIDValid(userid));
if( !pgpUserIDIsValid(userid) ) {
pgpDebugMsg( "Error: invalid EncryptToUserID useridref" );
err = kPGPError_BadParams;
goto error;
}
if( IsPGPError( err = pgpGetUserIDKey( userid, FALSE, &key ) ) )
goto error;
if( *enckeyref == kInvalidPGPKeyRef )
*enckeyref = key;
if( IsPGPError( err = pgpSetupPubkey( context, optionList, key,
failValidity, warnValidity,
&preferredAlgs, pubkeys,
warnKeySet ) ) )
goto error;
if( IsPGPError( err = pgpSearchOption( optionList,
kPGPOptionType_EncryptToUserID, ++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 = PGPOrderKeySet( keySet, kPGPAnyOrdering,
&keyList ) ) )
goto error;
if( IsPGPError( err = PGPNewKeyIter ( keyList, &keyIter ) ) )
goto error;
while( IsntPGPError( err = PGPKeyIterNext( keyIter, &key ) ) ) {
if( *enckeyref == kInvalidPGPKeyRef )
*enckeyref = key;
if( IsPGPError( err = pgpSetupPubkey( context, optionList, key,
failValidity, warnValidity,
&preferredAlgs, pubkeys,
warnKeySet ) ) )
goto error;
}
PGPFreeKeyIter( keyIter );
keyIter = NULL;
PGPFreeKeyList( keyList );
keyList = NULL;
if( IsPGPError( err = pgpSearchOption( optionList,
kPGPOptionType_EncryptToKeySet, ++keyCount, &op ) ) )
goto error;
}
if( IsntNull( warnKeySet ) ) {
PGPUInt32 numKeys;
if ( IsPGPError( PGPCountKeys( warnKeySet, &numKeys ) ) )
goto error;
if( numKeys > 0 ) {
if( IsPGPError( pgpWarnUser( context, optionList,
kPGPError_KeyInvalid, warnKeySet ) ) )
goto error;
}
PGPFreeKeySet( warnKeySet );
warnKeySet = NULL;
}
if( IsntNull( *pubkeys ) ) {
if( IsPGPError( err = pgpSetPreferredAlgorithm( optionList,
&preferredAlgs, env ) ) )
goto error;
}
pgpCleanupPreferredAlgorithms( context, &preferredAlgs );
return kPGPError_NoErr;
error:
pgpCleanupPreferredAlgorithms( context, &preferredAlgs );
while( IsntNull( *pubkeys ) ) {
PGPPubKey *pk1 = pgpPubKeyNext (*pubkeys);
pgpPubKeyDestroy (*pubkeys);
*pubkeys = pk1;
}
if( IsntNull( warnKeySet ) )
PGPFreeKeySet( warnKeySet );
if( IsntNull( keyList ) )
PGPFreeKeyList( keyList );
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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -