kc-30-xara-key-helpers.h [plain text]
#include "kc-30-xara-helpers.h"
#include "kc-key-helpers.h"
#ifndef kc_30_xara_key_helpers_h
#define kc_30_xara_key_helpers_h
#if TARGET_OS_MAC
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
#pragma clang diagnostic ignored "-Wunused-function"
static void makeCustomKeyWithIntegrity(const char* name, SecKeychainRef kc, CFStringRef label, CFStringRef expectedHash) {
SecKeyRef key = createCustomKey(name, kc, label);
checkIntegrityHash(name, (SecKeychainItemRef) key, expectedHash);
checkPartitionIDs(name, (SecKeychainItemRef) key, 1);
CFReleaseNull(key);
}
#define makeCustomKeyWithIntegrityTests (createCustomKeyTests + checkIntegrityHashTests + checkPartitionIDsTests)
static void makeKeyWithIntegrity(const char* name, SecKeychainRef kc, CFStringRef expectedHash) {
makeCustomKeyWithIntegrity(name, kc, CFSTR("test_key"), expectedHash);
}
#define makeKeyWithIntegrityTests makeCustomKeyWithIntegrityTests
static void makeKeyPairWithIntegrity(const char* name, SecKeychainRef kc, CFStringRef expectedPubHash, CFStringRef expectedPrivHash) {
SecKeyRef pub;
SecKeyRef priv;
makeKeyPair(name, kc, &pub, &priv);
checkIntegrityHash(name, (SecKeychainItemRef) pub, expectedPubHash);
checkIntegrityHash(name, (SecKeychainItemRef) priv, expectedPrivHash);
}
#define makeKeyPairWithIntegrityTests (makeKeyTests + checkIntegrityHashTests)
static void testAddKey(CFStringRef expectedHash) {
char* name = "testAddKey";
SecKeychainRef kc = newKeychain(name);
makeKeyWithIntegrity(name, kc, expectedHash);
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
CFReleaseNull(kc);
}
#define testAddKeyTests (newKeychainTests + makeKeyWithIntegrityTests + 1)
static void testAddFreeKey(CFStringRef expectedHash) {
}
#define testAddFreeKeyTests 0
static void testCopyMatchingKey(CFStringRef expectedHash) {
char* name = "testCopyMatchingKey";
secnotice("integrity", "************************************* %s", name);
SecKeychainRef kc = newKeychain(name);
checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 0);
makeKeyWithIntegrity(name, kc, expectedHash);
SecKeyRef item = (SecKeyRef) checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
checkIntegrityHash(name, (SecKeychainItemRef) item, expectedHash);
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
CFReleaseNull(item);
CFReleaseNull(kc);
}
#define testCopyMatchingKeyTests (newKeychainTests + checkNTests + makeKeyWithIntegrityTests + checkNTests + checkIntegrityHashTests + 1)
static void testUpdateKey(CFStringRef expectedHash, CFStringRef expectedHashAfter) {
char * name = "testUpdateKey";
secnotice("integrity", "************************************* %s", name);
SecKeychainRef kc = newKeychain(name);
makeKeyWithIntegrity(name, kc, expectedHash);
SecKeychainItemRef item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
CFReleaseNull(item);
CFStringRef label = CFSTR("a modified label");
CFMutableDictionaryRef query = createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric);
CFMutableDictionaryRef update = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(update, kSecAttrLabel, label);
ok_status(SecItemUpdate(query, update), "%s: SecItemUpdate", name);
CFReleaseNull(query);
CFReleaseNull(update);
query = createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric);
CFDictionarySetValue(query, kSecAttrLabel, label);
item = checkNCopyFirst(name, query, 1);
checkIntegrityHash(name, item, expectedHashAfter);
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
CFReleaseNull(kc);
}
#define testUpdateKeyTests (newKeychainTests + makeKeyWithIntegrityTests + checkNTests + 1 + checkNTests + checkIntegrityHashTests + 1)
static void testKeyPair() {
char* name = "testKeyPair";
secnotice("integrity", "************************************* %s", name);
SecKeychainRef kc = newKeychain(name);
checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 0);
checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 0);
SecKeyRef pub;
SecKeyRef priv;
makeKeyPair(name, kc, &pub, &priv);
CFStringRef label = CFSTR("a modified label");
CFMutableDictionaryRef query;
CFMutableDictionaryRef update;
SecKeyRef item;
item = (SecKeyRef) checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
checkHashesMatch(name, (SecKeychainItemRef)pub, (SecKeychainItemRef)item);
query = createQueryKeyDictionary(kc, kSecAttrKeyClassPublic);
CFDictionarySetValue(query, kSecAttrLabel, label);
item = (SecKeyRef) checkNCopyFirst(name, query, 0);
query = createQueryKeyDictionary(kc, kSecAttrKeyClassPublic);
update = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(update, kSecAttrLabel, label);
ok_status(SecItemUpdate(query, update), "%s: SecItemUpdate (public key)", name);
query = createQueryKeyDictionary(kc, kSecAttrKeyClassPublic);
CFDictionarySetValue(query, kSecAttrLabel, label);
item = (SecKeyRef) checkNCopyFirst(name, query, 1);
CFReleaseNull(item);
item = (SecKeyRef) checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
checkHashesMatch(name, (SecKeychainItemRef)priv, (SecKeychainItemRef)item);
query = createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate);
CFDictionarySetValue(query, kSecAttrLabel, label);
item = (SecKeyRef) checkNCopyFirst(name, query, 0);
query = createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate);
update = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(update, kSecAttrLabel, label);
ok_status(SecItemUpdate(query, update), "%s: SecItemUpdate (private key)", name);
query = createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate);
CFDictionarySetValue(query, kSecAttrLabel, label);
item = (SecKeyRef) checkNCopyFirst(name, query, 1);
CFReleaseNull(item);
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
CFReleaseNull(kc);
}
#define testKeyPairTests (newKeychainTests + checkNTests + checkNTests + makeKeyPairTests \
+ checkNTests + checkHashesMatchTests \
+ checkNTests + 1 + checkNTests \
+ checkNTests + checkHashesMatchTests \
+ checkNTests + 1 + checkNTests \
+ 1)
static void testAddDuplicateKey(CFStringRef expectedHash) {
char * name = "testAddDuplicateKey";
secnotice("integrity", "************************************* %s", name);
SecKeychainRef kc = newKeychain(name);
checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 0);
makeKeyWithIntegrity(name, kc, expectedHash);
SecKeychainItemRef item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
makeDuplicateKey(name, kc);
checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
CFReleaseNull(item);
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
CFReleaseNull(kc);
}
#define testAddDuplicateKeyTests (newKeychainTests + checkNTests +makeKeyWithIntegrityTests + checkNTests + makeDuplicateKeyTests + checkNTests + 1)
static void testAddDuplicateFreeKey(CFStringRef expectedHash) {
}
#define testAddDuplicateFreeKeyTests 0
static void testExportImportKeyPair() {
char* name = "testExportImportKeyPair";
secnotice("integrity", "************************************* %s", name);
SecKeychainRef kc = newKeychain(name);
checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 0);
checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 0);
SecKeyRef pub;
SecKeyRef priv;
makeKeyPair(name, kc, &pub, &priv);
SecKeyRef item;
item = (SecKeyRef) checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
checkHashesMatch(name, (SecKeychainItemRef)pub, (SecKeychainItemRef)item);
item = (SecKeyRef) checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
checkHashesMatch(name, (SecKeychainItemRef)priv, (SecKeychainItemRef)item);
CFMutableArrayRef applications = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks);
SecTrustedApplicationRef app = NULL;
ok_status(SecTrustedApplicationCreateFromPath(NULL, &app), "%s: SecTrustedApplicationCreateFromPath", name);
CFArrayAppendValue(applications, app);
ok_status(SecTrustedApplicationCreateFromPath("/usr/bin/codesign", &app), "%s: SecTrustedApplicationCreateFromPath", name);
CFArrayAppendValue(applications, app);
SecAccessRef accessRef = NULL;
ok_status(SecAccessCreate(CFSTR("accessDescription"), applications, &accessRef), "%s: SecAccessCreate", name);
const SecItemImportExportKeyParameters keyParams =
{
SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION,
0,
CFSTR( "" ),
CFSTR( "" ),
CFSTR( "" ),
accessRef, 0, 0
};
CFArrayRef items = NULL;
CFDataRef keyData = NULL;
ok_status(SecItemExport(pub, kSecFormatPEMSequence, kSecItemPemArmour, &keyParams, &keyData), "%s: SecItemExport", name);
ok_status(SecKeychainItemDelete((SecKeychainItemRef)pub), "%s: SecKeychainItemDelete", name);;
CFRelease(pub);
pub = NULL;
checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 0);
ok_status(SecItemImport(keyData, NULL, NULL, NULL, kSecItemPemArmour, &keyParams, kc, &items), "%s: SecItemImport", name);
checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
ok_status(SecItemExport(priv, kSecFormatPEMSequence, kSecItemPemArmour, &keyParams, &keyData), "%s: SecItemExport", name);
ok_status(SecKeychainItemDelete((SecKeychainItemRef)priv), "%s: SecKeychainItemDelete", name);;
CFRelease(priv);
priv = NULL;
checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 0);
ok_status(SecItemImport(keyData, NULL, NULL, NULL, kSecItemPemArmour, &keyParams, kc, &items), "%s: SecItemImport", name);
checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
SecAccessRef newRef = NULL;
ok_status(SecKeychainItemCopyAccess((SecKeychainItemRef) CFArrayGetValueAtIndex(items, 0), &newRef), "%s:SecKeychainItemCopyAccess", name);
SecKeyRef importedKey = items && CFArrayGetCount(items) > 0 ? (SecKeyRef)CFArrayGetValueAtIndex(items, 0) : NULL;
if (importedKey) {
CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(query, kSecClass, kSecClassKey);
CFDictionaryAddValue(query, kSecValueRef, importedKey);
CFMutableDictionaryRef attrs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(attrs, kSecAttrLabel, CFSTR("private key custom label"));
ok_status( SecItemUpdate(query, attrs), "%s: SecItemUpdate", name);
} else {
fail("%s: Didn't have an item to update", name);
}
ok_status(SecKeychainItemCopyAccess((SecKeychainItemRef) CFArrayGetValueAtIndex(items, 0), &newRef), "%s:SecKeychainItemCopyAccess", name);
checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
CFReleaseNull(kc);
}
#define testExportImportKeyPairTests (newKeychainTests + checkNTests + checkNTests + makeKeyPairTests \
+ checkNTests + checkHashesMatchTests \
+ checkNTests + checkHashesMatchTests \
+ 5 + checkNTests + 1 + checkNTests \
+ 2 + checkNTests + 1 + checkNTests + 1 + 1 + 1 + checkNTests\
+ 1)
#pragma clang diagnostic pop
#else
#endif
#endif