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

📄 pgpkeysig.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 3 页
字号:
	if( IsPGPError(err ) )
		goto error;
	pgpPubKeyDestroy( (PGPPubKey *)pub );
	pub = NULL;

	/* Process cert into a structure using ASN.1 library */
	err = pgpX509BufferToCert( context, x509cert, x509len, &cert );
	if( IsPGPError( err ) )
		goto error;

	/* At this point we can destroy the raw X.509 buffer data */
	x509cert = NULL;

	/* Check to see if data from X.509 cert matches parent key and userid */

	err = pgpX509CertToKeyBuffer(context, &keydb->objPool, keydb, cert,
								 loversion, &buf, &len);
	if( IsPGPError( err )  ||  sObjDiffers( parentkey, buf, len ) )
		goto error;

	err = pgpX509CertToUserIDBuffer (context, &keydb->objPool, cert, loversion,
									 &buf, &len );
	if( IsPGPError( err )  ||  sObjDiffers( parentuserid, buf, len ) )
		goto error;

	err = pgpX509CertToSigBuffer (context, &keydb->objPool, cert, loversion,
								  &buf, &len );
	if( IsPGPError( err )  ||  sObjDiffers( obj, buf, len ) )
		goto error;

	pgpX509FreeCert( context, cert );
	memPoolCutBack( &keydb->objPool, &mempoolinit );

	/* All OK */
	return TRUE;

 error:
	if( IsntNull( pub ) )
		pgpPubKeyDestroy( (PGPPubKey *)pub );
	if( IsntNull( cert ) )
		pgpX509FreeCert( context, cert );
	memPoolCutBack( &keydb->objPool, &mempoolinit );
	return FALSE;
}



/*
 * Mark all the signatures in its keydb that crl revokes as REVOKEDBYCRL.
 * crl's parent is "key".
 * If otherdb is not null, ONLY mark the ones there.  In that case
 * return changedSet as being the changed keys in that set as it is the
 * primary one of interest.  (The idea here is that this is used for the
 * case where "otherdb" is really the main db and the key is a signer
 * in another keydb.)
 */
	static PGPError
sPropagateOneCRL( PGPKeyDBObj *key, PGPKeyDBObj *crl, PGPKeyDBRef otherdb,
	PGPKeySetRef changedSet )
{
	PGPASN_Certificate *cert = NULL;
	PGPASN_CertificateRevocationList *crl509 = NULL;
	PGPASN_revokedCertificates_SEQ_OF *revs;
	PGPASN_INTEGER *certnum, *revnum;
	PGPByte *buf;
	PGPSize len;
	PGPByte *x509cert;
	PGPSize x509len;
	PGPKeyDBObj *sig;
	PGPInt32 i;
	PGPInt32 count;
	PGPInt32 numrevsleft;
	PGPKeyInfo *kinfo;
	PGPKeyDBObj *pairkey = NULL;
	PGPSigInfo *sinfo = NULL;
	PGPKeyDB *keydb;
	PGPContextRef context;
	PGPError err = kPGPError_NoErr;
	
	pgpAssert (OBJISKEY(key));
	pgpAssert (OBJISCRL(crl));

	keydb = PGPPeekKeyDBObjKeyDB( crl );
	context = PGPPeekKeyDBContext( keydb );
	kinfo = pgpKeyToKeyInfo( key );

	buf = (PGPByte *)pgpFetchObject( crl, &len );
	if( IsNull(buf) )
	{
		err = pgpKeyDBError( keydb );
		goto error;
	}

	buf = (PGPByte *)pgpCRLFindCRL( buf, len, &len );
	if( IsNull( buf ) )
	{
		/* Unknown CRL type, ignore it */
		err = kPGPError_NoErr;
		goto error;
	}
	err = pgpX509BufferToCRL( context, buf, len, &crl509 );
	if( IsPGPError( err ) )
		goto error;

	if( IsNull( crl509->tbsCertList.revokedCertificates ) )
	{
		/* Nothing to do */
		goto error;
	}

	revs = crl509->tbsCertList.revokedCertificates;
	count = revs->n;
	if( count == 0 )
	{
		/* Nothing to do */
		goto error;
	}
	numrevsleft = count;

	/* Find corresponding key in otherdb if it exists */
	if( IsntNull( otherdb ) )
	{
		pairkey = pgpFindPairedX509Key( key, otherdb );
		/* If no such key in otherdb, we are done */
		if( IsNull( pairkey ) )
			goto error;
		kinfo = pgpKeyToKeyInfo( pairkey );
		/* By setting kinfo we will look in otherdb for sigs to propagate */
	}
		
	/* Check all sigs issued by key to see if any are revoked */
	for( sig=kinfo->sigsby; IsntNull(sig); sig=sinfo->nextby )
	{
		pgpAssert( OBJISSIG( sig ) );
		sinfo = pgpSigToSigInfo(sig);
		if( !SIGISX509(sinfo) )
			continue;
		buf = (PGPByte *)pgpFetchObject( sig, &len );
		if( IsNull(buf) )
		{
			err = pgpKeyDBError( keydb );
			goto error;
		}

		x509cert = (PGPByte *)pgpSigFindNAISubSubpacket(buf,
								SIGSUBSUB_X509, 0, &x509len, NULL, NULL,
								NULL, NULL);
		if( IsNull( x509cert )  )
			continue;

		/* Skip type, version bytes */
		pgpAssert (x509cert[0] == SIGSUBSUB_X509);
		x509cert += 3;
		x509len -= 3;

		/* Process cert into a structure using ASN.1 library */
		err = pgpX509BufferToCert( context, x509cert, x509len, &cert );
		if( IsPGPError( err ) )
			continue;

		/* Get pointer to cert's serial number, which we will compare */
		certnum = &cert->tbsCertificate.serialNumber;

		/* Compare against each entry in the CRL */
		for (i=0; i<count; ++i)
		{
			revnum = &revs->elt[i]->userCertificate;
			if( certnum->len == revnum->len &&
					pgpMemoryEqual( certnum->val, revnum->val, revnum->len) )
			{
				/* Have a match, cert is revoked */
				if( IsntNull( changedSet ) &&
							!(sinfo->trust & PGP_SIGTRUSTF_REVOKEDBYCRL) )
					PGPAddKey( PGPPeekKeyDBObjKey(sig), changedSet );
				sinfo->trust |= PGP_SIGTRUSTF_REVOKEDBYCRL;
				if( --numrevsleft == 0 )
				{
					/* We have accounted for all revocations */
					err = kPGPError_NoErr;
					goto error;
				}
				break;
			}
		}
		pgpX509FreeCert( context, cert );
		cert = NULL;
	}

error:
	if( IsntNull( cert ) )
		pgpX509FreeCert( context, cert );
	if( IsntNull( crl509 ) )
		pgpX509FreeCRL( context, crl509 );

	return err;
}




