2 * Copyright (c) 2015 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #ifndef kc_30_xara_helpers_h
25 #define kc_30_xara_helpers_h
27 #include <Security/Security.h>
28 #include <Security/cssmapi.h>
29 #include <security_utilities/debugging.h>
30 #include "utilities/SecCFRelease.h"
32 static char keychainFile
[1000];
33 static char keychainName
[1000];
37 #pragma clang diagnostic push
38 #pragma clang diagnostic ignored "-Wunused-variable"
39 #pragma clang diagnostic ignored "-Wunused-function"
41 /* name is the name of the test, not the name of the keychain */
42 static SecKeychainRef
newKeychain(const char * name
) {
43 SecKeychainRef kc
= NULL
;
44 char* password
= "password";
46 // Kill the test keychain if it exists.
49 ok_status(SecKeychainCreate(keychainName
, (UInt32
) strlen(password
), password
, false, NULL
, &kc
), "%s: SecKeychainCreate", name
);
52 #define newKeychainTests 1
54 /* name is the name of the test, not the name of the keychain */
55 static SecKeychainRef
newCustomKeychain(const char * name
, const char * path
, const char * password
) {
56 SecKeychainRef kc
= NULL
;
58 // Kill the keychain if it exists.
61 ok_status(SecKeychainCreate(path
, (UInt32
) strlen(password
), password
, false, NULL
, &kc
), "%s: SecKeychainCreate", name
);
64 #define newCustomKeychainTests 1
66 static SecKeychainRef
openCustomKeychain(const char * name
, const char * path
, const char * password
) {
67 SecKeychainRef kc
= NULL
;
68 ok_status(SecKeychainOpen(path
, &kc
), "%s: SecKeychainOpen", name
);
71 ok_status(SecKeychainUnlock(kc
, (UInt32
) strlen(password
), password
, true), "%s: SecKeychainUnlock", name
);
73 pass("make test count right");
78 #define openCustomKeychainTests 2
80 static SecKeychainRef
openKeychain(const char * name
) {
81 return openCustomKeychain(name
, "test.keychain", NULL
);
83 #define openKeychainTests (openCustomKeychainTests)
85 #define getIntegrityHashTests 3
86 static CFStringRef
getIntegrityHash(const char* name
, SecKeychainItemRef item
) {
88 for(int i
= 0; i
< getIntegrityHashTests
; i
++) {
89 fail("%s: getIntegrityHash not passed an item", name
);
93 SecAccessRef access
= NULL
;
94 ok_status(SecKeychainItemCopyAccess(item
, &access
), "%s: SecKeychainItemCopyAccess", name
);
96 CFArrayRef acllist
= NULL
;
97 ok_status(SecAccessCopyACLList(access
, &acllist
), "%s: SecAccessCopyACLList", name
);
100 CFStringRef output
= NULL
;
103 for(int i
= 0; i
< CFArrayGetCount(acllist
); i
++) {
104 SecACLRef acl
= (SecACLRef
) CFArrayGetValueAtIndex(acllist
, i
);
106 CFArrayRef auths
= SecACLCopyAuthorizations(acl
);
107 CFRange searchrange
= {0, CFArrayGetCount(auths
)};
108 if(CFArrayContainsValue(auths
, searchrange
, kSecACLAuthorizationIntegrity
)) {
110 CFArrayRef applications
= NULL
;
111 CFStringRef description
= NULL
;
112 SecKeychainPromptSelector selector
;
113 SecACLCopyContents(acl
, &applications
, &description
, &selector
);
115 // found a hash. match it.
118 output
= description
;
121 CFReleaseNull(auths
);
124 CFReleaseNull(acllist
);
127 is(hashesFound
, 1, "%s: Wrong number of hashes found", name
);
131 // Pulls the Integrity hash out of an item and compares it against the given one.
132 static void checkIntegrityHash(const char* name
, SecKeychainItemRef item
, CFStringRef expectedHash
) {
133 CFStringRef hash
= getIntegrityHash(name
, item
);
136 fail("No hash to match");
140 // We can't use use the ok macro here, because we
141 // might run it too many times and mess up the test count.
142 if(CFStringCompare(expectedHash
, hash
, 0) == kCFCompareEqualTo
) {
143 pass("Hashes match.");
145 printf("%s: Hashes didn't match. Was: ", name
);
148 fail("Hashes don't match");
151 #define checkIntegrityHashTests (getIntegrityHashTests + 1)
153 static void checkHashesMatch(const char* name
, SecKeychainItemRef item
, SecKeychainItemRef comp
) {
154 CFStringRef itemhash
= getIntegrityHash(name
, item
);
155 CFStringRef comparehash
= getIntegrityHash(name
, comp
);
158 fail("%s: original item not passed in", name
);
162 fail("%s: compare item not passed in", name
);
166 is(CFStringCompare(itemhash
, comparehash
, 0), kCFCompareEqualTo
, "%s: hashes do not match", name
);
167 if(CFStringCompare(itemhash
, comparehash
, 0) != kCFCompareEqualTo
) {
173 #define checkHashesMatchTests (getIntegrityHashTests + getIntegrityHashTests + 1)
175 /* Checks to be sure there are N elements in this search, and returns the first
177 static SecKeychainItemRef
checkN(char* testName
, const CFDictionaryRef query
, uint32_t n
) {
178 CFArrayRef results
= NULL
;
180 ok_status(SecItemCopyMatching(query
, (CFTypeRef
*) &results
), "%s: SecItemCopyMatching", testName
);
182 is(SecItemCopyMatching(query
, (CFTypeRef
*) &results
), errSecItemNotFound
, "%s: SecItemCopyMatching (for no items)", testName
);
186 SecKeychainItemRef item
= NULL
;
188 is(CFArrayGetCount(results
), n
, "%s: Wrong number of results", testName
);
190 ok(item
= (SecKeychainItemRef
) CFArrayGetValueAtIndex(results
, 0), "%s: Couldn't get item", testName
);
192 pass("make test numbers match");
194 } else if((!results
) && n
== 0) {
195 pass("%s: no results found (and none expected)", testName
);
196 pass("make test numbers match");
198 fail("%s: no results found (and %d expected)", testName
, n
);
199 pass("make test numbers match");
203 #define checkNTests 3
208 #endif /* TARGET_OS_MAC */
210 #endif /* kc_30_xara_helpers_h */