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"
31 #include "kc-helpers.h"
35 #pragma clang diagnostic push
36 #pragma clang diagnostic ignored "-Wunused-variable"
37 #pragma clang diagnostic ignored "-Wunused-function"
39 /* name is the name of the test, not the name of the keychain */
40 static CF_RETURNS_RETAINED SecKeychainRef
newKeychain(const char * name
) {
41 SecKeychainRef kc
= NULL
;
42 char* password
= "password";
44 // Kill the test keychain if it exists.
46 unlink(keychainDbFile
);
48 // Delete from CDSA-land? No tests, here, it'll work or it won't.
49 SecKeychainOpen(keychainName
, &kc
);
51 SecKeychainDelete(kc
);
55 ok_status(SecKeychainCreate(keychainName
, (UInt32
) strlen(password
), password
, false, NULL
, &kc
), "%s: SecKeychainCreate", name
);
58 UInt32 len
= sizeof(path
);
59 ok_status(SecKeychainGetPath(kc
, &len
, path
), "%s: SecKeychainGetPath", name
);
60 eq_stringn(path
, len
, keychainDbFile
, strlen(keychainDbFile
), "%s: paths do not match", name
);
63 #define newKeychainTests 3
65 /* name is the name of the test, not the name of the keychain */
66 static SecKeychainRef
newCustomKeychain(const char * name
, const char * path
, const char * password
) {
67 SecKeychainRef kc
= NULL
;
69 // Kill the keychain if it exists.
72 ok_status(SecKeychainCreate(path
, (UInt32
) strlen(password
), password
, false, NULL
, &kc
), "%s: SecKeychainCreate", name
);
75 #define newCustomKeychainTests 1
77 static CF_RETURNS_RETAINED SecKeychainRef
openCustomKeychain(const char * name
, const char * path
, const char * password
) {
78 SecKeychainRef kc
= NULL
;
79 ok_status(SecKeychainOpen(path
, &kc
), "%s: SecKeychainOpen", name
);
82 ok_status(SecKeychainUnlock(kc
, (UInt32
) strlen(password
), password
, true), "%s: SecKeychainUnlock", name
);
84 pass("make test count right");
89 #define openCustomKeychainTests 2
91 static CF_RETURNS_RETAINED SecKeychainRef
openKeychain(const char * name
) {
92 return openCustomKeychain(name
, keychainName
, NULL
);
94 #define openKeychainTests (openCustomKeychainTests)
96 #define checkPartitionIDsTests 3
97 static void checkPartitionIDs(const char* name
, SecKeychainItemRef item
, uint32_t n
) {
99 for(int i
= 0; i
< checkPartitionIDsTests
; i
++) {
100 fail("%s: checkNoPartitionIDs not passed an item", name
);
104 SecAccessRef access
= NULL
;
105 ok_status(SecKeychainItemCopyAccess(item
, &access
), "%s: SecKeychainItemCopyAccess", name
);
107 CFArrayRef acllist
= NULL
;
108 ok_status(SecAccessCopyACLList(access
, &acllist
), "%s: SecAccessCopyACLList", name
);
110 int partitionIDsFound
= 0;
111 CFStringRef output
= NULL
;
114 for(int i
= 0; i
< CFArrayGetCount(acllist
); i
++) {
115 SecACLRef acl
= (SecACLRef
) CFArrayGetValueAtIndex(acllist
, i
);
117 CFArrayRef auths
= SecACLCopyAuthorizations(acl
);
118 CFRange searchrange
= {0, CFArrayGetCount(auths
)};
119 if(CFArrayContainsValue(auths
, searchrange
, kSecACLAuthorizationPartitionID
)) {
121 // found a hash. match it.
125 CFReleaseNull(auths
);
128 CFReleaseNull(acllist
);
131 is(partitionIDsFound
, n
, "%s: Wrong number of partition IDs found", name
);
134 #define getIntegrityHashTests 3
135 static CFStringRef
getIntegrityHash(const char* name
, SecKeychainItemRef item
) {
137 for(int i
= 0; i
< getIntegrityHashTests
; i
++) {
138 fail("%s: getIntegrityHash not passed an item", name
);
142 SecAccessRef access
= NULL
;
143 ok_status(SecKeychainItemCopyAccess(item
, &access
), "%s: SecKeychainItemCopyAccess", name
);
145 CFArrayRef acllist
= NULL
;
146 ok_status(SecAccessCopyACLList(access
, &acllist
), "%s: SecAccessCopyACLList", name
);
149 CFStringRef output
= NULL
;
152 for(int i
= 0; i
< CFArrayGetCount(acllist
); i
++) {
153 SecACLRef acl
= (SecACLRef
) CFArrayGetValueAtIndex(acllist
, i
);
155 CFArrayRef auths
= SecACLCopyAuthorizations(acl
);
156 CFRange searchrange
= {0, CFArrayGetCount(auths
)};
157 if(CFArrayContainsValue(auths
, searchrange
, kSecACLAuthorizationIntegrity
)) {
159 CFArrayRef applications
= NULL
;
160 CFStringRef description
= NULL
;
161 SecKeychainPromptSelector selector
;
162 SecACLCopyContents(acl
, &applications
, &description
, &selector
);
164 // found a hash. match it.
167 output
= description
;
170 CFReleaseNull(auths
);
173 CFReleaseNull(acllist
);
176 is(hashesFound
, 1, "%s: Wrong number of hashes found", name
);
180 // Pulls the Integrity hash out of an item and compares it against the given one.
181 static void checkIntegrityHash(const char* name
, SecKeychainItemRef item
, CFStringRef expectedHash
) {
182 CFStringRef hash
= getIntegrityHash(name
, item
);
185 fail("No hash to match");
189 // We can't use use the ok macro here, because we
190 // might run it too many times and mess up the test count.
191 if(CFStringCompare(expectedHash
, hash
, 0) == kCFCompareEqualTo
) {
192 pass("Hashes match.");
194 printf("%s: Hashes didn't match. Was: ", name
);
197 printf(" expected: ");
199 CFShow(expectedHash
);
201 fail("Hashes don't match");
204 #define checkIntegrityHashTests (getIntegrityHashTests + 1)
206 static void checkHashesMatch(const char* name
, SecKeychainItemRef item
, SecKeychainItemRef comp
) {
207 CFStringRef itemhash
= getIntegrityHash(name
, item
);
208 CFStringRef comparehash
= getIntegrityHash(name
, comp
);
211 fail("%s: original item not passed in", name
);
215 fail("%s: compare item not passed in", name
);
219 is(CFStringCompare(itemhash
, comparehash
, 0), kCFCompareEqualTo
, "%s: hashes do not match", name
);
220 if(CFStringCompare(itemhash
, comparehash
, 0) != kCFCompareEqualTo
) {
226 #define checkHashesMatchTests (getIntegrityHashTests + getIntegrityHashTests + 1)
228 #pragma clang diagnostic pop
231 #endif /* TARGET_OS_MAC */
233 #endif /* kc_30_xara_helpers_h */