kc-20-identity-persistent-refs.c [plain text]
#import <Security/Security.h>
#include "keychain_regressions.h"
#include "kc-helpers.h"
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#include <Security/Security.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <time.h>
#include <sys/param.h>
#include "kc-identity-helpers.h"
#define MAXNAMELEN MAXPATHLEN
#define MAXITEMS INT32_MAX
static CFDataRef
copyPersistentReferenceForItem(CFTypeRef item)
{
OSStatus status;
CFDataRef persistentRef = NULL;
CFDictionaryRef query = NULL;
const void *keys[] = { kSecReturnPersistentRef, kSecValueRef };
const void *values[] = { kCFBooleanTrue, item };
query = CFDictionaryCreate(NULL, keys, values,
(sizeof(keys) / sizeof(*keys)), NULL, NULL);
status = SecItemCopyMatching(query, (CFTypeRef *)&persistentRef);
ok_status(status, "%s: SecItemCopyMatching (copyPersistentReferenceForItem)", testName);
CFRelease(query);
return persistentRef;
}
static CFTypeRef
copyItemForPersistentReference(CFDataRef persistentRef)
{
OSStatus status;
CFTypeRef itemRef = NULL;
CFDictionaryRef query = NULL;
const void *keys[] = { kSecReturnRef, kSecValuePersistentRef };
const void *values[] = { kCFBooleanTrue, persistentRef };
query = CFDictionaryCreate(NULL, keys, values,
(sizeof(keys) / sizeof(*keys)), NULL, NULL);
status = SecItemCopyMatching(query, &itemRef);
ok_status(status, "%s: SecItemCopyMatching (copyItemForPersistentReference)", testName);
CFRelease(query);
return itemRef;
}
static void
testIdentityPersistence(SecKeychainRef kc)
{
startTest(__FUNCTION__);
SecIdentityRef identity = copyFirstIdentity(kc);
is(CFGetTypeID(identity), SecIdentityGetTypeID(), "%s: retrieved identity is an identity", testName);
CFDataRef data = copyPersistentReferenceForItem((CFTypeRef)identity);
SecIdentityRef identity2 = (SecIdentityRef) copyItemForPersistentReference(data);
CFReleaseNull(data);
ok(identity2, "%s: retrieved an identity", testName);
if(identity2) {
is(CFGetTypeID(identity2), SecIdentityGetTypeID(), "%s: retrieved identity is an identity", testName);
} else {
fail("%s: no identity to test", testName);
}
eq_cf(identity2, identity, "%s: identities are equal", testName);
CFReleaseNull(identity);
CFReleaseNull(identity2);
}
static void
testCertificatePersistence(SecKeychainRef kc)
{
startTest(__FUNCTION__);
SecIdentityRef identity = copyFirstIdentity(kc);
SecCertificateRef cert = NULL, cert2 = NULL;
OSStatus status = SecIdentityCopyCertificate(identity, &cert);
ok_status(status, "%s: SecIdentityCopyCertificate", testName);
ok(cert, "%s: No certificate returned from SecIdentityCopyCertificate", testName);
CFReleaseNull(identity);
CFDataRef data = (CFDataRef) copyPersistentReferenceForItem(cert);
cert2 = (SecCertificateRef) copyItemForPersistentReference(data);
ok(cert2, "%s: retrieved a certificate", testName);
if(cert2) {
is(CFGetTypeID(cert2), SecCertificateGetTypeID(), "%s: returned value is a certificate", testName);
} else {
fail("%s: no certificate to test", testName);
}
eq_cf(cert2, cert, "%s: Certificates are equal", testName);
CFReleaseNull(data);
CFReleaseNull(cert);
CFReleaseNull(cert2);
}
int kc_20_identity_persistent_refs(int argc, char *const *argv)
{
plan_tests(18);
initializeKeychainTests(__FUNCTION__);
SecKeychainRef kc = getPopulatedTestKeychain();
addToSearchList(kc);
testCertificatePersistence(kc);
testIdentityPersistence(kc);
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", testName);
CFReleaseNull(kc);
deleteTestFiles();
return 0;
}