1 #include <Security/SecKeychainItem.h>
2 #include <Security/SecKeychain.h>
3 #include <CoreFoundation/CFRunLoop.h>
6 #include "keychain_regressions.h"
7 #include "kc-helpers.h"
9 static char account
[] = "account";
10 static char service
[] = "service";
11 static char password
[] = "password";
12 static bool callbackCalled
= false;
14 static void checkContent(SecKeychainItemRef itemRef
)
16 SecItemClass itemClass
;
18 SecKeychainAttribute attrs
[] =
20 { kSecLabelItemAttr
, 0, NULL
},
21 { kSecAccountItemAttr
, 0, NULL
},
22 { kSecServiceItemAttr
, 0, NULL
}
25 SecKeychainAttributeList attrList
=
26 { sizeof(attrs
) / sizeof(*attrs
), attrs
};
30 ok_status(SecKeychainItemCopyContent(itemRef
, &itemClass
, &attrList
,
31 &length
, &data
), "get item data in callback");
32 is(length
, sizeof(password
), "<rdar://problem/3867900> "
33 "SecKeychainItemCopyContent() returns bad data on items "
34 "from notifications");
36 ok(!memcmp(password
, data
, length
), "password data matches.");
38 ok_status(SecKeychainItemFreeContent(&attrList
, data
),
39 "free item data in callback");
42 static OSStatus
callbackFunction(SecKeychainEvent keychainEvent
,
43 SecKeychainCallbackInfo
*info
, void *context
)
45 is(keychainEvent
, kSecAddEvent
, "Got an incorrect keychain event");
46 ok(context
!= NULL
, "context is null");
47 ok(info
!= NULL
, "info is NULL");
48 ok(info
->item
!= NULL
, "info-<item is NULL");
50 checkContent(info
->item
);
51 *((UInt32
*)context
) = 1;
53 ok_status(SecKeychainItemDelete(info
->item
), "delete item");
55 // We processed an item, quit the run loop
56 callbackCalled
= true;
57 CFRunLoopStop(CFRunLoopGetCurrent());
62 kc_21_item_use_callback(int argc
, char *const *argv
)
66 // Run the CFRunLoop to clear out existing notifications
67 CFRunLoopRunInMode(kCFRunLoopDefaultMode
, 1.0, false);
69 UInt32 didGetNotification
= 0;
70 ok_status(SecKeychainAddCallback(callbackFunction
, kSecAddEventMask
,
71 &didGetNotification
), "add callback");
73 SecKeychainRef keychain
= createNewKeychain("test", "test");
74 SecKeychainItemRef itemRef
;
75 ok_status(SecKeychainAddGenericPassword(keychain
,
76 sizeof(account
), account
,
77 sizeof(service
), service
,
78 sizeof(password
), password
,
80 "add generic password, release and wait for callback");
82 // Run the CFRunLoop to process events (and call our callback)
83 CFRunLoopRunInMode(kCFRunLoopDefaultMode
, 10.0, false);
84 is(callbackCalled
, true, "Keychain callback function was not called or did not finish");
88 ok_status(SecKeychainDelete(keychain
), "%s: SecKeychainDelete", testName
);