X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/822b670c6f91d089ccb51b77e24b6ac80406b337..e3d460c9de4426da6c630c3ae3f46173a99f82d8:/OSX/libsecurity_keychain/regressions/kc-30-xara-helpers.h diff --git a/OSX/libsecurity_keychain/regressions/kc-30-xara-helpers.h b/OSX/libsecurity_keychain/regressions/kc-30-xara-helpers.h new file mode 100644 index 00000000..e5e89a0c --- /dev/null +++ b/OSX/libsecurity_keychain/regressions/kc-30-xara-helpers.h @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2015 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef kc_30_xara_helpers_h +#define kc_30_xara_helpers_h + +#include +#include +#include +#include "utilities/SecCFRelease.h" + +static char keychainFile[1000]; +static char keychainName[1000]; + +#if TARGET_OS_MAC + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic ignored "-Wunused-function" + +/* name is the name of the test, not the name of the keychain */ +static SecKeychainRef newKeychain(const char * name) { + SecKeychainRef kc = NULL; + char* password = "password"; + + // Kill the test keychain if it exists. + unlink(keychainFile); + + ok_status(SecKeychainCreate(keychainName, (UInt32) strlen(password), password, false, NULL, &kc), "%s: SecKeychainCreate", name); + return kc; +} +#define newKeychainTests 1 + +/* name is the name of the test, not the name of the keychain */ +static SecKeychainRef newCustomKeychain(const char * name, const char * path, const char * password) { + SecKeychainRef kc = NULL; + + // Kill the keychain if it exists. + unlink(path); + + ok_status(SecKeychainCreate(path, (UInt32) strlen(password), password, false, NULL, &kc), "%s: SecKeychainCreate", name); + return kc; +} +#define newCustomKeychainTests 1 + +static SecKeychainRef openCustomKeychain(const char * name, const char * path, const char * password) { + SecKeychainRef kc = NULL; + ok_status(SecKeychainOpen(path, &kc), "%s: SecKeychainOpen", name); + + if(password) { + ok_status(SecKeychainUnlock(kc, (UInt32) strlen(password), password, true), "%s: SecKeychainUnlock", name); + } else { + pass("make test count right"); + } + + return kc; +} +#define openCustomKeychainTests 2 + +static SecKeychainRef openKeychain(const char * name) { + return openCustomKeychain(name, "test.keychain", NULL); +} +#define openKeychainTests (openCustomKeychainTests) + +#define getIntegrityHashTests 3 +static CFStringRef getIntegrityHash(const char* name, SecKeychainItemRef item) { + if(!item) { + for(int i = 0; i < getIntegrityHashTests; i++) { + fail("%s: getIntegrityHash not passed an item", name); + } + return NULL; + } + SecAccessRef access = NULL; + ok_status(SecKeychainItemCopyAccess(item, &access), "%s: SecKeychainItemCopyAccess", name); + + CFArrayRef acllist = NULL; + ok_status(SecAccessCopyACLList(access, &acllist), "%s: SecAccessCopyACLList", name); + + int hashesFound = 0; + CFStringRef output = NULL; + + if(acllist) { + for(int i = 0; i < CFArrayGetCount(acllist); i++) { + SecACLRef acl = (SecACLRef) CFArrayGetValueAtIndex(acllist, i); + + CFArrayRef auths = SecACLCopyAuthorizations(acl); + CFRange searchrange = {0, CFArrayGetCount(auths)}; + if(CFArrayContainsValue(auths, searchrange, kSecACLAuthorizationIntegrity)) { + + CFArrayRef applications = NULL; + CFStringRef description = NULL; + SecKeychainPromptSelector selector; + SecACLCopyContents(acl, &applications, &description, &selector); + + // found a hash. match it. + hashesFound++; + + output = description; + } + + CFReleaseNull(auths); + } + + CFReleaseNull(acllist); + } + + is(hashesFound, 1, "%s: Wrong number of hashes found", name); + return output; +} + +// Pulls the Integrity hash out of an item and compares it against the given one. +static void checkIntegrityHash(const char* name, SecKeychainItemRef item, CFStringRef expectedHash) { + CFStringRef hash = getIntegrityHash(name, item); + + if(!hash) { + fail("No hash to match"); + return; + } + + // We can't use use the ok macro here, because we + // might run it too many times and mess up the test count. + if(CFStringCompare(expectedHash, hash, 0) == kCFCompareEqualTo) { + pass("Hashes match."); + } else { + printf("%s: Hashes didn't match. Was: ", name); + fflush(stdout); + CFShow(hash); + fail("Hashes don't match"); + } +} +#define checkIntegrityHashTests (getIntegrityHashTests + 1) + +static void checkHashesMatch(const char* name, SecKeychainItemRef item, SecKeychainItemRef comp) { + CFStringRef itemhash = getIntegrityHash(name, item); + CFStringRef comparehash = getIntegrityHash(name, comp); + + if(!itemhash) { + fail("%s: original item not passed in", name); + return; + } + if(!comparehash) { + fail("%s: compare item not passed in", name); + return; + } + + is(CFStringCompare(itemhash, comparehash, 0), kCFCompareEqualTo, "%s: hashes do not match", name); + if(CFStringCompare(itemhash, comparehash, 0) != kCFCompareEqualTo) { + fflush(stdout); + CFShow(itemhash); + CFShow(comparehash); + } +} +#define checkHashesMatchTests (getIntegrityHashTests + getIntegrityHashTests + 1) + +/* Checks to be sure there are N elements in this search, and returns the first + * if it exists. */ +static SecKeychainItemRef checkN(char* testName, const CFDictionaryRef query, uint32_t n) { + CFArrayRef results = NULL; + if(n > 0) { + ok_status(SecItemCopyMatching(query, (CFTypeRef*) &results), "%s: SecItemCopyMatching", testName); + } else { + is(SecItemCopyMatching(query, (CFTypeRef*) &results), errSecItemNotFound, "%s: SecItemCopyMatching (for no items)", testName); + } + CFRelease(query); + + SecKeychainItemRef item = NULL; + if(results) { + is(CFArrayGetCount(results), n, "%s: Wrong number of results", testName); + if(n >= 1) { + ok(item = (SecKeychainItemRef) CFArrayGetValueAtIndex(results, 0), "%s: Couldn't get item", testName); + } else { + pass("make test numbers match"); + } + } else if((!results) && n == 0) { + pass("%s: no results found (and none expected)", testName); + pass("make test numbers match"); + } else { + fail("%s: no results found (and %d expected)", testName, n); + pass("make test numbers match"); + } + return item; +} +#define checkNTests 3 + +#pragma clang pop +#else + +#endif /* TARGET_OS_MAC */ + +#endif /* kc_30_xara_helpers_h */