5 * Copyright (c) 2008-2010,2012-2013 Apple Inc. All Rights Reserved.
9 #include <CoreFoundation/CoreFoundation.h>
10 #include <Security/SecBase.h>
11 #include <Security/SecItem.h>
12 #include <Security/SecInternal.h>
13 #include <Security/SecItemPriv.h>
14 #include <utilities/array_size.h>
18 #include "Security_regressions.h"
20 static void tests(void)
23 CFNumberRef eighty
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &v_eighty
);
24 const char *v_data
= "test";
25 CFDataRef pwdata
= CFDataCreate(NULL
, (UInt8
*)v_data
, strlen(v_data
));
26 const void *keys
[] = {
32 kSecAttrAuthenticationType
,
33 kSecReturnPersistentRef
,
36 const void *values
[] = {
37 kSecClassInternetPassword
,
46 CFDictionaryRef item
= CFDictionaryCreate(NULL
, keys
, values
,
47 array_size(keys
), NULL
, NULL
);
49 CFTypeRef persist
= NULL
;
50 ok_status(SecItemAdd(item
, &persist
), "add internet password");
51 ok(persist
, "got back persistent ref");
53 /* Create a dict with all attrs except the data. */
54 keys
[(array_size(keys
)) - 2] = kSecReturnAttributes
;
55 CFDictionaryRef query
= CFDictionaryCreate(NULL
, keys
, values
,
56 (array_size(keys
)) - 1, NULL
, NULL
);
57 CFTypeRef results
= NULL
;
58 ok_status(SecItemCopyMatching(query
, &results
), "find internet password by attr");
60 const void *keys_persist
[] = {
62 kSecValuePersistentRef
64 const void *values_persist
[] = {
68 CFDictionaryRef query2
= CFDictionaryCreate(NULL
, keys_persist
, values_persist
,
69 (array_size(keys_persist
)), NULL
, NULL
);
70 CFTypeRef results2
= NULL
;
71 ok_status(SecItemCopyMatching(query2
, &results2
), "find internet password by persistent ref");
72 ok(CFEqual(results
, results2
? results2
: CFSTR("")), "same item (attributes)");
74 CFReleaseNull(results
);
75 CFReleaseNull(results2
);
77 ok_status(SecItemDelete(query
), "delete internet password");
79 ok_status(!SecItemCopyMatching(query
, &results
),
80 "don't find internet password by attributes");
81 ok(!results
, "no results");
83 /* clean up left over from aborted run */
85 CFDictionaryRef cleanup
= CFDictionaryCreate(NULL
, (const void **)&kSecValuePersistentRef
,
86 &results
, 1, NULL
, NULL
);
87 SecItemDelete(cleanup
);
92 ok_status(!SecItemCopyMatching(query2
, &results2
),
93 "don't find internet password by persistent ref anymore");
94 ok(!results2
, "no results");
96 CFReleaseNull(persist
);
98 /* Add a new item and get its persistent ref. */
99 ok_status(SecItemAdd(item
, &persist
), "add internet password");
100 CFTypeRef persist2
= NULL
;
101 CFMutableDictionaryRef item2
= CFDictionaryCreateMutableCopy(NULL
, 0, item
);
102 CFDictionarySetValue(item2
, kSecAttrAccount
, CFSTR("johndoe"));
103 ok_status(SecItemAdd(item2
, &persist2
), "add second internet password");
104 is(CFGetTypeID(persist
), CFDataGetTypeID(), "result is a CFData");
105 CFMutableDictionaryRef query3
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
106 CFDictionaryAddValue(query3
, kSecValuePersistentRef
, persist
);
107 CFMutableDictionaryRef update
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
108 CFDictionaryAddValue(update
, kSecAttrServer
, CFSTR("zuigt.com"));
109 ok_status(SecItemUpdate(query3
, update
), "update via persitant ref");
111 /* Verify that the update really worked. */
112 CFDictionaryAddValue(query3
, kSecReturnAttributes
, kCFBooleanTrue
);
113 ok_status(SecItemCopyMatching(query3
, &results2
), "find updated internet password by persistent ref");
114 CFStringRef server
= CFDictionaryGetValue(results2
, kSecAttrServer
);
115 ok(CFEqual(server
, CFSTR("zuigt.com")), "verify attribute was modified by update");
116 CFReleaseNull(results2
);
117 CFDictionaryRemoveValue(query3
, kSecReturnAttributes
);
119 /* Verify that item2 wasn't affected by the update. */
120 CFMutableDictionaryRef query4
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
121 CFDictionaryAddValue(query4
, kSecValuePersistentRef
, persist2
);
122 CFDictionaryAddValue(query4
, kSecReturnAttributes
, kCFBooleanTrue
);
123 ok_status(SecItemCopyMatching(query4
, &results2
), "find non updated internet password by persistent ref");
124 server
= CFDictionaryGetValue(results2
, kSecAttrServer
);
125 ok(CFEqual(server
, CFSTR("zuigt.nl")), "verify second items attribute was not modified by update");
126 CFReleaseNull(results2
);
128 /* Delete the item via persitant ref. */
129 ok_status(SecItemDelete(query3
), "delete via persitant ref");
130 is_status(SecItemCopyMatching(query3
, &results2
), errSecItemNotFound
,
131 "don't find deleted internet password by persistent ref");
132 CFReleaseNull(results2
);
133 ok_status(SecItemCopyMatching(query4
, &results2
),
134 "find non deleted internet password by persistent ref");
135 CFReleaseNull(results2
);
136 ok_status(SecItemDelete(query4
),
137 "delete internet password by persistent ref");
145 CFReleaseNull(item2
);
146 CFReleaseNull(eighty
);
147 CFReleaseNull(pwdata
);
148 CFReleaseNull(persist
);
149 CFReleaseNull(persist2
);
152 int si_43_persistent(int argc
, char *const *argv
)