]> git.saurik.com Git - apple/security.git/blob - sec/Security/Regressions/secitem/si-12-item-stress.c
Security-55471.14.4.tar.gz
[apple/security.git] / sec / Security / Regressions / secitem / si-12-item-stress.c
1 //
2 // si-12-item-stress.c
3 // sec
4 //
5 // Created by Michael Brouwer on 8/1/13.
6 // Copyright (c) 2013 Apple Inc. All Rights Reserved.
7 //
8 //
9
10 #include <CoreFoundation/CoreFoundation.h>
11 #include <Security/SecCertificate.h>
12 #include <Security/SecItem.h>
13 #include <Security/SecItemPriv.h>
14 #include <Security/SecBase.h>
15 #include <utilities/array_size.h>
16 #include <utilities/SecCFWrappers.h>
17 #include <stdlib.h>
18 #include <unistd.h>
19
20 #include "Security_regressions.h"
21
22 #if 0
23 static void persistentRefIs(CFDataRef pref, CFDataRef data) {
24 CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
25 CFTypeRef result = NULL;
26 CFDictionaryAddValue(dict, kSecValuePersistentRef, pref);
27 CFDictionaryAddValue(dict, kSecReturnData, kCFBooleanTrue);
28 ok_status(SecItemCopyMatching(dict, &result), "lookup item data by persistent ref");
29 ok(CFEqual(data, result), "result %@ equals expected data %@", result, data);
30 CFReleaseNull(result);
31 CFReleaseNull(dict);
32 }
33 #endif
34
35 enum ItemAttrType {
36 kBoolItemAttr,
37 kNumberItemAttr,
38 kStringItemAttr,
39 kDataItemAttr,
40 kBlobItemAttr,
41 kDateItemAttr,
42 kAccessabilityItemAttr,
43 kAccessGroupItemAttr,
44 };
45
46 static void WithEachString(void(^each)(CFStringRef attr, enum ItemAttrType atype), ...) {
47 va_list ap;
48 va_start(ap, each);
49 CFStringRef attr;
50 while((attr = va_arg(ap, CFStringRef)) != NULL) {
51 enum ItemAttrType atype = va_arg(ap, enum ItemAttrType);
52 each(attr, atype);
53 }
54 va_end(ap);
55 }
56
57 #if 0
58 static void ItemForEachAttr(CFMutableDictionaryRef item, void(^each)(CFStringRef attr, enum ItemAttrType atype)) {
59 CFStringRef iclass = CFDictionaryGetValue(item, kSecClass);
60 if (!iclass) {
61 return;
62 } else if (CFEqual(iclass, kSecClassGenericPassword)) {
63 WithEachString(each,
64 kSecAttrAccessible, kAccessabilityItemAttr,
65 kSecAttrAccessGroup, kAccessGroupItemAttr,
66 kSecAttrCreationDate, kDateItemAttr,
67 kSecAttrModificationDate, kDateItemAttr,
68 kSecAttrDescription, kStringItemAttr,
69 kSecAttrComment, kStringItemAttr,
70 kSecAttrCreator, kNumberItemAttr,
71 kSecAttrType, kNumberItemAttr,
72 kSecAttrLabel, kStringItemAttr,
73 kSecAttrIsInvisible, kBoolItemAttr,
74 kSecAttrIsNegative, kBoolItemAttr,
75 kSecAttrAccount, kStringItemAttr,
76 kSecAttrService, kStringItemAttr,
77 kSecAttrGeneric, kDataItemAttr,
78 kSecAttrSynchronizable, kBoolItemAttr,
79 NULL);
80 } else if (CFEqual(iclass, kSecClassInternetPassword)) {
81 WithEachString(each,
82 kSecAttrAccessible, kAccessabilityItemAttr,
83 kSecAttrAccessGroup, kAccessGroupItemAttr,
84 kSecAttrCreationDate, kDateItemAttr,
85 kSecAttrModificationDate, kDateItemAttr,
86 kSecAttrDescription, kStringItemAttr,
87 kSecAttrComment, kStringItemAttr,
88 kSecAttrCreator, kNumberItemAttr,
89 kSecAttrType, kNumberItemAttr,
90 kSecAttrLabel, kStringItemAttr,
91 kSecAttrIsInvisible, kBoolItemAttr,
92 kSecAttrIsNegative, kBoolItemAttr,
93 kSecAttrAccount, kStringItemAttr,
94 kSecAttrSecurityDomain, kStringItemAttr,
95 kSecAttrServer, kStringItemAttr,
96 kSecAttrProtocol, kNumberItemAttr,
97 kSecAttrAuthenticationType, kNumberItemAttr,
98 kSecAttrPort, kNumberItemAttr,
99 kSecAttrPath, kStringItemAttr,
100 kSecAttrSynchronizable, kBoolItemAttr,
101 NULL);
102 } else if (CFEqual(iclass, kSecClassCertificate)) {
103 WithEachString(each,
104 kSecAttrAccessible, kAccessabilityItemAttr,
105 kSecAttrAccessGroup, kAccessGroupItemAttr,
106 kSecAttrCertificateType, kNumberItemAttr,
107 kSecAttrCertificateEncoding, kNumberItemAttr,
108 kSecAttrLabel, kStringItemAttr,
109 kSecAttrSubject, kDataItemAttr,
110 kSecAttrIssuer, kDataItemAttr,
111 kSecAttrSerialNumber, kDataItemAttr,
112 kSecAttrSubjectKeyID, kDataItemAttr,
113 kSecAttrPublicKeyHash, kDataItemAttr,
114 kSecAttrSynchronizable, kBoolItemAttr,
115 NULL);
116 } else if (CFEqual(iclass, kSecClassKey)) {
117 WithEachString(each,
118 kSecAttrAccessible, kAccessabilityItemAttr,
119 kSecAttrAccessGroup, kAccessGroupItemAttr,
120 kSecAttrKeyClass, kStringItemAttr, // Might be Number on replies
121 kSecAttrLabel, kStringItemAttr,
122 kSecAttrApplicationLabel, kDataItemAttr,
123 kSecAttrIsPermanent, kBoolItemAttr,
124 kSecAttrApplicationTag, kDataItemAttr,
125 kSecAttrKeyType, kNumberItemAttr,
126 kSecAttrKeySizeInBits, kNumberItemAttr,
127 kSecAttrEffectiveKeySize, kNumberItemAttr,
128 kSecAttrCanEncrypt, kBoolItemAttr,
129 kSecAttrCanDecrypt, kBoolItemAttr,
130 kSecAttrCanDerive, kBoolItemAttr,
131 kSecAttrCanSign, kBoolItemAttr,
132 kSecAttrCanVerify, kBoolItemAttr,
133 kSecAttrCanWrap, kBoolItemAttr,
134 kSecAttrCanUnwrap, kBoolItemAttr,
135 kSecAttrStartDate, kDateItemAttr,
136 kSecAttrEndDate, kDateItemAttr,
137 kSecAttrSynchronizable, kBoolItemAttr,
138 NULL);
139 } else if (CFEqual(iclass, kSecClassIdentity)) {
140 WithEachString(each,
141 kSecAttrAccessible, kAccessabilityItemAttr,
142 kSecAttrAccessGroup, kAccessGroupItemAttr,
143 kSecAttrCertificateType, kNumberItemAttr,
144 kSecAttrCertificateEncoding, kNumberItemAttr,
145 kSecAttrLabel, kStringItemAttr,
146 kSecAttrSubject, kDataItemAttr,
147 kSecAttrIssuer, kDataItemAttr,
148 kSecAttrSerialNumber, kDataItemAttr,
149 kSecAttrSubjectKeyID, kDataItemAttr,
150 kSecAttrPublicKeyHash, kDataItemAttr,
151 kSecAttrKeyClass, kStringItemAttr, // Might be Number on replies
152 kSecAttrApplicationLabel, kDataItemAttr,
153 kSecAttrIsPermanent, kBoolItemAttr,
154 kSecAttrApplicationTag, kDataItemAttr,
155 kSecAttrKeyType, kNumberItemAttr,
156 kSecAttrKeySizeInBits, kNumberItemAttr,
157 kSecAttrEffectiveKeySize, kNumberItemAttr,
158 kSecAttrCanEncrypt, kBoolItemAttr,
159 kSecAttrCanDecrypt, kBoolItemAttr,
160 kSecAttrCanDerive, kBoolItemAttr,
161 kSecAttrCanSign, kBoolItemAttr,
162 kSecAttrCanVerify, kBoolItemAttr,
163 kSecAttrCanWrap, kBoolItemAttr,
164 kSecAttrCanUnwrap, kBoolItemAttr,
165 kSecAttrStartDate, kDateItemAttr,
166 kSecAttrEndDate, kDateItemAttr,
167 kSecAttrSynchronizable, kBoolItemAttr,
168 NULL);
169 }
170 }
171 #endif
172
173 static void ItemForEachPKAttr(CFMutableDictionaryRef item, void(^each)(CFStringRef attr, enum ItemAttrType atype)) {
174 CFStringRef iclass = CFDictionaryGetValue(item, kSecClass);
175 if (!iclass) {
176 return;
177 } else if (CFEqual(iclass, kSecClassGenericPassword)) {
178 WithEachString(each,
179 kSecAttrAccessGroup, kAccessGroupItemAttr,
180 kSecAttrAccount, kStringItemAttr,
181 kSecAttrService, kStringItemAttr,
182 kSecAttrSynchronizable, kBoolItemAttr,
183 NULL);
184 } else if (CFEqual(iclass, kSecClassInternetPassword)) {
185 WithEachString(each,
186 kSecAttrAccessGroup, kAccessGroupItemAttr,
187 kSecAttrAccount, kStringItemAttr,
188 kSecAttrSecurityDomain, kStringItemAttr,
189 kSecAttrServer, kStringItemAttr,
190 kSecAttrProtocol, kNumberItemAttr,
191 kSecAttrAuthenticationType, kNumberItemAttr,
192 kSecAttrPort, kNumberItemAttr,
193 kSecAttrPath, kStringItemAttr,
194 kSecAttrSynchronizable, kBoolItemAttr,
195 NULL);
196 } else if (CFEqual(iclass, kSecClassCertificate)) {
197 WithEachString(each,
198 kSecAttrAccessGroup, kAccessGroupItemAttr,
199 kSecAttrCertificateType, kNumberItemAttr,
200 kSecAttrIssuer, kDataItemAttr,
201 kSecAttrSerialNumber, kDataItemAttr,
202 kSecAttrSynchronizable, kBoolItemAttr,
203 NULL);
204 } else if (CFEqual(iclass, kSecClassKey)) {
205 WithEachString(each,
206 kSecAttrAccessGroup, kAccessGroupItemAttr,
207 kSecAttrKeyClass, kStringItemAttr, // kNumberItemAttr on replies
208 kSecAttrApplicationLabel, kDataItemAttr,
209 kSecAttrApplicationTag, kDataItemAttr,
210 kSecAttrKeyType, kNumberItemAttr,
211 kSecAttrKeySizeInBits, kNumberItemAttr,
212 kSecAttrEffectiveKeySize, kNumberItemAttr,
213 kSecAttrStartDate, kDateItemAttr,
214 kSecAttrEndDate, kDateItemAttr,
215 kSecAttrSynchronizable, kBoolItemAttr,
216 NULL);
217 } else if (CFEqual(iclass, kSecClassIdentity)) {
218 WithEachString(each,
219 kSecAttrAccessGroup, kAccessGroupItemAttr,
220 kSecAttrCertificateType, kNumberItemAttr,
221 kSecAttrIssuer, kDataItemAttr,
222 kSecAttrSerialNumber, kDataItemAttr,
223 kSecAttrSynchronizable, kBoolItemAttr,
224 kSecAttrKeyClass, kStringItemAttr, // kNumberItemAttr on replies
225 kSecAttrApplicationLabel, kDataItemAttr,
226 kSecAttrApplicationTag, kDataItemAttr,
227 kSecAttrKeyType, kNumberItemAttr,
228 kSecAttrKeySizeInBits, kNumberItemAttr,
229 kSecAttrEffectiveKeySize, kNumberItemAttr,
230 kSecAttrStartDate, kDateItemAttr,
231 kSecAttrEndDate, kDateItemAttr,
232 kSecAttrSynchronizable, kBoolItemAttr,
233 NULL);
234 }
235 }
236
237 static CFMutableDictionaryRef ItemCreate(int num) {
238 CFStringRef iclass = NULL;
239 switch (num % 4) {
240 case 0:
241 iclass = kSecClassInternetPassword;
242 break;
243 case 1:
244 iclass = kSecClassGenericPassword;
245 break;
246 case 2:
247 iclass = kSecClassKey;
248 break;
249 case 3:
250 iclass = kSecClassCertificate;
251 break;
252 }
253 return CFDictionaryCreateMutableForCFTypesWith(kCFAllocatorDefault, kSecClass, iclass, NULL);
254 }
255
256 /* Test add api in all it's variants. */
257 static void tests(void)
258 {
259 for (int num = 0 ; num < 8; ++num) {
260 CFMutableDictionaryRef item = ItemCreate(num);
261 ItemForEachPKAttr(item, ^(CFStringRef attr, enum ItemAttrType atype) {
262 CFTypeRef value = NULL;
263 switch (atype) {
264 case kBoolItemAttr:
265 value = (num % 2 == 0 ? kCFBooleanTrue : kCFBooleanFalse);
266 CFRetain(value);
267 break;
268 case kNumberItemAttr:
269 value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &num);
270 break;
271 case kStringItemAttr:
272 case kBlobItemAttr:
273 value = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("string-%d"), num);
274 break;
275 case kDataItemAttr:
276 {
277 char buf[10];
278 int len = snprintf(buf, sizeof(buf), "data-%d", num);
279 value = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)buf, len);
280 break;
281 }
282 case kDateItemAttr:
283 value = NULL; // Don't mess with dates on create.
284 break;
285 case kAccessabilityItemAttr:
286 {
287 CFStringRef accessabilites[] = {
288 kSecAttrAccessibleWhenUnlocked,
289 kSecAttrAccessibleAfterFirstUnlock,
290 kSecAttrAccessibleAlways,
291 kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
292 kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,
293 kSecAttrAccessibleAlwaysThisDeviceOnly,
294 };
295 value = accessabilites[num % array_size(accessabilites)];
296 break;
297 }
298 case kAccessGroupItemAttr:
299 {
300 CFStringRef accessGroups[] = {
301 NULL,
302 #if 0
303 #if NO_SERVER
304 CFSTR("test"),
305 CFSTR("apple"),
306 CFSTR("lockdown-identities"),
307 #else
308 CFSTR("sync"),
309 #endif
310 CFSTR("com.apple.security.sos"), // Secd internally uses this
311
312 CFSTR("com.apple.security.regressions"), // SecurityTestApp is in this group.
313 #endif
314 };
315 value = accessGroups[num % array_size(accessGroups)];
316 break;
317 }
318 }
319 if (value)
320 CFDictionarySetValue(item, attr, value);
321 CFReleaseSafe(value);
322 });
323
324 CFDictionarySetValue(item, kSecAttrSynchronizable, kCFBooleanTrue);
325 ok_status(SecItemAdd(item, NULL), "add sync");
326
327 CFDictionarySetValue(item, kSecUseTombstones, kCFBooleanTrue);
328 ok_status(SecItemDelete(item), "delete sync");
329
330 CFDictionarySetValue(item, kSecAttrTombstone, kCFBooleanTrue);
331 ok_status(SecItemCopyMatching(item, NULL), "find tombstone after delete sync");
332 ok_status(SecItemDelete(item), "delete sync tombstone");
333 CFDictionaryRemoveValue(item, kSecAttrTombstone);
334
335 ok_status(SecItemAdd(item, NULL), "add sync again");
336
337 CFDictionarySetValue(item, kSecUseTombstones, kCFBooleanFalse);
338 ok_status(SecItemDelete(item), "delete sync without leaving a tombstone behind");
339 CFDictionaryRemoveValue(item, kSecUseTombstones);
340
341 CFDictionarySetValue(item, kSecAttrTombstone, kCFBooleanTrue);
342 is_status(SecItemCopyMatching(item, NULL), errSecItemNotFound, "do not find tombstone after delete sync with kSecUseTombstones=false");
343
344 CFDictionaryRemoveValue(item, kSecAttrSynchronizable);
345 ok_status(SecItemAdd(item, NULL), "add local");
346 ok_status(SecItemDelete(item), "delete local");
347
348 CFDictionarySetValue(item, kSecAttrTombstone, kCFBooleanTrue);
349 is_status(SecItemCopyMatching(item, NULL), errSecItemNotFound, "do not find tombstone after delete local");
350 is_status(SecItemDelete(item), errSecItemNotFound, "do not delete tombstone after delete local");
351 CFDictionaryRemoveValue(item, kSecAttrTombstone);
352
353 ok_status(SecItemAdd(item, NULL), "add local again");
354
355 CFDictionarySetValue(item, kSecUseTombstones, kCFBooleanTrue);
356 ok_status(SecItemDelete(item), "delete local and leave a tombstone behind");
357 CFDictionaryRemoveValue(item, kSecUseTombstones);
358
359 CFDictionarySetValue(item, kSecAttrTombstone, kCFBooleanTrue);
360 ok_status(SecItemCopyMatching(item, NULL), "find tombstone after delete sync with kSecUseTombstones=true");
361
362 CFDictionarySetValue(item, kSecUseTombstones, kCFBooleanTrue);
363 ok_status(SecItemDelete(item), "delete local tombstone kSecUseTombstones=true");
364 CFDictionaryRemoveValue(item, kSecUseTombstones);
365
366 ok_status(SecItemCopyMatching(item, NULL), "find tombstone after delete local tombstone with kSecUseTombstones=true");
367 ok_status(SecItemDelete(item), "delete local tombstone");
368 is_status(SecItemCopyMatching(item, NULL), errSecItemNotFound, "do not find tombstone after delete local");
369
370 CFRelease(item);
371 }
372 }
373
374 int si_12_item_stress(int argc, char *const *argv)
375 {
376 plan_tests(144);
377
378 tests();
379
380 return 0;
381 }