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

📄 pgpkeyobj.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 5 页
字号:
/*____________________________________________________________________________
        Copyright (C) 2002 PGP Corporation
        All rights reserved.

		low level functions for keydb objects
		
        $Id: pgpKeyObj.c,v 1.99 2002/10/29 04:50:59 ajivsov Exp $
____________________________________________________________________________*/
#include "pgpConfig.h"
#include <string.h>

#include <ctype.h>	/* For tolower() */

#include "pgpDebug.h"
#include "pgpKeyPriv.h"
#include "pgpErrors.h"
#include "pgpPubKey.h"
#include "pgpPktByte.h"
#include "pgpSigSpec.h"
#include "pgpMem.h"
#include "pgpContext.h"
#include "pgpEnv.h"
#include "pgpP11Key.h"
#include "pgpTrustPriv.h"
#include "pgpX509Priv.h"
#include "pgpHashPriv.h"
#include "pgpRegExp.h"
#include "pgpSymmetricCipherPriv.h"
#include "pgpPassCach.h"

#ifndef NULL
#define NULL 0
#endif


/* Return the type of a PGPKeyDBObj */
	PGPUInt32
pgpObjectType(PGPKeyDBObj const *obj)
{
	pgpAssert (obj);
	if (obj->objflags & kPGPKeyDBObjType_Key )
		return RINGTYPE_KEY;
	if (obj->objflags & kPGPKeyDBObjType_SubKey )
		return RINGTYPE_SUBKEY;
	if (obj->objflags & kPGPKeyDBObjType_UserID )
		return RINGTYPE_USERID;
	if (obj->objflags & kPGPKeyDBObjType_Signature )
		return RINGTYPE_SIG;
	if (obj->objflags & kPGPKeyDBObjType_CRL )
		return RINGTYPE_CRL;
	return RINGTYPE_UNK;
}


	static ObjDataHeader **
sObjectDataPointer( PGPKeyDBObj const *obj )
{
	PGPKeyInfo *kinfo;
	PGPUserIDInfo *uinfo;
	PGPSigInfo *sinfo;
	PGPCRLInfo *cinfo;
	PGPUnkInfo *xinfo;
	ObjDataHeader **dptr = NULL;

	switch( pgpObjectType( obj ) )
	{
	case RINGTYPE_KEY:
	case RINGTYPE_SUBKEY:
		kinfo = pgpKeyToKeyInfo( obj );
		dptr = &kinfo->data;
		break;
	case RINGTYPE_USERID:
		uinfo = pgpUserIDToUserIDInfo( obj );
		dptr = &uinfo->data;
		break;
	case RINGTYPE_SIG:
		sinfo = pgpSigToSigInfo( obj );
		dptr = &sinfo->data;
		break;
	case RINGTYPE_CRL:
		cinfo = pgpCRLToCRLInfo( obj );
		dptr = &cinfo->data;
		break;
	case RINGTYPE_UNK:
		xinfo = pgpUnkToUnkInfo( obj );
		dptr = &xinfo->data;
		break;
	default:
		pgpAssert( 0 );
		break;
	}
	return dptr;
}


/* Return pointer to obj's info id field */
	static PGPUInt32 *
sObjectIDPointer( PGPKeyDBObj const *obj )
{
	PGPKeyInfo *kinfo;
	PGPUserIDInfo *uinfo;
	PGPSigInfo *sinfo;
	PGPCRLInfo *cinfo;
	PGPUnkInfo *xinfo;
	PGPUInt32 *idptr = NULL;

	switch( pgpObjectType( obj ) )
	{
	case RINGTYPE_KEY:
	case RINGTYPE_SUBKEY:
		kinfo = pgpKeyToKeyInfo( obj );
		idptr = &kinfo->id;
		break;
	case RINGTYPE_USERID:
		uinfo = pgpUserIDToUserIDInfo( obj );
		idptr = &uinfo->id;
		break;
	case RINGTYPE_SIG:
		sinfo = pgpSigToSigInfo( obj );
		idptr = &sinfo->id;
		break;
	case RINGTYPE_CRL:
		cinfo = pgpCRLToCRLInfo( obj );
		idptr = &cinfo->id;
		break;
	case RINGTYPE_UNK:
		xinfo = pgpUnkToUnkInfo( obj );
		idptr = &xinfo->id;
		break;
	default:
		pgpAssert( 0 );
		break;
	}
	return idptr;
}

/* Return ID corresponding to front end object */
	PGPUInt32
pgpKeyDBObjID( PGPKeyDBObj const *obj )
{
	if( obj->objflags & kPGPKeyDBObjFlags_ID )
		return obj->idinfo.id;
	else
		return *sObjectIDPointer(obj);
}

/* True if key belongs to a front-end keydb */
	PGPBoolean
pgpFrontEndKey( PGPKeyDBObj const *obj )
{
	PGPKeyDB *db = PGPPeekKeyDBObjKeyDB( (PGPKeyDBObj *)obj );
	return pgpFrontEndKeyDB( db );
}


	static ObjDataHeader *
sObjectDataHeader( PGPKeyDBObj const *obj )
{
	return *sObjectDataPointer( obj );
}


/* Refcount the data buffers */
void
pgpObjectHold(PGPKeyDBObj *obj)
{
	ObjDataHeader *objdata;

	objdata = sObjectDataHeader( obj );
	if( IsntNull( objdata ) )
		++objdata->refcount;
}

void
pgpObjectRelease(PGPKeyDBObj *obj)
{
	ObjDataHeader *objdata;

	objdata = sObjectDataHeader( obj );
	if( IsntNull( objdata )  &&  objdata->refcount > 0)
		--objdata->refcount;
}

	PGPByte const *
pgpFetchObject( PGPKeyDBObj const *obj, PGPSize *len )
{
	ObjDataHeader *objdata;

	objdata = sObjectDataHeader( obj );
	if( IsNull( objdata ) )
	{
		PGPByte *buf;
		PGPSize buflen;
		PGPKeyDB *kdb = PGPPeekKeyDBObjKeyDB( (PGPKeyDBObj *)obj );
		PGPContextRef context = PGPPeekKeyDBContext( kdb );
		pgpFetchObjectData_back( context, pgpKeyDBObjID( obj ),
								 &buf, &buflen );
		objdata = pgpNewObjData( kdb, buf, buflen );
		PGPFreeData( buf );
		*sObjectDataPointer( obj ) = objdata;
		
	}
	*len = objdata->len;
	return objdata->data;
}


/* Return a new data header suitable for assigning to ->data */
	void *
pgpNewObjData( PGPKeyDB *kdb, PGPByte const *buf, PGPSize len )
{
	ObjDataHeader *data;
	PGPByte *databuf;
	MemPool cutback;

	cutback = kdb->objPool;
	
	data = memPoolAlloc( &kdb->objPool, sizeof(ObjDataHeader), 4 );
	if( data == NULL )
		goto outofmem;

	databuf = memPoolAlloc( &kdb->objPool, len, 1 );
	if( databuf == NULL )
		goto outofmem;
	pgpCopyMemory( buf, databuf, len );

	data->data = databuf;
	data->len = len;
	data->refcount = 1;
	return data;

 outofmem:
	memPoolCutBack( &kdb->objPool, &cutback );
	pgpKeyDBSetError( kdb, kPGPError_OutOfMemory );
	return NULL;
}

/* Change the data buffer associated with an object */
	PGPError
pgpUpdateObjData( PGPKeyDBObj *obj, PGPByte *buf, PGPSize len )
{
	ObjDataHeader *objdata;
	PGPKeyDB *kdb;
	PGPByte *databuf;

	objdata = sObjectDataHeader( obj );
	if( IsNull( objdata ) )
	{
		return pgpKeyDBError( PGPPeekKeyDBObjKeyDB( obj ) );
	}

	kdb = PGPPeekKeyDBObjKeyDB( obj );
	databuf = memPoolAlloc( &kdb->objPool, len, 1 );
	if( databuf == NULL )
		return kPGPError_OutOfMemory;

	pgpCopyMemory( buf, databuf, len );
	objdata->data = databuf;
	objdata->len = len;

	return kPGPError_NoErr;
}


/*** Access functions for information about objects ***/

	PGPUInt32
pgpKeyBits(PGPKeyDBObj *key)
{
	PGPKeyInfo *kinfo;

	pgpAssert(OBJISKEY(key));
	kinfo = pgpKeyToKeyInfo( key );
	return kinfo->keybits;
}

	PGPUInt32
pgpKeyCreation(PGPKeyDBObj *key)
{
	PGPKeyInfo *kinfo;

	pgpAssert(OBJISKEY(key));
	kinfo = pgpKeyToKeyInfo( key );
	return kinfo->creationtime;
}

	PGPUInt32
pgpKeyExpiration(PGPKeyDBObj *key)
{
	PGPKeyInfo *kinfo;

	pgpAssert(OBJISKEY(key));
	kinfo = pgpKeyToKeyInfo( key );
	if (kinfo->creationtime == 0 || kinfo->validityperiod == 0)
		return 0;    /* valid indefinitely */
	else
		return kinfo->creationtime + (kinfo->validityperiod * 3600 * 24);
}

