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

📄 pgpkeyman.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (error) {
		ringSetDestroy (addset);
		return error;
	}
	error = pgpAddObjects (keys, addset);
	ringSetDestroy (addset);
	return error;
}


/* Given a cert, return the certifying key object. The signing key does not
	have to be in the same set as <cert>, and may be in the <allkeys> set. */

PGPError
pgpGetCertifier (PGPCert *cert, PGPKeySet *allkeys, PGPKey **certkey)
{
	char	keyID[33];
	size_t	keyIDLength = sizeof(keyID);

	pgpa(pgpaPGPCertValid(cert));
	CHECKREMOVED(cert);
	pgpGetCertString(cert, kPGPCertPropKeyID, keyID, &keyIDLength);
	*certkey = pgpGetKeyByKeyID(allkeys, (unsigned char *) keyID, keyIDLength);
	return PGPERR_OK;
}


/* Revoke a certification. If allkeys == NULL, the certifying key
	must be in the same keyDB as the certificate. */

PGPError
pgpRevokeCert (PGPCert *cert, PGPKeySet *allkeys, char *passphrase)
{
	PGPKeyDB			*keys;
	PGPKey				*certkey;
	struct RingSet		*allset, *addset, *signerset;
	union RingObject	*sigobj, *nameobj;
	Boolean				revoked;
	PGPError			error = PGPERR_OK;

	pgpa(pgpaPGPCertValid(cert));
	CHECKREMOVED(cert);
	keys = cert->up.userID->key->keyDB;
	sigobj = cert->cert;
	if (!(*keys->isMutable) (keys))
		return PGPERR_KEYDB_KEYDBREADONLY;

	error = pgpGetCertBoolean (cert, kPGPCertPropIsRevoked, &revoked);
	if (error)
		return error;
	if (revoked)
		return PGPERR_OK; /* already revoked */

	/* Get certifying key and its RingSet */
	error = pgpGetCertifier (cert, allkeys, &certkey);
	if (error)
		return error;
	if (!certkey)
		return PGPERR_NO_SECKEY;
	if (pgpKeyIsDead (certkey))
		return PGPERR_KEYDB_CERTIFYINGKEY_DEAD;
	signerset = pgpKeyDBRingSet (certkey->keyDB);

	/* Get signature RingSet and its name object */
	allset = pgpKeyDBRingSet (cert->up.userID->key->keyDB);
	nameobj = cert->up.userID->userID;

	error = pgpCopyKey (allset, nameobj, &addset);
	if (error)
		return error;
	error = pgpCertifyObject (nameobj, addset, certkey->key, signerset,
							PGP_SIGTYPE_KEY_UID_REVOKE, passphrase, FALSE);
	if (error) {
		ringSetDestroy (addset);
		return error;
	}
	error = pgpAddObjects (keys, addset);
	ringSetDestroy (addset);
	return error;
}


/* Remove a certification. If the certification was revoked, the
	revocation signature remains. This ensures that the same
	signature on someone else's keyring is properly revoked
	if this key is exported. A future certification will have
	a later creation timestamp than the revocation and will therefore
	not be affected. */

PGPError
pgpRemoveCert (PGPCert *cert)
{
	PGPKeyDB			*keys;
	union RingObject	*sigobj;

	pgpa(pgpaPGPCertValid(cert));
	CHECKREMOVED(cert);
	keys = cert->up.userID->key->keyDB;
	sigobj = cert->cert;
	if (!(*keys->isMutable) (keys))
		return PGPERR_KEYDB_KEYDBREADONLY;
	if (!(*keys->objIsMutable) (keys, sigobj))
		return PGPERR_KEYDB_OBJECTREADONLY;
	return pgpRemoveObject (keys, sigobj);
}


/* Given a key, return the nth (0 based) message recovery key, if one exists.
	Also return the class of the MRK, and the number of MRK's for the
	base key. Any of the return pointers may be NULL. */

PGPError
pgpGetMessageRecoveryKey (PGPKey *basekey, PGPKeySet *allkeys, unsigned nth,
PGPKey **mrkey, byte *mrclass, unsigned *numbermrks)
{
	struct RingSet		*ringset;		 /* Aurora ringset to look in */
	union RingObject *keyobj;	 	/* Aurora base key */
	union RingObject *rkey;		 	/* Aurora message recovery key */
	unsigned			nmrks;		 	/* Number MRK's available */
	byte				tclass;		 /* Class code from MRK */
	PGPError			error;		 	/* Error return from Aurora */
	byte				keyID[8];	 	/* keyid of MRK */

	pgpa(pgpaPGPKeyValid(basekey));
	ringset = pgpKeyDBRingSet (basekey->keyDB);
	keyobj = basekey->key;
	rkey = ringKeyRecoveryKey (keyobj, ringset, nth, &tclass, &nmrks, &error);
	if (!rkey) {
		/* No key found, or error */
		if (mrkey)
			*mrkey = NULL;
		if (mrclass)
			*mrclass = 0;
		if (numbermrks)
			*numbermrks = 0;
		return error;
	}
	/* Success */
	if (mrkey) {
		/* Can only look up master keys at this level */
		if (ringKeyIsSubkey(ringset, rkey))
			rkey = ringKeyMasterkey (ringset, rkey);
		ringKeyID8 (ringset, rkey, NULL, keyID);
		*mrkey = pgpGetKeyByKeyID (allkeys, keyID, sizeof(keyID));
	}
	if (mrclass)
		*mrclass = tclass;
	if (numbermrks)
		*numbermrks = nmrks;
	return PGPERR_OK;
}


/* Trust-related functions */

PGPError
pgpSetUserIDConf (PGPUserID *userid, unsigned long confidence)
{
	PGPKeyDB			*keys;
	struct RingSet		*allset = NULL, *addset = NULL;
	union RingObject *nameobj;
	PGPError			error = PGPERR_OK;

	pgpa(pgpaPGPUserIDValid(userid));
	pgpAssert (pgpTrustModel (pgpRingPool) > PGPTRUST0);
	CHECKREMOVED(userid);
	if (pgpKeyIsDead (userid->key))
		return PGPERR_BADPARAM;

	keys = userid->key->keyDB;
	allset = pgpKeyDBRingSet (keys);
	nameobj = userid->userID;
	if (ringKeyIsSec (allset, userid->key->key))
		return PGPERR_BADPARAM;
	if (!(*keys->isMutable) (keys))
		return PGPERR_KEYDB_KEYDBREADONLY;

	error = pgpCopyKey (allset, nameobj, &addset);
	if (error)
		return error;
	if (!(*keys->objIsMutable) (keys, nameobj)) {
		error = pgpAddObjects (keys, addset);
		if (error)
			goto cleanup;
	}
	ringNameSetConfidence (allset, nameobj, (unsigned short) confidence);
	pgpKeyDBChanged (keys, addset);
cleanup:
	if (addset)
		ringSetDestroy (addset);
	return error;
}


/* Set the trust on a key. Cannot be used to set undefined or
	axiomatic trust. The key must be valid to assign trust. */

PGPError
pgpSetKeyTrust (PGPKey *key, unsigned char trust)
{
	PGPKeyDB			*keys;
	struct RingSet		*allset, *addset = NULL;
	union RingObject	*keyobj;
	PGPError			error = PGPERR_OK;
#if ONLY_TRUST_VALID_KEYS
	long validity;
#endif

	pgpa(pgpaPGPKeyValid(key));
	pgpAssert (pgpTrustModel (pgpRingPool) == PGPTRUST0);

	keys = key->keyDB;
	if (!(*keys->isMutable) (keys))
		return PGPERR_KEYDB_KEYDBREADONLY;

	allset = pgpKeyDBRingSet (keys);
	keyobj = key->key;

	if (trust <= PGP_KEYTRUST_UNDEFINED || trust > PGP_KEYTRUST_COMPLETE ||
		pgpKeyIsDead (key) || ringKeyAxiomatic (allset, keyobj))
	return PGPERR_BADPARAM;

#if ONLY_TRUST_VALID_KEYS
	/* Should not set trust on key that is not completely valid
		(who is it we are trusting?) */
	pgpGetKeyNumber (key, kPGPKeyPropValidity, &validity);
	if (validity != PGP_VALIDITY_COMPLETE)
	return PGPERR_BADPARAM;
#endif

	error = pgpCopyKey (allset, keyobj, &addset);
	if (error)
		return error;
	if (!(*keys->objIsMutable) (keys, keyobj)) {
		error = pgpAddObjects (keys, addset);
		if (error)
			goto cleanup;
	}

	ringKeySetTrust (allset, keyobj, trust);
	pgpKeyDBChanged (keys, addset);
cleanup:
	if (addset)
		ringSetDestroy (addset);
	return error;
}


/* Set a secret key as the axiomatic key. If checkPassphrase == TRUE,
	the user must prove knowledge of the passphrase in order to do
	this. */

