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

📄 pgpkeyfilter.c

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

		value = (PGPByte *)pgpContextMemAlloc( context, len, 0);
		if( IsntNull( value ) )
		{
			pgpCopyMemory (val, value, len);
			newFilter->value.propbuffer.prop = prop;
			newFilter->value.propbuffer.val = value;
			newFilter->value.propbuffer.len = len;
		}
		else
		{
			PGPFreeFilter( newFilter );
			newFilter	= NULL;
			err	= kPGPError_OutOfMemory;
		}
	}
	
	*outFilter = newFilter;
	pgpAssertErrWithPtr( err, *outFilter );
	return err;
}



#if NOT_YET		/* [ */

/*
 * Create a filtered KeySet based on the same KeyDB as the specified
 * original.  The original must be unfiltered.  The filtering type
 * is chosen automatically based on the string.
 *
 * Currently, a "0x" prefix looks up by keyID, otherwise
 * by userid name substring matching.
 */
	PGPError 
PGPNewKeyFilterFromStringQuery(
	PGPContextRef		context,
	char const *		query,
	PGPFilterRef *		outFilter)
{
	PGPError		err	= kPGPError_NoErr;
	PGPFilterRef	filter = kInvalidPGPKeySetRef;

	PGPValidatePtr( outFilter );
	PGPValidatePtr( query );
	*outFilter	= NULL;
	PGPValidateContext( context );
	
not yet

	if (query[0] == '0' && query[1] == 'x')
	{
		PGPKeyIDRef		keyID;

		err = PGPNewKeyIDFromString( context, query, &keyID );
		if ( IsntPGPError( err ) )
		{
			err = PGPNewKeyIDFilter( context, keyID, &filter );
			PGPFreeKeyID( keyID );
		}
	}
	else
	{
		err = PGPNewUserIDStringFilter( context, query,
										kPGPMatchCriterion_SubString,
										&filter );
	}

	*outFilter	= filter;
	pgpAssertErrWithPtr( err, *outFilter );
	return err;
}

#endif	/* ] NOT_YET */

	static PGPBoolean
sComparisonMatchesCriterion(
	long				comparison,
	PGPMatchCriterion	criterion )
{
	switch (criterion)
	{
		case kPGPMatchCriterion_LessOrEqual:
			return comparison <= 0;
		case kPGPMatchCriterion_GreaterOrEqual:
			return comparison >= 0;
		case kPGPMatchCriterion_Equal:
			return comparison == 0;
		default:
			pgpAssert(0);
			break;
	}
	return FALSE;
}


	static PGPBoolean
sFilterUserID(
	PGPFilterRef		filter,
	PGPKeyDBObj		   *userid,
	char const *		string,
	PGPSize				stringLength)
{
	PGPBoolean			result = FALSE;
	char const *		nameStr;
	PGPSize				nameLength;
	char const *		p;

	nameStr = pgpUserIDName(userid, &nameLength);
	switch (filter->filterType)
	{
		case kPGPFilterTypeUserIDEmail:
			p = (char *)memchr(nameStr, '<', nameLength);
			if (p == NULL)
			{
				nameLength = 0;
				break;
			}
			p++;
			nameLength -= (p - nameStr);
			nameStr = p;
			p = (char *)memchr(nameStr, '>', nameLength);
			if (p != NULL)
				nameLength = p - nameStr;
			break;
		case kPGPFilterTypeUserIDName:
			p = (char *)memchr(nameStr, '<', nameLength);
			if (p == NULL)
				break;
			while (p > nameStr && p[-1] == ' ')
				p--;
			nameLength = p - nameStr;
			break;
		case kPGPFilterTypeUserIDString:
			break;
		default:
			/* This should never happen */
			pgpAssert(0);
			break;
	}
	if (filter->match == kPGPMatchCriterion_Equal)
	{
		if (nameLength == stringLength &&
			xmemimem(nameStr, nameLength,
				string, stringLength) != NULL)
		{
			result = TRUE;
		}
	}
	else if (filter->match == kPGPMatchCriterion_SubString)
	{
		if (xmemimem(nameStr, nameLength,
					 string, stringLength))
		{
			result = TRUE;
		}
	}
	return result;
}


/* Find the object or a parent of the specified type, or return NULL */
	static PGPKeyDBObj *
