I'm trying to call iOS Keychain framework from C++, following various documentation pages and StackOverflow questions I arrived at the following:
// library is multiplaform so for now using macros for platform imports
#ifdef ANDROID
// Android specific imports
#else
#include <CoreFoundation/CoreFoundation.h>
#include <Security/Security.h>
#endif // ANDROID
// ...some glue code
CFStringRef keys[4];
keys[0] = kSecClass;
keys[1] = kSecAttrAccount;
keys[2] = kSecAttrService;
keys[3] = kSecValueData;
CFTypeRef values[4];
values[0] = kSecClassGenericPassword;
values[1] = CFSTR("accountname2");
// TODO change this to bundle identifier
values[2] = CFSTR("jsi-rn-wallet-core");
values[3] = CFSTR("testvalueblahblah");
CFDictionaryRef query = CFDictionaryCreate(
kCFAllocatorDefault,
(const void**) keys,
(const void**) values,
4,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
OSStatus status = SecItemAdd(query, NULL);
if(status != errSecSuccess) {
cout << "DID NOT STORE DATA, status: " << status << endl;
return {};
}
cout << "Data stored" << endl;
No matter what I do, I get a status of -50, which according to documentation is an incorrect param, however, I don't know which one exactly.
Any idea what might be wrong?
I figured it out, as it turns out, on macOS you can put CFStrings directly in the query dictionary, but on iOS you need to store binary data. Something like this:
string value = "testvalueblahblah";
std::vector<uint8_t> vec(value.begin(), value.end());
...
values[3] = CFDataCreate(kCFAllocatorDefault, &vec[0], vec.size());
After data is converted, everything started working.