#include <TargetConditionals.h>
#include <Security/cssmapi.h>
#include <stdlib.h>
+#include <sys/stat.h>
+#include <copyfile.h>
+#include <unistd.h>
#include "kc-30-xara-item-helpers.h"
#include "kc-30-xara-key-helpers.h"
static CSSM_DL_DB_HANDLE initializeDL() {
CSSM_VERSION version = { 2, 0 };
- CSSM_DL_DB_HANDLE dldbHandle;
+ CSSM_DL_DB_HANDLE dldbHandle = { 0, 0 };
CSSM_GUID myGuid = { 0xFADE, 0, 0, { 1, 2, 3, 4, 5, 6, 7, 0 } };
CSSM_PVC_MODE pvcPolicy = CSSM_PVC_NONE;
static void testAttackItem(CSSM_DL_DB_HANDLE dldbHandle) {
char * name = "testAttackItem";
- secdebugfunc("integrity", "************************************* %s", name);
+ secnotice("integrity", "************************************* %s", name);
SecKeychainRef kc = newKeychain(name);
- checkN(name, makeQueryItemDictionary(kc, kSecClassGenericPassword), 0);
+ checkN(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 0);
makeItemWithIntegrity(name, kc, kSecClassGenericPassword, CFSTR("265438ea6807b509c9c6962df3f5033fd1af118f76c5f550e3ed90cb0d3ffce4"));
- SecKeychainItemRef item = checkN(name, makeQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ SecKeychainItemRef item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ CFReleaseNull(item);
CFReleaseNull(kc);
char * modification = "evil_application";
- modifyAttributeInKeychain(name, dldbHandle, keychainFile, CSSM_DL_DB_RECORD_GENERIC_PASSWORD, "PrintName", modification, strlen(modification));
+ modifyAttributeInKeychain(name, dldbHandle, keychainDbFile, CSSM_DL_DB_RECORD_GENERIC_PASSWORD, "PrintName", modification, strlen(modification));
kc = openKeychain(name);
- checkN(name, makeQueryItemDictionary(kc, kSecClassGenericPassword), 0);
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ readPasswordContentsWithResult(item, errSecInvalidItemRef, NULL);
+
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
+ CFReleaseNull(kc);
}
-#define testAttackItemTests (newKeychainTests + checkNTests + makeItemWithIntegrityTests + checkNTests + modifyAttributeInKeychainTests + openKeychainTests + checkNTests + 1)
+#define testAttackItemTests (newKeychainTests + checkNTests + makeItemWithIntegrityTests + checkNTests + modifyAttributeInKeychainTests + openKeychainTests + checkNTests + readPasswordContentsWithResultTests + 1)
static void testAttackKey(CSSM_DL_DB_HANDLE dldbHandle) {
char * name = "testAttackKey";
- secdebugfunc("integrity", "************************************* %s", name);
+ secnotice("integrity", "************************************* %s", name);
SecKeychainRef kc = newKeychain(name);
- checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 0);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 0);
makeKeyWithIntegrity(name, kc, CFSTR("44f10f6bb508d47f8905859efc06eaee500304bc4da408b1f4d2a58c6502147b"));
- SecKeychainItemRef item = checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
+ SecKeychainItemRef item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
+
+ checkKeyUse((SecKeyRef) item, errSecSuccess);
+
+ CFReleaseNull(item);
CFReleaseNull(kc);
char * modification = "evil_application";
- modifyAttributeInKeychain(name, dldbHandle, keychainFile, CSSM_DL_DB_RECORD_SYMMETRIC_KEY, "Label", modification, strlen(modification));
+ modifyAttributeInKeychain(name, dldbHandle, keychainDbFile, CSSM_DL_DB_RECORD_SYMMETRIC_KEY, "Label", modification, strlen(modification));
kc = openKeychain(name);
- checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 0);
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
+ checkKeyUse((SecKeyRef) item, errSecInvalidItemRef);
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
+ CFReleaseNull(kc);
}
-#define testAttackKeyTests (newKeychainTests + checkNTests + makeKeyWithIntegrityTests + checkNTests + modifyAttributeInKeychainTests + openKeychainTests + checkNTests + 1)
+#define testAttackKeyTests (newKeychainTests + checkNTests + makeKeyWithIntegrityTests + checkNTests + checkKeyUseTests + modifyAttributeInKeychainTests \
+ + openKeychainTests + checkNTests + checkKeyUseTests + 1)
static void testAddAfterCorruptItem(CSSM_DL_DB_HANDLE dldbHandle) {
char * name = "testAddAfterCorruptItem";
- secdebugfunc("integrity", "************************************* %s", name);
+ secnotice("integrity", "************************************* %s", name);
SecKeychainRef kc = newKeychain(name);
- checkN(name, makeQueryItemDictionary(kc, kSecClassGenericPassword), 0);
+ checkN(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 0);
makeCustomItemWithIntegrity(name, kc, kSecClassGenericPassword, CFSTR("test_label"), CFSTR("265438ea6807b509c9c6962df3f5033fd1af118f76c5f550e3ed90cb0d3ffce4"));
- SecKeychainItemRef item = checkN(name, makeQueryItemDictionary(kc, kSecClassGenericPassword), 1);
- CFReleaseNull(item);
+ checkN(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
makeDuplicateItem(name, kc, kSecClassGenericPassword);
CFReleaseNull(kc);
char * modification = "evil_application";
- modifyAttributeInKeychain(name, dldbHandle, keychainFile, CSSM_DL_DB_RECORD_GENERIC_PASSWORD, "PrintName", modification, strlen(modification));
+ modifyAttributeInKeychain(name, dldbHandle, keychainDbFile, CSSM_DL_DB_RECORD_GENERIC_PASSWORD, "PrintName", modification, strlen(modification));
kc = openKeychain(name);
- checkN(name, makeQueryItemDictionary(kc, kSecClassGenericPassword), 0);
+ SecKeychainItemRef item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ deleteItem(item);
+ checkN(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 0);
makeCustomItemWithIntegrity(name, kc, kSecClassGenericPassword, CFSTR("evil_application"), CFSTR("d2aa97b30a1f96f9e61fcade2b00d9f4284976a83a5b68392251ee5ec827f8cc"));
- checkN(name, makeQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ checkN(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
makeCustomDuplicateItem(name, kc, kSecClassGenericPassword, CFSTR("evil_application"));
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
+ CFReleaseNull(kc);
}
#define testAddAfterCorruptItemTests (newKeychainTests + checkNTests + makeCustomItemWithIntegrityTests + checkNTests + makeDuplicateItemTests \
- + modifyAttributeInKeychainTests + openKeychainTests + checkNTests + makeCustomItemWithIntegrityTests + checkNTests + makeCustomDuplicateItemTests + 1)
+ + modifyAttributeInKeychainTests + openKeychainTests + checkNTests + deleteItemTests \
+ + checkNTests + makeCustomItemWithIntegrityTests + checkNTests + makeCustomDuplicateItemTests + 1)
static void testAddAfterCorruptKey(CSSM_DL_DB_HANDLE dldbHandle) {
char * name = "testAddAfterCorruptKey";
- secdebugfunc("integrity", "************************************* %s", name);
+ secnotice("integrity", "************************************* %s", name);
SecKeychainRef kc = newKeychain(name);
- checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 0);
- checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 0);
- checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 0);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 0);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 0);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 0);
// Make a symmetric key
makeCustomKeyWithIntegrity(name, kc, CFSTR("test_key"), CFSTR("44f10f6bb508d47f8905859efc06eaee500304bc4da408b1f4d2a58c6502147b"));
- SecKeychainItemRef item = checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
+ SecKeychainItemRef item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
makeCustomDuplicateKey(name, kc, CFSTR("test_key"));
CFReleaseNull(item);
SecKeyRef pub;
SecKeyRef priv;
makeCustomKeyPair(name, kc, CFSTR("test_key_pair"), &pub, &priv);
- checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
- checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
CFReleaseNull(pub);
CFReleaseNull(priv);
ok_status(SecKeychainListRemoveKeychain(&kc), "%s: SecKeychainListRemoveKeychain", name);
char * modification = "evil_application";
- modifyAttributeInKeychain(name, dldbHandle, keychainFile, CSSM_DL_DB_RECORD_SYMMETRIC_KEY, "PrintName", modification, strlen(modification));
- modifyAttributeInKeychain(name, dldbHandle, keychainFile, CSSM_DL_DB_RECORD_PUBLIC_KEY, "PrintName", modification, strlen(modification));
- modifyAttributeInKeychain(name, dldbHandle, keychainFile, CSSM_DL_DB_RECORD_PRIVATE_KEY, "PrintName", modification, strlen(modification));
+ modifyAttributeInKeychain(name, dldbHandle, keychainDbFile, CSSM_DL_DB_RECORD_SYMMETRIC_KEY, "PrintName", modification, strlen(modification));
+ modifyAttributeInKeychain(name, dldbHandle, keychainDbFile, CSSM_DL_DB_RECORD_PUBLIC_KEY, "PrintName", modification, strlen(modification));
+ modifyAttributeInKeychain(name, dldbHandle, keychainDbFile, CSSM_DL_DB_RECORD_PRIVATE_KEY, "PrintName", modification, strlen(modification));
kc = openKeychain(name);
- checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 0);
- checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 0);
- checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 0);
+
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
+ deleteItem(item);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 0);
+
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
+ deleteItem(item);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 0);
+
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
+ deleteItem(item);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 0);
makeCustomKeyWithIntegrity(name, kc, CFSTR("evil_application"), CFSTR("ca6d90a0b053113e43bbb67f64030230c96537f77601f66bdf821d8684431dfc"));
- item = checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
makeCustomDuplicateKey(name, kc, CFSTR("evil_application"));
makeCustomKeyPair(name, kc, CFSTR("evil_application"), &pub, &priv);
- checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
- checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
// We cannot create a duplicate key pair, so don't try.
CFReleaseNull(item);
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
+ CFReleaseNull(kc);
}
#define testAddAfterCorruptKeyTests (newKeychainTests \
+ checkNTests + checkNTests + checkNTests \
+ modifyAttributeInKeychainTests \
+ modifyAttributeInKeychainTests \
+ openKeychainTests \
- + checkNTests + checkNTests + checkNTests \
+ + checkNTests + deleteItemTests + checkNTests \
+ + checkNTests + deleteItemTests + checkNTests \
+ + checkNTests + deleteItemTests + checkNTests \
+ makeCustomKeyWithIntegrityTests + checkNTests \
+ makeCustomDuplicateKeyTests \
+ makeCustomKeyPairTests + checkNTests + checkNTests \
+ 1)
+// These constants are in CommonBlob, but we're in C and can't access them
+#define version_MacOS_10_0 0x00000100
+#define version_partition 0x00000200
+
static void testKeychainUpgrade() {
char name[100];
sprintf(name, "testKeychainUpgrade");
- secdebugfunc("integrity", "************************************* %s", name);
+ secnotice("integrity", "************************************* %s", name);
+ UInt32 version;
+ char* path = malloc(sizeof(char) * 400);
+ UInt32 len = 400;
+
+ // To test multi-threading, we want the upgrade to take a while. Add a bunch of passwords...
+ char oldkcFile[MAXPATHLEN];
+ snprintf(oldkcFile, sizeof(oldkcFile), "%s/Library/test.keychain", getenv("HOME"));
+ unlink(oldkcFile);
+ writeOldKeychain(name, oldkcFile);
+
+ SecKeychainRef kc = openCustomKeychain(name, oldkcFile, "password");
+
+ for(int i = 0; i < 200; i++) {
+ CFTypeRef result = NULL;
+ CFStringRef cflabel = CFStringCreateWithFormat(NULL, NULL, CFSTR("item%d"), i);
+ CFMutableDictionaryRef query = createAddCustomItemDictionaryWithService(kc, kSecClassInternetPassword, cflabel, cflabel, CFSTR("no service"));
+ SecItemAdd(query, &result); // don't particuluarly care if this fails...
+ CFReleaseNull(query);
+ CFReleaseNull(cflabel);
+ CFReleaseNull(result);
+ }
- writeOldKeychain(name, keychainFile);
- SecKeychainRef kc = openCustomKeychain(name, "test.keychain", "password");
+ CFReleaseNull(kc);
+
+ ok_status(copyfile(oldkcFile, keychainFile, NULL, COPYFILE_UNLINK | COPYFILE_ALL), "%s: copyfile", name);
+ unlink(oldkcFile);
+ unlink(keychainDbFile);
+ static dispatch_once_t onceToken = 0;
+ static dispatch_queue_t release_queue = NULL;
+ dispatch_once(&onceToken, ^{
+ release_queue = dispatch_queue_create("com.apple.security.keychain-upgrade-queue", DISPATCH_QUEUE_CONCURRENT);
+ });
+
+ dispatch_group_t g = dispatch_group_create();
SecKeychainItemRef item;
- item = checkN(name, makeQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ char* __block blockName = NULL;
+ asprintf(&blockName, "%s", name);
+
+ kc = openCustomKeychain(name, keychainName, "password");
+
+ // Directly after an upgrade, no items should have partition ID lists
+ dispatch_group_async(g, release_queue, ^() {
+ secerror("beginning 1\n");
+ SecKeychainRef blockKc;
+ SecKeychainOpen(keychainName, &blockKc);
+ SecKeychainItemRef item = checkNCopyFirst(blockName, createQueryItemDictionary(blockKc, kSecClassGenericPassword), 1);
+ checkIntegrityHash(blockName, item, CFSTR("39c56eadd3e3b496b6099e5f3d5ff88eaee9ca2e3a50c1be8319807a72e451e5"));
+ checkPartitionIDs(blockName, item, 0);
+ CFReleaseSafe(blockKc);
+ CFReleaseSafe(item);
+ secerror("ending 1\n");
+ });
+
+ dispatch_group_async(g, release_queue, ^() {
+ usleep(0.1 * USEC_PER_SEC); // use different timings to try to find multithreaded upgrade bugs
+ secerror("beginning 2\n");
+ SecKeychainRef blockKc;
+ SecKeychainOpen(keychainName, &blockKc);
+ SecKeychainItemRef item = checkNCopyFirst(blockName, createQueryItemDictionaryWithService(blockKc, kSecClassInternetPassword, CFSTR("test_service")), 1);
+ checkIntegrityHash(blockName, item, CFSTR("4f1b64e3c156968916e72d8ff3f1a8eb78b32abe0b2b43f0578eb07c722aaf03"));
+ checkPartitionIDs(blockName, item, 0);
+ CFReleaseSafe(blockKc);
+ CFReleaseSafe(item);
+ secerror("ending 2\n");
+ });
+
+ dispatch_group_async(g, release_queue, ^() {
+ usleep(0.3 * USEC_PER_SEC);
+ secerror("beginning 3\n");
+ SecKeychainRef blockKc;
+ SecKeychainOpen(keychainName, &blockKc);
+ SecKeychainItemRef item = checkNCopyFirst(blockName, createQueryKeyDictionary(blockKc, kSecAttrKeyClassSymmetric), 1);
+ checkIntegrityHash(blockName, (SecKeychainItemRef) item, CFSTR("44f10f6bb508d47f8905859efc06eaee500304bc4da408b1f4d2a58c6502147b"));
+ checkPartitionIDs(blockName, (SecKeychainItemRef) item, 0);
+ CFReleaseSafe(blockKc);
+ CFReleaseSafe(item);
+ secerror("ending 3\n");
+ });
+
+ dispatch_group_async(g, release_queue, ^() {
+ usleep(0.5 * USEC_PER_SEC);
+ secerror("beginning 4\n");
+ SecKeychainRef blockKc;
+ SecKeychainOpen(keychainName, &blockKc);
+ SecKeychainItemRef item = checkNCopyFirst(blockName, createQueryKeyDictionary(blockKc, kSecAttrKeyClassPublic), 1);
+ checkIntegrityHash(blockName, (SecKeychainItemRef) item, CFSTR("42d29fd5e9935edffcf6d0261eabddb00782ec775caa93716119e8e553ab5578"));
+ checkPartitionIDs(blockName, (SecKeychainItemRef) item, 0);
+ CFReleaseSafe(blockKc);
+ CFReleaseSafe(item);
+ secerror("ending 4\n");
+ });
+
+ dispatch_group_async(g, release_queue, ^() {
+ usleep(1 * USEC_PER_SEC);
+ secerror("beginning 5\n");
+ SecKeychainRef blockKc;
+ SecKeychainOpen(keychainName, &blockKc);
+ SecKeychainItemRef item = checkNCopyFirst(blockName, createQueryKeyDictionary(blockKc, kSecAttrKeyClassPrivate), 1);
+ checkIntegrityHash(blockName, (SecKeychainItemRef) item, CFSTR("bdf219cdbc2dc6c4521cf39d1beda2e3491ef0330ba59eb41229dd909632f48d"));
+ checkPartitionIDs(blockName, (SecKeychainItemRef) item, 0);
+ CFReleaseSafe(blockKc);
+ CFReleaseSafe(item);
+ secerror("ending 5\n");
+ });
+
+ dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
+
+ // @@@ I'm worried that there are still some thread issues in AppleDatabase; if these are run in the blocks above
+ // you can sometimes get CSSMERR_DL_INVALID_RECORD_UID/errSecInvalidRecord instead of errSecDuplicateItem
+ // <rdar://problem/27085024> Multi-threading duplicate item creation sometimes returns -67701
+ makeCustomDuplicateItem(name, kc, kSecClassGenericPassword, CFSTR("test_generic"));
+ makeCustomDuplicateItem(name, kc, kSecClassInternetPassword, CFSTR("test_internet"));
+
+ // Check the keychain's version and path
+ ok_status(SecKeychainGetKeychainVersion(kc, &version), "%s: SecKeychainGetKeychainVersion", name);
+ is(version, version_partition, "%s: version of upgraded keychain is incorrect", name);
+ ok_status(SecKeychainGetPath(kc, &len, path), "%s: SecKeychainGetKeychainPath", name);
+ eq_stringn(path, len, keychainDbFile, strlen(keychainDbFile), "%s: paths do not match", name);
+ free(path);
+
+ // Now close the keychain and open it again
+ CFReleaseNull(kc);
+ kc = openCustomKeychain(name, keychainName, "password");
+
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
checkIntegrityHash(name, item, CFSTR("39c56eadd3e3b496b6099e5f3d5ff88eaee9ca2e3a50c1be8319807a72e451e5"));
+ checkPartitionIDs(name, item, 0);
makeCustomDuplicateItem(name, kc, kSecClassGenericPassword, CFSTR("test_generic"));
- item = checkN(name, makeQueryItemDictionary(kc, kSecClassInternetPassword), 1);
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassInternetPassword), 1);
checkIntegrityHash(name, item, CFSTR("4f1b64e3c156968916e72d8ff3f1a8eb78b32abe0b2b43f0578eb07c722aaf03"));
+ checkPartitionIDs(name, item, 0);
makeCustomDuplicateItem(name, kc, kSecClassInternetPassword, CFSTR("test_internet"));
- item = checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
checkIntegrityHash(name, (SecKeychainItemRef) item, CFSTR("44f10f6bb508d47f8905859efc06eaee500304bc4da408b1f4d2a58c6502147b"));
+ checkPartitionIDs(name, (SecKeychainItemRef) item, 0);
- item = checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
checkIntegrityHash(name, (SecKeychainItemRef) item, CFSTR("42d29fd5e9935edffcf6d0261eabddb00782ec775caa93716119e8e553ab5578"));
+ checkPartitionIDs(name, (SecKeychainItemRef) item, 0);
- item = checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
checkIntegrityHash(name, (SecKeychainItemRef) item, CFSTR("bdf219cdbc2dc6c4521cf39d1beda2e3491ef0330ba59eb41229dd909632f48d"));
+ checkPartitionIDs(name, (SecKeychainItemRef) item, 0);
- // Now close the keychain and open it again
+ ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
CFReleaseNull(kc);
- kc = openCustomKeychain(name, "test.keychain", "password");
- item = checkN(name, makeQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ // make sure we clean up any files left over
+ unlink(keychainDbFile);
+ unlink(keychainFile);
+ unlink(oldkcFile);
+}
+#define testKeychainUpgradeTests (openCustomKeychainTests + 1 + openCustomKeychainTests + 4 \
+ + checkNTests + checkIntegrityHashTests + checkPartitionIDsTests + makeCustomDuplicateItemTests \
+ + checkNTests + checkIntegrityHashTests + checkPartitionIDsTests + makeCustomDuplicateItemTests \
+ + checkNTests + checkIntegrityHashTests + checkPartitionIDsTests \
+ + checkNTests + checkIntegrityHashTests + checkPartitionIDsTests \
+ + checkNTests + checkIntegrityHashTests + checkPartitionIDsTests \
+ + openCustomKeychainTests \
+ + checkNTests + checkIntegrityHashTests + checkPartitionIDsTests + makeCustomDuplicateItemTests \
+ + checkNTests + checkIntegrityHashTests + checkPartitionIDsTests + makeCustomDuplicateItemTests \
+ + checkNTests + checkIntegrityHashTests + checkPartitionIDsTests \
+ + checkNTests + checkIntegrityHashTests + checkPartitionIDsTests \
+ + checkNTests + checkIntegrityHashTests + checkPartitionIDsTests \
+ + 1)
+
+// tests that SecKeychainCreate over an old .keychain file returns an empty keychain
+static void testKeychainCreateOver() {
+ char name[100];
+ sprintf(name, "testKeychainCreateOver");
+ secnotice("integrity", "************************************* %s", name);
+ UInt32 version;
+ char* path = malloc(sizeof(char) * 400);
+ UInt32 len = 400;
+
+ writeOldKeychain(name, keychainFile);
+ unlink(keychainDbFile);
+
+ SecKeychainItemRef item = NULL;
+
+ // Check that we upgrade on SecKeychainOpen
+ SecKeychainRef kc = openCustomKeychain(name, keychainName, "password");
+
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
checkIntegrityHash(name, item, CFSTR("39c56eadd3e3b496b6099e5f3d5ff88eaee9ca2e3a50c1be8319807a72e451e5"));
+ CFReleaseNull(item);
+
+ ok_status(SecKeychainDelete(kc));
+ CFReleaseNull(kc);
+
+ // the old file should still exist, but the -db file should not.
+ struct stat filebuf;
+ is(stat(keychainFile, &filebuf), 0, "%s: check %s exists", name, keychainFile);
+ isnt(stat(keychainDbFile, &filebuf), 0, "%s: check %s does not exist", name, keychainDbFile);
+
+ // Now create a new keychain over the old remnants.
+ ok_status(SecKeychainCreate(keychainFile, (UInt32) strlen("password"), "password", false, NULL, &kc), "%s: SecKeychainCreate", name);
+
+ // Directly after creating a keychain, there shouldn't be any items (even though an old keychain exists underneath)
+ checkN(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 0);
+ checkN(name, createQueryItemDictionary(kc, kSecClassInternetPassword), 0);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 0);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 0);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 0);
+
+ // Check the keychain's version and path
+ ok_status(SecKeychainGetKeychainVersion(kc, &version), "%s: SecKeychainGetKeychainVersion", name);
+ is(version, version_partition, "%s: version of upgraded keychain is incorrect", name);
+ ok_status(SecKeychainGetPath(kc, &len, path), "%s: SecKeychainGetKeychainPath", name);
+ eq_stringn(path, len, keychainDbFile, strlen(keychainDbFile), "%s: paths do not match", name);
+ free(path);
+
+ ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
+ CFReleaseNull(kc);
+
+ // final check that the files on-disk are as we expect
+ is(stat(keychainFile, &filebuf), 0, "%s: check %s exists", name, keychainFile);
+ isnt(stat(keychainDbFile, &filebuf), 0, "%s: check %s does not exist", name, keychainDbFile);
+
+ // make sure we clean up any files left over
+ unlink(keychainDbFile);
+ unlink(keychainFile);
+}
+#define testKeychainCreateOverTests (openCustomKeychainTests + \
++ checkNTests + checkIntegrityHashTests \
++ 1 + 2 + 1 \
++ checkNTests \
++ checkNTests \
++ checkNTests \
++ checkNTests \
++ checkNTests \
++ 4 + 1 + 2)
+
+static void testKeychainDowngrade() {
+ char *name = "testKeychainDowngrade";
+ secnotice("integrity", "************************************* %s", name);
+
+ // For now, don't worry about filenames
+ writeFullV512Keychain(name, keychainDbFile);
+ unlink(keychainFile);
+ writeFullV512Keyfile(name, keychainTempFile);
+
+ SecKeychainRef kc = openCustomKeychain(name, keychainName, "password");
+ UInt32 version;
+
+ ok_status(SecKeychainGetKeychainVersion(kc, &version), "%s: SecKeychainGetKeychainVersion", name);
+ is(version, version_partition, "%s: version of initial keychain is incorrect", name);
+
+ SecKeychainItemRef item;
+
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ checkIntegrityHash(name, item, CFSTR("6ba8d9f77ddba54d9373b11ae5c8f7b55a5e81da27e05e86723eeceb0a9a8e0c"));
makeCustomDuplicateItem(name, kc, kSecClassGenericPassword, CFSTR("test_generic"));
- item = checkN(name, makeQueryItemDictionary(kc, kSecClassInternetPassword), 1);
- checkIntegrityHash(name, item, CFSTR("4f1b64e3c156968916e72d8ff3f1a8eb78b32abe0b2b43f0578eb07c722aaf03"));
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassInternetPassword), 1);
+ checkIntegrityHash(name, item, CFSTR("630a9fe4f0191db8a99d6e8455e7114f628ce8f0f9eb3559efa572a98877a2b2"));
makeCustomDuplicateItem(name, kc, kSecClassInternetPassword, CFSTR("test_internet"));
- item = checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
checkIntegrityHash(name, (SecKeychainItemRef) item, CFSTR("44f10f6bb508d47f8905859efc06eaee500304bc4da408b1f4d2a58c6502147b"));
- item = checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
- checkIntegrityHash(name, (SecKeychainItemRef) item, CFSTR("42d29fd5e9935edffcf6d0261eabddb00782ec775caa93716119e8e553ab5578"));
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
+ checkIntegrityHash(name, (SecKeychainItemRef) item, CFSTR("d27ee2be4920d5b6f47f6b19696d09c9a6c1a5d80c6f148f778db27b4ba99d9a"));
- item = checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
- checkIntegrityHash(name, (SecKeychainItemRef) item, CFSTR("bdf219cdbc2dc6c4521cf39d1beda2e3491ef0330ba59eb41229dd909632f48d"));
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
+ checkIntegrityHash(name, (SecKeychainItemRef) item, CFSTR("4b3f7bd7f9e48dc71006ce670990aed9dba6d5089b84d4113121bab41d0a3228"));
+
+
+
+ ok_status(SecKeychainAttemptMigrationWithMasterKey(kc, version_MacOS_10_0, keychainTempFile), "%s: SecKeychainAttemptKeychainMigrationWithMasterKey", name);
+ ok_status(SecKeychainGetKeychainVersion(kc, &version), "%s: SecKeychainGetKeychainVersion", name);
+ is(version, version_MacOS_10_0, "%s: version of downgraded keychain is incorrect", name);
+
+ checkN(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ makeCustomDuplicateItem(name, kc, kSecClassGenericPassword, CFSTR("test_generic"));
+ checkN(name, createQueryItemDictionary(kc, kSecClassInternetPassword), 1);
+ makeCustomDuplicateItem(name, kc, kSecClassInternetPassword, CFSTR("test_internet"));
+
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
+ checkN(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
+ CFReleaseNull(kc);
+
+ // make sure we clean up
+ unlink(keychainTempFile);
+ unlink(keychainDbFile);
+ unlink(keychainFile);
}
-#define testKeychainUpgradeTests (openCustomKeychainTests \
- + checkNTests + checkIntegrityHashTests + makeCustomDuplicateItemTests \
- + checkNTests + checkIntegrityHashTests + makeCustomDuplicateItemTests \
- + checkNTests + checkIntegrityHashTests + \
- + checkNTests + checkIntegrityHashTests + \
- + checkNTests + checkIntegrityHashTests + \
- + openCustomKeychainTests \
+#define testKeychainDowngradeTests (openCustomKeychainTests + 2 \
+ checkNTests + checkIntegrityHashTests + makeCustomDuplicateItemTests \
+ checkNTests + checkIntegrityHashTests + makeCustomDuplicateItemTests \
+ checkNTests + checkIntegrityHashTests +\
+ checkNTests + checkIntegrityHashTests +\
+ checkNTests + checkIntegrityHashTests +\
- 1)
+ + 3 + \
+ + checkNTests + makeCustomDuplicateItemTests \
+ + checkNTests + makeCustomDuplicateItemTests \
+ + checkNTests \
+ + checkNTests \
+ + checkNTests \
+ + 1)\
+
+// Test opening and upgrading a v256 keychain at a -db filename.
+static void testKeychainWrongFile256() {
+ char name[100];
+ sprintf(name, "testKeychainWrongFile256");
+ secnotice("integrity", "************************************* %s", name);
+ UInt32 version;
+
+ unlink(keychainFile);
+ writeOldKeychain(name, keychainDbFile);
+
+ // Only keychainDb file should exist
+ struct stat filebuf;
+ isnt(stat(keychainFile, &filebuf), 0, "%s: %s exists and shouldn't", name, keychainFile);
+ is(stat(keychainDbFile, &filebuf), 0, "%s: %s does not exist", name, keychainDbFile);
+
+ SecKeychainRef kc = openCustomKeychain(name, keychainName, "password");
+
+ SecKeychainItemRef item;
+
+ // Iterate over the keychain to trigger upgrade
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ makeCustomDuplicateItem(name, kc, kSecClassGenericPassword, CFSTR("test_generic"));
+
+ // We should have created keychainFile, check for it
+ is(stat(keychainFile, &filebuf), 0, "%s: %s does not exist", name, keychainFile);
+ is(stat(keychainDbFile, &filebuf), 0, "%s: %s does not exist", name, keychainDbFile);
+
+ // Check the keychain's version and path
+ char path[400];
+ UInt32 len = sizeof(path);
+
+ ok_status(SecKeychainGetKeychainVersion(kc, &version), "%s: SecKeychainGetKeychainVersion", name);
+ is(version, version_partition, "%s: version of re-upgraded keychain is incorrect", name);
+ ok_status(SecKeychainGetPath(kc, &len, path), "%s: SecKeychainGetPath", name);
+ eq_stringn(path, len, keychainDbFile, strlen(keychainDbFile), "%s: paths do not match", name);
+
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ makeCustomDuplicateItem(name, kc, kSecClassGenericPassword, CFSTR("test_generic"));
+
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassInternetPassword), 1);
+ makeCustomDuplicateItem(name, kc, kSecClassInternetPassword, CFSTR("test_internet"));
+
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
+
+ ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
+ CFReleaseNull(kc);
+
+ // make sure we clean up any files left over
+ unlink(keychainDbFile);
+ unlink(keychainFile);
+}
+#define testKeychainWrongFile256Tests (2 + openCustomKeychainTests \
+ + checkNTests + makeCustomDuplicateItemTests \
+ + 2 + 4 \
+ + checkNTests + makeCustomDuplicateItemTests \
+ + checkNTests + makeCustomDuplicateItemTests \
+ + checkNTests \
+ + checkNTests \
+ + checkNTests \
+ + 1)
+
+// Test opening and upgrading a v512 keychain at a .keychain filename.
+static void testKeychainWrongFile512() {
+ char name[100];
+ sprintf(name, "testKeychainWrongFile512");
+ secnotice("integrity", "************************************* %s", name);
+ UInt32 version;
+
+ writeFullV512Keychain(name, keychainFile);
+ unlink(keychainDbFile);
+
+ // Only keychain file should exist
+ struct stat filebuf;
+ isnt(stat(keychainDbFile, &filebuf), 0, "%s: %s exists and shouldn't", name, keychainFile);
+ is(stat(keychainFile, &filebuf), 0, "%s: %s does not exist", name, keychainDbFile);
+
+ SecKeychainRef kc = openCustomKeychain(name, keychainName, "password");
+
+ SecKeychainItemRef item;
+
+ // Iterate over the keychain to trigger upgrade
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ makeCustomDuplicateItem(name, kc, kSecClassGenericPassword, CFSTR("test_generic"));
+
+ // We should have move the keychain to keychainDbFile, check for it
+ isnt(stat(keychainFile, &filebuf), 0, "%s: %s still exists", name, keychainFile);
+ is(stat(keychainDbFile, &filebuf), 0, "%s: %s does not exist", name, keychainDbFile);
+
+ // Check the keychain's version and path
+ char path[400];
+ UInt32 len = sizeof(path);
+
+ ok_status(SecKeychainGetKeychainVersion(kc, &version), "%s: SecKeychainGetKeychainVersion", name);
+ is(version, version_partition, "%s: version of moved keychain is incorrect", name);
+ ok_status(SecKeychainGetPath(kc, &len, path), "%s: SecKeychainGetPath", name);
+ eq_stringn(path, len, keychainDbFile, strlen(keychainDbFile), "%s: paths do not match", name);
+
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ makeCustomDuplicateItem(name, kc, kSecClassGenericPassword, CFSTR("test_generic"));
+
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassInternetPassword), 1);
+ makeCustomDuplicateItem(name, kc, kSecClassInternetPassword, CFSTR("test_internet"));
+
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
+
+ ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
+ CFReleaseNull(kc);
+
+ // make sure we clean up any files left over
+ unlink(keychainDbFile);
+ unlink(keychainFile);
+}
+#define testKeychainWrongFile512Tests (2 + openCustomKeychainTests \
++ checkNTests + makeCustomDuplicateItemTests \
++ 2 + 4 \
++ checkNTests + makeCustomDuplicateItemTests \
++ checkNTests + makeCustomDuplicateItemTests \
++ checkNTests \
++ checkNTests \
++ checkNTests \
++ 1)
+
+
+#undef version_partition
+#undef version_MacOS_10_0
static SecAccessRef makeUidAccess(uid_t uid)
{
static void testUidAccess() {
char name[100];
sprintf(name, "testUidAccess");
- secdebugfunc("integrity", "************************************* %s", name);
+ secnotice("integrity", "************************************* %s", name);
SecAccessRef access = makeUidAccess(getuid());
SecKeychainRef kc = newKeychain(name);
- CFMutableDictionaryRef query = makeAddItemDictionary(kc, kSecClassGenericPassword, CFSTR("test label"));
+ CFMutableDictionaryRef query = createAddItemDictionary(kc, kSecClassGenericPassword, CFSTR("test label"));
CFDictionarySetValue(query, kSecAttrAccess, access);
CFTypeRef result = NULL;
ok_status(SecItemAdd(query, &result), "%s: SecItemAdd", name);
+ CFReleaseNull(query);
ok(result != NULL, "%s: SecItemAdd returned a result", name);
- SecKeychainItemRef item = checkN(name, makeQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ SecKeychainItemRef item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
ok_status(SecKeychainItemSetAccess(item, access), "%s: SecKeychainItemSetAccess", name);
- checkN(name, makeQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ checkN(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
// Check to make sure the ACL stays
access = NULL;
checkAccessLength(name, access, 2);
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
+ CFReleaseNull(kc);
}
#define testUidAccessTests (newKeychainTests + 2 + checkNTests + 1 + checkNTests + 1 + checkAccessLengthTests \
+ 2 + checkAccessLengthTests + 1)
static void testMultipleUidAccess() {
char name[100];
sprintf(name, "testMultipleUidAccess");
- secdebugfunc("integrity", "************************************* %s", name);
+ secnotice("integrity", "************************************* %s", name);
uid_t uids[5];
uids[0] = getuid();
SecAccessRef access = makeMultipleUidAccess(uids, 5);
SecKeychainRef kc = newKeychain(name);
- CFMutableDictionaryRef query = makeAddItemDictionary(kc, kSecClassGenericPassword, CFSTR("test label"));
+ CFMutableDictionaryRef query = createAddItemDictionary(kc, kSecClassGenericPassword, CFSTR("test label"));
CFDictionarySetValue(query, kSecAttrAccess, access);
CFTypeRef result = NULL;
ok_status(SecItemAdd(query, &result), "%s: SecItemAdd", name);
+ CFReleaseNull(query);
ok(result != NULL, "%s: SecItemAdd returned a result", name);
- checkN(name, makeQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ checkN(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
+ CFReleaseNull(kc);
}
#define testMultipleUidAccessTests (newKeychainTests + checkNTests + 3)
static void testRootUidAccess() {
char name[100];
sprintf(name, "testRootUidAccess");
- secdebugfunc("integrity", "************************************* %s", name);
+ secnotice("integrity", "************************************* %s", name);
+
+ CFErrorRef error = NULL;
- SecAccessRef access = SecAccessCreateWithOwnerAndACL(getuid(), 0, (kSecUseOnlyUID | kSecHonorRoot), NULL, NULL);
+ SecAccessRef access = SecAccessCreateWithOwnerAndACL(getuid(), 0, (kSecUseOnlyUID | kSecHonorRoot), NULL, &error);
+ ok(access, "%s: SecAccessCreateWithOwnerAndACL returned an access", name);
+ CFStringRef errorDesc = error ? CFErrorCopyDescription(error) : NULL;
+ is(error, NULL, "%s: SecAccessCreateWithOwnerAndACL did not return an error: %@", name, errorDesc ? errorDesc : CFSTR("no error"));
+ CFReleaseNull(errorDesc);
SecKeychainRef kc = newKeychain(name);
- CFMutableDictionaryRef query = makeAddItemDictionary(kc, kSecClassGenericPassword, CFSTR("test label"));
+ CFMutableDictionaryRef query = createAddItemDictionary(kc, kSecClassGenericPassword, CFSTR("test label"));
CFDictionarySetValue(query, kSecAttrAccess, access);
CFTypeRef result = NULL;
ok_status(SecItemAdd(query, &result), "%s: SecItemAdd", name);
+ CFReleaseNull(query);
ok(result != NULL, "%s: SecItemAdd returned a result", name);
- query = makeQueryItemDictionary(kc, kSecClassGenericPassword);
+ query = createQueryItemDictionary(kc, kSecClassGenericPassword);
- SecKeychainItemRef item = checkN(name, query, 1);
+ SecKeychainItemRef item = checkNCopyFirst(name, query, 1);
ok_status(SecKeychainItemSetAccess(item, access), "%s: SecKeychainItemSetAccess", name);
- checkN(name, makeQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ CFReleaseNull(access);
+ checkN(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
+ CFReleaseNull(kc);
}
-#define testRootUidAccessTests (newKeychainTests + checkNTests + 4 + checkNTests)
+#define testRootUidAccessTests (newKeychainTests + 2 + checkNTests + 4 + checkNTests)
+
+static void testBadACL() {
+ char name[100];
+ sprintf(name, "testBadACL");
+ secnotice("integrity", "************************************* %s", name);
+
+ SecKeychainItemRef item = NULL;
+
+ unlink(keychainFile);
+ writeFullV512Keychain(name, keychainDbFile);
+
+ SecKeychainRef kc = openCustomKeychain(name, keychainName, "password");
+
+ // Check that these exist in this keychain...
+ checkN(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ checkN(name, createQueryItemDictionary(kc, kSecClassInternetPassword), 1);
+
+ ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
+ CFRelease(kc);
+
+ // Corrupt all the ACLs, by changing the partition id plist entry
+ uint8_t * fileBuffer = (uint8_t*) malloc(FULL_V512_SIZE);
+ memcpy(fileBuffer, full_v512, FULL_V512_SIZE);
+
+ void* p;
+ char * str = "<key>Partitions</key>";
+ while( (p = memmem(fileBuffer, FULL_V512_SIZE, (void*) str, strlen(str))) ) {
+ *(uint8_t*) p = 0;
+ }
+ writeFile(keychainDbFile, fileBuffer, FULL_V512_SIZE);
+ free(fileBuffer);
+
+ kc = openCustomKeychain(name, keychainName, "password");
+
+ // These items exist in this keychain, but their ACL is corrupted. We should be able to find them, but not fetch data.
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ readPasswordContentsWithResult(item, errSecInvalidItemRef, NULL); // we don't expect to be able to read this
+ deleteItem(item);
+ checkN(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 0);
+
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassInternetPassword), 1);
+ readPasswordContentsWithResult(item, errSecInvalidItemRef, NULL); // we don't expect to be able to read this
+ deleteItem(item);
+ checkN(name, createQueryItemDictionary(kc, kSecClassInternetPassword), 0);
+
+ // These should work
+ makeItem(name, kc, kSecClassGenericPassword, CFSTR("test_generic"));
+ makeItem(name, kc, kSecClassInternetPassword, CFSTR("test_internet"));
+
+ // And now the items should exist
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ readPasswordContents(item, CFSTR("data"));
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassInternetPassword), 1);
+ readPasswordContents(item, CFSTR("data"));
+
+ ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
+ CFReleaseNull(kc);
+}
+#define testBadACLTests (openCustomKeychainTests + checkNTests * 2 + 1 + openCustomKeychainTests \
+ + 2*(checkNTests + readPasswordContentsWithResultTests + deleteItemTests + checkNTests) \
+ + makeItemTests*2 + checkNTests*2 + readPasswordContentsTests*2 + 1)
+
+static void testIterateLockedKeychain() {
+ char name[100];
+ sprintf(name, "testIterateLockedKeychain");
+ secnotice("integrity", "************************************* %s", name);
+
+ SecKeychainItemRef item = NULL;
+
+ unlink(keychainFile);
+ writeFullV512Keychain(name, keychainDbFile);
+
+ SecKeychainRef kc = openCustomKeychain(name, keychainName, "password");
+
+ ok_status(SecKeychainLock(kc), "%s: SecKeychainLock", name);
+
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassGenericPassword), 1);
+ item = checkNCopyFirst(name, createQueryItemDictionary(kc, kSecClassInternetPassword), 1);
+
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
+ item = checkNCopyFirst(name, createQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
+
+ ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
+ CFReleaseNull(kc);
+}
+#define testIterateLockedKeychainTests (openCustomKeychainTests + 1 + checkNTests*5 + 1)
#define kTestCount (0 \
+ testAddItemTests \
+ unloadDLTests \
\
+ testKeychainUpgradeTests \
+ + testKeychainCreateOverTests \
+ + testKeychainDowngradeTests \
+ + testKeychainWrongFile256Tests \
+ + testKeychainWrongFile512Tests \
+ testUidAccessTests \
+ testMultipleUidAccessTests \
+ testRootUidAccessTests \
+ + testBadACLTests \
+ + testIterateLockedKeychainTests \
)
static void tests(void)
{
- const char *home_dir = getenv("HOME");
- sprintf(keychainFile, "%s/Library/Keychains/test.keychain", home_dir);
- sprintf(keychainName, "test.keychain");
+ initializeKeychainTests("kc-30-xara");
+
+ testKeychainUpgrade();
+ testKeychainCreateOver();
+ testKeychainDowngrade();
+ testKeychainWrongFile256();
+ testKeychainWrongFile512();
+ testUidAccess();
+ testMultipleUidAccess();
+ testRootUidAccess();
+ testBadACL();
+ testIterateLockedKeychain();
testAddItem(kSecClassGenericPassword, CFSTR("265438ea6807b509c9c6962df3f5033fd1af118f76c5f550e3ed90cb0d3ffce4"));
testAddItem(kSecClassInternetPassword, CFSTR("be34c4562153063ce9cdefc2c34451d5e6e98a447f293d68a67349c1b5d1164f"));
testAddAfterCorruptKey(dldbHandle);
unloadDL(&dldbHandle);
- testKeychainUpgrade();
- testUidAccess();
- testMultipleUidAccess();
- testRootUidAccess();
-
//makeOldKeychainBlob();
}
-#pragma clang pop
+#pragma clang diagnostic pop
#else
#define kTestCount (0)
tests();
+ deleteTestFiles();
return 0;
}