sFindParent( PGPKeyDBObj *obj, PGPUInt32 type )
{
	PGPUInt32		objtype;

	pgpAssert( type != RINGTYPE_KEY );
	while( (objtype = pgpObjectType( obj )) != type )
	{
		if( objtype == RINGTYPE_KEY )
			return NULL;
		obj = obj->up;
	}
	return obj;
}



/* Compare the time from the key object to the time from the filter */
	static PGPBoolean
sCompareTime(
			PGPFilterRef		filter,
			PGPTime				keyTime)
{
	PGPBoolean	result = FALSE;
	PGPTime		filterTime = filter->value.proptime.val;

	if (keyTime == filterTime)
		result = TRUE;	/* All match criteria include equality */
	else if (filter->match == kPGPMatchCriterion_Equal)
		result = FALSE;
	else
	{
		/*
		 * Now we know that the two times are unequal,
		 * and the match criterion is either <= or >=.
		 * So we'll just evaluate <=, and then invert
		 * the result if the criterion was >=.
		 */
		
		result = (keyTime <= filterTime);

		if( filter->filterType == kPGPFilterTypeKeyTime &&
		   (filter->value.proptime.prop == kPGPKeyProperty_Expiration ||
			filter->value.proptime.prop == kPGPSubKeyProperty_Expiration ) )
		{
			if (filterTime == kPGPExpirationTime_Never)
				result = TRUE;
			else if (keyTime == kPGPExpirationTime_Never)
				result = FALSE;
		}
		
		if (filter->match == kPGPMatchCriterion_GreaterOrEqual)
		{
			result = !result;
		}
		else
		{
			pgpAssert(filter->match == kPGPMatchCriterion_LessOrEqual);
		}
	}
	return result;
}

/* Comparison structure for string buffers - must be equal or substring */
	static PGPBoolean
sCompareString(
			PGPFilterRef		filter,
			void			   *bufval,
			PGPSize				buflen)
{
	PGPBoolean result;

	if( filter->value.propbuffer.prop == kPGPKeyProperty_KeyID ||
		filter->value.propbuffer.prop == kPGPSubKeyProperty_KeyID ||
		filter->value.propbuffer.prop == kPGPSigProperty_KeyID )
	{
		pgpAssert( filter->match == kPGPMatchCriterion_Equal );
		
		result = pgpKeyIDsEqual( filter->value.propbuffer.val, bufval );
	}
	else
	{
		if (filter->match == kPGPMatchCriterion_Equal)
		{
			result = (buflen == filter->value.propbuffer.len) &&
					 pgpMemoryEqual( bufval, filter->value.propbuffer.val,
									 buflen );
		}
		else
		{
			pgpAssert (filter->match == kPGPMatchCriterion_SubString);
			result = (NULL != xmemimem( bufval, buflen,
										filter->value.propbuffer.val,
										filter->value.propbuffer.len ) );
		}
	}
	return result;
}



	PGPBoolean
