📄 pgpkeyfilter.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
Key filtering routines implementing the PGPFilterRef abstract data type
$Id: pgpKeyFilter.c,v 1.30 2002/11/20 08:33:15 ajivsov Exp $
____________________________________________________________________________*/
#include "pgpConfig.h"
#include <string.h>
#include <ctype.h>
#include "pgpDebug.h"
#include "pgpErrors.h"
#include "pgpContext.h"
#include "pgpKeyPriv.h"
#include "pgpKeyFilterPriv.h"
#include "pgpPubKey.h"
#include "pgpTimeDate.h"
#include "pgpX509Priv.h"
#define PGPValidateMatchCriterion( m ) \
pgpAssert( (m) == kPGPMatchCriterion_Equal || \
(m) == kPGPMatchCriterion_GreaterOrEqual || \
(m) == kPGPMatchCriterion_LessOrEqual || \
(m) == kPGPMatchCriterion_SubString )
#define sCompareBoolean(f,v) (!(f)->value.propbool.val == !(v))
#define sCompareNumber(f,v) sComparisonMatchesCriterion( \
(v) - (f)->value.propnum.val, (f)->match )
PGPBoolean
PGPFilterIsValid( PGPFilterRef filter )
{
return( IsntNull( filter ) && filter->magic == kPGPFilterMagic );
}
/*
* Stolen from pgpRngPub.c:
*
* Return pointer to first instance of (s1,l1) in (s0,l0),
* ignoring case. Uses a fairly simple-minded algorithm.
* Search for the first char of s1 in s0, and when we have it,
* scan for the rest.
*
* Is it worth mucking with Boyer-Moore or the like?
*/
static char const *
xmemimem(char const *s0, size_t l0, char const *s1, size_t l1)
{
char c0, c1, c2;
size_t l;
/*
* The trivial cases - this means that NULL inputs are very legal
* if the correspinding lengths are zero.
*/
if (l0 < l1)
return NULL;
if (!l1)
return s0;
l0 -= l1;
c1 = tolower((unsigned char)*s1);
do {
c0 = tolower((unsigned char)*s0);
if (c0 == c1) {
l = 0;
do {
if (++l == l1)
return s0;
c0 = tolower((unsigned char)s0[l]);
c2 = tolower((unsigned char)s1[l]);
} while (c0 == c2);
}
s0++;
} while (l0--);
return NULL;
}
static PGPError
sAllocateFilter(
PGPContextRef context,
PGPFilterType filterType,
PGPMatchCriterion match,
PGPFilterRef * outFilter)
{
PGPFilterRef newFilter = NULL;
PGPError err = kPGPError_NoErr;
PGPValidatePtr( outFilter );
*outFilter = NULL;
PGPValidateContext( context );
PGPValidateParam( filterType < kPGPFilterTypeEnd );
PGPValidateMatchCriterion( match );
newFilter = (PGPFilterRef)
pgpContextMemAlloc( context, sizeof( PGPFilter),
kPGPMemoryMgrFlags_Clear);
if( IsntNull( newFilter ) )
{
newFilter->magic = kPGPFilterMagic;
newFilter->context = context;
newFilter->refCount = 1;
newFilter->filterType = filterType;
newFilter->match = match;
}
else
{
err = kPGPError_OutOfMemory;
}
*outFilter = newFilter;
pgpAssertErrWithPtr( err, *outFilter );
return err;
}
PGPError
PGPIncFilterRefCount( PGPFilterRef filter )
{
PGPValidateFilter( filter );
pgpEnterPGPErrorFunction();
filter->refCount++;
return kPGPError_NoErr;
}
PGPError
PGPFilterChildObjects( PGPFilterRef filter, PGPBoolean filterChildren )
{
PGPValidateFilter( filter );
pgpEnterPGPErrorFunction();
filter->filterChildren = filterChildren;
return kPGPError_NoErr;
}
PGPError
PGPFreeFilter( PGPFilterRef filter )
{
PGPError err = kPGPError_NoErr;
PGPValidateFilter( filter );
pgpEnterPGPErrorFunction();
pgpAssert( filter->refCount >= 1 );
filter->refCount--;
if( filter->refCount == 0 )
{
PGPContextRef context = filter->context;
void * ptrToFree = NULL;
switch( filter->filterType)
{
default:
break;
case kPGPFilterTypeKeyKeyID:
break;
case kPGPFilterTypeKeySubKeyID:
break;
case kPGPFilterTypeKeyFingerPrint:
ptrToFree = filter->value.keyFingerPrint.keyFingerPrintData;
break;
case kPGPFilterTypeUserIDEmail:
ptrToFree = filter->value.userIDEmail;
break;
case kPGPFilterTypeUserIDName:
ptrToFree = filter->value.userIDName;
break;
case kPGPFilterTypeUserIDString:
ptrToFree = filter->value.userIDString;
break;
case kPGPFilterTypeSigKeyID:
break;
case kPGPFilterTypeKeyBuffer:
case kPGPFilterTypeSubKeyBuffer:
case kPGPFilterTypeUserIDBuffer:
case kPGPFilterTypeSigBuffer:
ptrToFree = filter->value.propbuffer.val;
break;
case kPGPFilterTypeNot:
PGPFreeFilter( filter->value.notFilter );
break;
case kPGPFilterTypeAnd:
PGPFreeFilter( filter->value.andFilter.andFilter1 );
PGPFreeFilter( filter->value.andFilter.andFilter2 );
break;
case kPGPFilterTypeOr:
PGPFreeFilter( filter->value.orFilter.orFilter1 );
PGPFreeFilter( filter->value.orFilter.orFilter2 );
break;
}
if ( IsntNull( ptrToFree ) )
{
pgpContextMemFree( context, ptrToFree);
}
pgpContextMemFree( context, filter );
}
return err;
}
/*____________________________________________________________________________
The passed in filter will be freed when the newly created filter is
freed. Therefore, if an error occurs, the passed filter must
also be freed. Caller should increment the passed-in filter
ref count if the filter should persist.
____________________________________________________________________________*/
PGPError
PGPNegateFilter(
PGPFilterRef filter,
PGPFilterRef * outFilter)
{
PGPError err = kPGPError_NoErr;
if ( IsntNull( outFilter ) )
{
*outFilter = NULL;
if ( ! PGPFilterIsValid( filter ) )
err = kPGPError_BadParams;
}
else
{
err = kPGPError_BadParams;
}
pgpEnterPGPErrorFunction();
if ( IsntPGPError( err ) )
{
err = sAllocateFilter( filter->context, kPGPFilterTypeNot,
kPGPMatchCriterion_Equal, outFilter);
pgpAssertErrWithPtr( err, *outFilter );
if ( IsntPGPError( err ) )
{
(*outFilter)->value.notFilter = filter;
}
}
/* careful to clean up in event of error */
if ( IsPGPError( err ) )
{
if ( PGPFilterIsValid( filter ) )
{
PGPFreeFilter( filter );
filter = NULL;
}
}
pgpAssertErrWithPtr( err, *outFilter );
return err;
}
/*____________________________________________________________________________
The passed in filters will be freed when the newly created filter is
freed. Therefore, if an error occurs, the passed filters must
also be freed. Caller should increment the passed-in filter
ref count if the filters should persist.
____________________________________________________________________________*/
PGPError
PGPIntersectFilters(
PGPFilterRef filter1,
PGPFilterRef filter2,
PGPFilterRef * outFilter)
{
PGPError err = kPGPError_NoErr;
if ( IsntNull( outFilter ) )
*outFilter = NULL;
pgpEnterPGPErrorFunction();
if ( IsntNull( outFilter ) &&
PGPFilterIsValid( filter1 ) &&
PGPFilterIsValid( filter2 ) )
{
err = sAllocateFilter( filter1->context, kPGPFilterTypeAnd,
kPGPMatchCriterion_Equal, outFilter);
if( IsntPGPError( err ) )
{
(*outFilter)->value.andFilter.andFilter1 = filter1;
(*outFilter)->value.andFilter.andFilter2 = filter2;
}
}
else
{
err = kPGPError_BadParams;
}
/* careful to clean up in event of error */
if ( IsPGPError( err ) )
{
if ( PGPFilterIsValid( filter1 ) )
PGPFreeFilter( filter1 );
if ( PGPFilterIsValid( filter2 ) )
PGPFreeFilter( filter2 );
}
pgpAssertErrWithPtr( err, *outFilter );
return err;
}
/*____________________________________________________________________________
The passed in filters will be freed when the newly created filter is
freed. Therefore, if an error occurs, the passed filters must
also be freed. Caller should increment the passed-in filter
ref count if the filters should persist.
____________________________________________________________________________*/
PGPError
PGPUnionFilters(
PGPFilterRef filter1,
PGPFilterRef filter2,
PGPFilterRef * outFilter)
{
PGPError err = kPGPError_NoErr;
if ( IsntNull( outFilter ) )
*outFilter = NULL;
pgpEnterPGPErrorFunction();
if ( IsntNull( outFilter ) &&
PGPFilterIsValid( filter1 ) &&
PGPFilterIsValid( filter2 ) )
{
err = sAllocateFilter( filter1->context, kPGPFilterTypeOr,
kPGPMatchCriterion_Equal, outFilter);
if( IsntPGPError( err ) )
{
(*outFilter)->value.orFilter.orFilter1 = filter1;
(*outFilter)->value.orFilter.orFilter2 = filter2;
}
}
else
{
err = kPGPError_BadParams;
}
/* careful to clean up in event of error */
if ( IsPGPError( err ) )
{
if ( PGPFilterIsValid( filter1 ) )
PGPFreeFilter( filter1 );
if ( PGPFilterIsValid( filter2 ) )
PGPFreeFilter( filter2 );
}
pgpAssertErrWithPtr( err, *outFilter );
return err;
}
/********************** Generic property filters ************************/
#define kPGPKeyProperty_FirstProperty 100
#define kPGPSubKeyProperty_FirstProperty 500
#define kPGPUserIDProperty_FirstProperty 900
#define kPGPSigProperty_FirstProperty 1300
PGPError
PGPNewKeyDBObjBooleanFilter(
PGPContextRef context,
PGPKeyDBObjProperty prop,
PGPBoolean match,
PGPFilterRef * outFilter)
{
PGPError err = kPGPError_NoErr;
PGPFilterType proptype;
PGPValidatePtr( outFilter );
*outFilter = NULL;
PGPValidateContext( context );
pgpEnterPGPErrorFunction();
if( prop < kPGPSubKeyProperty_FirstProperty )
proptype = kPGPFilterTypeKeyBoolean;
else if( prop < kPGPUserIDProperty_FirstProperty )
proptype = kPGPFilterTypeSubKeyBoolean;
else if( prop < kPGPSigProperty_FirstProperty )
proptype = kPGPFilterTypeUserIDBoolean;
else
proptype = kPGPFilterTypeSigBoolean;
err = sAllocateFilter( context, proptype, kPGPMatchCriterion_Equal,
outFilter);
if( IsntPGPError( err ) )
{
(*outFilter)->value.propbool.prop = prop;
(*outFilter)->value.propbool.val = match;
}
pgpAssertErrWithPtr( err, *outFilter );
return err;
}
PGPError
PGPNewKeyDBObjNumericFilter(
PGPContextRef context,
PGPKeyDBObjProperty prop,
PGPUInt32 val,
PGPMatchCriterion match,
PGPFilterRef * outFilter)
{
PGPError err = kPGPError_NoErr;
PGPFilterType proptype;
PGPValidatePtr( outFilter );
*outFilter = NULL;
PGPValidateContext( context );
pgpEnterPGPErrorFunction();
if( prop < kPGPSubKeyProperty_FirstProperty )
proptype = kPGPFilterTypeKeyNumber;
else if( prop < kPGPUserIDProperty_FirstProperty )
proptype = kPGPFilterTypeSubKeyNumber;
else if( prop < kPGPSigProperty_FirstProperty )
proptype = kPGPFilterTypeUserIDNumber;
else
proptype = kPGPFilterTypeSigNumber;
err = sAllocateFilter( context, proptype, match, outFilter);
if( IsntPGPError( err ) )
{
(*outFilter)->value.propnum.prop = prop;
(*outFilter)->value.propnum.val = val;
}
pgpAssertErrWithPtr( err, *outFilter );
return err;
}
PGPError
PGPNewKeyDBObjTimeFilter(
PGPContextRef context,
PGPKeyDBObjProperty prop,
PGPTime val,
PGPMatchCriterion match,
PGPFilterRef * outFilter)
{
PGPError err = kPGPError_NoErr;
PGPFilterType proptype;
PGPValidatePtr( outFilter );
*outFilter = NULL;
PGPValidateContext( context );
pgpEnterPGPErrorFunction();
if( prop < kPGPSubKeyProperty_FirstProperty )
proptype = kPGPFilterTypeKeyTime;
else if( prop < kPGPUserIDProperty_FirstProperty )
proptype = kPGPFilterTypeSubKeyTime;
else if( prop < kPGPSigProperty_FirstProperty )
proptype = kPGPFilterTypeUserIDTime;
else
proptype = kPGPFilterTypeSigTime;
err = sAllocateFilter( context, proptype, match, outFilter);
if( IsntPGPError( err ) )
{
(*outFilter)->value.proptime.prop = prop;
(*outFilter)->value.proptime.val = val;
}
pgpAssertErrWithPtr( err, *outFilter );
return err;
}
PGPError
PGPNewKeyDBObjDataFilter(
PGPContextRef context,
PGPKeyDBObjProperty prop,
const void *val,
PGPSize len,
PGPMatchCriterion match,
PGPFilterRef * outFilter)
{
PGPError err = kPGPError_NoErr;
PGPFilterType proptype;
PGPFilterRef newFilter;
PGPValidatePtr( outFilter );
*outFilter = NULL;
PGPValidateContext( context );
pgpEnterPGPErrorFunction();
if( prop < kPGPSubKeyProperty_FirstProperty )
proptype = kPGPFilterTypeKeyBuffer;
else if( prop < kPGPUserIDProperty_FirstProperty )
proptype = kPGPFilterTypeSubKeyBuffer;
else if( prop < kPGPSigProperty_FirstProperty )
proptype = kPGPFilterTypeUserIDBuffer;
else
proptype = kPGPFilterTypeSigBuffer;
err = sAllocateFilter( context, proptype, match, &newFilter);
if( IsntPGPError( err ) )
{
PGPByte * value;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -