| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- // adapted from https://raw.github.com/rackspace/rackspace-ios/master/Classes/Keychain.m
- //
- // PPOTSimpleKeychain.m
- // OpenStack
- //
- // Based on CardIOKeychain
- // Based on KeychainWrapper in BadassVNC by Dylan Barrie
- //
- // Created by Mike Mayo on 10/1/10.
- // The OpenStack project is provided under the Apache 2.0 license.
- //
- #import "PPOTSimpleKeychain.h"
- #import "PPOTMacros.h"
- #import <Security/Security.h>
- #import <TargetConditionals.h>
- @implementation PPOTSimpleKeychain
- + (NSString *)keychainKeyForKey:(NSString *)key {
- // WARNING: don't change this line unless you know what you doing
- // If the app upgraded from mSDK (PayPal Touch) to OTC, we want to re-use app GUID;
- // therefore we are using the same keychain key.
- return [NSString stringWithFormat:CARDIO_STR(@"card.io - %@"), key];
- }
- + (BOOL)setData:(NSData *)data forKey:(NSString *)key {
- if (!key) {
- return NO;
- }
- BOOL success = YES;
- key = [self keychainKeyForKey:key];
- #if TARGET_IPHONE_SIMULATOR
- // since keychain sometimes is not available when running unit tests from the terminal
- // we decided to simply use user defaults
- [[NSUserDefaults standardUserDefaults] setValue:data ? data : [NSData data] forKey:key];
- [[NSUserDefaults standardUserDefaults] synchronize];
- return success;
- #else
- // First check if it already exists, by creating a search dictionary and requesting that
- // nothing be returned, and performing the search anyway.
- NSMutableDictionary *existsQueryDictionary = [NSMutableDictionary dictionary];
- [existsQueryDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
- // Add the keys to the search dict
- [existsQueryDictionary setObject:CARDIO_STR(@"service") forKey:(__bridge id)kSecAttrService];
- [existsQueryDictionary setObject:key forKey:(__bridge id)kSecAttrAccount];
- OSStatus res = SecItemCopyMatching((__bridge CFDictionaryRef)existsQueryDictionary, NULL);
- if (res == errSecItemNotFound) {
- if (data) {
- NSMutableDictionary *addDict = existsQueryDictionary;
- [addDict setObject:data forKey:(__bridge id)kSecValueData];
- [addDict setObject:(__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible];
- res = SecItemAdd((__bridge CFDictionaryRef)addDict, NULL);
- if (res != errSecSuccess) {
- success = NO;
- }
- }
- } else if (res == errSecSuccess) {
- if(data) {
- // Modify an existing one
- // Actually pull it now off the keychain at this point.
- NSDictionary *attributeDict = [NSDictionary dictionaryWithObject:data forKey:(__bridge id)kSecValueData];
- res = SecItemUpdate((__bridge CFDictionaryRef)existsQueryDictionary, (__bridge CFDictionaryRef)attributeDict);
- if (res != errSecSuccess) {
- success = NO;
- }
- } else {
- SecItemDelete((__bridge CFDictionaryRef)existsQueryDictionary);
- }
- } else {
- success = NO;
- }
- return success;
- #endif
- }
- + (NSData *)dataForKey:(NSString *)key {
- key = [self keychainKeyForKey:key];
- #if TARGET_IPHONE_SIMULATOR
- return [[NSUserDefaults standardUserDefaults] valueForKey:key];
- #else
- NSMutableDictionary *existsQueryDictionary = [NSMutableDictionary dictionary];
- [existsQueryDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
- // Add the keys to the search dict
- [existsQueryDictionary setObject:CARDIO_STR(@"service") forKey:(__bridge id)kSecAttrService];
- [existsQueryDictionary setObject:key forKey:(__bridge id)kSecAttrAccount];
- // We want the data back!
- [existsQueryDictionary setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
- CFTypeRef cfData = NULL;
- OSStatus res = SecItemCopyMatching((__bridge CFDictionaryRef)existsQueryDictionary, &cfData);
- NSData *data = (id)CFBridgingRelease(cfData);
- if (res == errSecSuccess) {
- return data;
- }
-
- return nil;
- #endif
- }
- + (id)unarchiveObjectWithDataForKey:(NSString *)key {
- NSData *data = [PPOTSimpleKeychain dataForKey:key];
- if ([data length]) {
- return [NSKeyedUnarchiver unarchiveObjectWithData:data];
- }
- else {
- return nil;
- }
- }
- @end
|