Update MacOS security routines

This commit is contained in:
Seth Hillbrand 2023-10-20 16:10:49 +02:00
parent 81214e1f0f
commit 91f28f84d7
1 changed files with 34 additions and 33 deletions

View File

@ -23,53 +23,54 @@
bool KIPLATFORM::SECRETS::StoreSecret(const wxString& aService, const wxString& aKey, const wxString& aValue) bool KIPLATFORM::SECRETS::StoreSecret(const wxString& aService, const wxString& aKey, const wxString& aValue)
{ {
SecKeychainItemRef itemRef = NULL; // Create a query for the secret
CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(query, kSecClass, kSecClassGenericPassword);
CFDictionarySetValue(query, kSecAttrService, CFStringCreateWithCString(NULL, aService.utf8_str(), kCFStringEncodingUTF8));
CFDictionarySetValue(query, kSecAttrAccount, CFStringCreateWithCString(NULL, aKey.utf8_str(), kCFStringEncodingUTF8));
OSStatus status = SecKeychainFindGenericPassword( NULL, aService.length(), aService.utf8_str(), // Try to find the existing item
aKey.length(), aKey.utf8_str(), OSStatus status = SecItemCopyMatching(query, NULL);
NULL, NULL, &itemRef );
if (status == errSecItemNotFound) if (status == errSecItemNotFound)
{ {
status = SecKeychainAddGenericPassword( NULL, aService.length(), aService.utf8_str(), // Add the new secret to the keychain
aKey.length(), aKey.utf8_str(), CFDictionarySetValue(query, kSecValueData, CFDataCreate(NULL, (const UInt8*)aValue.utf8_str(), aValue.length()));
aValue.length(), aValue.utf8_str(), status = SecItemAdd(query, NULL);
NULL );
CFRelease( itemRef );
} }
else if (status == errSecSuccess) else if (status == errSecSuccess)
{ {
status = SecKeychainItemModifyAttributesAndData( itemRef, NULL, aValue.length(), aValue.utf8_str() ); // Update the existing secret in the keychain
CFMutableDictionaryRef updateQuery = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(updateQuery, kSecValueData, CFDataCreate(NULL, (const UInt8*)aValue.utf8_str(), aValue.length()));
status = SecItemUpdate(query, updateQuery);
CFRelease(updateQuery);
} }
CFRelease(query);
return status == errSecSuccess; return status == errSecSuccess;
} }
bool KIPLATFORM::SECRETS::GetSecret(const wxString& aService, const wxString& aKey, wxString& aValue) bool KIPLATFORM::SECRETS::GetSecret(const wxString& aService, const wxString& aKey, wxString& aValue)
{ {
SecKeychainItemRef itemRef = NULL; // Create a query for the secret
CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(query, kSecClass, kSecClassGenericPassword);
CFDictionarySetValue(query, kSecAttrService, CFStringCreateWithCString(NULL, aService.utf8_str(), kCFStringEncodingUTF8));
CFDictionarySetValue(query, kSecAttrAccount, CFStringCreateWithCString(NULL, aKey.utf8_str(), kCFStringEncodingUTF8));
CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue); // Return the secret data
OSStatus status = SecKeychainFindGenericPassword( NULL, aService.length(), aService.utf8_str(), // Retrieve the secret from the keychain
aKey.length(), aKey.utf8_str(), CFDataRef secretData = NULL;
NULL, NULL, &itemRef ); OSStatus status = SecItemCopyMatching(query, (CFTypeRef*)&secretData);
if (status == errSecSuccess) if (status == errSecSuccess)
{ {
UInt32 length; aValue = wxString::FromUTF8((const char*)CFDataGetBytePtr(secretData), CFDataGetLength(secretData));
char* data; CFRelease(secretData);
status = SecKeychainItemCopyAttributesAndData( itemRef, NULL, NULL, NULL, &length, (void**)&data );
if( status == errSecSuccess )
{
aValue = wxString::FromUTF8( data, length );
SecKeychainItemFreeAttributesAndData( NULL, data );
}
CFRelease( itemRef );
} }
CFRelease(query);
return status == errSecSuccess; return status == errSecSuccess;
} }