📄 pgpkeyman.c
字号:
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenParams, TRUE,
"%d%d", &pkalg, &bits ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenName, TRUE,
"%p%l", &name, &nameLength ) ) )
goto error;
/* Now get optional parameters */
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passphrase, FALSE,
"%p%l", &passphrase, &passphraseLength ) ) )
goto error;
if (IsNull( passphrase )) {
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passkey, FALSE,
"%p%l", &passphrase, &passphraseLength ) ) )
goto error;
if( IsntNull( passphrase ) )
passphraseIsKey = TRUE;
}
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_CreationDate, FALSE,
"%T", &creationDate ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Expiration, FALSE,
"%d", &expiration ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_EventHandler, FALSE,
"%p%p", &progress, &userValue ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_PreferredAlgorithms, FALSE,
"%p%l", &prefalg, &prefalgLength ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_AdditionalRecipientRequestKeySet,
FALSE, "%p%d", &adkset, &adkclass ) ) )
goto error;
if( IsntNull( adkset ) ) {
if( IsPGPError( err = pgpKeySetRingSet( adkset, TRUE, &adkringset ) ) )
goto error;
}
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_RevocationKeySet, FALSE,
"%p%d", &rakset, &rakclass ) ) )
goto error;
if( IsntNull( rakset ) ) {
if( IsPGPError( err = pgpKeySetRingSet( rakset, TRUE, &rakringset ) ) )
goto error;
}
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenFast, FALSE,
"%b%d", &fastgenop, &fastgen ) ) )
goto error;
if( !fastgenop ) {
fastgen = pgpenvGetInt (pgpEnv, PGPENV_FASTKEYGEN, NULL, NULL);
}
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenUseExistingEntropy, FALSE,
"%d", &noentropy ) ) )
goto error;
*key = NULL;
newkey = NULL; /* Necessary to flag masterkey vs subkey */
err = pgpDoGenerateKey( keyset->keyDB, &newkey, NULL, (PGPByte)pkalg,
bits, creationDate, (PGPUInt16)expiration,
(const char *)name, nameLength,
(const char *)passphrase, passphraseLength,
passphraseIsKey, NULL, 0,
progress, userValue,
(PGPBoolean)fastgen, (PGPBoolean)!noentropy,
adkringset, (PGPByte)adkclass,
rakringset, (PGPByte)rakclass,
prefalg, prefalgLength );
if( IsntPGPError( err ) )
*key = newkey;
error:
if( IsntNull( adkringset ) )
ringSetDestroy( (RingSet *) adkringset );
if( IsntNull( rakringset ) )
ringSetDestroy( (RingSet *) rakringset );
return err;
}
static const PGPOptionType subkeygenOptionSet[] = {
kPGPOptionType_KeyGenMasterKey,
kPGPOptionType_KeyGenParams,
kPGPOptionType_Passphrase,
kPGPOptionType_Passkey,
kPGPOptionType_Expiration,
kPGPOptionType_CreationDate,
kPGPOptionType_EventHandler,
kPGPOptionType_KeyGenFast,
kPGPOptionType_KeyGenUseExistingEntropy
};
PGPError
pgpGenerateSubKeyInternal(
PGPContextRef context,
PGPSubKeyRef *subkey,
PGPOptionListRef optionList
)
{
PGPUInt32 pkalg;
PGPUInt32 bits;
PGPTime creationDate;
PGPUInt32 expiration;
PGPByte *passphrase;
PGPUInt32 passphraseLength;
PGPBoolean passphraseIsKey = FALSE;
PGPEventHandlerProcPtr progress;
PGPUserValue userValue;
PGPKeyRef masterkey;
PGPSubKeyRef newsubkey;
PGPEnv *pgpEnv;
PGPBoolean fastgenop;
PGPUInt32 fastgen;
PGPUInt32 noentropy = FALSE;
PGPError err;
if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
subkeygenOptionSet, elemsof( subkeygenOptionSet ) ) ) )
return err;
if( IsNull( subkey ) )
return kPGPError_BadParams;
pgpEnv = pgpContextGetEnvironment( context );
/* First pick up mandatory options */
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenMasterKey, TRUE,
"%p", &masterkey ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenParams, TRUE,
"%d%d", &pkalg, &bits ) ) )
goto error;
/* Now get optional parameters */
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passphrase, FALSE,
"%p%l", &passphrase, &passphraseLength ) ) )
goto error;
if (IsNull( passphrase )) {
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passkey, FALSE,
"%p%l", &passphrase, &passphraseLength ) ) )
goto error;
if( IsntNull( passphrase ) )
passphraseIsKey = TRUE;
}
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_CreationDate, FALSE,
"%T", &creationDate ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Expiration, FALSE,
"%d", &expiration ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_EventHandler, FALSE,
"%p%p", &progress, &userValue ) ) )
goto error;
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenFast, FALSE,
"%b%d", &fastgenop, &fastgen ) ) )
goto error;
if( !fastgenop ) {
fastgen = pgpenvGetInt (pgpEnv, PGPENV_FASTKEYGEN, NULL, NULL);
}
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_KeyGenUseExistingEntropy, FALSE,
"%d", &noentropy ) ) )
goto error;
err = pgpKeyDeadCheck(masterkey);
if ( IsPGPError( err ) )
return err;
#if 0
if (bits < 512 || bits > 4096)
return kPGPError_BadParams;
PGPGetKeyNumber (masterkey, kPGPKeyPropAlgID, &pkalg);
if (pkalg != kPGPPublicKeyAlgorithm_DSA)
return kPGPError_BadParams;
#endif
*subkey = NULL;
err = pgpDoGenerateKey (masterkey->keyDB, &masterkey, &newsubkey,
(PGPByte)pkalg, bits, creationDate,
(PGPUInt16)expiration,
NULL, 0, (char const *)passphrase,
passphraseLength, passphraseIsKey,
(char const *)passphrase, passphraseLength,
progress, userValue,
(PGPBoolean)fastgen, (PGPBoolean)!noentropy,
NULL, (PGPByte)0, NULL, (PGPByte)0, NULL, 0);
if( IsntPGPError( err ) )
*subkey = newsubkey;
error:
return err;
}
/* Handle editing key properties which are held in self signatures */
static const PGPOptionType keyoptionOptionSet[] = {
kPGPOptionType_Passphrase,
kPGPOptionType_Passkey,
kPGPOptionType_RevocationKeySet,
kPGPOptionType_PreferredAlgorithms,
#if 0
/* not yet implemented */
kPGPOptionType_Expiration,
kPGPOptionType_AdditionalRecipientRequestKeySet,
#endif
};
PGPError
pgpAddKeyOptionsInternal (
PGPKeyRef key,
PGPOptionListRef optionList
)
{
char * passphrase;
PGPSize passphraseLength;
PGPBoolean hashedPhrase = FALSE;
PGPKeySetRef rakset = NULL;
PGPUInt32 rakclass = 0;
RingSet const *rakringset = NULL;
RingSet *addset = NULL;
RingSet *rak1set = NULL;
RingIterator *rakiter = NULL;
PGPKeyDB *keys;
RingObject *keyobj;
RingSet const *allset;
PGPContextRef context;
PGPError err = kPGPError_NoErr;
if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
keyoptionOptionSet, elemsof( keyoptionOptionSet ) ) ) )
goto error;
/* Pick up passphrase options */
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;
}
/* Get data to add (require revocationkeyset for now) */
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_RevocationKeySet, TRUE,
"%p%d", &rakset, &rakclass ) ) )
goto error;
pgpAssert( IsntNull( rakset ) );
if( IsPGPError( err = pgpKeySetRingSet( rakset, TRUE, &rakringset ) ) ) {
goto error;
}
/*
* This code is temporary and will be redesigned to support a wider
* set of key options.
*/
keys = key->keyDB;
keyobj = key->key;
context = keys->context;
if ( !keys->objIsMutable( keys, keyobj ) ) {
err = kPGPError_ItemIsReadOnly;
goto error;
}
if ( IsPGPError( pgpKeyDeadCheck(key) ) ) {
goto error; /* no need if already revoked */
}
allset = pgpKeyDBRingSet (keys);
if( IsPGPError( err = pgpCopyKey (allset, keyobj, &addset) ) )
goto error;
rakiter = ringIterCreate(rakringset);
if( IsNull( rakiter ) ) {
err = ringSetError(rakringset)->error;
goto error;
}
/* Add 1 RAK key at a time in separate self signatures */
while (ringIterNextObject (rakiter, 1) == 1) {
RingObject *rakkey = ringIterCurrentObject (rakiter, 1);
pgpAssert (ringObjectType(rakkey) == RINGTYPE_KEY);
rak1set = ringSetCreate (ringSetPool(rakringset));
if( IsNull( rak1set ) ) {
err = ringSetError(rakringset)->error;
goto error;
}
ringSetAddObject (rak1set, rakkey);
ringSetFreeze (rak1set);
err = pgpCertifyObject (context, keyobj, addset, keyobj, allset,
PGP_SIGTYPE_KEY_PROPERTY, passphrase,
passphraseLength, hashedPhrase, FALSE,
SIG_EXPORTABLE, 0,
0, kPGPExpirationTime_Never,
0, 0, NULL, rak1set, rakclass);
if( IsPGPError( err ) ) {
goto error;
}
ringSetDestroy (rak1set);
rak1set = NULL;
}
/* Update the KeyDB */
err = pgpAddObjects (keys, addset);
/* Calculate trust changes as a result */
if( err == kPGPError_NoErr )
(void)pgpPropagateTrustKeyDB (keys);
error:
if( IsntNull( addset ) )
ringSetDestroy (addset);
if( IsntNull( rakringset ) )
ringSetDestroy ((RingSet *)rakringset);
if( IsntNull( rakiter ) )
ringIterDestroy (rakiter);
if( IsntNull( rak1set ) )
ringSetDestroy (rak1set);
return err;
}
PGPError
pgpRemoveKeyOptionsInternal (
PGPKeyRef key,
PGPOptionListRef optionList
)
{
(void) key;
(void) optionList;
return kPGPError_FeatureNotAvailable;
}
PGPError
pgpUpdateKeyOptionsInternal (
PGPKeyRef key,
PGPOptionListRef optionList
)
{
PGPKeyDB *keys;
RingSet const *allset;
RingSet *addset = NULL;
PGPEnv *pgpEnv;
PGPRandomContext *pgpRng;
PGPSecKey *seckey = NULL;
PGPSigSpec *sigspec = NULL;
int tzFix;
PGPTime timestamp;
char * passphrase;
PGPSize passphraseLength;
PGPBoolean hashedPhrase = FALSE;
RingObject *keyobj;
PGPContextRef context;
PGPCipherAlgorithm *prefalg;
PGPSize prefalgLength;
PGPByte *prefalgByte = NULL;
PGPUserIDRef userid;
RingObject *latestsig;
PGPError err = kPGPError_NoErr;
if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
keyoptionOptionSet, elemsof( keyoptionOptionSet ) ) ) )
goto error;
/* Pick up passphrase options */
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;
}
/* Get data to modify (require preferred algs for now) */
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_PreferredAlgorithms, TRUE,
"%p%l", &prefalg, &prefalgLength ) ) )
goto error;
if( IsNull( prefalg ) )
goto error; /* Nothing to do */
/* Prepare for action */
keys = key->keyDB;
keyobj = key->key;
context = keys->context;
pgpRng = pgpContextGetX9_17RandomContext( context );
pgpEnv = pgpContextGetEnvironment( context );
tzFix = pgpenvGetInt (pgpEnv, PGPENV_TZFIX, NULL, NULL);
timestamp = pgpTimeStamp (tzFix);
allset = pgpKeyDBRingSet (keys);
/* Parse preferred algorithms into tight buffer */
prefalgByte = NULL;
if (prefalgLength > 0) {
PGPUInt32 i;
/* Convert preferred algorithm to byte array */
prefalgLength /= sizeof(PGPCipherAlgorithm);
prefalgByte = (PGPByte *)pgpContextMemAlloc( context,
prefalgLength, 0);
if( IsNull( prefalgByte ) ) {
err = kPGPError_OutOfMemory;
goto error;
}
for (i=0; i<prefalgLength; ++i) {
prefalgByte[i] = (PGPByte)prefalg[i];
}
}
/* Try to unlock secret key object */
seckey = ringSecSecKey (allset, keyobj, PGP_PKUSE_SIGN);
if (!seckey) {
err = ringSetError(allset)->error;
goto error;
}
if (pgpSecKeyIslocked (seckey)) {
if (IsNull( passphrase )) {
err = kPGPError_BadPassphrase;
goto error;
}
err = (PGPError)pgpSecKeyUnlock (seckey, pgpEnv, passphrase,
passphraseLength, hashedPhrase);
if (err != 1)
{
if (err == 0)
err = kPGPError_BadPassphrase;
goto error;
}
}
if ( !keys->objIsMutable( keys, keyobj ) ) {
err = kPGPError_ItemIsReadOnly;
goto error;
}
if ( IsPGPError( pgpKeyDeadCheck(key) ) ) {
goto error; /* no need if already revoked */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -