⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpkeyman.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}
	
	if( IsPGPError( err = pgpCopyKey (allset, keyobj, &addset) ) )
		goto error;

	/* Update each self-sig on each name */
	for (userid = (PGPUserID *) key->userIDs.next; 
		 userid != (PGPUserID *) &key->userIDs;
		 userid = userid->next) {
	    if (userid->removed)
			continue;
	
		latestsig = ringLatestSigByKey( userid->userID, addset, keyobj );
		if( IsntNull( latestsig ) )
		{
			/* Revoke existing cert */
			sigspec = pgpSigSpecCreate (pgpEnv, seckey,
										PGP_SIGTYPE_KEY_UID_REVOKE);
			pgpSigSpecSetTimestamp( sigspec, timestamp );
			err = ringSignObject (addset, userid->userID, sigspec, pgpRng);
			pgpSigSpecDestroy (sigspec);
			sigspec = NULL;

			/* Copy existing sigspec, set new timestamp */
			sigspec = ringSigSigSpec (latestsig, addset, &err);
			if( IsNull( sigspec ) )
				continue;
			pgpSecKeyDestroy( pgpSigSpecSeckey( sigspec ) );
			pgpSigSpecSetSeckey( sigspec, seckey );
			pgpSigSpecSetTimestamp( sigspec, timestamp+1 );

		}
		else
		{
			/* No previous sig, must create one */
			sigspec = pgpSigSpecCreate (pgpEnv, seckey,
										PGP_SIGTYPE_KEY_GENERIC);
			if( IsNull( sigspec ) )
				continue;
			pgpSigSpecSetTimestamp( sigspec, timestamp+1 );
		}

		/* Set new values */
		pgpSigSpecSetPrefAlgs (sigspec, 0, prefalgByte, prefalgLength);

		/* Issue new signature */
		err = ringSignObject (addset, userid->userID, sigspec, pgpRng);
		pgpSigSpecDestroy (sigspec);
		sigspec = 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( sigspec ) )
		pgpSigSpecDestroy (sigspec);
	if( IsntNull( prefalgByte ) )
		PGPFreeData (prefalgByte);
	if( IsntNull( seckey ) )
		pgpSecKeyDestroy (seckey);


	return err;
}





/*  Disable the key.  If key is not stored in a writeable KeySet, copy it 
	locally.  Private keys cannot be disabled. */

PGPError
PGPDisableKey (PGPKey *key)
{
	PGPKeyDB		   *keys = NULL;
	RingSet const    *allset = NULL;
	RingSet			*addset = NULL;
	union RingObject   *keyobj;
	PGPError			error = kPGPError_NoErr;

	PGPValidateKey( key );
	
	error	= pgpKeyDeadCheck( key ) ;
	if ( IsPGPError( error ) )
		return error;
		
	keys =		key->keyDB;
	keyobj =	key->key;
	allset =	pgpKeyDBRingSet (keys);

	/*  Axiomatic keys cannot be disabled, but plain old private
	    keys can (because they may belong to someone else).  */
	if (ringKeyAxiomatic (allset, keyobj))
		return kPGPError_BadParams;
	if (!keys->objIsMutable(keys, keyobj))
		return kPGPError_ItemIsReadOnly;

	if ((error = pgpCopyKey (allset, keyobj, &addset)) != kPGPError_NoErr)
		return error;
	if (!ringKeyDisabled (allset, keyobj)) {
	    ringKeyDisable (allset, keyobj);
		pgpKeyDBChanged (keys, addset);
	}

	if (addset)
		ringSetDestroy (addset);
	return error;
}


/*  Enable the key. */

PGPError
PGPEnableKey (PGPKey *key)
{
	PGPKeyDB		   *keys;
    RingSet const	*	allset;
    RingSet *			addset;
	union RingObject   *keyobj;
	PGPError		    error = kPGPError_NoErr;
	
	PGPValidateKey( key );
	error	= pgpKeyDeadCheck( key) ;
	if ( IsPGPError( error ) )
		return error;
		
	keys =		key->keyDB;
	keyobj =	key->key;
	allset =	pgpKeyDBRingSet (keys);

	if (!keys->objIsMutable(keys, keyobj))
		return kPGPError_ItemIsReadOnly;

	if (ringKeyDisabled (allset, keyobj)) {
		if ((error = pgpCopyKey (allset, keyobj, &addset)) != kPGPError_NoErr)
			return error;
	  	ringKeyEnable (allset, keyobj);
		pgpKeyDBChanged (keys, addset);
		ringSetDestroy (addset);
	}
	return kPGPError_NoErr;
}


/*  Change the passphrase.  If the new passphrase is the same as the
	old passphrase, we still unlock the key as the user may be trying to
	set the key's isAxiomatic flag.  */

PGPError
pgpDoChangePassphraseInternal (PGPKeyDB *keyDB, RingSet const *ringset, 
							 RingObject *keyobj, RingObject *masterkeyobj, 
							 const char *oldphrase, PGPSize oldphraseLength,
							 const char *newphrase, PGPSize newphraseLength,
							 PGPBoolean newPassphraseIsKey)
{
	unsigned long		 validity;
	RingSet				*addset = NULL;
	union RingObject	*newsecobj, *oldsecobj = NULL;
	PGPKeySpec			*keyspec = NULL;
	PGPError			 error = kPGPError_NoErr;
	PGPSecKey			*seckey = NULL;
	PgpVersion			 version;
	PGPEnv				*pgpEnv;
	PGPEnv				*pgpEnvCopy = NULL;
	PGPRandomContext	*pgpRng;
	PGPStringToKeyType	 s2ktype;
	PGPByte				*prefAlgs;
	PGPSize				 prefAlgsLength;
	PGPUInt32			 i;
	PGPBoolean			 locked = 0;

	if (IsntNull(oldphrase) && oldphraseLength == 0)
		oldphrase = NULL;
	if (IsntNull(newphrase) && newphraseLength == 0)
		newphrase = NULL;

	if (!keyDB->objIsMutable(keyDB, keyobj))
		return kPGPError_ItemIsReadOnly;

	if (!ringKeyIsSec (ringset, keyobj))
	    return kPGPError_SecretKeyNotFound;

	/* Find old secret object */
	oldsecobj = ringBestSec (ringset, keyobj);
	if( IsNull( oldsecobj ) )
	    return kPGPError_SecretKeyNotFound;

	/* Does the caller know the current passphrase? */
	pgpEnv = pgpContextGetEnvironment( keyDB->context );
	seckey = ringSecSecKey (ringset, oldsecobj, 0);
	if (!seckey)
	    return ringSetError(ringset)->error;
	if (pgpSecKeyIslocked (seckey)) {
		locked = 1;
	    if (!oldphrase) {
		    error = kPGPError_BadPassphrase;
			goto cleanup;
		}
		error = (PGPError)pgpSecKeyUnlock (seckey, pgpEnv, oldphrase, 
								 oldphraseLength, FALSE);
		if (error != 1) {
		    if (error == 0) 
			    error = kPGPError_BadPassphrase;
			goto cleanup;
		}
	}
	
	/*  All done if passphrase has not changed */
	if ((!oldphrase && !newphrase) ||
		(oldphrase && locked && newphrase && (oldphraseLength==newphraseLength)
		 && strcmp (oldphrase, newphrase) == 0))
	{
	    error = kPGPError_NoErr;
		goto cleanup;
	}

	error = pgpCopyKey (ringset, keyobj, &addset);
	if (error)
		goto cleanup;

	pgpRng = pgpContextGetX9_17RandomContext( keyDB->context );

	if (newPassphraseIsKey) {
		s2ktype = kPGPStringToKey_LiteralShared;
	} else if (seckey->pkAlg <= kPGPPublicKeyAlgorithm_RSA + 2) {
		s2ktype = kPGPStringToKey_Simple;
	} else {
		s2ktype = kPGPStringToKey_IteratedSalted;
	}

	/* Lock using key's preferred algorithm if known */
	if( IsPGPError( error = pgpenvCopy( pgpEnv, &pgpEnvCopy ) ) )
		goto cleanup;
	prefAlgs = (PGPByte *)ringKeyFindSubpacket (
			(masterkeyobj?masterkeyobj:keyobj), ringset,
			SIGSUB_PREFERRED_ENCRYPTION_ALGS, 0,
			&prefAlgsLength, NULL, NULL, NULL, NULL, &error);
	for( i = 0; i < prefAlgsLength; ++i ) {
		PGPCipherAlgorithm lockAlg = (PGPCipherAlgorithm)prefAlgs[i];
		if( IsntNull( pgpCipherGetVTBL ( lockAlg ) ) ) {
			pgpenvSetInt (pgpEnvCopy, PGPENV_CIPHER, lockAlg,
						  PGPENV_PRI_FORCE);
			break;
		}
	}

    error = (PGPError)pgpSecKeyChangeLock (seckey, pgpEnvCopy, pgpRng, 
								 newphrase, newphraseLength, s2ktype);
	if (error)
	    goto cleanup;

	keyspec = pgpKeySpecCreate (pgpEnv);
	if (!keyspec) {
	    error = kPGPError_OutOfMemory;
		goto cleanup;
	}

	/* We need to make this keyspec just like the existing one */
	pgpKeySpecSetCreation (keyspec, ringKeyCreation (ringset, keyobj));

	/* Fix "version bug", don't change version from earlier one. */
	version = ringSecVersion (ringset, keyobj);
	pgpKeySpecSetVersion (keyspec, version);

	validity = ringKeyExpiration (ringset, keyobj);
	if (validity != 0) {
		    validity -= ringKeyCreation (ringset, keyobj);
			validity /= 3600*24;
	}
	pgpKeySpecSetValidity (keyspec, (PGPUInt16) validity);

	newsecobj = ringCreateSec (addset, masterkeyobj, seckey, keyspec, 
							   seckey->pkAlg);
	if (!newsecobj) {
	    error = ringSetError(addset)->error;
	    goto cleanup;
	}
	pgpKeySpecDestroy (keyspec); keyspec = NULL;
	pgpSecKeyDestroy (seckey); seckey = NULL;

	error = pgpAddObjects (keyDB, addset);

	/* This step is necessary for the RingFile to close cleanly */
	if (!error) {
		/* 
		 * pgpRemoveObject not appropriate since this is not an object
		 * type that it knows how to deal with.
		 */
		error = keyDB->remove(keyDB, oldsecobj);
	}

cleanup:
	if (seckey)
		pgpSecKeyDestroy (seckey);
	if (addset)
		ringSetDestroy (addset);
	if (keyspec)
		pgpKeySpecDestroy (keyspec);
	if (pgpEnvCopy)
		pgpenvDestroy (pgpEnvCopy);
	return error;
}


static const PGPOptionType changepassphraseOptionSet[] = {
	kPGPOptionType_Passphrase,
	kPGPOptionType_Passkey
};

PGPError
pgpChangePassphraseInternal(
	PGPKeyRef			key,
	PGPOptionListRef	optionList
	)
{
	PGPContextRef		context;
	PGPOption			oldOp, newOp;
	RingSet	const		*ringset;
	void *				oldPassphrase;
	void *				newPassphrase;
	PGPSize				oldPassphraseLength;
	PGPSize				newPassphraseLength;
	PGPBoolean			oldWasPasskey;
	PGPBoolean			newWasPasskey;
	PGPError			err = kPGPError_NoErr;

	pgpa(pgpaPGPKeyValid(key));
	PGPValidateKey( key );
	
	oldWasPasskey = FALSE;
	newWasPasskey = FALSE;

	context = key->keyDB->context;

	if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
									changepassphraseOptionSet,
									elemsof( changepassphraseOptionSet ) ) ) )
		goto error;

	/*
	 * Can't use our regular parsing functions because we are allowing
	 * the same option to be used more than once.
	 */

	/* Pick up old passphrase */
	if( IsPGPError( err = pgpGetIndexedOption( optionList,
					  0, TRUE, &oldOp ) ) )
		goto error;
	
	oldWasPasskey = oldOp.type == kPGPOptionType_Passkey;

	if( !oldWasPasskey && oldOp.type != kPGPOptionType_Passphrase )
	{
		err = kPGPError_BadParams;
		goto error;
	}
		
	/* Pick up new passphrase */
	if( IsPGPError( err = pgpGetIndexedOption( optionList,
					  1, TRUE, &newOp ) ) )
		goto error;
	
	newWasPasskey = newOp.type == kPGPOptionType_Passkey;

	if( !newWasPasskey && newOp.type != kPGPOptionType_Passphrase )
	{
		err = kPGPError_BadParams;
		goto error;
	}
		
	pgpOptionPtrLength( &oldOp, &oldPassphrase, &oldPassphraseLength );
	pgpOptionPtrLength( &newOp, &newPassphrase, &newPassphraseLength );

	ringset = pgpKeyDBRingSet (key->keyDB);
	err = pgpDoChangePassphraseInternal (key->keyDB, ringset, key->key, NULL,
							 (char const *)oldPassphrase, oldPassphraseLength,
							 (char const *)newPassphrase, newPassphraseLength,
							 newWasPasskey);
	if (!err) {
		/* Ringset for keydb may be changed by above call */
		ringset = pgpKeyDBRingSet (key->keyDB);
	}

