📄 pgpkeyman.c
字号:
{
PGPKeyDB *keys;
RingSet const *allset;
union RingObject *subkeyobj;
pgpa(pgpaPGPSubKeyValid(subkey));
PGPValidateSubKey( subkey );
CHECKREMOVED(subkey);
keys = subkey->key->keyDB;
allset = pgpKeyDBRingSet (keys);
subkeyobj = subkey->subKey;
if (!keys->objIsMutable(keys, subkeyobj))
return kPGPError_ItemIsReadOnly;
return pgpRemoveObject (keys, subkeyobj);
}
static PGPError
sRevokeSubKey (
PGPContextRef context,
PGPSubKeyRef subkey,
char const * passphrase,
PGPSize passphraseLength,
PGPBoolean hashedPhrase
)
{
PGPKeyDB *keys;
RingSet const *allset;
RingSet * addset;
union RingObject *subkeyobj, *keyobj;
union RingObject *signkeyobj = NULL;
PGPUInt32 revnum;
PGPError error = kPGPError_NoErr;
CHECKREMOVED(subkey);
keys = subkey->key->keyDB;
subkeyobj = subkey->subKey;
keyobj = subkey->key->key;
if (pgpSubKeyIsDead (subkey))
return kPGPError_NoErr;
if (!keys->objIsMutable(keys, subkeyobj))
return kPGPError_ItemIsReadOnly;
allset = pgpKeyDBRingSet (keys);
error = pgpCopyKey (allset, keyobj, &addset);
if (error)
return error;
revnum = 0;
for ( ; ; ) {
signkeyobj = keyobj;
/* See if we have an authorized revocation signature */
if (!ringKeyIsSec (allset, keyobj)) {
PGPByte revclass;
signkeyobj = ringKeyRevocationKey (keyobj, allset, revnum++,
NULL, NULL,
&revclass, NULL, &error);
if( IsPGPError( error ) ) {
if( error == kPGPError_ItemNotFound )
error = kPGPError_NoErr;
break;
}
if( IsNull( signkeyobj ) ) {
continue;
}
if (!(revclass & 0x80))
continue;
if (!ringKeyIsSec (allset, signkeyobj))
continue;
}
/* Note special subkey revocation sigtype */
error = pgpCertifyObject (context, subkeyobj, addset, signkeyobj,
allset, PGP_SIGTYPE_KEY_SUBKEY_REVOKE, passphrase,
passphraseLength, hashedPhrase, FALSE,
SIG_EXPORTABLE, 0, 0, kPGPExpirationTime_Never, 0, 0, NULL,
NULL, 0);
/* Retry if bad passphrase and we are an authorized revoker */
if (error != kPGPError_BadPassphrase || signkeyobj == keyobj)
break;
}
if (error) {
ringSetDestroy (addset);
return error;
}
/* Update the KeyDB */
error = pgpAddObjects (keys, addset);
ringSetDestroy (addset);
/* Calculate trust changes as a result */
if( error == kPGPError_NoErr )
(void)pgpPropagateTrustKeyDB (keys);
return error;
}
static const PGPOptionType revsubkeyOptionSet[] = {
kPGPOptionType_Passphrase,
kPGPOptionType_Passkey
};
PGPError
pgpRevokeSubKeyInternal(
PGPSubKeyRef subkey,
PGPOptionListRef optionList
)
{
PGPContextRef context;
char * passphrase;
PGPSize passphraseLength;
PGPBoolean hashedPhrase = FALSE;
PGPError err = kPGPError_NoErr;
pgpa(pgpaPGPSubKeyValid(subkey));
PGPValidateSubKey( subkey );
context = subkey->key->keyDB->context;
if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
revsubkeyOptionSet, elemsof( revsubkeyOptionSet ) ) ) )
return err;
/* Pick up optional 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;
}
err = sRevokeSubKey( context, subkey, passphrase, passphraseLength,
hashedPhrase );
error:
return err;
}
/* Convert a passphrase to a passkeybuffer, for a given key */
static const PGPOptionType getpasskeyOptionSet[] = {
kPGPOptionType_Passphrase,
};
PGPError
pgpGetKeyPasskeyBufferInternal (
PGPKeyRef key,
void *passkeyBuffer,
PGPOptionListRef optionList
)
{
RingObject *keyObj;
RingSet const *ringSet;
PGPEnv *pgpEnv;
PGPSecKey *secKey;
PGPError err;
char const *passphrase;
PGPSize passphraseLength;
/* Pick up mandatory passphrase option */
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passphrase, TRUE,
"%p%l", &passphrase, &passphraseLength ) ) )
return err;
keyObj = key->key;
ringSet = pgpKeyDBRingSet( key->keyDB );
pgpEnv = pgpContextGetEnvironment( key->keyDB->context );
secKey = ringSecSecKey( ringSet, keyObj, 0 );
if( IsNull( secKey ) )
return ringSetError(ringSet)->error;
err = pgpSecKeyConvertPassphrase( secKey, pgpEnv, passphrase,
passphraseLength, (PGPByte *) passkeyBuffer );
pgpSecKeyDestroy (secKey);
return err;
}
/* Convert a passphrase to a passkeybuffer, for a given subkey */
PGPError
pgpGetSubKeyPasskeyBufferInternal (
PGPSubKeyRef subkey,
void *passkeyBuffer,
PGPOptionListRef optionList
)
{
RingObject *keyObj;
RingSet const *ringSet;
PGPEnv *pgpEnv;
PGPSecKey *secKey;
PGPError err;
char const *passphrase;
PGPSize passphraseLength;
/* Pick up mandatory passphrase option */
if( IsPGPError( err = pgpFindOptionArgs( optionList,
kPGPOptionType_Passphrase, TRUE,
"%p%l", &passphrase, &passphraseLength ) ) )
return err;
keyObj = subkey->subKey;
ringSet = pgpKeyDBRingSet( subkey->key->keyDB );
pgpEnv = pgpContextGetEnvironment( subkey->key->keyDB->context );
secKey = ringSecSecKey( ringSet, keyObj, 0 );
if( IsNull( secKey ) )
return ringSetError(ringSet)->error;
err = pgpSecKeyConvertPassphrase( secKey, pgpEnv, passphrase,
passphraseLength, (PGPByte *) passkeyBuffer );
pgpSecKeyDestroy (secKey);
return err;
}
/* Remove a User ID. If the KeySet is read-only, or the UserID object
itself is read-only, we return an error. */
PGPError
PGPRemoveUserID (PGPUserID *userid)
{
PGPKeyDB *keys;
PGPUserID *uidtmp;
int uidcount = 0;
RingSet const *allset;
union RingObject *nameobj;
PGPValidateUserID( userid );
CHECKREMOVED(userid);
/* Cannot remove only UserID */
for (uidtmp = (PGPUserID *) userid->key->userIDs.next;
uidtmp != (PGPUserID *) &userid->key->userIDs;
uidtmp = uidtmp->next) {
if (!uidtmp->removed)
uidcount++;
}
if (uidcount == 1)
return kPGPError_BadParams;
keys = userid->key->keyDB;
allset = pgpKeyDBRingSet (keys);
nameobj = userid->userID;
if (!keys->objIsMutable(keys, nameobj))
return kPGPError_ItemIsReadOnly;
return pgpRemoveObject (keys, nameobj);
}
/*
* Add a new User ID to a key. User IDs cannot be added to other than the
* user's own keys. The new User ID is added to the end of the list. To
* make it the primary User ID, call PGPSetPrimaryUserID() below.
*/
static PGPError
sAddUserID (
PGPContextRef context,
PGPKeyRef key,
PGPBoolean isAttribute,
PGPAttributeType attributeType,
char const * userIDData,
PGPSize userIDLength,
char const * passphrase,
PGPSize passphraseLength,
PGPBoolean hashedPhrase
)
{
PGPKeyDB *keys;
PGPUserID *userid;
RingSet const *allset;
RingSet * addset;
union RingObject *keyobj, *nameobj;
PGPError error;
error = pgpKeyDeadCheck( key) ;
if ( IsPGPError( error ) )
return error;
keys = key->keyDB;
allset = pgpKeyDBRingSet (keys);
keyobj = key->key;
if (!keys->objIsMutable(keys, keyobj))
return kPGPError_ItemIsReadOnly;
/* Can only add User ID to our own keys */
if (!ringKeyIsSec (allset, keyobj))
return kPGPError_SecretKeyNotFound;
error = pgpCopyKey (allset, keyobj, &addset);
if (error)
return error;
if (isAttribute)
nameobj = ringCreateAttribute (addset, keyobj, (PGPByte)attributeType,
(PGPByte *)userIDData, userIDLength);
else
nameobj = ringCreateName (addset, keyobj, userIDData, userIDLength);
if (!nameobj) {
error = ringSetError(addset)->error;
ringSetDestroy (addset);
return error;
}
/* ringCreateName will return a duplicate nameobj if
the name already exists for this key. Check the
list of PGPUserID objects to see if the nameobj
is already referenced. */
for (userid = (PGPUserID *) key->userIDs.next;
userid != (PGPUserID *) &key->userIDs;
userid = userid->next) {
if (!userid->removed && userid->userID == nameobj) {
ringSetDestroy (addset);
return kPGPError_DuplicateUserID;
}
}
/* Must self-certify here */
error = pgpCertifyObject (context, nameobj, addset, keyobj, allset,
PGP_SIGTYPE_KEY_GENERIC, passphrase,
passphraseLength, hashedPhrase, TRUE,
SIG_EXPORTABLE, 0, 0, kPGPExpirationTime_Never,
0, 0, NULL, NULL, 0);
if (error) {
ringSetDestroy (addset);
return error;
}
error = pgpAddObjects (keys, addset);
ringSetDestroy (addset);
/* Calculate trust changes as a result */
if( error == kPGPError_NoErr )
(void)pgpPropagateTrustKeyDB (keys);
return error;
}
static const PGPOptionType adduserOptionSet[] = {
kPGPOptionType_Passphrase,
kPGPOptionType_Passkey
};
PGPError
pgpAddUserIDInternal(
PGPKeyRef key,
char const * userID,
PGPOptionListRef optionList
)
{
PGPContextRef context;
char * passphrase;
PGPSize passphraseLength;
PGPBoolean hashedPhrase = FALSE;
PGPSize userIDLength;
PGPError err = kPGPError_NoErr;
pgpa(pgpaPGPKeyValid(key));
PGPValidateKey( key );
if( IsNull( userID ) )
return kPGPError_BadParams;
userIDLength = strlen(userID);
context = key->keyDB->context;
if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
adduserOptionSet, elemsof( adduserOptionSet ) ) ) )
return err;
/* Pick up optional 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;
}
err = sAddUserID( context, key, FALSE, (PGPAttributeType)0,
userID, userIDLength, passphrase, passphraseLength,
hashedPhrase);
error:
return err;
}
static const PGPOptionType addattrOptionSet[] = {
kPGPOptionType_Passphrase,
kPGPOptionType_Passkey
};
PGPError
pgpAddAttributeInternal(
PGPKeyRef key,
PGPAttributeType attributeType,
PGPByte const *attributeData,
PGPSize attributeLength,
PGPOptionListRef optionList
)
{
PGPContextRef context;
char * passphrase;
PGPSize passphraseLength;
PGPBoolean hashedPhrase = FALSE;
PGPError err = kPGPError_NoErr;
pgpa(pgpaPGPKeyValid(key));
PGPValidateKey( key );
if( IsNull( attributeData ) )
return kPGPError_BadParams;
context = key->keyDB->context;
if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
adduserOptionSet, elemsof( adduserOptionSet ) ) ) )
return err;
/* Pick up optional 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;
}
err = sAddUserID( context, key, TRUE, attributeType,
(const char *)attributeData, attributeLength,
passphrase, passphraseLength, hashedPhrase);
error:
return err;
}
PGPError
PGPSetPrimaryUserID (PGPUserID *userid)
{
PGPKeyDB *keys;
PGPKey *key;
RingSet const * allset;
RingSet * addset;
PGPError error;
PGPValidateUserID( userid );
CHECKREMOVED(userid);
key = userid->key;
error = pgpKeyDeadCheck( key) ;
if ( IsPGPError( error ) )
return error;
keys = key->keyDB;
if (!keys->objIsMutable(keys, key->key))
return kPGPError_ItemIsReadOnly;
allset = pgpKeyDBRingSet (keys);
error = pgpCopyKey (allset, key->key, &addset);
if (error)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -