]> git.saurik.com Git - apple/security.git/blob - sec/Security/Regressions/secitem/si-72-syncableitems.c
Security-55471.14.tar.gz
[apple/security.git] / sec / Security / Regressions / secitem / si-72-syncableitems.c
1
2 //
3 // si-72-syncableitems.c
4 // regressions
5 //
6 // Created by Ken McLeod on 5/18/13.
7 //
8 //
9 #include <CoreFoundation/CoreFoundation.h>
10 #include <Security/Security.h>
11 #include <Security/SecItemPriv.h>
12 #include <Security/SecInternal.h>
13 #include <utilities/array_size.h>
14
15 #include "Security_regressions.h"
16
17 static void tests(void)
18 {
19 CFUUIDRef uuid = CFUUIDCreate(0);
20 const CFStringRef uuidstr = CFUUIDCreateString(0, uuid);
21 const CFStringRef account = CFStringCreateWithFormat(NULL, NULL, CFSTR("Test Account %@"), uuidstr);
22 const CFStringRef service = CFSTR("Test Service");
23 const CFStringRef label = CFSTR("Test Synchronizable Item");
24 const CFStringRef comment = CFSTR("Test Comment");
25 const CFDataRef passwordData = CFDataCreate(NULL, (const UInt8*)"Test", (CFIndex)5);
26
27 CFReleaseSafe(uuid);
28 CFReleaseSafe(uuidstr);
29
30 CFDictionaryRef query = NULL;
31 CFDictionaryRef attrs = NULL;
32 CFDictionaryRef result = NULL;
33
34 /* Test adding a synchronizable item */
35 {
36 const void *keys[] = {
37 kSecClass, kSecAttrLabel, kSecAttrComment, kSecAttrAccount, kSecAttrService,
38 kSecAttrSynchronizable,
39 kSecValueData, kSecReturnAttributes };
40 const void *values[] = {
41 kSecClassGenericPassword, label, comment, account, service,
42 kCFBooleanTrue,
43 passwordData, kCFBooleanTrue };
44
45 attrs = CFDictionaryCreate(NULL, keys, values,
46 array_size(keys),
47 &kCFTypeDictionaryKeyCallBacks,
48 &kCFTypeDictionaryValueCallBacks);
49
50 is_status(SecItemAdd(attrs, (CFTypeRef *)&result),
51 errSecSuccess, "SecItemAdd sync=true");
52
53 CFReleaseSafe(attrs);
54 CFReleaseNull(result);
55 }
56
57 /* Test finding the synchronizable item we just added, using sync=true */
58 {
59 const void *keys[] = {
60 kSecClass, // class attribute is required
61 kSecAttrAccount, kSecAttrService, // we'll look up by account and service, which determine uniqueness
62 kSecAttrSynchronizable, // we want to get synchronizable results
63 kSecReturnAttributes };
64 const void *values[] = {
65 kSecClassGenericPassword,
66 account, service,
67 kCFBooleanTrue, // only return synchronizable results
68 kCFBooleanTrue };
69
70 query = CFDictionaryCreate(NULL, keys, values,
71 array_size(keys),
72 &kCFTypeDictionaryKeyCallBacks,
73 &kCFTypeDictionaryValueCallBacks);
74
75 is_status(SecItemCopyMatching(query, (CFTypeRef *)&result),
76 errSecSuccess, "SecItemCopyMatching sync=true");
77
78 CFReleaseSafe(query);
79 CFReleaseNull(result);
80 }
81
82 /* Test finding the synchronizable item we just added, using sync=any */
83 {
84 const void *keys[] = {
85 kSecClass, // class attribute is required
86 kSecAttrAccount, kSecAttrService, // we'll look up by account and service, which determine uniqueness
87 kSecAttrSynchronizable, // we want to get synchronizable results
88 kSecReturnAttributes };
89 const void *values[] = {
90 kSecClassGenericPassword,
91 account, service,
92 kSecAttrSynchronizableAny, // return any match, regardless of whether it is synchronizable
93 kCFBooleanTrue };
94
95 query = CFDictionaryCreate(NULL, keys, values,
96 array_size(keys),
97 &kCFTypeDictionaryKeyCallBacks,
98 &kCFTypeDictionaryValueCallBacks);
99
100 is_status(SecItemCopyMatching(query, (CFTypeRef *)&result),
101 errSecSuccess, "SecItemCopyMatching sync=any");
102
103 CFReleaseSafe(query);
104 CFReleaseNull(result);
105 }
106
107 /* Test updating the synchronizable item */
108 {
109 const void *keys[] = {
110 kSecClass, // class attribute is required
111 kSecAttrAccount, kSecAttrService, // we'll look up by account and service, which determine uniqueness
112 kSecAttrSynchronizable }; // we want synchronizable results
113 const void *values[] = {
114 kSecClassGenericPassword,
115 account, service,
116 kCFBooleanTrue }; // we only want to find the synchronizable item here, not a non-synchronizable one
117
118 query = CFDictionaryCreate(NULL, keys, values,
119 array_size(keys),
120 &kCFTypeDictionaryKeyCallBacks,
121 &kCFTypeDictionaryValueCallBacks);
122
123 const void *update_keys[] = { kSecAttrComment };
124 const void *update_values[] = { CFSTR("Updated Comment") };
125 attrs = CFDictionaryCreate(NULL, update_keys, update_values,
126 array_size(update_keys),
127 &kCFTypeDictionaryKeyCallBacks,
128 &kCFTypeDictionaryValueCallBacks);
129
130 is_status(SecItemUpdate(query, attrs),
131 errSecSuccess, "SecItemUpdate sync=true");
132
133 CFReleaseSafe(query);
134 CFReleaseSafe(attrs);
135 }
136
137 /* Test finding the updated item with its new attribute */
138 {
139 const void *keys[] = {
140 kSecClass, // class attribute is required
141 kSecAttrAccount, kSecAttrService, // we'll look up by account and service, which determine uniqueness
142 kSecAttrComment, // also search on the attr we just changed, so we know we've found the updated item
143 kSecAttrSynchronizable }; // we want synchronizable results
144 const void *values[] = {
145 kSecClassGenericPassword,
146 account, service,
147 CFSTR("Updated Comment"),
148 kCFBooleanTrue }; // we only want to find the synchronizable item here, not a non-synchronizable one
149
150 query = CFDictionaryCreate(NULL, keys, values,
151 array_size(keys),
152 &kCFTypeDictionaryKeyCallBacks,
153 &kCFTypeDictionaryValueCallBacks);
154
155 is_status(SecItemCopyMatching(query, (CFTypeRef *)&result),
156 errSecSuccess, "SecItemCopyMatching post-update");
157
158 CFReleaseSafe(result);
159 // re-use query in next test...
160 }
161
162 /* Test deleting the item */
163 {
164 is_status(SecItemDelete(query), errSecSuccess, "SecItemDelete sync=true");
165
166 CFReleaseSafe(query);
167 }
168 }
169
170 int si_72_syncableitems(int argc, char * const *argv)
171 {
172 plan_tests(6);
173 tests();
174
175 return 0;
176 }