/*
 * Check one CRL on a keyring.  Set its trust flags to show whether the
 * signature checks OK.
 */
	static PGPError
sCheckOneCRL( PGPKeyDBObj *key, PGPKeyDBObj *crl, PGPKeySetRef changedSet )
{
	PGPByte *buf;
	PGPSize len;
	PGPPubKey *pub = NULL;
	PGPKeyDB *keydb;
	PGPContextRef context;
	PGPCRLInfo *cinfo;
	PGPError err = kPGPError_NoErr;

	pgpAssert (OBJISKEY(key));
	pgpAssert (OBJISCRL(crl));

	keydb = PGPPeekKeyDBObjKeyDB( key );
	context = PGPPeekKeyDBContext( keydb );
	cinfo = pgpCRLToCRLInfo( crl );

	/* Get the pubkey struct for signing key */
	pub = pgpKeyPubKey(key, PGP_PKUSE_SIGN);
	if( IsNull(pub) )
	{
		err = pgpKeyDBError(keydb);
		if( pgpIsKeyRelatedError( err ) )
			err = kPGPError_NoErr;
		goto error;
	}

	buf = (PGPByte *)pgpFetchObject( crl, &len );
	if( IsNull(buf) )
	{
		err = pgpKeyDBError(keydb);
		goto error;
	}

	buf = (PGPByte *)pgpCRLFindCRL( buf, len, &len );
	err = pgpX509VerifySignedObject( context, pub, buf, len );

	if( IsPGPError(err ) )
	{
		if( err == kPGPError_X509InvalidCertificateSignature  )
		{
			if( IsntNull( changedSet ) &&
				(cinfo->trust & PGP_SIGTRUSTF_CHECKED_TRIED) !=
													PGP_SIGTRUSTF_TRIED )
				PGPAddKey( key, changedSet );
			cinfo->trust &= ~PGP_SIGTRUSTF_CHECKED;
			cinfo->trust |= PGP_SIGTRUSTF_TRIED;
		}
		err = kPGPError_NoErr;
	} else {
		if( IsntNull( changedSet ) &&
			(cinfo->trust & PGP_SIGTRUSTF_CHECKED_TRIED) !=
											PGP_SIGTRUSTF_CHECKED_TRIED )
			PGPAddKey( key, changedSet );
		cinfo->trust |= PGP_SIGTRUSTF_CHECKED_TRIED;
	}
	
error:	
	if( IsntNull( pub ) )
		pgpPubKeyDestroy( pub );
	return err;
}


/*
 * Check the CRLs on a keyring.  If allflag is true, recheck all, else
 * only check unchecked ones.  Propagate revocations to sigs in keyset.
 * If otherdb is not null, we return the changedSet as keys in that
 * set, as it is the primary one of interest.
 */
	static PGPError
sCheckCRLs( PGPKeySet *keyset, int allflag, PGPKeyDBRef otherdb,
	PGPKeySetRef changedSet )
{
	PGPKeyDBObj *key = NULL;
	PGPKeyDB *keydb;
	PGPKeyDBObj *obj;
	PGPCRLInfo *cinfo;
	PGPError err = kPGPError_NoErr;

	keydb = PGPPeekKeySetKeyDB( keyset );

	for( key = keydb->firstKeyInDB; IsntNull( key ); key = key->next )
	{
		if( !pgpKeyDBObjIsReal( key ) )
			continue;
		if( !pgpKeySetIsMember( key, keyset ) )
			continue;
		for( obj = key->down; IsntNull( obj ); obj = obj->next )
		{
			if( !pgpKeyDBObjIsReal( obj ) )
				continue;
			if( !OBJISCRL(obj) )
				continue;

			cinfo = pgpCRLToCRLInfo( obj );

			if( allflag || !(cinfo->trust & PGP_SIGTRUSTF_CHECKED_TRIED) )
			{
				pgpAssert( IsntNull( key ) );
				err = sCheckOneCRL (key, obj,
									IsntNull(otherdb)?changedSet:NULL);
				if( IsPGPError( err ) )
					goto error;
			}
			if( cinfo->trust & PGP_SIGTRUSTF_CHECKED )
			{
				err = sPropagateOneCRL (key, obj, otherdb, changedSet);
				if( IsPGPError( err ) )
					goto error;
			}
		}
	}
error:
	return err;
}



/*
 * Check the signatures in a keydb.  Checks only unchecked signatures,
 * or all signatures if allflag is true.  If revocationonly is set,
 * only revocation signatures are checked (allflag again controls whether
 * previously checked rev sigs are rechecked).
 *
 * Signatures may be made either by keys in keydb or in otherdb.
 *
 * If func is non-null, calls it with each checked signature, after
 * checking.  This is for progress indications.  If func returns a
 * negative value, the check is aborted.
 *
 * If frontEnd is true we are called on the front end and must do it all
 * on the back end.
 */
	PGPError
pgpCheckKeySigs(PGPKeySet *keyset, PGPKeyDB *otherdb,
	PGPBoolean allflag, PGPBoolean revocationonly, PGPBoolean frontEnd,
	PGPError (*func)(void *, PGPKeyDBObj *, int), void *arg,
	PGPKeySetRef changeSet )
{
	PGPContextRef context;
	PGPKeyDB	*keydb;
	PGPKeyDBObj *key;
	PGPKeyDBObj *child;
	PGPKeyDBObj *gchild;
	PGPUInt32	setID;
	PGPUInt32	otherID;
	PGPBoolean	handled, verified, changed;
	PGPError err = kPGPError_NoErr;

	if( frontEnd )
		pgpAssert( IsntNull( func ) );
	keydb = PGPPeekKeySetKeyDB( keyset );
	context = PGPPeekKeyDBContext( keydb );
	setID = keydb->id;
	otherID = IsNull(otherdb) ? 0 : otherdb->id;

	if( !frontEnd )
	{
		if( IsPGPError( err = sCheckCRLs( keyset, allflag, NULL, changeSet )))
			goto error;
		if( IsntNull( otherdb ) )
		{
			/* Must check CRLs in otherdb against this one */
			PGPKeySetRef oroot = PGPPeekKeyDBRootKeySet( otherdb );
			if( IsPGPError( err = sCheckCRLs( oroot, allflag,
											  keydb, changeSet ) ) )
				goto error;
		}
	}

	for( key = keydb->firstKeyInDB; IsntNull( key ); key = key->next)
	{
		if( !pgpKeyDBObjIsReal( key ) )
			continue;
		if( !pgpKeySetIsMember( key, keyset ) )
			continue;
		for( child = key->down; IsntNull( child ); child = child->next)
		{
			if( !pgpKeyDBObjIsReal( child ) )
				continue;
			if( !pgpKeySetIsMember( child, keyset ) )
				continue;
			if( pgpObjectType( child ) == RINGTYPE_SIG )
			{
				if( frontEnd )
				{
					err = pgpCheckSig_back( context, setID,
											pgpKeyDBObjID(child), otherID,
											allflag, revocationonly,
											&handled, &changed, &verified);
				} else {
					err = pgpCheckSig_internal( keydb, child, otherdb,
												allflag, revocationonly,
												&handled, &changed,
												&verified);
				}
				if( IsPGPError( err ) )
					goto error;
				if( changed && IsntNull(changeSet) )
					PGPAddKey( key, changeSet );
				if( handled && IsntNull(func) )
				{
					err = func( arg, child, verified );
					if( IsPGPError( err ) )
						goto error;
				}
			}
			for( gchild = child->down; IsntNull(gchild); gchild = gchild->next)
			{
				if( !pgpKeyDBObjIsReal( gchild ) )
					continue;
				if( !pgpKeySetIsMember( gchild, keyset ) )
					continue;
				if( pgpObjectType( gchild ) == RINGTYPE_SIG )
				{
					if( frontEnd )
					{
						err = pgpCheckSig_back( context, setID,
												pgpKeyDBObjID(gchild), otherID,
												allflag, revocationonly,
												&handled, &changed, &verified);
					} else {
						err = pgpCheckSig_internal( keydb, gchild, otherdb,
													allflag, revocationonly,

⌨️ 快捷键说明

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