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

📄 pgprngpriv.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 4 页
字号:
			pgpIsRingSetMember(set, sig) &&
		    ringSigMaker(set, sig, set)==key &&
		    ringSigType(set, sig) == PGP_SIGTYPE_KEY_SUBKEY) {
			if (!ringSigTried(set, sig))
				return 1; /* could check it here... */
			if (ringSigChecked(set, sig))
				return 1;
		}
	}
	return 0;
}

void
ringPurgeCachedName(RingPool const *pool, RingName *name, PGPVirtMask *mask)
{
	pgpAssert(NAMEISNAME(name));

	if (NAMEISCACHED(name)) {
		PGPInt32 bit = NAMEFILEMASK(name);
		PGPVirtMask tmask;
		pgpVirtMaskInit (pool, &tmask);
		pgpVirtMaskSetBit (pool, &tmask, bit);

		if (pgpVirtMaskIsOverlapping (&tmask, mask)) {
			/* Replace buffer with a hash of it */
			name->name.hash = ringHashBuf((PGPByte const *)name->name.ptr,
										  name->len);
			NAMECLEARCACHED(name);
		}
		pgpVirtMaskCleanup (pool, &tmask);
	}
}

/*
 * This function is called by the MemPool code when it runs out of memory.
 * We try to free up more memory by purging the uids from cache.
 * Returns zero if it was unable to make more memory available;
 * non-zero if it might be useful to retry an allocation.
 */
static int
ringPurgeUidCache(void *arg)
{
	RingPool *pool = (RingPool *)arg;
	PGPVirtMask notmemringmask;
	union RingObject *k, *n;
	unsigned i;

	/*
	 * Quick check to see if we can do anything.  As memory gets
	 * full, the full walk needed to clear the cache gets expensive,
	 * so avoid it unless it does some good.
	 */
	i = MEMRINGBIT+1;
	while (IsntNull(pool->files[i]) &&
		   memPoolIsEmpty(&pool->files[i]->strings)) {
		if (++i == pool->nfiles) /* Last resort: try garbage collect */
			return ringGarbageCollect(pool);
	}

	/*
	 * Okay, we have something cached to free; replace all the
	 * pointers to non-MEMRINGBIT cached named with hashes
	 * of the names and then deallocate the names.
	 */

	pgpVirtMaskInit (pool, &notmemringmask);
	pgpVirtMaskCopy (pool, &pool->memringmask, &notmemringmask);
	pgpVirtMaskNOT (pool, &notmemringmask, pool->nfiles);

	for (k = pool->keys; k; k = k->g.next) {
		pgpAssert(OBJISKEY(k));
		for (n = k->g.down; n; n = n->g.next) {
			if (OBJISNAME(n))
				ringPurgeCachedName(pool, &n->n, &notmemringmask);
		}
	}

	/* Free the pools */
	for (i = 0; i < pool->nfiles; i++)
		if (IsntNull(pool->files[i]))
			memPoolEmpty(&pool->files[i]->strings);

	pgpVirtMaskCleanup (pool, &notmemringmask);

	return 1;	/* We freed some memory */
}

/* 
 * Initialize a new RingFile structure.  This does not set the mask field.
 */
static void
ringFileInit(
	RingPool *pool, RingFile *file)
{
	pgpAssert( pgpContextIsValid( pool->context ) );
	
	file->set.pool = pool;
	file->set.next = NULL;
	pgpVirtMaskInit (pool, &file->set.mask);
	file->set.type = RINGSET_FILE;

	file->f = NULL;
	file->destructor = NULL;
	file->arg = NULL;
	memPoolInit( pool->context, &file->strings);
	memPoolInit( pool->context, &file->troublepool);
	memPoolSetPurge(&file->troublepool, ringPurgeUidCache, (void *)pool);
	file->trouble = NULL;
	file->troubletail = &file->trouble;
	memPoolInit( pool->context, &file->fpos);
	memPoolSetPurge(&file->fpos, ringPurgeUidCache, (void *)pool);
	file->freepos = NULL;
	pgpVirtMaskInit (pool, &file->higherpri);
	file->flags = 0;
}

/*
 * Initialize pool->files to hold entries so we can access newfile
 */
void
ringFilesInit(RingPool *pool, PGPUInt32 newfile)
{
	void *vfiles;
	RingFile *file;

	if (pool->nfiles < newfile+1) {
		vfiles = pool->files;
		pgpContextMemRealloc (pool->context, &vfiles,
				  (newfile+1) * sizeof(RingFile *), kPGPMemoryMgrFlags_Clear);
		pool->files = (RingFile **) vfiles;
		pool->nfiles = newfile+1;
	}
	/* Init newly allocated file struct */
	pool->files[newfile] = (RingFile *)pgpContextMemAlloc (pool->context,
								sizeof(RingFile), kPGPMemoryMgrFlags_Clear);
	file = pool->files[newfile];
	ringFileInit (pool, file);
	
	pgpVirtMaskSetBit (pool, &file->set.mask, newfile);
}

/*
 * Initialize a newly allocated RingPool.
 */
void
ringPoolInit(
	PGPContextRef	context,
	RingPool *		pool,
	PGPEnv const *	env)
{
	int i;

	pgpAssert( pgpContextIsValid( context ) );
	
	pool->context	= context;
	
	memPoolInit( context, &pool->structs);
	memPoolSetPurge(&pool->structs, ringPurgeUidCache, (void *)pool);
	pool->keys = NULL;

	for (i = 0; i < RINGTYPE_MAX; i++)
		pool->freeobjs[i] = NULL;
	pool->sets = NULL;
	pool->freesets = NULL;
	pool->freeiter = NULL;

	pool->pktbuf = NULL;
	pool->pktbuflen = 0;
	pool->pktbufalloc = 0;

	/* Reserve first keyring for memory */
	pgpVirtMaskInit (pool, &pool->memringmask);
	pgpVirtMaskInit (pool, &pool->allocmask);
	pgpVirtMaskInit (pool, &pool->filemask);
	pgpVirtMaskSetBit (pool, &pool->memringmask, MEMRINGBIT);
	pgpVirtMaskCopy (pool, &pool->memringmask, &pool->allocmask);
	pgpVirtMaskCopy (pool, &pool->memringmask, &pool->filemask);

	pool->flags = 0;

	if (env) {
		i = pgpenvGetInt(env, PGPENV_CERTDEPTH, NULL, NULL);
		pool->certdepth = i;

		/* Values used for TRUSTMODEL 0 */
		i = pgpenvGetInt(env, PGPENV_MARGINALS, NULL, NULL);
		pool->num_marginals = (i < 0) ? 0 : (i > 255) ? 255 : i;
		i = pgpenvGetInt(env, PGPENV_COMPLETES, NULL, NULL);
		pool->num_completes = (i < 0) ? 0 : (i > 255) ? 255 : i;

		/* Values used for TRUSTMODEL 1 */
		i = pgpenvGetInt(env, PGPENV_TRUSTED, NULL, NULL);
		pool->threshold = (i > PGP_NEWTRUST_INFINITE) ?
			PGP_NEWTRUST_INFINITE : (i < 0) ? 0 : i;

		i = pgpenvGetInt(env, PGPENV_MARGINALS, NULL, NULL);
		i = (i < 1) ? 0 : (pool->threshold+i-1)/i;
		pool->marginalconfidence = i;
	
		i = pgpenvGetInt(env, PGPENV_COMPLETES, NULL, NULL);
		i = (i < 1) ? 0 : (pool->threshold+i-1)/i;
		pool->completeconfidence = i;
	} else {
		pool->certdepth = 4;
		pool->num_marginals = 2;
		pool->num_completes = 1;
		pool->threshold = 3*PGP_TRUST_DECADE_INTERNAL;
		pool->marginalconfidence = 3*PGP_TRUST_DECADE_INTERNAL/2;
		pool->completeconfidence = 3*PGP_TRUST_DECADE_INTERNAL;
	}
#if PGPTRUSTMODEL==2
	memPoolInit (context, &pool->pathpool);
	pool->paths = NULL;
	pool->pathlists = NULL;
#endif
	
	ringPoolClearError(pool);

	for (i = 0; i < 256; i++)
		pool->hashtable[i] = NULL;

	pool->nfiles = 0;
	pool->files = NULL;
	ringFilesInit (pool, MEMRINGBIT);

	/* Also purge strings cache if needed to create a new object. */
	memPoolSetPurge(&pool->files[MEMRINGBIT]->strings,
	                ringPurgeUidCache, (void *)pool);
}

/*
 * Deallocate everything in sight on a RingPool preparatory to
 * deallocating it.
 */
void
ringPoolFini(RingPool *pool)
{
	RingFile *file;
	int bit;
	
	/*
	 * Do this first part, until the destructors are called,
	 * "properly" so structures aren't dangling undefined.
	 */
	for (bit = 0; bit < (int)pool->nfiles; bit++)
		if (IsntNull(pool->files[bit]))
			ringFilePurgeTrouble(pool->files[bit]);

	for (bit = 0; bit < (int)pool->nfiles; bit++) {
		file = pool->files[bit];
		if (file && file->destructor) {
			file->destructor(file, file->f, file->arg);
			file->destructor = NULL;
		}
	}

	memPoolEmpty(&pool->structs);
#if PGPTRUSTMODEL==2
	memPoolEmpty (&pool->pathpool);
#endif

	for (bit = 0; bit < (int)pool->nfiles; bit++) {
		file = pool->files[bit];
		if (IsntNull(file)) {
			memPoolEmpty(&file->strings);
			memPoolEmpty(&file->fpos);
			pgpVirtMaskCleanup(pool, &file->set.mask);
			pgpContextMemFree (pool->context, file);
			pool->files[bit] = NULL;
		}
	}

	if (IsntNull (pool->files)) {
		pgpContextMemFree (pool->context, pool->files);
		pool->files = NULL;
		pool->nfiles = 0;
	}

	if( IsntNull( pool->pktbuf ) )
		pgpContextMemFree( pool->context, pool->pktbuf);

	pgpVirtMaskCleanup (pool, &pool->memringmask);
	pgpVirtMaskCleanup (pool, &pool->allocmask);
	pgpVirtMaskCleanup (pool, &pool->filemask);

	/* Nuke the lot */
	pgpClearMemory( pool,  sizeof(*pool));
}

/*
 * This is defined as a macro.
 *
 * void
 * ringFileMarkDirty(RingFile *file)
 * {
 *	file->flags |= RINGFILEF_DIRTY;
 * }
 */

/*
 * Mark every file under a given mask as dirty.
 */
void
ringPoolMarkDirty(RingPool *pool, PGPVirtMask *mask)
{
	PGPVirtMask tmask;

	pgpVirtMaskInit (pool, &tmask);
	pgpVirtMaskCopy (pool, mask, &tmask);
	pgpVirtMaskAND (pool, &pool->filemask, &tmask);

	while (!pgpVirtMaskIsEmpty (&tmask)) {
		PGPInt32 bit = pgpVirtMaskLSBit (&tmask);
		pgpAssert (bit >= 0);
		ringFileMarkDirty(pool->files[bit]);
		pgpVirtMaskClearBit (pool, &tmask, bit);
	}
	pgpVirtMaskCleanup (pool, &tmask);
}

void
ringPoolMarkTrustChanged(RingPool *pool, PGPVirtMask *mask)
{
	PGPVirtMask tmask;

	pgpVirtMaskInit (pool, &tmask);
	pgpVirtMaskCopy (pool, mask, &tmask);
	pgpVirtMaskAND (pool, &pool->filemask, &tmask);

	while (!pgpVirtMaskIsEmpty (&tmask)) {
		PGPInt32 bit = pgpVirtMaskLSBit (&tmask);
		pgpAssert (bit >= 0);
		pool->files[bit]->flags |= RINGFILEF_TRUSTCHANGED;
		pgpVirtMaskClearBit (pool, &tmask, bit);
	}
	pgpVirtMaskCleanup (pool, &tmask);
}


/*
 * Do a fingerprint20 (SHA-1) hash on the specified buffer, which
 * should be key data.  We prefix it with the type and length bytes
 * for compatibility with key signature hashes (once they become SHA
 * based).  Return the number of bytes in the hash, or negative on
 * error.
 */
int
pgpFingerprint20HashBuf(PGPContextRef context, PGPByte const *buf, size_t len,
						PGPByte *hash)
{
	PGPHashVTBL const *h;
	PGPHashContext *hc;
	PGPByte tmpbuf[3];
	PGPByte const *p;
    PGPMemoryMgrRef	memoryMgr	= PGPGetContextMemoryMgr( context );

	h = pgpHashByNumber (kPGPHashAlgorithm_SHA);
	if (!h)
		return kPGPError_BadHashNumber;
	hc = pgpHashCreate( memoryMgr, h);
	if (!hc)
		return kPGPError_OutOfMemory;
	/* We use this format even for subkeys */
	tmpbuf[0] = PKTBYTE_BUILD(PKTBYTE_PUBKEY, 1);
	tmpbuf[1] = (PGPByte)(len>>8);
	tmpbuf[2] = (PGPByte)len;
	PGPContinueHash(hc, tmpbuf, 3);
	PGPContinueHash(hc, buf, len);
	p = (PGPByte *) pgpHashFinal(hc);
	memcpy(hash, p, h->hashsize);
	PGPFreeHashContext(hc);
	return h->hashsize;
}

/* Call this for sigs known to use a regexp, to return the regexp.  Loads
 * from disk if necessary.  Returns NULL on error.
 */
	void *
ringSigRegexp( RingSet const *set, RingObject *sig )
{
	PGPByte *buf;
	PGPSize len;
	regexp *rexp;
	char const *packet;

	pgpAssert( OBJISSIG( sig ) );
	pgpAssert( pgpIsRingSetMember(set, sig) );
	pgpAssert( SIGUSESREGEXP( &sig->s ) );

	if( !sig->s.regexp ) {
		/* Here we must load the regexp */

		buf = (PGPByte *)ringFetchObject(set, sig, &len);
		if( !buf )
			return NULL;
		/* Note that this may alter the contents of buf */
		packet = (char *)ringSigFindSubpacket(buf, SIGSUB_REGEXP, 0, &len,
											  NULL, NULL, NULL, NULL);
		pgpAssert( packet );
		if (IsPGPError( pgpRegComp( set->pool->context, packet, &rexp ) ) )
			return NULL;
		sig->s.regexp = (void *) rexp;
	}
	return sig->s.regexp;
}

	
/*
 * Return true if sig is a valid revocation signature.  It must either be
 * a self sig, or it must be by a revocation key.  May be on either a subkey
 * or main key.  This does not check for expirations.
 */
	PGPBoolean
sigRevokesKey (RingSet const *set, RingObject *sig)
{
	RingObject 			*parent;
	RingObject 			*top;

	pgpAssert (OBJISSIG (sig));
	pgpAssert (pgpIsRingSetMember(set, sig));
	
	parent = sig->g.up;
	if (!OBJISKEY(parent))
		return FALSE;
	top = parent;
	while (!OBJISTOPKEY(top))
		top = top->g.up;

	if (sig->s.type != ( (top==parent) ? PGP_SIGTYPE_KEY_REVOKE
						 			   : PGP_SIGTYPE_KEY_SUBKEY_REVOKE ))
		return FALSE;
	if ((sig->s.trust & PGP_SIGTRUSTF_TRIED) &&
		!(sig->s.trust & PGP_SIGTRUSTF_CHECKED))
		return FALSE;
	/*
	 * If untried, don't accept on a subkey.  Accept on a top-level key
	 * if already shown as revoked because we don't store trust packets
	 * on such keys, so as not to break PGP 2.X.
	 */
	if (!(sig->s.trust & PGP_SIGTRUSTF_TRIED) &&
		((top != parent) ||
		 !(parent->k.trust & PGP_KEYTRUSTF_REVOKED)))
		return FALSE;

	if (sig->s.by == top)
		return TRUE;

	/*
	 * Here we have a revocation signature which is valid but is by some
	 * other key.  We will accept it only if that is a key which is marked
	 * as a revocation authorization key by this one.
	 */

	return ringKeyIsRevocationKey (top, set, sig->s.by);
}

⌨️ 快捷键说明

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