]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/regressions/kc-30-xara-key-helpers.h
Security-57337.40.85.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / regressions / kc-30-xara-key-helpers.h
1 /*
2 * Copyright (c) 2015 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include "kc-30-xara-helpers.h"
25
26 #ifndef kc_30_xara_key_helpers_h
27 #define kc_30_xara_key_helpers_h
28
29 #if TARGET_OS_MAC
30
31 static CFMutableDictionaryRef makeBaseKeyDictionary() {
32 CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
33 CFDictionarySetValue(query, kSecClass, kSecClassKey);
34 return query;
35 }
36
37 static CFMutableDictionaryRef makeQueryKeyDictionary(SecKeychainRef kc, CFStringRef keyClass) {
38 CFMutableDictionaryRef query = makeBaseKeyDictionary();
39
40 CFMutableArrayRef searchList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks);
41 CFArrayAppendValue((CFMutableArrayRef)searchList, kc);
42 CFDictionarySetValue(query, kSecMatchSearchList, searchList);
43
44 CFDictionarySetValue(query, kSecAttrKeyClass, keyClass);
45
46 CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll);
47 return query;
48 }
49
50 static CFMutableDictionaryRef makeAddKeyDictionary(SecKeychainRef kc, CFStringRef keyClass, CFStringRef label) {
51 CFMutableDictionaryRef query = makeBaseKeyDictionary();
52 CFDictionaryAddValue(query, kSecUseKeychain, kc);
53
54 CFDictionarySetValue(query, kSecAttrLabel, label);
55 CFDictionarySetValue(query, kSecAttrApplicationLabel, CFSTR("test_application")); // without setting this, it uses the current datetime.
56
57 int32_t n = 0;
58 if(CFEqual(keyClass, kSecAttrKeyClassSymmetric)) {
59 CFDictionarySetValue(query, kSecAttrKeyType, kSecAttrKeyTypeAES);
60 n = 128;
61 } else if(CFEqual(keyClass, kSecAttrKeyClassPublic) ||
62 CFEqual(keyClass, kSecAttrKeyClassPrivate)) {
63 CFDictionarySetValue(query, kSecAttrKeyType, kSecAttrKeyTypeRSA);
64 n = 1024;
65 }
66 CFNumberRef num = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &n);
67 CFDictionarySetValue(query, kSecAttrKeySizeInBits, num);
68
69 return query;
70 }
71
72 static SecKeyRef makeCustomKey(const char* name, SecKeychainRef kc, CFStringRef label) {
73 CFMutableDictionaryRef query = makeAddKeyDictionary(kc, kSecAttrKeyClassSymmetric, label);
74
75 CFErrorRef error = NULL;
76 SecKeyRef item = SecKeyGenerateSymmetric(query, &error);
77 ok(item != NULL, "%s: SecKeyGenerateSymmetric errored: %ld", name, error ? CFErrorGetCode(error) : -1);
78
79 CFReleaseNull(query);
80 return item;
81 }
82 #define makeCustomKeyTests 1
83
84 static SecKeyRef makeKey(const char* name, SecKeychainRef kc) {
85 return makeCustomKey(name, kc, CFSTR("test_key"));
86 }
87 #define makeKeyTests makeCustomKeyTests
88
89
90 static void makeCustomKeyWithIntegrity(const char* name, SecKeychainRef kc, CFStringRef label, CFStringRef expectedHash) {
91 SecKeyRef key = makeCustomKey(name, kc, label);
92 checkIntegrityHash(name, (SecKeychainItemRef) key, expectedHash);
93 CFReleaseNull(key);
94 }
95 #define makeCustomKeyWithIntegrityTests (makeCustomKeyTests + checkIntegrityHashTests)
96
97 static void makeKeyWithIntegrity(const char* name, SecKeychainRef kc, CFStringRef expectedHash) {
98 makeCustomKeyWithIntegrity(name, kc, CFSTR("test_key"), expectedHash);
99 }
100 #define makeKeyWithIntegrityTests makeCustomKeyWithIntegrityTests
101
102 static void makeCustomKeyPair(const char* name, SecKeychainRef kc, CFStringRef label, SecKeyRef* aPub, SecKeyRef* aPriv) {
103 CFMutableDictionaryRef query = makeAddKeyDictionary(kc, kSecAttrKeyClassPublic, label);
104
105 CFErrorRef error = NULL;
106 SecKeyRef pub;
107 SecKeyRef priv;
108 ok_status(SecKeyGeneratePair(query, &pub, &priv), "%s: SecKeyGeneratePair returned a result", name);
109
110 if(aPub) {
111 *aPub = pub;
112 }
113 if(aPriv) {
114 *aPriv = priv;
115 }
116
117 CFReleaseNull(query);
118 }
119 #define makeCustomKeyPairTests 1
120
121 static void makeKeyPair(const char* name, SecKeychainRef kc, SecKeyRef* aPub, SecKeyRef* aPriv) {
122 makeCustomKeyPair(name, kc, CFSTR("test_key"), aPub, aPriv);
123 }
124 #define makeKeyPairTests makeCustomKeyPairTests
125
126 // Note that this is nearly useless, as key pairs will never have stable hashes
127 static void makeKeyPairWithIntegrity(const char* name, SecKeychainRef kc, CFStringRef expectedPubHash, CFStringRef expectedPrivHash) {
128 SecKeyRef pub;
129 SecKeyRef priv;
130 makeKeyPair(name, kc, &pub, &priv);
131
132 checkIntegrityHash(name, (SecKeychainItemRef) pub, expectedPubHash);
133 checkIntegrityHash(name, (SecKeychainItemRef) priv, expectedPrivHash);
134 }
135 #define makeKeyPairWithIntegrityTests (makeKeyTests + checkIntegrityHashTests)
136
137 // This only works for symmetric keys; key pairs cannot ever generate a duplicate (due to setting kSecKeyLabel to the hash of the public key)
138 static void makeCustomDuplicateKey(const char* name, SecKeychainRef kc, CFStringRef label) {
139 CFMutableDictionaryRef query;
140
141 query = makeAddKeyDictionary(kc, kSecAttrKeyClassSymmetric, label);
142 CFErrorRef error = NULL;
143 SecKeyRef item = SecKeyGenerateSymmetric(query, &error);
144 is(CFErrorGetCode(error), errSecDuplicateItem, "%s: SecKeyGenerateSymmetric (duplicate) errored: %ld", name, error ? CFErrorGetCode(error) : -1);
145
146 CFReleaseNull(query);
147 }
148 #define makeCustomDuplicateKeyTests 1
149
150 static void makeDuplicateKey(const char* name, SecKeychainRef kc) {
151 makeCustomDuplicateKey(name, kc, CFSTR("test_key"));
152 }
153 #define makeDuplicateKeyTests makeCustomDuplicateKeyTests
154
155 static SecKeyRef makeCustomFreeKey(const char* name, SecKeychainRef kc, CFStringRef label) {
156 SecKeyRef symkey;
157
158 ok_status(SecKeyGenerate(
159 NULL,
160 CSSM_ALGID_AES, 128,
161 0, /* contextHandle */
162 CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
163 CSSM_KEYATTR_EXTRACTABLE,
164 NULL, /* initialAccess */
165 &symkey), "%s: SecKeyGenerate", name);;
166
167 CFMutableDictionaryRef query = makeAddKeyDictionary(kc, kSecAttrKeyClassSymmetric, label);
168
169 CFMutableArrayRef itemList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks);
170 CFArrayAppendValue((CFMutableArrayRef)itemList, symkey);
171
172 CFDictionarySetValue(query, kSecUseItemList, itemList);
173
174 CFTypeRef result = NULL;
175 ok_status(SecItemAdd(query, &result), "%s: SecItemAdd", name);
176 ok(result != NULL, "%s: SecItemAdd returned a result", name);
177 CFReleaseNull(symkey);
178 return (SecKeyRef) result;
179 }
180 #define makeCustomFreeKeyTests 3
181
182 static SecKeyRef makeFreeKey(const char* name, SecKeychainRef kc) {
183 return makeCustomFreeKey(name, kc, CFSTR("test_free_key"));
184 }
185 #define makeFreeKeyTests makeCustomFreeKeyTests
186
187 static SecKeyRef makeCustomDuplicateFreeKey(const char* name, SecKeychainRef kc, CFStringRef label) {
188 SecKeyRef symkey;
189
190 ok_status(SecKeyGenerate(
191 NULL,
192 CSSM_ALGID_AES, 128,
193 0, /* contextHandle */
194 CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
195 CSSM_KEYATTR_EXTRACTABLE,
196 NULL, /* initialAccess */
197 &symkey), "%s: SecKeyGenerate", name);;
198
199 CFMutableDictionaryRef query = makeAddKeyDictionary(kc, kSecAttrKeyClassSymmetric, label);
200
201 CFMutableArrayRef itemList = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks);
202 CFArrayAppendValue((CFMutableArrayRef)itemList, symkey);
203
204 CFDictionarySetValue(query, kSecUseItemList, itemList);
205
206 CFTypeRef result = NULL;
207 is(SecItemAdd(query, &result), errSecDuplicateItem, "%s: SecItemAdd (duplicate)", name);
208 CFReleaseNull(symkey);
209 return (SecKeyRef) result;
210 }
211 #define makeCustomDuplicateFreeKeyTests 2
212
213 static SecKeyRef makeDuplicateFreeKey(const char* name, SecKeychainRef kc) {
214 return makeCustomFreeKey(name, kc, CFSTR("test_free_key"));
215 }
216 #define makeDuplicateFreeKeyTests makeCustomDuplicateFreeKeyTests
217
218
219 // And now for the actual tests
220
221 static void testAddKey(CFStringRef expectedHash) {
222 char* name = "testAddKey";
223 SecKeychainRef kc = newKeychain(name);
224 makeKeyWithIntegrity(name, kc, expectedHash);
225 ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
226 }
227 #define testAddKeyTests (newKeychainTests + makeKeyWithIntegrityTests + 1)
228
229 static void testAddFreeKey(CFStringRef expectedHash) {
230 // Due to <rdar://problem/8431281> SecItemAdd() will not add a generated symmetric key to the keychain
231 // we can't actually run this test. Code is included here as a reference.
232 //char* name = "testAddFreeKey";
233 //SecKeychainRef kc = newKeychain(name);
234
235 //SecKeyRef key = makeFreeKey(name, kc);
236 //checkIntegrityHash(name, (SecKeychainItemRef) key, expectedHash);
237
238 //ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
239 }
240 //#define testAddFreeKeyTests (newKeychainTests + makeFreeKeyTests + checkIntegrityHashTests + 1)
241 #define testAddFreeKeyTests 0
242
243 static void testCopyMatchingKey(CFStringRef expectedHash) {
244 char* name = "testCopyMatchingKey";
245 secdebugfunc("integrity", "************************************* %s", name);
246
247 SecKeychainRef kc = newKeychain(name);
248 checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 0);
249
250 makeKeyWithIntegrity(name, kc, expectedHash);
251
252 SecKeyRef item = (SecKeyRef) checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
253 checkIntegrityHash(name, (SecKeychainItemRef) item, expectedHash);
254 ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
255 }
256 #define testCopyMatchingKeyTests (newKeychainTests + checkNTests + makeKeyWithIntegrityTests + checkNTests + checkIntegrityHashTests + 1)
257
258
259 static void testUpdateKey(CFStringRef expectedHash, CFStringRef expectedHashAfter) {
260 char * name = "testUpdateKey";
261 secdebugfunc("integrity", "************************************* %s", name);
262
263 SecKeychainRef kc = newKeychain(name);
264 makeKeyWithIntegrity(name, kc, expectedHash);
265 SecKeychainItemRef item = checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
266 CFReleaseNull(item);
267
268 CFStringRef label = CFSTR("a modified label");
269
270 CFMutableDictionaryRef query = makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric);
271 CFMutableDictionaryRef update = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
272 CFDictionarySetValue(update, kSecAttrLabel, label);
273 ok_status(SecItemUpdate(query, update), "%s: SecItemUpdate", name);
274
275 CFReleaseNull(query);
276 CFReleaseNull(update);
277
278 // Find the item again.
279 query = makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric);
280 CFDictionarySetValue(query, kSecAttrLabel, label);
281 item = checkN(name, query, 1);
282 checkIntegrityHash(name, item, expectedHashAfter);
283 ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
284 }
285 #define testUpdateKeyTests (newKeychainTests + makeKeyWithIntegrityTests + checkNTests + 1 + checkNTests + checkIntegrityHashTests + 1)
286
287 // Key Pairs have non-predictable hashes, since they receive an attribute kSecKeyLabel that is
288 // the hash of the public key. Since the key is generated randomly, so is the label.
289 //
290 // We can't do our normal "add", "copymatching", "update" tests here, so do
291 // something special...
292
293 static void testKeyPair() {
294 char* name = "testKeyPair";
295 secdebugfunc("integrity", "************************************* %s", name);
296
297 SecKeychainRef kc = newKeychain(name);
298 checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 0);
299 checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 0);
300
301 SecKeyRef pub;
302 SecKeyRef priv;
303 makeKeyPair(name, kc, &pub, &priv);
304
305 // Now that we have the key pair, make sure we can pull the individual keys
306 // out (and the hashes match)
307
308 SecKeyRef item;
309 item = (SecKeyRef) checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
310 checkHashesMatch(name, (SecKeychainItemRef)pub, (SecKeychainItemRef)item);
311
312 item = (SecKeyRef) checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
313 checkHashesMatch(name, (SecKeychainItemRef)priv, (SecKeychainItemRef)item);
314
315 // TODO: is there a way to test SecItemUpdate?
316
317 ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
318 }
319 #define testKeyPairTests (newKeychainTests + checkNTests + checkNTests + makeKeyPairTests \
320 + checkNTests + checkHashesMatchTests \
321 + checkNTests + checkHashesMatchTests + 1)
322
323 static void testAddDuplicateKey(CFStringRef expectedHash) {
324 char * name = "testAddDuplicateKey";
325 secdebugfunc("integrity", "************************************* %s", name);
326
327 SecKeychainRef kc = newKeychain(name);
328 checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 0);
329
330 makeKeyWithIntegrity(name, kc, expectedHash);
331
332 SecKeychainItemRef item = checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
333 makeDuplicateKey(name, kc);
334 checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
335
336 ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
337 }
338 #define testAddDuplicateKeyTests (newKeychainTests + checkNTests +makeKeyWithIntegrityTests + checkNTests + makeDuplicateKeyTests + checkNTests + 1)
339
340 static void testAddDuplicateFreeKey(CFStringRef expectedHash) {
341 // Due to <rdar://problem/8431281> SecItemAdd() will not add a generated symmetric key to the keychain
342 // we can't actually run this test. Code is included here as a reference.
343 //char * name = "testAddDuplicateFreeKey";
344 //secdebugfunc("integrity", "************************************* %s", name);
345 //SecKeychainRef kc = newKeychain(name);
346 //checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 0);
347
348 //SecKeyRef key = makeFreeKey(name, kc);
349 //checkIntegrityHash(name, (SecKeychainItemRef) key, expectedHash);
350 //SecKeychainItemRef item = checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
351
352 //makeDuplicateFreeKey(name, kc);
353 //checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassSymmetric), 1);
354
355 //ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
356 }
357 //#define testAddDuplicateFreeKeyTests (newKeychainTests + checkNTests + makeFreeKeyTests + checkIntegrityHashTests + checkNTests \
358 // + makeDuplicateKeyTests + checkNTests + 1)
359 #define testAddDuplicateFreeKeyTests 0
360
361 // testAddDuplicateKeyPair:
362 //
363 // By use of the Sec* APIs, you will almost certainly never get an
364 // errSecDuplicateItem out of SecKeychainGeneratePair. Since it sets a primary
365 // key attribute as the hash of the public key, it just will never generate a
366 // duplicate item.
367
368 static void testExportImportKeyPair() {
369 char* name = "testExportImportKeyPair";
370 secdebugfunc("integrity", "************************************* %s", name);
371
372 SecKeychainRef kc = newKeychain(name);
373 checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 0);
374 checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 0);
375
376 SecKeyRef pub;
377 SecKeyRef priv;
378 makeKeyPair(name, kc, &pub, &priv);
379
380 // Now that we have the key pair, make sure we can pull the individual keys out
381
382 SecKeyRef item;
383 item = (SecKeyRef) checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
384 checkHashesMatch(name, (SecKeychainItemRef)pub, (SecKeychainItemRef)item);
385
386 item = (SecKeyRef) checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
387 checkHashesMatch(name, (SecKeychainItemRef)priv, (SecKeychainItemRef)item);
388
389 CFMutableArrayRef applications = (CFMutableArrayRef) CFArrayCreateMutable(kCFAllocatorDefault, 1, &kCFTypeArrayCallBacks);
390 SecTrustedApplicationRef app = NULL;
391
392 ok_status(SecTrustedApplicationCreateFromPath(NULL, &app), "%s: SecTrustedApplicationCreateFromPath", name);
393 CFArrayAppendValue(applications, app);
394
395 ok_status(SecTrustedApplicationCreateFromPath("/usr/bin/codesign", &app), "%s: SecTrustedApplicationCreateFromPath", name);
396 CFArrayAppendValue(applications, app);
397
398 SecAccessRef accessRef = NULL;
399 ok_status(SecAccessCreate(CFSTR("accessDescription"), applications, &accessRef), "%s: SecAccessCreate", name);
400
401 const SecItemImportExportKeyParameters keyParams =
402 {
403 SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION,
404 0,
405 CFSTR( "" ),
406 CFSTR( "" ),
407 CFSTR( "" ),
408 accessRef, 0, 0
409 };
410 CFArrayRef items = NULL;
411
412 CFDataRef keyData = NULL;
413 ok_status(SecItemExport(pub, kSecFormatPEMSequence, kSecItemPemArmour, &keyParams, &keyData), "%s: SecItemExport", name);
414 ok_status(SecKeychainItemDelete((SecKeychainItemRef)pub), "%s: SecKeychainDelete", name);;
415 CFRelease(pub);
416 pub = NULL;
417
418 checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 0);
419 ok_status(SecItemImport(keyData, NULL, NULL, NULL, kSecItemPemArmour, &keyParams, kc, &items), "%s: SecItemImport", name);
420 checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPublic), 1);
421
422
423 ok_status(SecItemExport(priv, kSecFormatPEMSequence, kSecItemPemArmour, &keyParams, &keyData), "%s: SecItemExport", name);
424 ok_status(SecKeychainItemDelete((SecKeychainItemRef)priv), "%s: SecKeychainDelete", name);;
425 CFRelease(priv);
426 priv = NULL;
427
428 checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 0);
429
430 ok_status(SecItemImport(keyData, NULL, NULL, NULL, kSecItemPemArmour, &keyParams, kc, &items), "%s: SecItemImport", name);
431
432 checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
433
434 SecAccessRef newRef = NULL;
435 ok_status(SecKeychainItemCopyAccess((SecKeychainItemRef) CFArrayGetValueAtIndex(items, 0), &newRef), "%s:SecKeychainItemCopyAccess", name);
436
437 SecKeyRef importedKey = items && CFArrayGetCount(items) > 0 ? (SecKeyRef)CFArrayGetValueAtIndex(items, 0) : NULL;
438 if (importedKey) {
439 CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
440 CFDictionaryAddValue(query, kSecClass, kSecClassKey);
441 CFDictionaryAddValue(query, kSecValueRef, importedKey);
442
443 CFMutableDictionaryRef attrs = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
444 CFDictionaryAddValue(attrs, kSecAttrLabel, CFSTR("private key custom label"));
445
446 ok_status( SecItemUpdate(query, attrs), "%s: SecItemUpdate", name);
447 } else {
448 fail("%s: Didn't have an item to update", name);
449 }
450
451 ok_status(SecKeychainItemCopyAccess((SecKeychainItemRef) CFArrayGetValueAtIndex(items, 0), &newRef), "%s:SecKeychainItemCopyAccess", name);
452 // TODO: should probably check this AccessRef object to make sure it's simple
453
454 checkN(name, makeQueryKeyDictionary(kc, kSecAttrKeyClassPrivate), 1);
455
456 ok_status(SecKeychainDelete(kc), "%s: SecKeychainDelete", name);
457 }
458 #define testExportImportKeyPairTests (newKeychainTests + checkNTests + checkNTests + makeKeyPairTests \
459 + checkNTests + checkHashesMatchTests \
460 + checkNTests + checkHashesMatchTests \
461 + 5 + checkNTests + 1 + checkNTests \
462 + 2 + checkNTests + 1 + checkNTests + 1 + 1 + 1 + checkNTests\
463 + 1)
464
465
466 #else
467
468 #endif /* TARGET_OS_MAC */
469
470
471 #endif /* kc_30_xara_key_helpers_h */