/*
 * If called for a subkey, force to just encryption if subkeyCanVerify is FALSE.
 * If called for a key with a subkey, return the "or" of both.
 * Else just do the key itself.
 * Internal form of pgpKeyUse - if unExpired is true, check that the
 * subkeys are unexpired before saying it has encryption usage.
 * pgpKeyUse and pgpKeyUnexpiredUse are macros that call this now.
 */
	PGPUInt32
pgpKeyUseInternal(PGPKeyDBObj *key, PGPBoolean unExpired, PGPBoolean revokedOK, PGPBoolean subkeyCanVerify)
{
	PGPKeyInfo *kinfo;
	int use;
	int first = TRUE;

	pgpAssert(OBJISKEY(key));
	kinfo = pgpKeyToKeyInfo( key );

	use = pgpKeyAlgUse(pgpPkalgByNumber(kinfo->pkalg));
	if (OBJISSUBKEY(key) && !subkeyCanVerify)
		use &= PGP_PKUSE_ENCRYPT;	/* force key capabilities to encryption only */
	for (key=key->down; key; key=key->next) {
		if( !pgpKeyDBObjIsReal(key) )
			continue;
		if (OBJISSUBKEY(key) && pgpSubkeyValid(key, unExpired, revokedOK))
		{
			kinfo = pgpKeyToKeyInfo( key );
			if( first )
				use &= PGP_PKUSE_SIGN;
			first = FALSE;
			use |= pgpKeyAlgUse(pgpPkalgByNumber(kinfo->pkalg));
		}
	}
	return use;
}


	PGPByte
pgpKeyTrust(PGPKeyDBObj *key)
{
	PGPKeyInfo *kinfo;

	pgpAssert(OBJISKEY(key));
	kinfo = pgpKeyToKeyInfo( key );
	return pgpMax(kinfo->trust & kPGPKeyTrust_Mask,
				  kinfo->signedTrust & kPGPKeyTrust_Mask);
}

void
pgpKeySetTrust(PGPKeyDBObj *key, PGPByte trust)
{
	PGPKeyInfo *kinfo;

	pgpAssert(OBJISKEY(key));
	kinfo = pgpKeyToKeyInfo( key );
	pgpAssert(trust==kPGPKeyTrust_Unknown  || trust==kPGPKeyTrust_Never ||
	       trust==kPGPKeyTrust_Marginal || trust==kPGPKeyTrust_Complete);
	pgpAssert (!(kinfo->trust & PGP_KEYTRUSTF_BUCKSTOP));
	if (kinfo->trust & (PGP_KEYTRUSTF_REVOKED | PGP_KEYTRUSTF_EXPIRED))
	    return;
	if ((kinfo->trust & kPGPKeyTrust_Mask) != trust) {
		kinfo->trust = (kinfo->trust & ~kPGPKeyTrust_Mask) + trust;
	}
}


/*
 * Used to set a key as an "axiomatic" key, that is, one for which
 * we hold the private key.  This also involves setting each name on that
 * key as having complete validity.
 */
void
pgpKeySetAxiomatic(PGPKeyDBObj *key)
{
	PGPKeyInfo *kinfo;
	PGPUserIDInfo *uinfo;
	PGPKeyDBObj *name = NULL;

    pgpAssert(OBJISKEY(key));
	kinfo = pgpKeyToKeyInfo( key );
    if( !pgpKeyIsSec (key) ||
			(kinfo->trust & PGP_KEYTRUSTF_REVOKED) )
        return;        /* already axiomatic or can't set */
    kinfo->trust &= ~kPGPKeyTrust_Mask;
    kinfo->trust |= (PGP_KEYTRUSTF_BUCKSTOP | kPGPKeyTrust_Ultimate);
	/* Make sure all names have axiomatic confidence */
	for (name=key->down; name; name=name->next) {
		if( !pgpKeyDBObjIsReal(name) )
			continue;
		if (OBJISUSERID(name)) {
			uinfo = pgpUserIDToUserIDInfo( name );
			uinfo->confidence = PGP_NEWTRUST_INFINITE;
		}
	}
}


/*  Reset an axiomatic key.  Trust is set to undefined. */