error:

	return err;
}


PGPError
pgpChangeSubKeyPassphraseInternal(
	PGPSubKeyRef		subkey,
	PGPOptionListRef	optionList
	)
{
	PGPContextRef		context;
	PGPOption			oldOp, newOp;
	RingSet	const		*ringset;
	void *				oldPassphrase;
	void *				newPassphrase;
	PGPSize				oldPassphraseLength;
	PGPSize				newPassphraseLength;
	PGPBoolean			oldWasPasskey;
	PGPBoolean			newWasPasskey;
	PGPError			err = kPGPError_NoErr;

	PGPValidateSubKey( subkey );
	
	oldWasPasskey = FALSE;
	newWasPasskey = FALSE;

	context = subkey->key->keyDB->context;

	if (IsPGPError( err = pgpCheckOptionsInSet( optionList,
									changepassphraseOptionSet,
									elemsof( changepassphraseOptionSet ) ) ) )
		goto error;

	/*
	 * Can't use our regular parsing functions because we are allowing
	 * the same option to be used more than once.
	 */

	/*
	 * Can't use our regular parsing functions because we are allowing
	 * the same option to be used more than once.
	 */

	/* Pick up old passphrase */
	if( IsPGPError( err = pgpGetIndexedOption( optionList,
					  0, TRUE, &oldOp ) ) )
		goto error;
	
	oldWasPasskey = oldOp.type == kPGPOptionType_Passkey;

	if( !oldWasPasskey && oldOp.type != kPGPOptionType_Passphrase )
	{
		err = kPGPError_BadParams;
		goto error;
	}
		
	/* Pick up new passphrase */
	if( IsPGPError( err = pgpGetIndexedOption( optionList,
					  1, TRUE, &newOp ) ) )
		goto error;
	
	newWasPasskey = newOp.type == kPGPOptionType_Passkey;

	if( !newWasPasskey && newOp.type != kPGPOptionType_Passphrase )
	{
		err = kPGPError_BadParams;
		goto error;
	}
		
	pgpOptionPtrLength( &oldOp, &oldPassphrase, &oldPassphraseLength );
	pgpOptionPtrLength( &newOp, &newPassphrase, &newPassphraseLength );

	CHECKREMOVED(subkey);
	ringset = pgpKeyDBRingSet (subkey->key->keyDB);

	err = pgpDoChangePassphraseInternal (subkey->key->keyDB, ringset,
						 subkey->subKey, subkey->key->key,
						 (char const *)oldPassphrase, oldPassphraseLength,
						 (char const *)newPassphrase, newPassphraseLength,
						 newWasPasskey);
error:

	return err;
}


/*  Remove a subkey */

PGPError
PGPRemoveSubKey (PGPSubKeyRef subkey)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -