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

📄 pgpkeyobj.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 5 页
字号:
	}
	else
		return 0;
}


	PGPUInt32
pgpSigType(PGPKeyDBObj const *sig)
{
	PGPSigInfo *sinfo;

	pgpAssert(OBJISSIG(sig));
	sinfo = pgpSigToSigInfo( sig );

	return sinfo->type;
}

	PGPUInt32
pgpSigTimestamp(PGPKeyDBObj const *sig)
{
	PGPSigInfo *sinfo;

	pgpAssert(OBJISSIG(sig));
	sinfo = pgpSigToSigInfo( sig );

	return sinfo->tstamp;
}

	PGPUInt32
pgpSigExpiration(PGPKeyDBObj const *sig)
{
	PGPSigInfo *sinfo;

	pgpAssert(OBJISSIG(sig));
	sinfo = pgpSigToSigInfo( sig );

	if (sinfo->tstamp == 0 || sinfo->sigvalidity == 0)
		return 0;    /* valid indefinitely */
	else
		return sinfo->tstamp + sinfo->sigvalidity;
}

/*
 * True if sig is a self-sig.
 */
	PGPBoolean
pgpSigIsSelfSig(PGPKeyDBObj const *sig)
{
	PGPKeyDBObj const	*parent;
	PGPSigInfo *sinfo;

	pgpAssert(OBJISSIG(sig));
	sinfo = pgpSigToSigInfo( sig );

	/* Find top-level key */
	parent = sig;
	while (!OBJISTOPKEY(parent))
		parent = parent->up;

	/* No good if not signed by top-level key (selfsig) */
	if (sinfo->by != parent)
		return FALSE;

	/* All OK */
	return TRUE;
}



/*
 * True if sig is an X509 sig.
 */
	PGPBoolean
pgpSigIsX509(PGPKeyDBObj const *sig)
{
	PGPSigInfo *sinfo;

	pgpAssert(OBJISSIG(sig));
	sinfo = pgpSigToSigInfo( sig );

	return SIGISX509(sinfo) != 0;
}

	PGPByte *
pgpSigX509Certificate(PGPKeyDBObj *sig, PGPSize *len)
{
	PGPSigInfo *sinfo;
	PGPByte *ptr;

	pgpAssert(OBJISSIG(sig));
	pgpAssert(IsntNull(len));
	sinfo = pgpSigToSigInfo( sig );

	*len = 0;
	if (!SIGISX509 (sinfo))
		return NULL;
	ptr = (PGPByte *)pgpFetchObject(sig, len);
	if (IsNull( ptr ) )
		return NULL;
	ptr = (PGPByte *)pgpSigFindNAISubSubpacket(ptr, SIGSUBSUB_X509, 0, len,
												NULL, NULL, NULL, NULL);
	if( IsntNull( ptr ) ) {
		/* Skip type, version bytes */
		pgpAssert (ptr[0] == SIGSUBSUB_X509);
		ptr += 3;
		*len -= 3;
	}

	return ptr;
}

	PGPBoolean
pgpCRLChecked(PGPKeyDBObj const *crl)
{
	PGPCRLInfo *cinfo;

	pgpAssert(OBJISCRL(crl));
	cinfo = pgpCRLToCRLInfo( crl );

	return (cinfo->trust & PGP_SIGTRUSTF_CHECKED) != 0;
}

	PGPBoolean
pgpCRLTried(PGPKeyDBObj const *crl)
{
	PGPCRLInfo *cinfo;

	pgpAssert(OBJISCRL(crl));
	cinfo = pgpCRLToCRLInfo( crl );

	return (cinfo->trust & PGP_SIGTRUSTF_TRIED) != 0;
}

	PGPUInt32
pgpCRLCreation(PGPKeyDBObj const *crl)
{
	PGPCRLInfo *cinfo;

	pgpAssert(OBJISCRL(crl));
	cinfo = pgpCRLToCRLInfo( crl );

	return cinfo->tstamp;
}

	PGPUInt32
pgpCRLExpiration(PGPKeyDBObj const *crl)
{
	PGPCRLInfo *cinfo;

	pgpAssert(OBJISCRL(crl));
	cinfo = pgpCRLToCRLInfo( crl );

	return cinfo->tstampnext;
}

/* True if the key has a CRL */
	PGPBoolean
pgpKeyHasCRL(PGPKeyDBObj *key)
{
	PGPKeyDBObj *child;

	for (child = key->down; IsntNull(child); child = child->next) {
		if (!OBJISCRL(child))
			continue;
		if( !pgpKeyDBObjIsReal(child) )
			continue;
		if (!pgpCRLChecked(child))
			continue;
		return TRUE;
	}
	return FALSE;
}

/* Return nth CRL of key, along with a count of all CRLs if requested.
 * Doesn't count superceded CRLs.
 * Call this the first time with n=0 and &crlcount, and later times with
 * crlcount holding NULL.
 */
	PGPKeyDBObj *
pgpKeyNthCRL(PGPKeyDBObj *key, PGPUInt32 n, PGPUInt32 *crlcount)
{
	PGPKeyDBObj *obj;
	PGPKeyDBObj *nthcrl = NULL;
	PGPUInt32 count = 0;

	if( IsntNull( crlcount ) )
		*crlcount = 0;

	for (obj = key->down; IsntNull(obj); obj = obj->next) {
		if (!OBJISCRL(obj))
			continue;
		if( !pgpKeyDBObjIsReal(obj) )
			continue;
		if (!pgpCRLChecked(obj))
			continue;
		if (!pgpCRLIsCurrent(obj, 0))
			continue;
		if (count++ == n) {
			nthcrl = obj;
			if (IsNull( crlcount ))
				break;
		}
	}
	if( IsntNull( crlcount ) )
		*crlcount = count;
	return nthcrl;
}


/*
 * Find the earliest non-replaced CRL issued by a key.
 * If expiration is true, use expiration dates, else creation dates.
 */
	PGPKeyDBObj *
pgpKeyEarliestCRL(PGPKeyDBObj *key, PGPBoolean expiration)
{
	PGPKeyDBObj	*crl;
	PGPKeyDBObj *bestcrl = NULL;
	PGPUInt32 crltime;
	PGPUInt32 besttime = (PGPUInt32)-1L;
	PGPUInt32 n = 0;
	PGPUInt32 crlcount = 0;

	do {
		crl = pgpKeyNthCRL(key, n, (n?NULL:&crlcount));
		if( IsNull( crl ) )
			break;
		if( expiration )
			crltime = pgpCRLExpiration( crl );
		else
			crltime = pgpCRLCreation( crl );
		if (crltime < besttime) {
			besttime = crltime;
			bestcrl = crl;
		}
	} while (n++ < crlcount);

	return bestcrl;
}


/*
 * See whether there is a more recent CRL for this key with the same
 * dist. point.
 * If tstamp is nonzero, also checks for expiration of CRL.
 */
	PGPBoolean
pgpCRLIsCurrent (PGPKeyDBObj *crl, PGPUInt32 tstamp)
{
	PGPKeyDBObj *obj;
	PGPKeyDBObj *key;
	PGPKeyDB	*db;
	PGPCRLInfo *cinfo;
	PGPCRLInfo *cinfo2;
	PGPUInt32 crlcreation, crlexpiration;
	PGPUInt32 objcreation;
	PGPByte const *tmpdpoint;
	PGPByte *dpoint = NULL;
	PGPByte const *dpoint2;
	PGPSize dpointlen;
	PGPSize dpoint2len;
	PGPContextRef context;

	pgpAssert (OBJISCRL(crl));
	cinfo = pgpCRLToCRLInfo( crl );

	db = PGPPeekKeyDBObjKeyDB( crl );
	context = PGPPeekKeyDBContext( db );
	
	crlcreation = pgpCRLCreation(crl);
	crlexpiration = pgpCRLExpiration(crl);
	if (tstamp != 0) {
		if (crlexpiration < tstamp)
			return FALSE;
	}

	if( CRLHASDPOINT( cinfo ) ) {
		/* Read dpoint data structure */
		tmpdpoint = pgpCRLDistributionPoint( crl, &dpointlen );
		dpoint = pgpContextMemAlloc( context, dpointlen, 0 );
		pgpCopyMemory( tmpdpoint, dpoint, dpointlen );
		if( IsNull( dpoint ) ) {
			return TRUE;
		}
	}

	/* Find key above CRL */
	key = crl->up;
	pgpAssert (OBJISKEY(key));
	for (obj = key->down; IsntNull(obj); obj = obj->next) {
		pgpAssert(obj);
		if (obj == crl)
			continue;
		if (!OBJISCRL(obj))
			continue;
		if( !pgpKeyDBObjIsReal(obj) )
			continue;
		if (!pgpCRLChecked(obj))
			continue;
		cinfo2 = pgpCRLToCRLInfo( obj );
		if (CRLHASDPOINT(cinfo2) != CRLHASDPOINT(cinfo))
			continue;
		if (CRLHASDPOINT(cinfo)) {
			dpoint2 = pgpCRLDistributionPoint( obj, &dpoint2len );
			if (dpointlen != dpoint2len ||
				!pgpMemoryEqual( dpoint, dpoint2, dpointlen ))
				continue;
		}
		objcreation = pgpCRLCreation(obj);
		if (objcreation > crlcreation) {
			if (CRLHASDPOINT( cinfo ) )
				pgpContextMemFree( context, dpoint );
			return FALSE;
		}
	}
	if (CRLHASDPOINT( cinfo ) )
		pgpContextMemFree( context, dpoint );
	return TRUE;
}

/* Return CRL Distribution Point, in the "fetch" buffer */
/* Return NULL if CRL has no distribution point */
	PGPByte const *
pgpCRLDistributionPoint( PGPKeyDBObj *crl, PGPSize *len )
{
	PGPByte const *ptr;
	PGPCRLInfo *cinfo;

	pgpAssert (OBJISCRL(crl));
	pgpAssert (IsntNull( len ) );
	cinfo = pgpCRLToCRLInfo( crl );

	*len = 0;
	if( !CRLHASDPOINT( cinfo ) ) 
		return NULL;

	ptr = pgpFetchObject(crl, len);
	if (IsNull( ptr ) )
		return NULL;
	ptr = pgpCRLFindDPoint( ptr, *len, len );

	return ptr;
}


/*
 * Return a buffer full of all the CRL Distribution Points associated with
 * a given key.  We find them by listing those in the CRLs we have stored
 * with the key, plus we search all certs which the key has issued and get
 * any others from those.  Also return the number of CDP's in the buffer.
 * The buffer is a newly allocated buffer.
 * Also return a newly allocated buffer of sizes of the CDP's.
 */
	PGPError
pgpListCRLDistributionPoints(
	PGPMemoryMgrRef mgr,				/* Input parameters */
	PGPKeyDBObj *key,
	PGPUInt32 *pnDistPoints,			/* Output parameters */
	PGPByte **pbuf,
	PGPSize **pbufsizes
	)
{
	PGPContextRef context;
	PGPKeyInfo *kinfo;
	PGPSigInfo *sinfo;
	PGPASN_XTBSCertificate *xtbscert;
	PGPUInt32 nDistPoints = 0;
	PGPByte *buf = NULL;
	PGPSize bufsize = 0;
	PGPSize *bufsizes = NULL;
	PGPByte const *crldpoint;
	PGPByte const *certdpoint = NULL;		/* dynamically allocated */
	PGPSize dpointlen;
	PGPError err = kPGPError_NoErr;
	PGPUInt32 nth;
	PGPKeyDBObj *crlobj;
	PGPKeyDBObj *sig;
	PGPByte *p;
	PGPSize len;
	void *vbuf;
	PGPUInt32 crlcount;

	pgpAssert( IsntNull( pbuf ) );
	pgpAssert( IsntNull( pbufsizes ) );
	pgpAssert( IsntNull( pnDistPoints ) );
    pgpAssert (OBJISTOPKEY(key));
	kinfo = pgpKeyToKeyInfo( key );
	context = PGPPeekKeyDBContext(PGPPeekKeyDBObjKeyDB( key ) );

	*pbuf = NULL;
	*pbufsizes = NULL;
	*pnDistPoints = 0;

	/* First check any CRLs stored with the key */
	nth = 0;
	do
	{
		crlobj = pgpKeyNthCRL( key, nth, &crlcount );
		if( IsNull( crlobj ) )
			break;
		crldpoint = pgpCRLDistributionPoint( crlobj, &dpointlen );
		if( IsntNull( crldpoint ) )
		{
			if( !pgpX509BufInSequenceList( crldpoint,dpointlen,buf,bufsize ) )
			{
				bufsize += dpointlen;
				vbuf = buf;
				err = PGPReallocData( mgr, &vbuf, bufsize, 0 );
				buf = vbuf;
				if( IsPGPError( err ) )
					goto error;
				pgpCopyMemory( crldpoint, buf+bufsize-dpointlen, dpointlen );
				++nDistPoints;
				vbuf = bufsizes;
				err = PGPReallocData( mgr, &vbuf,
									  nDistPoints*sizeof(PGPSize), 0 );
				bufsizes = vbuf;
				if( IsPGPError( err ) )
					goto error;
				bufsizes[nDistPoints-1] = dpointlen;
			}
		}
	} while (++nth < crlcount);

	/* Now check all certs signed by key */
	for( sig = kinfo->sigsby; IsntNull( sig ); sig = sinfo->nextby )
	{
		sinfo = pgpSigToSigInfo(sig);
		if( !pgpKeyDBObjIsReal(sig) )
			continue;
		if( !SIGISX509( sinfo )  ||  !SIGHASDISTPOINT( sinfo ) )
			continue;
		/* Find distribution point in cert */
		p = (PGPByte *)pgpFetchObject(sig, &len);
		if( IsNull( p ) )
			continue;
		p = (PGPByte *)pgpSigFindNAISubSubpacket(p, SIGSUBSUB_X509, 0, &len,
												  NULL, NULL, NULL, NULL);
		if( IsNull( p ) )
			continue;
		p += 3;
		len -= 3;
		err = pgpX509BufferToXTBSCert( context, p, len, &xtbscert);
		if( IsPGPError( err ) ) {
			err = kPGPError_NoErr;
			continue;
		}
		/* Note that dpointcert is dynamically allocated */
		certdpoint = pgpX509XTBSCertToDistPoint( xtbscert, &dpointlen );
		pgpX509FreeXTBSCert( context, xtbscert );

		if( IsntNull( certdpoint ) &&
			!pgpX509BufInSequenceList( certdpoint, dpointlen, buf, bufsize ) )
		{
			bufsize += dpointlen;
			vbuf = buf;
			err = PGPReallocData( mgr, &vbuf, bufsize, 0 );
			buf = vbuf;
			if( IsPGPError( err ) )
				goto error;
			pgpCopyMemory( certdpoint, buf+bufsize-dpointlen, dpointlen );
			++nDistPoints;
			vbuf = bufsizes;
			err = PGPReallocData( mgr, &vbuf,
								  nDistPoints*sizeof(PGPSize), 0);
			bufsizes = vbuf;
			if( IsPGPError( err ) )
				goto error;
			bufsizes[nDistPoints-1] = dpointlen;
		}
		PGPFreeData( (PGPByte *)certdpoint );
		certdpoint = NULL;
	}
	
	*pbuf = buf;
	*pbufsizes = bufsizes;
	*pnDistPoints = nDistPoints;

	return kPGPError_NoErr;

 error:

	if( IsntNull( buf ) )
		PGPFreeData( buf );
	if( IsntNull( bufsizes ) )
		PGPFreeData( bufsizes );
	if( IsntNull( certdpoint ) )
		PGPFreeData( (PGPByte *)certdpoint );
	return err;

}

/* Helper function for below - Given a sig, see if it has a subpacket
 * of the type we are interested in.  Given that we have seen *pmatches
 * other subpackets of that type so far, see if this is the nth one.
 * If so, set the various return parameters to point at the data for
 * this subpacket.
 */
static PGPError
sFindSubpacket (PGPKeyDBObj *sig, int subpacktype, unsigned nth,
	PGPByte const **pdata, PGPSize *plen, PGPBoolean *pcritical,
	PGPBoolean *phashed, PGPUInt32 *pcreation, unsigned *pmatches,
	PGPKeyDBObj **psig )
{
	PGPByte *p;
	PGPByte *subp;
	PGPUInt32 matches;
	PGPSize len;

	/* Here we have a nonrevocable self signature */
	p = (PGPByte *)pgpFetchObject(sig, &len);
	if (!p)
		return pgpKeyDBError(PGPPeekKeyDBObjKeyDB(sig));

	subp = (PGPByte *)pgpSigFindSubpacket (p, subpacktype, 0, NULL, NULL,
										   NULL, NULL, &matches);
	if (subp)
	{
		if (nth >= *pmatches && nth < *pmatches+matches)
		{
			/* This packet has the nth instance */
			*psig = sig;
			*pdata = pgpSigFindSubpacket (p, subpacktype, nth - *pmatches,
								plen, pcritical, phashed, pcreation, NULL );
		}
		*pmatches += matches;
	}
	return kPGPError_NoErr;
}



/*
 * Return key self-sig subpacket information.  Searches all sigs below
 * the key for a self sig, finds most recent one with desired info.
 * nth is 0 to find first matching packet, 1 for second, etc.  The
 * semantics have changed (yet again) from earlier versions in order
 * to more easily supercede old signatures.
 * 
 * The rule now is that non-revocable signatures always have precedence.
 * Any subpacket in such a signature cannot be revoked, and will be returned

⌨️ 快捷键说明

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