void
pgpKeyResetAxiomatic (PGPKeyDBObj *key)
{
	PGPKeyInfo *kinfo;
	PGPUserIDInfo *uinfo;
	PGPKeyDBObj *name = NULL;

    pgpAssert(OBJISKEY(key));
	kinfo = pgpKeyToKeyInfo( key );
    kinfo->trust &= ~PGP_KEYTRUSTF_BUCKSTOP;
    kinfo->trust = (kinfo->trust & ~kPGPKeyTrust_Mask) + 
                           kPGPKeyTrust_Undefined;
	/* Make sure all names have undefined confidence */
	for (name=key->down; name; name=name->next) {
		if( !pgpKeyDBObjIsReal(name) )
			continue;
		if (OBJISUSERID(name)) {
			uinfo = pgpUserIDToUserIDInfo( name );
			uinfo->confidence = PGP_NEWTRUST_UNDEFINED;
		}
	}
}


	PGPBoolean
pgpKeyAxiomatic(PGPKeyDBObj *key)
{
	PGPKeyInfo *kinfo;

	pgpAssert(OBJISKEY(key));
	kinfo = pgpKeyToKeyInfo( key );
	return (kinfo->trust & PGP_KEYTRUSTF_BUCKSTOP) != 0;
}


/* Return TRUE if the key is a subkey */
	PGPBoolean
pgpKeyIsSubkey (PGPKeyDBObj const *key)
{
     return OBJISSUBKEY(key) != 0;
}


	PGPBoolean
pgpKeyDisabled(PGPKeyDBObj *key)
{
	PGPKeyInfo *kinfo;

	pgpAssert(OBJISKEY(key));
	kinfo = pgpKeyToKeyInfo( key );
	return (kinfo->trust & PGP_KEYTRUSTF_DISABLED) != 0;
}

void
pgpKeyDisable(PGPKeyDBObj *key)
{
	PGPKeyInfo *kinfo;

	pgpAssert(OBJISKEY(key));
	kinfo = pgpKeyToKeyInfo( key );
	if (!(kinfo->trust & PGP_KEYTRUSTF_DISABLED)) {
		kinfo->trust |= PGP_KEYTRUSTF_DISABLED;
	}
}

void
pgpKeyEnable(PGPKeyDBObj *key)
{
	PGPKeyInfo *kinfo;

	pgpAssert(OBJISKEY(key));
	kinfo = pgpKeyToKeyInfo( key );
	if (kinfo->trust & PGP_KEYTRUSTF_DISABLED) {
		kinfo->trust &= ~PGP_KEYTRUSTF_DISABLED;
	}
}



	PGPBoolean
pgpKeyRevoked(PGPKeyDBObj *key)
{
	PGPKeyInfo *kinfo;

	pgpAssert(OBJISKEY(key));
	kinfo = pgpKeyToKeyInfo( key );
	return (kinfo->trust & PGP_KEYTRUSTF_REVOKED) != 0;
}


/* Flag for keys whose secret part is on a token.  Only for back end. 
   'tok' is the token object to which 'key' belongs, or NULL if this is unknown
*/
void
pgpKeyOnToken(PGPKeyDBObj *key, PGPToken *tok)
{
	PGPKeyInfo *kinfo;

	pgpAssert(OBJISKEY(key));
	pgpAssert(!pgpFrontEndKey(key));
	kinfo = pgpKeyToKeyInfo( key );
	KEYSETTOKEN( kinfo );
	pgpKeySetAxiomatic( key );

	pgpSetKeyTokenNum( key, tok );
}

void
pgpKeyOffToken(PGPKeyDBObj *key)
{
	PGPKeyInfo *kinfo;

	pgpAssert(OBJISKEY(key));
	pgpAssert(!pgpFrontEndKey(key));
	kinfo = pgpKeyToKeyInfo( key );
	KEYCLEARTOKEN( kinfo );
	/* Mark as no longer axiomatic unless we have a secret part */
	if( !KEYISSEC( kinfo ) )
		pgpKeyResetAxiomatic( key );
	kinfo->tokenNum1 = 0;
}

	PGPBoolean
pgpKeyIsOnToken(PGPKeyDBObj *key)
{
	PGPKeyInfo *kinfo;

	pgpAssert(OBJISKEY(key));
	kinfo = pgpKeyToKeyInfo( key );
	return KEYISTOKEN( kinfo );
}

/* Flag for keys whose secret part has been mathematically checked */
void
pgpSecSetValidated(PGPKeyDBObj *sec)
{
	PGPKeyInfo *kinfo;

	pgpAssert(OBJISKEY(sec));
	pgpAssert(pgpKeyIsSec(sec));
	kinfo = pgpKeyToKeyInfo( sec );
	KEYSETVALIDATED( kinfo );
}

⌨️ 快捷键说明

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