#include "identSearch.h"
#include <Security/SecKeychainItemPriv.h>
bool idHasEmail(
SecIdentityRef idRef,
const void *emailAddress, unsigned emailAddressLen)
{
SecCertificateRef certRef;
OSStatus ortn;
bool ourRtn = false;
ortn = SecIdentityCopyCertificate(idRef, &certRef);
if(ortn) {
cssmPerror("SecIdentityCopyCertificate", ortn);
return ortn;
}
UInt32 oneTag = kSecAlias;
SecKeychainAttributeInfo attrInfo;
attrInfo.count = 1;
attrInfo.tag = &oneTag;
attrInfo.format = NULL;
SecKeychainAttributeList *attrList = NULL;
SecKeychainAttribute *attr = NULL;
ortn = SecKeychainItemCopyAttributesAndData((SecKeychainItemRef)certRef,
&attrInfo,
NULL, &attrList,
NULL, NULL); if(ortn || (attrList == NULL) || (attrList->count != 1)) {
cssmPerror("SecKeychainItemCopyAttributesAndData", ortn);
goto errOut;
}
attr = attrList->attr;
if(attr->length == emailAddressLen) {
if(!memcmp(attr->data, emailAddress, emailAddressLen)) {
ourRtn = true;
}
}
errOut:
SecKeychainItemFreeAttributesAndData(attrList, NULL);
CFRelease(certRef);
return ourRtn;
}
OSStatus findIdentity(
const void *emailAddress, unsigned emailAddressLen,
SecKeychainRef kcRef, SecIdentityRef *idRef) {
OSStatus ortn;
SecIdentitySearchRef srchRef = nil;
ortn = SecIdentitySearchCreate(kcRef,
0, &srchRef);
if(ortn) {
cssmPerror("SecIdentitySearchCreate", ortn);
return ortn;
}
SecIdentityRef foundId = NULL;
do {
SecIdentityRef thisId;
ortn = SecIdentitySearchCopyNext(srchRef, &thisId);
if(ortn != noErr) {
break;
}
if(idHasEmail(thisId, emailAddress, emailAddressLen)) {
foundId = thisId;
break;
}
else {
CFRelease(thisId);
}
} while(ortn == noErr);
CFRelease(srchRef);
if(foundId) {
*idRef = foundId;
return noErr;
}
else {
return errSecItemNotFound;
}
}