122 lines
4.8 KiB
Objective-C
122 lines
4.8 KiB
Objective-C
#import "TDKeychainItemWrapper.h"
|
|
#import "TDLogging.h"
|
|
|
|
static NSString * const TDKeychainService = @"com.thinkingddata.analytics.service";
|
|
static NSString * const TDInstallTimes = @"com.thinkingddata.analytics.installtimes";
|
|
static NSString * const TDDeviceID = @"com.thinkingddata.analytics.deviceid";
|
|
|
|
@interface TDKeychainItemWrapper ()
|
|
|
|
@property (atomic, strong) NSDictionary *oldKeychain;
|
|
|
|
@end
|
|
|
|
@implementation TDKeychainItemWrapper
|
|
|
|
- (void)saveItem:(NSString *)string forKey:(NSString *)key {
|
|
NSData *encodeData = [string dataUsingEncoding:NSUTF8StringEncoding];
|
|
NSString *originPassword = [self dataForKey:key];
|
|
if (originPassword.length > 0) {
|
|
NSMutableDictionary *updateAttributes = [NSMutableDictionary dictionary];
|
|
updateAttributes[(__bridge id)kSecValueData] = encodeData;
|
|
NSMutableDictionary *query = [self keychainQueryWithAccount:key];
|
|
OSStatus statusCode = SecItemUpdate((__bridge CFDictionaryRef)query,(__bridge CFDictionaryRef)updateAttributes);
|
|
if (statusCode != noErr) {
|
|
TDLogError(@"Couldn't update the Keychain Item." );
|
|
}
|
|
} else {
|
|
NSMutableDictionary *attributes = [self keychainQueryWithAccount:key];
|
|
attributes[(__bridge id)kSecValueData] = encodeData;
|
|
OSStatus statusCode = SecItemAdd((__bridge CFDictionaryRef)attributes, nil);
|
|
if (statusCode != noErr) {
|
|
TDLogError(@"Couldn't add the Keychain Item.");
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)saveInstallTimes:(NSString *)string {
|
|
[self saveItem:string forKey:TDInstallTimes];
|
|
}
|
|
|
|
- (void)saveDeviceId:(NSString *)string {
|
|
[self saveItem:string forKey:TDDeviceID];
|
|
}
|
|
|
|
- (NSString *)dataForKey:(NSString *)key {
|
|
NSMutableDictionary *attributes = [self keychainQueryWithAccount:key];
|
|
attributes[(__bridge id)kSecMatchLimit] = (__bridge id)(kSecMatchLimitOne);
|
|
attributes[(__bridge id)kSecReturnData] = (__bridge id)(kCFBooleanTrue);
|
|
CFTypeRef data = nil;
|
|
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)attributes,(CFTypeRef *)&data);
|
|
if (status != errSecSuccess) {
|
|
return nil;
|
|
}
|
|
NSData *encodeData = [NSData dataWithData:(__bridge NSData *)data];
|
|
if (data) {
|
|
CFRelease(data);
|
|
}
|
|
if (encodeData) {
|
|
return [[NSString alloc] initWithData:encodeData encoding:NSUTF8StringEncoding];
|
|
}
|
|
|
|
return nil;
|
|
}
|
|
|
|
- (void)readOldKeychain {
|
|
NSMutableDictionary *genericPasswordQuery = [[NSMutableDictionary alloc] init];
|
|
[genericPasswordQuery setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
|
[genericPasswordQuery setObject:@"ThinkingdataService" forKey:(__bridge id)kSecAttrGeneric];
|
|
[genericPasswordQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
|
|
[genericPasswordQuery setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes];
|
|
NSDictionary *tempQuery = [NSDictionary dictionaryWithDictionary:genericPasswordQuery];
|
|
CFTypeRef cfDictionary = NULL;
|
|
if (SecItemCopyMatching((__bridge CFDictionaryRef)tempQuery, &cfDictionary) == noErr) {
|
|
NSMutableDictionary *returnDict = [NSMutableDictionary dictionaryWithDictionary:(__bridge_transfer NSDictionary *)cfDictionary];
|
|
[returnDict setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
|
|
[returnDict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
|
|
|
OSStatus keychainErr = noErr;
|
|
CFTypeRef cfXmlData = NULL;
|
|
keychainErr = SecItemCopyMatching((__bridge CFDictionaryRef)returnDict, &cfXmlData);
|
|
|
|
if (keychainErr == noErr) {
|
|
NSData *xmlData = (__bridge_transfer NSData *)cfXmlData;
|
|
NSPropertyListFormat fmt;
|
|
NSDictionary *resultsInfo = [NSPropertyListSerialization propertyListWithData:xmlData options:NSPropertyListMutableContainersAndLeaves format:&fmt error:nil];
|
|
self.oldKeychain = resultsInfo;
|
|
}
|
|
}
|
|
}
|
|
|
|
- (NSString *)getInstallTimesOld {
|
|
if (self.oldKeychain)
|
|
return [NSString stringWithFormat:@"%@",[self.oldKeychain objectForKey:@"thinking_setup_index"]];
|
|
return nil;
|
|
}
|
|
|
|
- (NSString *)getDeviceIdOld {
|
|
if (self.oldKeychain)
|
|
return [self.oldKeychain objectForKey:@"thinking_device_id"];
|
|
return nil;
|
|
}
|
|
|
|
- (NSString *)readDeviceId {
|
|
NSString *data = [self dataForKey:TDDeviceID];
|
|
return data;
|
|
}
|
|
|
|
- (NSString *)readInstallTimes {
|
|
NSString *data = [self dataForKey:TDInstallTimes];
|
|
return data;
|
|
}
|
|
|
|
- (NSMutableDictionary *)keychainQueryWithAccount:(NSString *)account {
|
|
NSMutableDictionary *query = [NSMutableDictionary dictionary];
|
|
query[(__bridge id)kSecClass] = (__bridge id)kSecClassGenericPassword;
|
|
query[(__bridge id)kSecAttrService] = TDKeychainService;
|
|
query[(__bridge id)kSecAttrAccount] = account;
|
|
return query;
|
|
}
|
|
|
|
@end
|