PGPError
pgpSetKeyAxiomatic (PGPKey *key, Boolean checkPassphrase, char *passphrase)
{
	Boolean	secret, axiomatic;
	struct RingSet	*allset, *addset = NULL;
	union RingObject	*keyobj;
	struct PgpSecKey	*seckey;
	PGPKeyDB	*keys;
	PGPError	error = PGPERR_OK;

	pgpa(pgpaPGPKeyValid(key));
	pgpGetKeyBoolean (key, kPGPKeyPropIsSecret, &secret);
	if (!secret)
	return PGPERR_BADPARAM;
	pgpGetKeyBoolean (key, kPGPKeyPropIsAxiomatic, &axiomatic);
	if (axiomatic)
	return PGPERR_OK;

	keys = key->keyDB;
	allset = pgpKeyDBRingSet (keys);
	keyobj = key->key;

	if (checkPassphrase) {
	/* Get the secret key and attempt to unlock it */
	seckey = ringSecSecKey (allset, keyobj, PGP_PKUSE_SIGN);
		if (!seckey)
		return ringSetError(allset)->error;
		if (pgpSecKeyIslocked (seckey)) {
		if (!passphrase) {
			pgpSecKeyDestroy (seckey);
			return PGPERR_KEYDB_BADPASSPHRASE;
			}
			error = pgpSecKeyUnlock (seckey, pgpEnv, passphrase,
									strlen (passphrase));
			pgpSecKeyDestroy (seckey);
			if (error != 1) {
				if (error == 0)
				error = PGPERR_KEYDB_BADPASSPHRASE;
				return error;
			}
		}
	}

	/* Make sure it's enabled first before setting axiomatic */
	if ((error = pgpEnableKey (key)) != PGPERR_OK)
	return error;
	if ((error = pgpCopyKey (allset, keyobj, &addset)) != PGPERR_OK)
		return error;
	if (!(*keys->objIsMutable) (keys, keyobj)) {
		if ((error = pgpAddObjects (keys, addset)) != PGPERR_OK)
			goto cleanup;
	}
	ringKeySetAxiomatic (allset, keyobj);
	pgpKeyDBChanged (keys, addset);
cleanup:
	if (addset)
	ringSetDestroy (addset);
	return error;
}


PGPError
pgpUnsetKeyAxiomatic (PGPKey *key)
{
	Boolean	axiomatic;
	struct RingSet	*allset, *addset = NULL;
		union RingObject	*keyobj;
		PGPKeyDB	*keys;
		PGPError	error = PGPERR_OK;

	pgpa(pgpaPGPKeyValid(key));
	pgpGetKeyBoolean (key, kPGPKeyPropIsAxiomatic, &axiomatic);
	if (!axiomatic)
	return PGPERR_BADPARAM;

	keys = key->keyDB;
	allset = pgpKeyDBRingSet (keys);
	keyobj = key->key;

	error = pgpCopyKey (allset, keyobj, &addset);
	if (error)
		return error;
	if (!(*keys->objIsMutable) (keys, keyobj)) {
		error = pgpAddObjects (keys, addset);
		if (error)
			goto cleanup;
	}
	ringKeyResetAxiomatic (allset, keyobj);
	pgpKeyDBChanged (keys, addset);
cleanup:
	if (addset)
	ringSetDestroy (addset);
	return error;
}



/* Get property functions. Internal GetKey functions work for both
master keys and subkeys. */


static PGPError
pgpReturnPropBuffer (char const *src, char *prop,
					size_t srclen, size_t proplen)
{
PGPError result = PGPERR_OK;

	if (srclen > proplen) {
	srclen = proplen;
		result = PGPERR_KEYDB_BUFFERTOOSHORT;
	}
	if (prop && srclen > 0)
	pgpCopyMemory (src, prop, srclen);
	return result;
}


static PGPError
pgpGetKeyNumberInternal (RingSet *ringset, RingObject *keyobj,
			 		 			PGPKeyPropName propname, long *prop)
{
		byte	 		 		keyid[8];
		unsigned long			longkeyid;
		unsigned char			pkalg;
		int	i;
		byte	trust;

	switch (propname) {
	case kPGPKeyPropKeyId:
		ringKeyID8 (ringset, keyobj, NULL, keyid);
		longkeyid = 0;
		for (i = 4; i < 8; i++)
			longkeyid = (longkeyid << 8) + keyid[i];
		*prop = (long) longkeyid; /* *prop should be cast to (unsigned long) */
		break;
	case kPGPKeyPropAlgId:
		ringKeyID8 (ringset, keyobj, &pkalg, NULL);
		*prop = (long) pkalg;
		break;
	case kPGPKeyPropBits:
		*prop = (long) ringKeyBits (ringset, keyobj);
		break;
	case kPGPKeyPropTrust:
		if (pgpTrustModel (pgpRingPool) == PGPTRUST0) {
			trust = ringKeyTrust (ringset, keyobj);
			if (trust == PGP_KEYTRUST_UNDEFINED ||
				trust == PGP_KEYTRUST_UNKNOWN)
			trust = PGP_KEYTRUST_NEVER;
			*prop = (long) trust;
			break;
		}
	default:
		return PGPERR_KEYDB_INVALIDPROPERTY;
	}
	return PGPERR_OK;
}


PGPError
pgpGetKeyNumber (PGPKey *key, PGPKeyPropName propname, long *prop)
{
	PGPError	error = PGPERR_OK;
		PGPUserID	*userid;
		RingSet	*ringset;
		long	trustval;

	pgpa(pgpaPGPKeyValid(key));
  switch (propname) {
	case kPGPKeyPropValidity:
		if (pgpTrustModel (pgpRingPool) == PGPTRUST0) {
			*prop = PGP_VALIDITY_UNKNOWN;
			pgpIncKeyRefCount (key);
			for (userid = (PGPUserID *) key->userIDs.next;
				userid != (PGPUserID *) &key->userIDs;
				userid = userid->next) {
				if (!userid->removed) {
					pgpGetUserIDNumber (userid, kPGPUserIDPropValidity,
										&trustval);
					if (trustval > *prop)
						*prop = trustval;
				}
			}
			pgpFreeKey (key);
		}
		else {
		ringset = pgpKeyDBRingSet (key->keyDB);
			*prop = (long) ringKeyConfidence (ringset, key->key);
		}
		break;
	default:
	ringset = pgpKeyDBRingSet (key->keyDB);
		error = pgpGetKeyNumberInternal (ringset, key->key, propname, prop);
	}
	return error;
}

PGPError
pgpGetSubKeyNumber (PGPSubKey *subkey, PGPKeyPropName propname, long *prop)
{
PGPError error = PGPERR_OK;
	RingSet *ringset;

	pgpa(pgpaPGPSubKeyValid(subkey));
	CHECKREMOVED(subkey);
	switch (propname) {
	case kPGPKeyPropKeyId:
	case kPGPKeyPropAlgId:
	case kPGPKeyPropBits:
	ringset = pgpKeyDBRingSet (subkey->key->keyDB);
	error = pgpGetKeyNumberInternal (ringset, subkey->subKey,
										propname, prop);
		break;
	default:
		return PGPERR_KEYDB_INVALIDPROPERTY;
	}
	return error;
}


static PGPError
pgpGetKeyTimeInternal (RingSet *ringset, RingObject *keyobj,
					PGPKeyPropName propname, PGPTime *prop)
{
	switch (propname) {
	case kPGPKeyPropCreation:
		*prop = ringKeyCreation (ringset, keyobj);
		break;
	case kPGPKeyPropExpiration:
		*prop = ringKeyExpiration (ringset, keyobj);
		break;
	default:
		return PGPERR_KEYDB_INVALIDPROPERTY;
	}
	return PGPERR_OK;
}


PGPError
pgpGetKeyTime (PGPKey *key, PGPKeyPropName propname, PGPTime *prop)
{
RingSet *ringset;
	
	pgpa(pgpaPGPKeyValid(key));
	ringset = pgpKeyDBRingSet (key->keyDB);
	return pgpGetKeyTimeInternal (ringset, key->key, propname, prop);
}


PGPError
pgpGetSubKeyTime (PGPSubKey *subkey, PGPKeyPropName propname, PGPTime *prop)
{
RingSet *ringset;
	
	pgpa(pgpaPGPSubKeyValid(subkey));
	CHECKREMOVED(subkey);
	ringset = pgpKeyDBRingSet (subkey->key->keyDB);
	return pgpGetKeyTimeInternal (ringset, subkey->subKey, propname, prop);
}


static PGPError
pgpGetKeyStringInternal (RingSet *ringset, RingObject *keyobj,
							PGPKeyPropName propname, char *prop, size_t *len)
{
		unsigned char			pkalg;
		unsigned char	buffer[20];
		size_t	length = *len;

	switch (propname) {
	case kPGPKeyPropKeyId:
		ringKeyID8 (ringset, keyobj, NULL, buffer);
		*len = 8;
		break;
	case kPGPKeyPropFingerprint:
		ringKeyID8 (ringset, keyobj, &pkalg, NULL);
		if (pkalg == 1) {

⌨️ 快捷键说明

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