pgpKeyDBObjMatchesFilter(
	PGPFilterRef		filter,
	PGPKeyDBObjRef		obj)
{
	PGPBoolean			boolval;
	PGPUInt32			numval;
	PGPTime				timeval;
	PGPByte			   *bufval;
	PGPSize				buflen;
	PGPBoolean			result = FALSE;
	PGPKeyDBObj		   *userid;
	PGPKeyDBObj		   *sig;
	PGPKeyDBObj		   *subkey;
	PGPKeyDBObj		   *key;
	PGPByte				pkAlg;
	PGPKeyID			keyID;
	PGPInt32			comparison;
	PGPError			err = kPGPError_NoErr;

	if ( ! PGPFilterIsValid( filter ) )
		return( FALSE );
	
	/* key object will be top level key (possibly same as obj) */
	for( key = obj; pgpObjectType(key) != RINGTYPE_KEY; key = key->up )
		;

	/* Shortcut to detect child validity if we've checked parent key */
	if( pgpObjectType( obj ) != RINGTYPE_KEY
		&& IsntNull( filter->cachedKeyQuery ) )
	{
		if( key == filter->cachedKeyQuery )
		{
			if( !filter->filterChildren )
				return filter->cachedResult;
			if( !filter->cachedResult )
				return FALSE;
			/* Continue on if we're filtering children and parent key was OK */
		}
	}

	switch(filter->filterType) 
	{
		/* Key property filters */
		case kPGPFilterTypeKeyBoolean:
			err = pgpGetKeyBoolean (key,
							(PGPKeyDBObjProperty)filter->value.propbool.prop,
							&boolval);
			if( IsntPGPError( err ) )
				result = sCompareBoolean( filter, boolval );
			break;
		case kPGPFilterTypeKeyNumber:
			err = pgpGetKeyNumber (key,
							(PGPKeyDBObjProperty)filter->value.propnum.prop,
							(PGPInt32 *)&numval);
			if( IsntPGPError( err ) )
				result = sCompareNumber( filter, numval );
			break;
		case kPGPFilterTypeKeyTime:
			err = pgpGetKeyTime (key,
							(PGPKeyDBObjProperty)filter->value.proptime.prop,
							&timeval);
			if( IsntPGPError( err ) )
				result = sCompareTime( filter, timeval );
			break;
		case kPGPFilterTypeKeyBuffer:
			err = pgpGetKeyAllocatedPropertyBuffer( key,
							(PGPKeyDBObjProperty)filter->value.propbuffer.prop,
							&bufval, &buflen );
			if( IsPGPError( err ) )
				break;
			result = sCompareString( filter, bufval, buflen );
			PGPFreeData( bufval );
			break;
		case kPGPFilterTypeSubKeyBoolean:
			if( filter->filterChildren
				&& IsntNull( subkey = sFindParent( obj, RINGTYPE_SUBKEY ) ) )
			{
				err = pgpGetSubKeyBoolean (subkey,
							(PGPKeyDBObjProperty)filter->value.propbool.prop,
							&boolval);
				if( IsntPGPError( err ) )
					result = sCompareBoolean( filter, boolval );
			} else for (subkey = key->down; !result && IsntNull( subkey );
				 				subkey = subkey->next)
			{
				if (!pgpKeyDBObjIsReal( subkey ) )
					continue;
				if( pgpObjectType( subkey ) != RINGTYPE_SUBKEY )
					continue;
				err = pgpGetSubKeyBoolean (subkey,
							(PGPKeyDBObjProperty)filter->value.propbool.prop,
							&boolval);
				if( IsntPGPError( err ) )
					result = sCompareBoolean( filter, boolval );
			}
			break;
		case kPGPFilterTypeSubKeyNumber:
			if( filter->filterChildren
				&& IsntNull( subkey = sFindParent( obj, RINGTYPE_SUBKEY ) ) )
			{
				err = pgpGetSubKeyNumber (subkey,
							(PGPKeyDBObjProperty)filter->value.propnum.prop,
							(PGPInt32 *)&numval);
				if( IsntPGPError( err ) )
					result = sCompareNumber( filter, numval );
			} else for (subkey = key->down; !result && IsntNull(subkey);
							 	subkey = subkey->next)
			{
				if (!pgpKeyDBObjIsReal( subkey ) )
					continue;
				if( pgpObjectType( subkey ) != RINGTYPE_SUBKEY )
					continue;
				err = pgpGetSubKeyNumber (subkey,
							(PGPKeyDBObjProperty)filter->value.propnum.prop,
							(PGPInt32 *)&numval);
				if( IsntPGPError( err ) )
					result = sCompareNumber( filter, numval );
			}
			break;
		case kPGPFilterTypeSubKeyTime:
			if( filter->filterChildren
				&& IsntNull( subkey = sFindParent( obj, RINGTYPE_SUBKEY ) ) )
			{
				err = pgpGetSubKeyTime (subkey,
							(PGPKeyDBObjProperty)filter->value.proptime.prop,
							&timeval);
				if( IsntPGPError( err ) )
					result = sCompareTime( filter, timeval );
			} else for (subkey = key->down; !result && IsntNull(subkey);
							 	subkey = subkey->next)
			{
				if (!pgpKeyDBObjIsReal( subkey ) )
					continue;
				if( pgpObjectType( subkey ) != RINGTYPE_SUBKEY )
					continue;
				err = pgpGetSubKeyTime (subkey,
							(PGPKeyDBObjProperty)filter->value.proptime.prop,
							&timeval);
				if( IsntPGPError( err ) )
					result = sCompareTime( filter, timeval );
			}
			break;
		case kPGPFilterTypeSubKeyBuffer:
			if( filter->filterChildren
				&& IsntNull( subkey = sFindParent( obj, RINGTYPE_SUBKEY ) ) )
			{
				err = pgpGetSubKeyAllocatedPropertyBuffer( subkey,
						(PGPKeyDBObjProperty)filter->value.propbuffer.prop,
						&bufval, &buflen );
				if( IsPGPError( err ) )
					return FALSE;
				result = sCompareString( filter, bufval, buflen );
				PGPFreeData( bufval );
			} else for (subkey = key->down; !result && IsntNull(subkey);
							 	subkey = subkey->next)
			{
				if (!pgpKeyDBObjIsReal( subkey ) )
					continue;
				if( pgpObjectType( subkey ) != RINGTYPE_SUBKEY )
					continue;
				err = pgpGetSubKeyAllocatedPropertyBuffer( subkey,
						(PGPKeyDBObjProperty)filter->value.propbuffer.prop,
						&bufval, &buflen );
				if( IsPGPError( err ) )
					continue;
				result = sCompareString( filter, bufval, buflen );
				PGPFreeData( bufval );
			}
			break;
		case kPGPFilterTypeUserIDBoolean:
			if( filter->filterChildren
				&& IsntNull( userid = sFindParent( obj, RINGTYPE_USERID ) ) )
			{
				err = pgpGetUserIDBoolean (userid,
							(PGPKeyDBObjProperty)filter->value.propbool.prop,
							&boolval);
				if( IsntPGPError( err ) )
					result = sCompareBoolean( filter, boolval );
			} else for (userid = key->down; !result && IsntNull(userid);
							 	userid = userid->next)
			{
				if (!pgpKeyDBObjIsReal( userid) )
					continue;
				if( pgpObjectType( userid ) != RINGTYPE_USERID )
					continue;
				err = pgpGetUserIDBoolean (userid,
							(PGPKeyDBObjProperty)filter->value.propbool.prop,
							&boolval);
				if( IsntPGPError( err ) )
					result = sCompareBoolean( filter, boolval );
			}
			break;
		case kPGPFilterTypeUserIDNumber:
			if( filter->filterChildren
				&& IsntNull( userid = sFindParent( obj, RINGTYPE_USERID ) ) )
			{
				err = pgpGetUserIDNumber (userid,
								(PGPKeyDBObjProperty)filter->value.propnum.prop,
								(PGPInt32 *)&numval);
				if( IsntPGPError( err ) )
					result = sCompareNumber( filter, numval );
			} else for (userid = key->down; !result && IsntNull(userid);
							 	userid = userid->next)
			{
				if (!pgpKeyDBObjIsReal( userid) )
					continue;
				if( pgpObjectType( userid ) != RINGTYPE_USERID )
					continue;
				err = pgpGetUserIDNumber (userid,
								(PGPKeyDBObjProperty)filter->value.propnum.prop,
								(PGPInt32 *)&numval);
				if( IsntPGPError( err ) )
					result = sCompareNumber( filter, numval );
			}
			break;
#if 0
/* Support this when we add a userid time prop function */
		case kPGPFilterTypeUserIDTime:
			if( filter->filterChildren
				&& IsntNull( userid = sFindParent( obj, RINGTYPE_USERID ) ) )
			{
				err = PGPGetUserIDTime (userid, filter->value.proptime.prop,
										   &timeval);
				if( IsntPGPError( err ) )
					result = sCompareTime( filter, timeval );
			} else for (userid = key->down; !result && IsntNull(userid);
							 	userid = userid->next)
			{
				if (!pgpKeyDBObjIsReal( userid) )
					continue;
				if( pgpObjectType( userid ) != RINGTYPE_USERID )
					continue;
				err = PGPGetUserIDTime (userid, filter->value.proptime.prop,
										   &timeval);
				if( IsntPGPError( err ) )
					result = sCompareTime( filter, timeval );
			}
			break;
#endif
		case kPGPFilterTypeUserIDBuffer:
			if( filter->filterChildren
				&& IsntNull( userid = sFindParent( obj, RINGTYPE_USERID ) ) )
			{
				err = pgpGetUserIDAllocatedStringBuffer( userid,
						(PGPKeyDBObjProperty)filter->value.propbuffer.prop,
						&bufval, &buflen );
				if( IsPGPError( err ) )
					break;
				result = sCompareString( filter, bufval, buflen );
				PGPFreeData( bufval );
			} else for (userid = key->down; !result && IsntNull(userid);
							 	userid = userid->next)
			{
				if (!pgpKeyDBObjIsReal( userid) )
					continue;
				if( pgpObjectType( userid ) != RINGTYPE_USERID )
					continue;
				err = pgpGetUserIDAllocatedStringBuffer( userid,
						(PGPKeyDBObjProperty)filter->value.propbuffer.prop,
						&bufval, &buflen );

⌨️ 快捷键说明

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