From 5a4d4e2afd3b221f4279bb91a021684c76702bc7 Mon Sep 17 00:00:00 2001 From: cebgcontract <99630598+cebgcontract@users.noreply.github.com> Date: Wed, 23 Nov 2022 19:13:07 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AF=BB=E5=8F=96=E5=AD=98?= =?UTF-8?q?=E5=82=A8keychain=E7=9A=84=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Classes_cocos/DataManager.h | 21 + Classes_cocos/DataManager.m | 87 + Classes_cocos/SSKeychain.h | 357 ----- Classes_cocos/SSKeychain.m | 262 --- Classes_cocos/UICKeyChainStore.h | 289 ++++ Classes_cocos/UICKeyChainStore.m | 1407 +++++++++++++++++ Classes_cocos/UIViewController+Wallet.mm | 17 +- Unity-iPhone.xcodeproj/project.pbxproj | 18 +- .../UserInterfaceState.xcuserstate | Bin 160142 -> 136060 bytes .../xcdebugger/Breakpoints_v2.xcbkptlist | 36 +- Unity-iPhone/Unity-iPhone.entitlements | 4 + 11 files changed, 1850 insertions(+), 648 deletions(-) create mode 100644 Classes_cocos/DataManager.h create mode 100644 Classes_cocos/DataManager.m delete mode 100644 Classes_cocos/SSKeychain.h delete mode 100644 Classes_cocos/SSKeychain.m create mode 100644 Classes_cocos/UICKeyChainStore.h create mode 100644 Classes_cocos/UICKeyChainStore.m diff --git a/Classes_cocos/DataManager.h b/Classes_cocos/DataManager.h new file mode 100644 index 0000000..5df7f2f --- /dev/null +++ b/Classes_cocos/DataManager.h @@ -0,0 +1,21 @@ +// +// DataManager.h +// Unity-iPhone +// +// Created by zhl on 2022/11/23. +// + +#import + +typedef NS_ENUM(NSUInteger, InitType) { + SynLock, + GCD, +}; + +@interface DataManager : NSObject + ++ (instancetype)sharedInstanceWith:(InitType)type; +-(void)saveKey:(NSString *) account key:(NSString *) key; +-(NSString *)loadKey:(NSString *) account; + +@end diff --git a/Classes_cocos/DataManager.m b/Classes_cocos/DataManager.m new file mode 100644 index 0000000..4c84480 --- /dev/null +++ b/Classes_cocos/DataManager.m @@ -0,0 +1,87 @@ +// +// DataManager.m +// Unity-iPhone +// +// Created by zhl on 2022/11/23. +// + +#import "DataManager.h" +#import "UICKeyChainStore.h" + + +@interface DataManager () + +@end + +static NSString * const cebgWalletService = @"com.cebg.wallet"; +//global var +static id _instance; + +UICKeyChainStore *keychain; + +InitType _instanceInitType; + +@implementation DataManager + ++ (instancetype)sharedInstanceWith:(InitType)type { + _instanceInitType = type; + if (type == SynLock) { + @synchronized (self) { + if (_instance == nil) { + _instance = [[self alloc] init]; + } + } + } + + else { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _instance = [[self alloc] init]; + }); + } + return _instance; +} + ++ (instancetype)allocWithZone:(struct _NSZone *)zone { + if (_instanceInitType == SynLock) { + @synchronized (self) { + if (_instance == nil) { + _instance = [super allocWithZone:zone]; + } + } + } + else { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _instance = [super allocWithZone:zone]; + }); + } + return _instance; +} + +- (id)copyWithZone:(nullable NSZone *)zone { + return _instance; +} + +-(void)saveKey:(NSString *) account key:(NSString *) key { + if (keychain == nil ){ + keychain = [UICKeyChainStore keyChainStoreWithService:cebgWalletService]; + keychain.synchronizable = YES; + } + keychain[account] = key; +} + +-(NSString *)loadKey:(NSString *) account { + if (keychain == nil ){ + keychain = [UICKeyChainStore keyChainStoreWithService:cebgWalletService]; + keychain.synchronizable = YES; + } + NSError *error; + NSString * result = [keychain stringForKey:account error:&error]; + if (error) { + NSLog(@"%@", error.localizedDescription); + } + return result; +} + +@end diff --git a/Classes_cocos/SSKeychain.h b/Classes_cocos/SSKeychain.h deleted file mode 100644 index 3f70404..0000000 --- a/Classes_cocos/SSKeychain.h +++ /dev/null @@ -1,357 +0,0 @@ -// -// SSKeychain.h -// SSToolkit -// -// Created by Sam Soffes on 5/19/10. -// Copyright (c) 2009-2011 Sam Soffes. All rights reserved. -// - -#import -#import - -/** Error codes that can be returned in NSError objects. */ -typedef enum { - /** No error. */ - SSKeychainErrorNone = noErr, - - /** Some of the arguments were invalid. */ - SSKeychainErrorBadArguments = -1001, - - /** There was no password. */ - SSKeychainErrorNoPassword = -1002, - - /** One or more parameters passed internally were not valid. */ - SSKeychainErrorInvalidParameter = errSecParam, - - /** Failed to allocate memory. */ - SSKeychainErrorFailedToAllocated = errSecAllocate, - - /** No trust results are available. */ - SSKeychainErrorNotAvailable = errSecNotAvailable, - - /** Authorization/Authentication failed. */ - SSKeychainErrorAuthorizationFailed = errSecAuthFailed, - - /** The item already exists. */ - SSKeychainErrorDuplicatedItem = errSecDuplicateItem, - - /** The item cannot be found.*/ - SSKeychainErrorNotFound = errSecItemNotFound, - - /** Interaction with the Security Server is not allowed. */ - SSKeychainErrorInteractionNotAllowed = errSecInteractionNotAllowed, - - /** Unable to decode the provided data. */ - SSKeychainErrorFailedToDecode = errSecDecode -} SSKeychainErrorCode; - -extern NSString *const kSSKeychainErrorDomain; - -/** Account name. */ -extern NSString *const kSSKeychainAccountKey; - -/** - Time the item was created. - - The value will be a string. - */ -extern NSString *const kSSKeychainCreatedAtKey; - -/** Item class. */ -extern NSString *const kSSKeychainClassKey; - -/** Item description. */ -extern NSString *const kSSKeychainDescriptionKey; - -/** Item label. */ -extern NSString *const kSSKeychainLabelKey; - -/** Time the item was last modified. - - The value will be a string. - */ -extern NSString *const kSSKeychainLastModifiedKey; - -/** Where the item was created. */ -extern NSString *const kSSKeychainWhereKey; - -/** - Simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system - Keychain on Mac OS X and iOS. - - This was originally inspired by EMKeychain and SDKeychain (both of which are now gone). Thanks to the authors. - SSKeychain has since switched to a simpler implementation that was abstracted from [SSToolkit](http://sstoolk.it). - */ -@interface SSKeychain : NSObject - -///----------------------- -/// @name Getting Accounts -///----------------------- - -/** - Returns an array containing the Keychain's accounts, or `nil` if the Keychain has no accounts. - - See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the - dictionaries returned by this method. - - @return An array of dictionaries containing the Keychain's accounts, or `nil` if the Keychain doesn't have any - accounts. The order of the objects in the array isn't defined. - - @see allAccounts: - */ -+ (NSArray *)allAccounts; - -/** - Returns an array containing the Keychain's accounts, or `nil` if the Keychain doesn't have any - accounts. - - See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the - dictionaries returned by this method. - - @param error If accessing the accounts fails, upon return contains an error that describes the problem. - - @return An array of dictionaries containing the Keychain's accounts, or `nil` if the Keychain doesn't have any - accounts. The order of the objects in the array isn't defined. - - @see allAccounts - */ -+ (NSArray *)allAccounts:(NSError **)error; - -/** - Returns an array containing the Keychain's accounts for a given service, or `nil` if the Keychain doesn't have any - accounts for the given service. - - See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the - dictionaries returned by this method. - - @param serviceName The service for which to return the corresponding accounts. - - @return An array of dictionaries containing the Keychain's accountsfor a given `serviceName`, or `nil` if the Keychain - doesn't have any accounts for the given `serviceName`. The order of the objects in the array isn't defined. - - @see accountsForService:error: - */ -+ (NSArray *)accountsForService:(NSString *)serviceName; - -/** - Returns an array containing the Keychain's accounts for a given service, or `nil` if the Keychain doesn't have any - accounts for the given service. - - @param serviceName The service for which to return the corresponding accounts. - - @param error If accessing the accounts fails, upon return contains an error that describes the problem. - - @return An array of dictionaries containing the Keychain's accountsfor a given `serviceName`, or `nil` if the Keychain - doesn't have any accounts for the given `serviceName`. The order of the objects in the array isn't defined. - - @see accountsForService: - */ -+ (NSArray *)accountsForService:(NSString *)serviceName error:(NSError **)error; - - -///------------------------ -/// @name Getting Passwords -///------------------------ - -/** - Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't have a - password for the given parameters. - - @param serviceName The service for which to return the corresponding password. - - @param account The account for which to return the corresponding password. - - @return Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't - have a password for the given parameters. - - @see passwordForService:account:error: - */ -+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account; - -/** - Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't have a - password for the given parameters. - - @param serviceName The service for which to return the corresponding password. - - @param account The account for which to return the corresponding password. - - @param error If accessing the password fails, upon return contains an error that describes the problem. - - @return Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't - have a password for the given parameters. - - @see passwordForService:account: - */ -+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - -/** - Returns the password data for a given account and service, or `nil` if the Keychain doesn't have data - for the given parameters. - - @param serviceName The service for which to return the corresponding password. - - @param account The account for which to return the corresponding password. - - @param error If accessing the password fails, upon return contains an error that describes the problem. - - @return Returns a the password data for the given account and service, or `nil` if the Keychain doesn't - have data for the given parameters. - - @see passwordDataForService:account:error: - */ -+ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account; - -/** - Returns the password data for a given account and service, or `nil` if the Keychain doesn't have data - for the given parameters. - - @param serviceName The service for which to return the corresponding password. - - @param account The account for which to return the corresponding password. - - @param error If accessing the password fails, upon return contains an error that describes the problem. - - @return Returns a the password data for the given account and service, or `nil` if the Keychain doesn't - have a password for the given parameters. - - @see passwordDataForService:account: - */ -+ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - - -///------------------------- -/// @name Deleting Passwords -///------------------------- - -/** - Deletes a password from the Keychain. - - @param serviceName The service for which to delete the corresponding password. - - @param account The account for which to delete the corresponding password. - - @return Returns `YES` on success, or `NO` on failure. - - @see deletePasswordForService:account:error: - */ -+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account; - -/** - Deletes a password from the Keychain. - - @param serviceName The service for which to delete the corresponding password. - - @param account The account for which to delete the corresponding password. - - @param error If deleting the password fails, upon return contains an error that describes the problem. - - @return Returns `YES` on success, or `NO` on failure. - - @see deletePasswordForService:account: - */ -+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - - -///------------------------ -/// @name Setting Passwords -///------------------------ - -/** - Sets a password in the Keychain. - - @param password The password to store in the Keychain. - - @param serviceName The service for which to set the corresponding password. - - @param account The account for which to set the corresponding password. - - @return Returns `YES` on success, or `NO` on failure. - - @see setPassword:forService:account:error: - */ -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account; - -/** - Sets a password in the Keychain. - - @param password The password to store in the Keychain. - - @param serviceName The service for which to set the corresponding password. - - @param account The account for which to set the corresponding password. - - @param error If setting the password fails, upon return contains an error that describes the problem. - - @return Returns `YES` on success, or `NO` on failure. - - @see setPassword:forService:account: - */ -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - -/** - Sets arbirary data in the Keychain. - - @param password The data to store in the Keychain. - - @param serviceName The service for which to set the corresponding password. - - @param account The account for which to set the corresponding password. - - @param error If setting the password fails, upon return contains an error that describes the problem. - - @return Returns `YES` on success, or `NO` on failure. - - @see setPasswordData:forService:account:error: - */ -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account; - -/** - Sets arbirary data in the Keychain. - - @param password The data to store in the Keychain. - - @param serviceName The service for which to set the corresponding password. - - @param account The account for which to set the corresponding password. - - @param error If setting the password fails, upon return contains an error that describes the problem. - - @return Returns `YES` on success, or `NO` on failure. - - @see setPasswordData:forService:account: - */ -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - - -///-------------------- -/// @name Configuration -///-------------------- - -#if __IPHONE_4_0 && TARGET_OS_IPHONE -/** - Returns the accessibility type for all future passwords saved to the Keychain. - - @return Returns the accessibility type. - - The return value will be `NULL` or one of the "Keychain Item Accessibility Constants" used for determining when a - keychain item should be readable. - - @see accessibilityType - */ -+ (CFTypeRef)accessibilityType; - -/** - Sets the accessibility type for all future passwords saved to the Keychain. - - @param accessibilityType One of the "Keychain Item Accessibility Constants" used for determining when a keychain item - should be readable. - - If the value is `NULL` (the default), the Keychain default will be used. - - @see accessibilityType - */ -+ (void)setAccessibilityType:(CFTypeRef)accessibilityType; -#endif - -@end diff --git a/Classes_cocos/SSKeychain.m b/Classes_cocos/SSKeychain.m deleted file mode 100644 index e0b0111..0000000 --- a/Classes_cocos/SSKeychain.m +++ /dev/null @@ -1,262 +0,0 @@ -// -// SSKeychain.m -// SSToolkit -// -// Created by Sam Soffes on 5/19/10. -// Copyright (c) 2009-2011 Sam Soffes. All rights reserved. -// - -#import "SSKeychain.h" - -NSString *const kSSKeychainErrorDomain = @"com.samsoffes.sskeychain"; - -NSString *const kSSKeychainAccountKey = @"acct"; -NSString *const kSSKeychainCreatedAtKey = @"cdat"; -NSString *const kSSKeychainClassKey = @"labl"; -NSString *const kSSKeychainDescriptionKey = @"desc"; -NSString *const kSSKeychainLabelKey = @"labl"; -NSString *const kSSKeychainLastModifiedKey = @"mdat"; -NSString *const kSSKeychainWhereKey = @"svce"; - -#if __IPHONE_4_0 && TARGET_OS_IPHONE -CFTypeRef SSKeychainAccessibilityType = NULL; -#endif - -@interface SSKeychain () -+ (NSMutableDictionary *)_queryForService:(NSString *)service account:(NSString *)account; -@end - -@implementation SSKeychain - -#pragma mark - Getting Accounts - -+ (NSArray *)allAccounts { - return [self accountsForService:nil error:nil]; -} - - -+ (NSArray *)allAccounts:(NSError **)error { - return [self accountsForService:nil error:error]; -} - - -+ (NSArray *)accountsForService:(NSString *)service { - return [self accountsForService:service error:nil]; -} - - -+ (NSArray *)accountsForService:(NSString *)service error:(NSError **)error { - OSStatus status = SSKeychainErrorBadArguments; - NSMutableDictionary *query = [self _queryForService:service account:nil]; -#if __has_feature(objc_arc) - [query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes]; - [query setObject:(__bridge id)kSecMatchLimitAll forKey:(__bridge id)kSecMatchLimit]; -#else - [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes]; - [query setObject:(id)kSecMatchLimitAll forKey:(id)kSecMatchLimit]; -#endif - - CFTypeRef result = NULL; -#if __has_feature(objc_arc) - status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); -#else - status = SecItemCopyMatching((CFDictionaryRef)query, &result); -#endif - if (status != noErr && error != NULL) { - *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil]; - return nil; - } - -#if __has_feature(objc_arc) - return (__bridge_transfer NSArray *)result; -#else - return [(NSArray *)result autorelease]; -#endif -} - - -#pragma mark - Getting Passwords - -+ (NSString *)passwordForService:(NSString *)service account:(NSString *)account { - return [self passwordForService:service account:account error:nil]; -} - - -+ (NSString *)passwordForService:(NSString *)service account:(NSString *)account error:(NSError **)error { - NSData *data = [self passwordDataForService:service account:account error:error]; - if (data.length > 0) { - NSString *string = [[NSString alloc] initWithData:(NSData *)data encoding:NSUTF8StringEncoding]; -#if !__has_feature(objc_arc) - [string autorelease]; -#endif - return string; - } - - return nil; -} - - -+ (NSData *)passwordDataForService:(NSString *)service account:(NSString *)account { - return [self passwordDataForService:service account:account error:nil]; -} - - -+ (NSData *)passwordDataForService:(NSString *)service account:(NSString *)account error:(NSError **)error { - OSStatus status = SSKeychainErrorBadArguments; - if (!service || !account) { - if (error) { - *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil]; - } - return nil; - } - - CFTypeRef result = NULL; - NSMutableDictionary *query = [self _queryForService:service account:account]; -#if __has_feature(objc_arc) - [query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; - [query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; - status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); -#else - [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; - [query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; - status = SecItemCopyMatching((CFDictionaryRef)query, &result); -#endif - - if (status != noErr && error != NULL) { - *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil]; - return nil; - } - -#if __has_feature(objc_arc) - return (__bridge_transfer NSData *)result; -#else - return [(NSData *)result autorelease]; -#endif -} - - -#pragma mark - Deleting Passwords - -+ (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account { - return [self deletePasswordForService:service account:account error:nil]; -} - - -+ (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account error:(NSError **)error { - OSStatus status = SSKeychainErrorBadArguments; - if (service && account) { - NSMutableDictionary *query = [self _queryForService:service account:account]; -#if __has_feature(objc_arc) - status = SecItemDelete((__bridge CFDictionaryRef)query); -#else - status = SecItemDelete((CFDictionaryRef)query); -#endif - } - if (status != noErr && error != NULL) { - *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil]; - } - return (status == noErr); - -} - - -#pragma mark - Setting Passwords - -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account { - return [self setPassword:password forService:service account:account error:nil]; -} - - -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account error:(NSError **)error { - NSData *data = [password dataUsingEncoding:NSUTF8StringEncoding]; - return [self setPasswordData:data forService:service account:account error:error]; -} - - -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)service account:(NSString *)account { - return [self setPasswordData:password forService:service account:account error:nil]; -} - - -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)service account:(NSString *)account error:(NSError **)error { - OSStatus status = SSKeychainErrorBadArguments; - if (password && service && account) { - [self deletePasswordForService:service account:account]; - NSMutableDictionary *query = [self _queryForService:service account:account]; -#if __has_feature(objc_arc) - [query setObject:password forKey:(__bridge id)kSecValueData]; -#else - [query setObject:password forKey:(id)kSecValueData]; -#endif - -#if __IPHONE_4_0 && TARGET_OS_IPHONE - if (SSKeychainAccessibilityType) { -#if __has_feature(objc_arc) - [query setObject:(id)[self accessibilityType] forKey:(__bridge id)kSecAttrAccessible]; -#else - [query setObject:(id)[self accessibilityType] forKey:(id)kSecAttrAccessible]; -#endif - } -#endif - -#if __has_feature(objc_arc) - status = SecItemAdd((__bridge CFDictionaryRef)query, NULL); -#else - status = SecItemAdd((CFDictionaryRef)query, NULL); -#endif - } - if (status != noErr && error != NULL) { - *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil]; - } - return (status == noErr); -} - - -#pragma mark - Configuration - -#if __IPHONE_4_0 && TARGET_OS_IPHONE -+ (CFTypeRef)accessibilityType { - return SSKeychainAccessibilityType; -} - - -+ (void)setAccessibilityType:(CFTypeRef)accessibilityType { - CFRetain(accessibilityType); - if (SSKeychainAccessibilityType) { - CFRelease(SSKeychainAccessibilityType); - } - SSKeychainAccessibilityType = accessibilityType; -} -#endif - - -#pragma mark - Private - -+ (NSMutableDictionary *)_queryForService:(NSString *)service account:(NSString *)account { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:3]; -#if __has_feature(objc_arc) - [dictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; -#else - [dictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass]; -#endif - - if (service) { -#if __has_feature(objc_arc) - [dictionary setObject:service forKey:(__bridge id)kSecAttrService]; -#else - [dictionary setObject:service forKey:(id)kSecAttrService]; -#endif - } - - if (account) { -#if __has_feature(objc_arc) - [dictionary setObject:account forKey:(__bridge id)kSecAttrAccount]; -#else - [dictionary setObject:account forKey:(id)kSecAttrAccount]; -#endif - } - - return dictionary; -} - -@end diff --git a/Classes_cocos/UICKeyChainStore.h b/Classes_cocos/UICKeyChainStore.h new file mode 100644 index 0000000..095720a --- /dev/null +++ b/Classes_cocos/UICKeyChainStore.h @@ -0,0 +1,289 @@ +// +// UICKeyChainStore.h +// UICKeyChainStore +// +// Created by Kishikawa Katsumi on 11/11/20. +// Copyright (c) 2011 Kishikawa Katsumi. All rights reserved. +// + +#import + +#if !__has_feature(nullability) +#define NS_ASSUME_NONNULL_BEGIN +#define NS_ASSUME_NONNULL_END +#define nullable +#define nonnull +#define null_unspecified +#define null_resettable +#define __nullable +#define __nonnull +#define __null_unspecified +#endif + +#if __has_extension(objc_generics) +#define UIC_KEY_TYPE +#define UIC_CREDENTIAL_TYPE *> +#else +#define UIC_KEY_TYPE +#define UIC_CREDENTIAL_TYPE +#endif + +NS_ASSUME_NONNULL_BEGIN + +extern NSString * const UICKeyChainStoreErrorDomain; + +typedef NS_ENUM(NSInteger, UICKeyChainStoreErrorCode) { + UICKeyChainStoreErrorInvalidArguments = 1, +}; + +typedef NS_ENUM(NSInteger, UICKeyChainStoreItemClass) { + UICKeyChainStoreItemClassGenericPassword = 1, + UICKeyChainStoreItemClassInternetPassword, +}; + +typedef NS_ENUM(NSInteger, UICKeyChainStoreProtocolType) { + UICKeyChainStoreProtocolTypeFTP = 1, + UICKeyChainStoreProtocolTypeFTPAccount, + UICKeyChainStoreProtocolTypeHTTP, + UICKeyChainStoreProtocolTypeIRC, + UICKeyChainStoreProtocolTypeNNTP, + UICKeyChainStoreProtocolTypePOP3, + UICKeyChainStoreProtocolTypeSMTP, + UICKeyChainStoreProtocolTypeSOCKS, + UICKeyChainStoreProtocolTypeIMAP, + UICKeyChainStoreProtocolTypeLDAP, + UICKeyChainStoreProtocolTypeAppleTalk, + UICKeyChainStoreProtocolTypeAFP, + UICKeyChainStoreProtocolTypeTelnet, + UICKeyChainStoreProtocolTypeSSH, + UICKeyChainStoreProtocolTypeFTPS, + UICKeyChainStoreProtocolTypeHTTPS, + UICKeyChainStoreProtocolTypeHTTPProxy, + UICKeyChainStoreProtocolTypeHTTPSProxy, + UICKeyChainStoreProtocolTypeFTPProxy, + UICKeyChainStoreProtocolTypeSMB, + UICKeyChainStoreProtocolTypeRTSP, + UICKeyChainStoreProtocolTypeRTSPProxy, + UICKeyChainStoreProtocolTypeDAAP, + UICKeyChainStoreProtocolTypeEPPC, + UICKeyChainStoreProtocolTypeNNTPS, + UICKeyChainStoreProtocolTypeLDAPS, + UICKeyChainStoreProtocolTypeTelnetS, + UICKeyChainStoreProtocolTypeIRCS, + UICKeyChainStoreProtocolTypePOP3S, +}; + +typedef NS_ENUM(NSInteger, UICKeyChainStoreAuthenticationType) { + UICKeyChainStoreAuthenticationTypeNTLM = 1, + UICKeyChainStoreAuthenticationTypeMSN, + UICKeyChainStoreAuthenticationTypeDPA, + UICKeyChainStoreAuthenticationTypeRPA, + UICKeyChainStoreAuthenticationTypeHTTPBasic, + UICKeyChainStoreAuthenticationTypeHTTPDigest, + UICKeyChainStoreAuthenticationTypeHTMLForm, + UICKeyChainStoreAuthenticationTypeDefault, +}; + +typedef NS_ENUM(NSInteger, UICKeyChainStoreAccessibility) { + UICKeyChainStoreAccessibilityWhenUnlocked = 1, + UICKeyChainStoreAccessibilityAfterFirstUnlock, + UICKeyChainStoreAccessibilityAlways, + UICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly + __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0), + UICKeyChainStoreAccessibilityWhenUnlockedThisDeviceOnly, + UICKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly, + UICKeyChainStoreAccessibilityAlwaysThisDeviceOnly, +} +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0); + +typedef NS_ENUM(unsigned long, UICKeyChainStoreAuthenticationPolicy) { + UICKeyChainStoreAuthenticationPolicyUserPresence = 1 << 0, + UICKeyChainStoreAuthenticationPolicyTouchIDAny NS_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 1, + UICKeyChainStoreAuthenticationPolicyTouchIDCurrentSet NS_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 3, + UICKeyChainStoreAuthenticationPolicyDevicePasscode NS_ENUM_AVAILABLE(10_11, 9_0) = 1u << 4, + UICKeyChainStoreAuthenticationPolicyControlOr NS_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 14, + UICKeyChainStoreAuthenticationPolicyControlAnd NS_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 15, + UICKeyChainStoreAuthenticationPolicyPrivateKeyUsage NS_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 30, + UICKeyChainStoreAuthenticationPolicyApplicationPassword NS_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 31, +}__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); + +@interface UICKeyChainStore : NSObject + +@property (nonatomic, readonly) UICKeyChainStoreItemClass itemClass; + +@property (nonatomic, readonly, nullable) NSString *service; +@property (nonatomic, readonly, nullable) NSString *accessGroup; + +@property (nonatomic, readonly, nullable) NSURL *server; +@property (nonatomic, readonly) UICKeyChainStoreProtocolType protocolType; +@property (nonatomic, readonly) UICKeyChainStoreAuthenticationType authenticationType; + +@property (nonatomic) UICKeyChainStoreAccessibility accessibility; +@property (nonatomic, readonly) UICKeyChainStoreAuthenticationPolicy authenticationPolicy +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); +@property (nonatomic) BOOL useAuthenticationUI; + +@property (nonatomic) BOOL synchronizable; + +@property (nonatomic, nullable) NSString *authenticationPrompt +__OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0); + +@property (nonatomic, readonly, nullable) NSArray UIC_KEY_TYPE *allKeys; +@property (nonatomic, readonly, nullable) NSArray *allItems; + ++ (NSString *)defaultService; ++ (void)setDefaultService:(NSString *)defaultService; + ++ (UICKeyChainStore *)keyChainStore; ++ (UICKeyChainStore *)keyChainStoreWithService:(nullable NSString *)service; ++ (UICKeyChainStore *)keyChainStoreWithService:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; + ++ (UICKeyChainStore *)keyChainStoreWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType; ++ (UICKeyChainStore *)keyChainStoreWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType authenticationType:(UICKeyChainStoreAuthenticationType)authenticationType; + +- (instancetype)init; +- (instancetype)initWithService:(nullable NSString *)service; +- (instancetype)initWithService:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; + +- (instancetype)initWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType; +- (instancetype)initWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType authenticationType:(UICKeyChainStoreAuthenticationType)authenticationType; + ++ (nullable NSString *)stringForKey:(NSString *)key; ++ (nullable NSString *)stringForKey:(NSString *)key service:(nullable NSString *)service; ++ (nullable NSString *)stringForKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; + ++ (nullable NSData *)dataForKey:(NSString *)key; ++ (nullable NSData *)dataForKey:(NSString *)key service:(nullable NSString *)service; ++ (nullable NSData *)dataForKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; + +- (BOOL)contains:(nullable NSString *)key; + +- (BOOL)setString:(nullable NSString *)string forKey:(nullable NSString *)key; +- (BOOL)setString:(nullable NSString *)string forKey:(nullable NSString *)key label:(nullable NSString *)label comment:(nullable NSString *)comment; +- (nullable NSString *)stringForKey:(NSString *)key; + +- (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key; +- (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key label:(nullable NSString *)label comment:(nullable NSString *)comment; +- (nullable NSData *)dataForKey:(NSString *)key; + ++ (BOOL)removeItemForKey:(NSString *)key; ++ (BOOL)removeItemForKey:(NSString *)key service:(nullable NSString *)service; ++ (BOOL)removeItemForKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; + ++ (BOOL)removeAllItems; ++ (BOOL)removeAllItemsForService:(nullable NSString *)service; ++ (BOOL)removeAllItemsForService:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; + +- (BOOL)removeItemForKey:(NSString *)key; + +- (BOOL)removeAllItems; + +- (nullable NSString *)objectForKeyedSubscript:(NSString *)key; +- (void)setObject:(nullable NSString *)obj forKeyedSubscript:(NSString *)key; + ++ (nullable NSArray UIC_KEY_TYPE *)allKeysWithItemClass:(UICKeyChainStoreItemClass)itemClass; +- (nullable NSArray UIC_KEY_TYPE *)allKeys; + ++ (nullable NSArray *)allItemsWithItemClass:(UICKeyChainStoreItemClass)itemClass; +- (nullable NSArray *)allItems; + +- (void)setAccessibility:(UICKeyChainStoreAccessibility)accessibility authenticationPolicy:(UICKeyChainStoreAuthenticationPolicy)authenticationPolicy +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); + +#if TARGET_OS_IOS +- (void)sharedPasswordWithCompletion:(nullable void (^)(NSString * __nullable account, NSString * __nullable password, NSError * __nullable error))completion; +- (void)sharedPasswordForAccount:(NSString *)account completion:(nullable void (^)(NSString * __nullable password, NSError * __nullable error))completion; + +- (void)setSharedPassword:(nullable NSString *)password forAccount:(NSString *)account completion:(nullable void (^)(NSError * __nullable error))completion; +- (void)removeSharedPasswordForAccount:(NSString *)account completion:(nullable void (^)(NSError * __nullable error))completion; + ++ (void)requestSharedWebCredentialWithCompletion:(nullable void (^)(NSArray UIC_CREDENTIAL_TYPE *credentials, NSError * __nullable error))completion; ++ (void)requestSharedWebCredentialForDomain:(nullable NSString *)domain account:(nullable NSString *)account completion:(nullable void (^)(NSArray UIC_CREDENTIAL_TYPE *credentials, NSError * __nullable error))completion; + ++ (NSString *)generatePassword; +#endif + +@end + +@interface UICKeyChainStore (ErrorHandling) + ++ (nullable NSString *)stringForKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (nullable NSString *)stringForKey:(NSString *)key service:(nullable NSString *)service error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (nullable NSString *)stringForKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (nullable NSData *)dataForKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (nullable NSData *)dataForKey:(NSString *)key service:(nullable NSString *)service error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (nullable NSData *)dataForKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup error:(NSError * __nullable __autoreleasing * __nullable)error; + +- (BOOL)setString:(nullable NSString *)string forKey:(NSString * )key error:(NSError * __nullable __autoreleasing * __nullable)error; +- (BOOL)setString:(nullable NSString *)string forKey:(NSString * )key label:(nullable NSString *)label comment:(nullable NSString *)comment error:(NSError * __nullable __autoreleasing * __nullable)error; + +- (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; +- (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key label:(nullable NSString *)label comment:(nullable NSString *)comment error:(NSError * __nullable __autoreleasing * __nullable)error; + +- (nullable NSString *)stringForKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; +- (nullable NSData *)dataForKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)removeItemForKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)removeItemForKey:(NSString *)key service:(nullable NSString *)service error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)removeItemForKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)removeAllItemsWithError:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)removeAllItemsForService:(nullable NSString *)service error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)removeAllItemsForService:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup error:(NSError * __nullable __autoreleasing * __nullable)error; + +- (BOOL)removeItemForKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; +- (BOOL)removeAllItemsWithError:(NSError * __nullable __autoreleasing * __nullable)error; + +@end + +@interface UICKeyChainStore (ForwardCompatibility) + ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service genericAttribute:(nullable id)genericAttribute; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup genericAttribute:(nullable id)genericAttribute; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service genericAttribute:(nullable id)genericAttribute; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup genericAttribute:(nullable id)genericAttribute; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + +- (BOOL)setString:(nullable NSString *)string forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute; +- (BOOL)setString:(nullable NSString *)string forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + +- (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute; +- (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + +@end + +@interface UICKeyChainStore (Deprecation) + +- (void)synchronize __attribute__((deprecated("calling this method is no longer required"))); +- (BOOL)synchronizeWithError:(NSError * __nullable __autoreleasing * __nullable)error __attribute__((deprecated("calling this method is no longer required"))); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Classes_cocos/UICKeyChainStore.m b/Classes_cocos/UICKeyChainStore.m new file mode 100644 index 0000000..413de04 --- /dev/null +++ b/Classes_cocos/UICKeyChainStore.m @@ -0,0 +1,1407 @@ +// +// UICKeyChainStore.m +// UICKeyChainStore +// +// Created by Kishikawa Katsumi on 11/11/20. +// Copyright (c) 2011 Kishikawa Katsumi. All rights reserved. +// + +#import "UICKeyChainStore.h" + +NSString * const UICKeyChainStoreErrorDomain = @"com.kishikawakatsumi.uickeychainstore"; +static NSString *_defaultService; + +@interface UICKeyChainStore () + +@end + +@implementation UICKeyChainStore + ++ (NSString *)defaultService +{ + if (!_defaultService) { + _defaultService = [[NSBundle mainBundle] bundleIdentifier] ?: @""; + } + + return _defaultService; +} + ++ (void)setDefaultService:(NSString *)defaultService +{ + _defaultService = defaultService; +} + +#pragma mark - + ++ (UICKeyChainStore *)keyChainStore +{ + return [[self alloc] initWithService:nil accessGroup:nil]; +} + ++ (UICKeyChainStore *)keyChainStoreWithService:(NSString *)service +{ + return [[self alloc] initWithService:service accessGroup:nil]; +} + ++ (UICKeyChainStore *)keyChainStoreWithService:(NSString *)service accessGroup:(NSString *)accessGroup +{ + return [[self alloc] initWithService:service accessGroup:accessGroup]; +} + +#pragma mark - + ++ (UICKeyChainStore *)keyChainStoreWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType +{ + return [[self alloc] initWithServer:server protocolType:protocolType authenticationType:UICKeyChainStoreAuthenticationTypeDefault]; +} + ++ (UICKeyChainStore *)keyChainStoreWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType authenticationType:(UICKeyChainStoreAuthenticationType)authenticationType +{ + return [[self alloc] initWithServer:server protocolType:protocolType authenticationType:authenticationType]; +} + +#pragma mark - + +- (instancetype)init +{ + return [self initWithService:[self.class defaultService] accessGroup:nil]; +} + +- (instancetype)initWithService:(NSString *)service +{ + return [self initWithService:service accessGroup:nil]; +} + +- (instancetype)initWithService:(NSString *)service accessGroup:(NSString *)accessGroup +{ + self = [super init]; + if (self) { + _itemClass = UICKeyChainStoreItemClassGenericPassword; + + if (!service) { + service = [self.class defaultService]; + } + _service = service.copy; + _accessGroup = accessGroup.copy; + [self commonInit]; + } + + return self; +} + +#pragma mark - + +- (instancetype)initWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType +{ + return [self initWithServer:server protocolType:protocolType authenticationType:UICKeyChainStoreAuthenticationTypeDefault]; +} + +- (instancetype)initWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType authenticationType:(UICKeyChainStoreAuthenticationType)authenticationType +{ + self = [super init]; + if (self) { + _itemClass = UICKeyChainStoreItemClassInternetPassword; + + _server = server.copy; + _protocolType = protocolType; + _authenticationType = authenticationType; + + [self commonInit]; + } + + return self; +} + +#pragma mark - + +- (void)commonInit +{ + _accessibility = UICKeyChainStoreAccessibilityAfterFirstUnlock; + _useAuthenticationUI = YES; +} + +#pragma mark - + ++ (NSString *)stringForKey:(NSString *)key +{ + return [self stringForKey:key service:nil accessGroup:nil error:nil]; +} + ++ (NSString *)stringForKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + return [self stringForKey:key service:nil accessGroup:nil error:error]; +} + ++ (NSString *)stringForKey:(NSString *)key service:(NSString *)service +{ + return [self stringForKey:key service:service accessGroup:nil error:nil]; +} + ++ (NSString *)stringForKey:(NSString *)key service:(NSString *)service error:(NSError *__autoreleasing *)error +{ + return [self stringForKey:key service:service accessGroup:nil error:error]; +} + ++ (NSString *)stringForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup +{ + return [self stringForKey:key service:service accessGroup:accessGroup error:nil]; +} + ++ (NSString *)stringForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup error:(NSError *__autoreleasing *)error +{ + if (!key) { + NSError *e = [self argumentError:NSLocalizedString(@"the key must not to be nil", nil)]; + if (error) { + *error = e; + } + return nil; + } + if (!service) { + service = [self defaultService]; + } + + UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:service accessGroup:accessGroup]; + return [keychain stringForKey:key error:error]; +} + +#pragma mark - + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key +{ + return [self setString:value forKey:key service:nil accessGroup:nil genericAttribute:nil error:nil]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + return [self setString:value forKey:key service:nil accessGroup:nil genericAttribute:nil error:error]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key genericAttribute:(id)genericAttribute +{ + return [self setString:value forKey:key service:nil accessGroup:nil genericAttribute:genericAttribute error:nil]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + return [self setString:value forKey:key service:nil accessGroup:nil genericAttribute:genericAttribute error:error]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service +{ + return [self setString:value forKey:key service:service accessGroup:nil genericAttribute:nil error:nil]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service error:(NSError *__autoreleasing *)error +{ + return [self setString:value forKey:key service:service accessGroup:nil genericAttribute:nil error:error]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service genericAttribute:(id)genericAttribute +{ + return [self setString:value forKey:key service:service accessGroup:nil genericAttribute:genericAttribute error:nil]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + return [self setString:value forKey:key service:service accessGroup:nil genericAttribute:genericAttribute error:error]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup +{ + return [self setString:value forKey:key service:service accessGroup:accessGroup genericAttribute:nil error:nil]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup error:(NSError *__autoreleasing *)error +{ + return [self setString:value forKey:key service:service accessGroup:accessGroup genericAttribute:nil error:error]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup genericAttribute:(id)genericAttribute +{ + return [self setString:value forKey:key service:service accessGroup:accessGroup genericAttribute:genericAttribute error:nil]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + if (!value) { + return [self removeItemForKey:key service:service accessGroup:accessGroup error:error]; + } + NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding]; + if (data) { + return [self setData:data forKey:key service:service accessGroup:accessGroup genericAttribute:genericAttribute error:error]; + } + NSError *e = [self conversionError:NSLocalizedString(@"failed to convert string to data", nil)]; + if (error) { + *error = e; + } + return NO; +} + +#pragma mark - + ++ (NSData *)dataForKey:(NSString *)key +{ + return [self dataForKey:key service:nil accessGroup:nil error:nil]; +} + ++ (NSData *)dataForKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + return [self dataForKey:key service:nil accessGroup:nil error:error]; +} + ++ (NSData *)dataForKey:(NSString *)key service:(NSString *)service +{ + return [self dataForKey:key service:service accessGroup:nil error:nil]; +} + ++ (NSData *)dataForKey:(NSString *)key service:(NSString *)service error:(NSError *__autoreleasing *)error +{ + return [self dataForKey:key service:service accessGroup:nil error:error]; +} + ++ (NSData *)dataForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup +{ + return [self dataForKey:key service:service accessGroup:accessGroup error:nil]; +} + ++ (NSData *)dataForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup error:(NSError *__autoreleasing *)error +{ + if (!key) { + NSError *e = [self argumentError:NSLocalizedString(@"the key must not to be nil", nil)]; + if (error) { + *error = e; + } + return nil; + } + if (!service) { + service = [self defaultService]; + } + + UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:service accessGroup:accessGroup]; + return [keychain dataForKey:key error:error]; +} + +#pragma mark - + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key +{ + return [self setData:data forKey:key service:nil accessGroup:nil genericAttribute:nil error:nil]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + return [self setData:data forKey:key service:nil accessGroup:nil genericAttribute:nil error:error]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key genericAttribute:(id)genericAttribute +{ + return [self setData:data forKey:key service:nil accessGroup:nil genericAttribute:genericAttribute error:nil]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + return [self setData:data forKey:key service:nil accessGroup:nil genericAttribute:genericAttribute error:error]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service +{ + return [self setData:data forKey:key service:service accessGroup:nil genericAttribute:nil error:nil]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service error:(NSError *__autoreleasing *)error +{ + return [self setData:data forKey:key service:service accessGroup:nil genericAttribute:nil error:error]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service genericAttribute:(id)genericAttribute +{ + return [self setData:data forKey:key service:service accessGroup:nil genericAttribute:genericAttribute error:nil]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + return [self setData:data forKey:key service:service accessGroup:nil genericAttribute:genericAttribute error:error]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup +{ + return [self setData:data forKey:key service:service accessGroup:accessGroup genericAttribute:nil error:nil]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup error:(NSError *__autoreleasing *)error +{ + return [self setData:data forKey:key service:service accessGroup:accessGroup genericAttribute:nil error:error]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup genericAttribute:(id)genericAttribute +{ + return [self setData:data forKey:key service:service accessGroup:accessGroup genericAttribute:genericAttribute error:nil]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + if (!key) { + NSError *e = [self argumentError:NSLocalizedString(@"the key must not to be nil", nil)]; + if (error) { + *error = e; + } + return NO; + } + if (!service) { + service = [self defaultService]; + } + + UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:service accessGroup:accessGroup]; + return [keychain setData:data forKey:key genericAttribute:genericAttribute]; +} + +#pragma mark - + +- (BOOL)contains:(NSString *)key +{ + NSMutableDictionary *query = [self query]; + query[(__bridge __strong id)kSecAttrAccount] = key; + + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL); + return status == errSecSuccess || status == errSecInteractionNotAllowed; +} + +#pragma mark - + +- (NSString *)stringForKey:(id)key +{ + return [self stringForKey:key error:nil]; +} + +- (NSString *)stringForKey:(id)key error:(NSError *__autoreleasing *)error +{ + NSData *data = [self dataForKey:key error:error]; + if (data) { + NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + if (string) { + return string; + } + NSError *e = [self.class conversionError:NSLocalizedString(@"failed to convert data to string", nil)]; + if (error) { + *error = e; + } + return nil; + } + + return nil; +} + +#pragma mark - + +- (BOOL)setString:(NSString *)string forKey:(NSString *)key +{ + return [self setString:string forKey:key genericAttribute:nil label:nil comment:nil error:nil]; +} + +- (BOOL)setString:(NSString *)string forKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + return [self setString:string forKey:key genericAttribute:nil label:nil comment:nil error:error]; +} + +- (BOOL)setString:(NSString *)string forKey:(NSString *)key genericAttribute:(id)genericAttribute +{ + return [self setString:string forKey:key genericAttribute:genericAttribute label:nil comment:nil error:nil]; +} + +- (BOOL)setString:(NSString *)string forKey:(NSString *)key genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + return [self setString:string forKey:key genericAttribute:genericAttribute label:nil comment:nil error:error]; +} + +- (BOOL)setString:(NSString *)string forKey:(NSString *)key label:(NSString *)label comment:(NSString *)comment +{ + return [self setString:string forKey:key genericAttribute:nil label:label comment:comment error:nil]; +} + +- (BOOL)setString:(NSString *)string forKey:(NSString *)key label:(NSString *)label comment:(NSString *)comment error:(NSError *__autoreleasing *)error +{ + return [self setString:string forKey:key genericAttribute:nil label:label comment:comment error:error]; +} + +- (BOOL)setString:(NSString *)string forKey:(NSString *)key genericAttribute:(id)genericAttribute label:(NSString *)label comment:(NSString *)comment error:(NSError *__autoreleasing *)error +{ + if (!string) { + return [self removeItemForKey:key error:error]; + } + NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; + if (data) { + return [self setData:data forKey:key genericAttribute:genericAttribute label:label comment:comment error:error]; + } + NSError *e = [self.class conversionError:NSLocalizedString(@"failed to convert string to data", nil)]; + if (error) { + *error = e; + } + return NO; +} + +#pragma mark - + +- (NSData *)dataForKey:(NSString *)key +{ + return [self dataForKey:key error:nil]; +} + +- (NSData *)dataForKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + NSMutableDictionary *query = [self query]; + query[(__bridge __strong id)kSecMatchLimit] = (__bridge id)kSecMatchLimitOne; + query[(__bridge __strong id)kSecReturnData] = (__bridge id)kCFBooleanTrue; + + query[(__bridge __strong id)kSecAttrAccount] = key; + + CFTypeRef data = nil; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &data); + + if (status == errSecSuccess) { + NSData *ret = [NSData dataWithData:(__bridge NSData *)data]; + if (data) { + CFRelease(data); + return ret; + } else { + NSError *e = [self.class unexpectedError:NSLocalizedString(@"Unexpected error has occurred.", nil)]; + if (error) { + *error = e; + } + return nil; + } + } else if (status == errSecItemNotFound) { + return nil; + } + + NSError *e = [self.class securityError:status]; + if (error) { + *error = e; + } + return nil; +} + +#pragma mark - + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key +{ + return [self setData:data forKey:key genericAttribute:nil label:nil comment:nil error:nil]; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + return [self setData:data forKey:key genericAttribute:nil label:nil comment:nil error:error]; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key genericAttribute:(id)genericAttribute +{ + return [self setData:data forKey:key genericAttribute:genericAttribute label:nil comment:nil error:nil]; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + return [self setData:data forKey:key genericAttribute:genericAttribute label:nil comment:nil error:error]; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key label:(NSString *)label comment:(NSString *)comment +{ + return [self setData:data forKey:key genericAttribute:nil label:label comment:comment error:nil]; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key label:(NSString *)label comment:(NSString *)comment error:(NSError *__autoreleasing *)error +{ + return [self setData:data forKey:key genericAttribute:nil label:label comment:comment error:error]; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key genericAttribute:(id)genericAttribute label:(NSString *)label comment:(NSString *)comment error:(NSError *__autoreleasing *)error +{ + if (!key) { + NSError *e = [self.class argumentError:NSLocalizedString(@"the key must not to be nil", nil)]; + if (error) { + *error = e; + } + return NO; + } + if (!data) { + return [self removeItemForKey:key error:error]; + } + + NSMutableDictionary *query = [self query]; + query[(__bridge __strong id)kSecAttrAccount] = key; +#if TARGET_OS_IOS + if (floor(NSFoundationVersionNumber) > floor(1144.17)) { // iOS 9+ + query[(__bridge __strong id)kSecUseAuthenticationUI] = (__bridge id)kSecUseAuthenticationUIFail; +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0 + } else if (floor(NSFoundationVersionNumber) > floor(1047.25)) { // iOS 8+ + query[(__bridge __strong id)kSecUseNoAuthenticationUI] = (__bridge id)kCFBooleanTrue; +#endif + } +#elif TARGET_OS_WATCH || TARGET_OS_TV + query[(__bridge __strong id)kSecUseAuthenticationUI] = (__bridge id)kSecUseAuthenticationUIFail; +#endif + + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL); + if (status == errSecSuccess || status == errSecInteractionNotAllowed) { + query = [self query]; + query[(__bridge __strong id)kSecAttrAccount] = key; + + NSError *unexpectedError = nil; + NSMutableDictionary *attributes = [self attributesWithKey:nil value:data error:&unexpectedError]; + + if (genericAttribute) { + attributes[(__bridge __strong id)kSecAttrGeneric] = genericAttribute; + } + if (label) { + attributes[(__bridge __strong id)kSecAttrLabel] = label; + } + if (comment) { + attributes[(__bridge __strong id)kSecAttrComment] = comment; + } + + if (unexpectedError) { + NSLog(@"error: [%@] %@", @(unexpectedError.code), NSLocalizedString(@"Unexpected error has occurred.", nil)); + if (error) { + *error = unexpectedError; + } + return NO; + } else { + + if (status == errSecInteractionNotAllowed && floor(NSFoundationVersionNumber) <= floor(1140.11)) { // iOS 8.0.x + if ([self removeItemForKey:key error:error]) { + return [self setData:data forKey:key label:label comment:comment error:error]; + } + } else { + status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributes); + } + if (status != errSecSuccess) { + NSError *e = [self.class securityError:status]; + if (error) { + *error = e; + } + return NO; + } + } + } else if (status == errSecItemNotFound) { + NSError *unexpectedError = nil; + NSMutableDictionary *attributes = [self attributesWithKey:key value:data error:&unexpectedError]; + + if (genericAttribute) { + attributes[(__bridge __strong id)kSecAttrGeneric] = genericAttribute; + } + if (label) { + attributes[(__bridge __strong id)kSecAttrLabel] = label; + } + if (comment) { + attributes[(__bridge __strong id)kSecAttrComment] = comment; + } + + if (unexpectedError) { + NSLog(@"error: [%@] %@", @(unexpectedError.code), NSLocalizedString(@"Unexpected error has occurred.", nil)); + if (error) { + *error = unexpectedError; + } + return NO; + } else { + status = SecItemAdd((__bridge CFDictionaryRef)attributes, NULL); + if (status != errSecSuccess) { + NSError *e = [self.class securityError:status]; + if (error) { + *error = e; + } + return NO; + } + } + } else { + NSError *e = [self.class securityError:status]; + if (error) { + *error = e; + } + return NO; + } + + return YES; +} + +#pragma mark - + ++ (BOOL)removeItemForKey:(NSString *)key +{ + return [self removeItemForKey:key service:nil accessGroup:nil error:nil]; +} + ++ (BOOL)removeItemForKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + return [self removeItemForKey:key service:nil accessGroup:nil error:error]; +} + ++ (BOOL)removeItemForKey:(NSString *)key service:(NSString *)service +{ + return [self removeItemForKey:key service:service accessGroup:nil error:nil]; +} + ++ (BOOL)removeItemForKey:(NSString *)key service:(NSString *)service error:(NSError *__autoreleasing *)error +{ + return [self removeItemForKey:key service:service accessGroup:nil error:error]; +} + ++ (BOOL)removeItemForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup +{ + return [self removeItemForKey:key service:service accessGroup:accessGroup error:nil]; +} + ++ (BOOL)removeItemForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup error:(NSError *__autoreleasing *)error +{ + if (!key) { + NSError *e = [self.class argumentError:NSLocalizedString(@"the key must not to be nil", nil)]; + if (error) { + *error = e; + } + return NO; + } + if (!service) { + service = [self defaultService]; + } + + UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:service accessGroup:accessGroup]; + return [keychain removeItemForKey:key error:error]; +} + +#pragma mark - + ++ (BOOL)removeAllItems +{ + return [self removeAllItemsForService:nil accessGroup:nil error:nil]; +} + ++ (BOOL)removeAllItemsWithError:(NSError *__autoreleasing *)error +{ + return [self removeAllItemsForService:nil accessGroup:nil error:error]; +} + ++ (BOOL)removeAllItemsForService:(NSString *)service +{ + return [self removeAllItemsForService:service accessGroup:nil error:nil]; +} + ++ (BOOL)removeAllItemsForService:(NSString *)service error:(NSError *__autoreleasing *)error +{ + return [self removeAllItemsForService:service accessGroup:nil error:error]; +} + ++ (BOOL)removeAllItemsForService:(NSString *)service accessGroup:(NSString *)accessGroup +{ + return [self removeAllItemsForService:service accessGroup:accessGroup error:nil]; +} + ++ (BOOL)removeAllItemsForService:(NSString *)service accessGroup:(NSString *)accessGroup error:(NSError *__autoreleasing *)error +{ + UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:service accessGroup:accessGroup]; + return [keychain removeAllItemsWithError:error]; +} + +#pragma mark - + +- (BOOL)removeItemForKey:(NSString *)key +{ + return [self removeItemForKey:key error:nil]; +} + +- (BOOL)removeItemForKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + NSMutableDictionary *query = [self query]; + query[(__bridge __strong id)kSecAttrAccount] = key; + + OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query); + if (status != errSecSuccess && status != errSecItemNotFound) { + NSError *e = [self.class securityError:status]; + if (error) { + *error = e; + } + return NO; + } + + return YES; +} + +#pragma mark - + +- (BOOL)removeAllItems +{ + return [self removeAllItemsWithError:nil]; +} + +- (BOOL)removeAllItemsWithError:(NSError *__autoreleasing *)error +{ + NSMutableDictionary *query = [self query]; +#if !TARGET_OS_IPHONE + query[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll; +#endif + + OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query); + if (status != errSecSuccess && status != errSecItemNotFound) { + NSError *e = [self.class securityError:status]; + if (error) { + *error = e; + } + return NO; + } + + return YES; +} + +#pragma mark - + +- (NSString *)objectForKeyedSubscript:(NSString *)key +{ + return [self stringForKey:key]; +} + +- (void)setObject:(NSString *)obj forKeyedSubscript:(NSString *)key +{ + if (!obj) { + [self removeItemForKey:key]; + } else { + [self setString:obj forKey:key]; + } +} + +#pragma mark - + +- (NSArray UIC_KEY_TYPE *)allKeys +{ + NSArray *items = [self.class prettify:[self itemClassObject] items:[self items]]; + NSMutableArray *keys = [[NSMutableArray alloc] init]; + for (NSDictionary *item in items) { + NSString *key = item[@"key"]; + if (key) { + [keys addObject:key]; + } + } + return keys.copy; +} + ++ (NSArray UIC_KEY_TYPE *)allKeysWithItemClass:(UICKeyChainStoreItemClass)itemClass +{ + CFTypeRef itemClassObject = kSecClassGenericPassword; + if (itemClass == UICKeyChainStoreItemClassGenericPassword) { + itemClassObject = kSecClassGenericPassword; + } else if (itemClass == UICKeyChainStoreItemClassInternetPassword) { + itemClassObject = kSecClassInternetPassword; + } + + NSMutableDictionary *query = [[NSMutableDictionary alloc] init]; + query[(__bridge __strong id)kSecClass] = (__bridge id)itemClassObject; + query[(__bridge __strong id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll; + query[(__bridge __strong id)kSecReturnAttributes] = (__bridge id)kCFBooleanTrue; + + CFArrayRef result = nil; + CFDictionaryRef cfquery = (CFDictionaryRef)CFBridgingRetain(query); + OSStatus status = SecItemCopyMatching(cfquery, (CFTypeRef *)&result); + CFRelease(cfquery); + + if (status == errSecSuccess) { + NSArray *items = [self prettify:itemClassObject items:(__bridge NSArray *)result]; + NSMutableArray *keys = [[NSMutableArray alloc] init]; + for (NSDictionary *item in items) { + if (itemClassObject == kSecClassGenericPassword) { + [keys addObject:@{@"service": item[@"service"] ?: @"", @"key": item[@"key"] ?: @""}]; + } else if (itemClassObject == kSecClassInternetPassword) { + [keys addObject:@{@"server": item[@"service"] ?: @"", @"key": item[@"key"] ?: @""}]; + } + } + return keys.copy; + } else if (status == errSecItemNotFound) { + return @[]; + } + + return nil; +} + ++ (NSArray *)allItemsWithItemClass:(UICKeyChainStoreItemClass)itemClass +{ + CFTypeRef itemClassObject = kSecClassGenericPassword; + if (itemClass == UICKeyChainStoreItemClassGenericPassword) { + itemClassObject = kSecClassGenericPassword; + } else if (itemClass == UICKeyChainStoreItemClassInternetPassword) { + itemClassObject = kSecClassInternetPassword; + } + + NSMutableDictionary *query = [[NSMutableDictionary alloc] init]; + query[(__bridge __strong id)kSecClass] = (__bridge id)itemClassObject; + query[(__bridge __strong id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll; + query[(__bridge __strong id)kSecReturnAttributes] = (__bridge id)kCFBooleanTrue; +#if TARGET_OS_IPHONE + query[(__bridge __strong id)kSecReturnData] = (__bridge id)kCFBooleanTrue; +#endif + + CFArrayRef result = nil; + CFDictionaryRef cfquery = (CFDictionaryRef)CFBridgingRetain(query); + OSStatus status = SecItemCopyMatching(cfquery, (CFTypeRef *)&result); + CFRelease(cfquery); + + if (status == errSecSuccess) { + return [self prettify:itemClassObject items:(__bridge NSArray *)result]; + } else if (status == errSecItemNotFound) { + return @[]; + } + + return nil; +} + +- (NSArray *)allItems +{ + return [self.class prettify:[self itemClassObject] items:[self items]]; +} + +- (NSArray *)items +{ + NSMutableDictionary *query = [self query]; + query[(__bridge __strong id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll; + query[(__bridge __strong id)kSecReturnAttributes] = (__bridge id)kCFBooleanTrue; +#if TARGET_OS_IPHONE + query[(__bridge __strong id)kSecReturnData] = (__bridge id)kCFBooleanTrue; +#endif + + CFArrayRef result = nil; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query,(CFTypeRef *)&result); + + if (status == errSecSuccess) { + return CFBridgingRelease(result); + } else if (status == errSecItemNotFound) { + return @[]; + } + + return nil; +} + ++ (NSArray *)prettify:(CFTypeRef)itemClass items:(NSArray *)items +{ + NSMutableArray *prettified = [[NSMutableArray alloc] init]; + + for (NSDictionary *attributes in items) { + NSMutableDictionary *item = [[NSMutableDictionary alloc] init]; + if (itemClass == kSecClassGenericPassword) { + item[@"class"] = @"GenericPassword"; + id service = attributes[(__bridge id)kSecAttrService]; + if (service) { + item[@"service"] = service; + } + id accessGroup = attributes[(__bridge id)kSecAttrAccessGroup]; + if (accessGroup) { + item[@"accessGroup"] = accessGroup; + } + } else if (itemClass == kSecClassInternetPassword) { + item[@"class"] = @"InternetPassword"; + id server = attributes[(__bridge id)kSecAttrServer]; + if (server) { + item[@"server"] = server; + } + id protocolType = attributes[(__bridge id)kSecAttrProtocol]; + if (protocolType) { + item[@"protocol"] = protocolType; + } + id authenticationType = attributes[(__bridge id)kSecAttrAuthenticationType]; + if (authenticationType) { + item[@"authenticationType"] = authenticationType; + } + } + id key = attributes[(__bridge id)kSecAttrAccount]; + if (key) { + item[@"key"] = key; + } + NSData *data = attributes[(__bridge id)kSecValueData]; + NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + if (string) { + item[@"value"] = string; + } else { + item[@"value"] = data; + } + + id accessible = attributes[(__bridge id)kSecAttrAccessible]; + if (accessible) { + item[@"accessibility"] = accessible; + } + + if (floor(NSFoundationVersionNumber) > floor(993.00)) { // iOS 7+ + id synchronizable = attributes[(__bridge id)kSecAttrSynchronizable]; + if (synchronizable) { + item[@"synchronizable"] = synchronizable; + } + } + + [prettified addObject:item]; + } + + return prettified.copy; +} + +#pragma mark - + +- (void)setSynchronizable:(BOOL)synchronizable +{ + _synchronizable = synchronizable; + if (_authenticationPolicy) { + NSLog(@"%@", @"Cannot specify both an authenticationPolicy and a synchronizable"); + } +} + +- (void)setAccessibility:(UICKeyChainStoreAccessibility)accessibility authenticationPolicy:(UICKeyChainStoreAuthenticationPolicy)authenticationPolicy +{ + _accessibility = accessibility; + _authenticationPolicy = authenticationPolicy; + if (_synchronizable) { + NSLog(@"%@", @"Cannot specify both an authenticationPolicy and a synchronizable"); + } +} + +#pragma mark - + +#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST +- (void)sharedPasswordWithCompletion:(void (^)(NSString *account, NSString *password, NSError *error))completion +{ + NSString *domain = self.server.host; + if (domain.length > 0) { + [self.class requestSharedWebCredentialForDomain:domain account:nil completion:^(NSArray *credentials, NSError *error) { + NSDictionary *credential = credentials.firstObject; + if (credential) { + NSString *account = credential[@"account"]; + NSString *password = credential[@"password"]; + if (completion) { + completion(account, password, error); + } + } else { + if (completion) { + completion(nil, nil, error); + } + } + }]; + } else { + NSError *error = [self.class argumentError:NSLocalizedString(@"the server property must not to be nil, should use 'keyChainStoreWithServer:protocolType:' initializer to instantiate keychain store", nil)]; + if (completion) { + completion(nil, nil, error); + } + } +} + +- (void)sharedPasswordForAccount:(NSString *)account completion:(void (^)(NSString *password, NSError *error))completion +{ + NSString *domain = self.server.host; + if (domain.length > 0) { + [self.class requestSharedWebCredentialForDomain:domain account:account completion:^(NSArray *credentials, NSError *error) { + NSDictionary *credential = credentials.firstObject; + if (credential) { + NSString *password = credential[@"password"]; + if (completion) { + completion(password, error); + } + } else { + if (completion) { + completion(nil, error); + } + } + }]; + } else { + NSError *error = [self.class argumentError:NSLocalizedString(@"the server property must not to be nil, should use 'keyChainStoreWithServer:protocolType:' initializer to instantiate keychain store", nil)]; + if (completion) { + completion(nil, error); + } + } +} + +- (void)setSharedPassword:(NSString *)password forAccount:(NSString *)account completion:(void (^)(NSError *error))completion +{ + NSString *domain = self.server.host; + if (domain.length > 0) { + SecAddSharedWebCredential((__bridge CFStringRef)domain, (__bridge CFStringRef)account, (__bridge CFStringRef)password, ^(CFErrorRef error) { + if (completion) { + completion((__bridge NSError *)error); + } + }); + } else { + NSError *error = [self.class argumentError:NSLocalizedString(@"the server property must not to be nil, should use 'keyChainStoreWithServer:protocolType:' initializer to instantiate keychain store", nil)]; + if (completion) { + completion(error); + } + } +} + +- (void)removeSharedPasswordForAccount:(NSString *)account completion:(void (^)(NSError *error))completion +{ + [self setSharedPassword:nil forAccount:account completion:completion]; +} + ++ (void)requestSharedWebCredentialWithCompletion:(void (^)(NSArray UIC_CREDENTIAL_TYPE *credentials, NSError *error))completion +{ + [self requestSharedWebCredentialForDomain:nil account:nil completion:completion]; +} + ++ (void)requestSharedWebCredentialForDomain:(NSString *)domain account:(NSString *)account completion:(void (^)(NSArray UIC_CREDENTIAL_TYPE *credentials, NSError *error))completion +{ + SecRequestSharedWebCredential((__bridge CFStringRef)domain, (__bridge CFStringRef)account, ^(CFArrayRef credentials, CFErrorRef error) { + if (error) { + NSError *e = (__bridge NSError *)error; + if (e.code != errSecItemNotFound) { + NSLog(@"error: [%@] %@", @(e.code), e.localizedDescription); + } + } + + NSMutableArray *sharedCredentials = [[NSMutableArray alloc] init]; + for (NSDictionary *credential in (__bridge NSArray *)credentials) { + NSMutableDictionary *sharedCredential = [[NSMutableDictionary alloc] init]; + NSString *server = credential[(__bridge __strong id)kSecAttrServer]; + if (server) { + sharedCredential[@"server"] = server; + } + NSString *account = credential[(__bridge __strong id)kSecAttrAccount]; + if (account) { + sharedCredential[@"account"] = account; + } + NSString *password = credential[(__bridge __strong id)kSecSharedPassword]; + if (password) { + sharedCredential[@"password"] = password; + } + [sharedCredentials addObject:sharedCredential]; + } + + if (completion) { + completion(sharedCredentials.copy, (__bridge NSError *)error); + } + }); +} + ++ (NSString *)generatePassword +{ + return (NSString *)CFBridgingRelease(SecCreateSharedWebCredentialPassword()); +} + +#endif + +#pragma mark - + +- (NSString *)description +{ + NSArray *items = [self allItems]; + if (items.count == 0) { + return @"()"; + } + NSMutableString *description = [[NSMutableString alloc] initWithString:@"(\n"]; + for (NSDictionary *item in items) { + [description appendFormat:@" %@", item]; + } + [description appendString:@")"]; + return description.copy; +} + +- (NSString *)debugDescription +{ + return [NSString stringWithFormat:@"%@", [self items]]; +} + +#pragma mark - + +- (NSMutableDictionary *)query +{ + NSMutableDictionary *query = [[NSMutableDictionary alloc] init]; + + CFTypeRef itemClass = [self itemClassObject]; + query[(__bridge __strong id)kSecClass] =(__bridge id)itemClass; + if (floor(NSFoundationVersionNumber) > floor(993.00)) { // iOS 7+ (NSFoundationVersionNumber_iOS_6_1) + query[(__bridge __strong id)kSecAttrSynchronizable] = (__bridge id)kSecAttrSynchronizableAny; + } + + if (itemClass == kSecClassGenericPassword) { + query[(__bridge __strong id)(kSecAttrService)] = _service; +#if !TARGET_OS_SIMULATOR + if (_accessGroup) { + query[(__bridge __strong id)kSecAttrAccessGroup] = _accessGroup; + } +#endif + } else { + if (_server.host) { + query[(__bridge __strong id)kSecAttrServer] = _server.host; + } + if (_server.port != nil) { + query[(__bridge __strong id)kSecAttrPort] = _server.port; + } + CFTypeRef protocolTypeObject = [self protocolTypeObject]; + if (protocolTypeObject) { + query[(__bridge __strong id)kSecAttrProtocol] = (__bridge id)protocolTypeObject; + } + CFTypeRef authenticationTypeObject = [self authenticationTypeObject]; + if (authenticationTypeObject) { + query[(__bridge __strong id)kSecAttrAuthenticationType] = (__bridge id)authenticationTypeObject; + } + } + +#if TARGET_OS_IOS + if (_authenticationPrompt) { + if (floor(NSFoundationVersionNumber) > floor(1047.25)) { // iOS 8+ (NSFoundationVersionNumber_iOS_7_1) + query[(__bridge __strong id)kSecUseOperationPrompt] = _authenticationPrompt; + } else { + NSLog(@"%@", @"Unavailable 'authenticationPrompt' attribute on iOS versions prior to 8.0."); + } + } +#endif + + if (!_useAuthenticationUI) { +#if TARGET_OS_IOS + if (floor(NSFoundationVersionNumber) > floor(1144.17)) { // iOS 9+ + query[(__bridge __strong id)kSecUseAuthenticationUI] = (__bridge id)kSecUseAuthenticationUIFail; +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0 + } else if (floor(NSFoundationVersionNumber) > floor(1047.25)) { // iOS 8+ + query[(__bridge __strong id)kSecUseNoAuthenticationUI] = (__bridge id)kCFBooleanTrue; +#endif + } +#elif TARGET_OS_WATCH || TARGET_OS_TV + query[(__bridge __strong id)kSecUseAuthenticationUI] = (__bridge id)kSecUseAuthenticationUIFail; +#endif + } + + return query; +} + +- (NSMutableDictionary *)attributesWithKey:(NSString *)key value:(NSData *)value error:(NSError *__autoreleasing *)error +{ + NSMutableDictionary *attributes; + + if (key) { + attributes = [self query]; + attributes[(__bridge __strong id)kSecAttrAccount] = key; + } else { + attributes = [[NSMutableDictionary alloc] init]; + } + + attributes[(__bridge __strong id)kSecValueData] = value; + +#if TARGET_OS_IOS + double iOS_7_1_or_10_9_2 = 1047.25; // NSFoundationVersionNumber_iOS_7_1 +#else + double iOS_7_1_or_10_9_2 = 1056.13; // NSFoundationVersionNumber10_9_2 +#endif + CFTypeRef accessibilityObject = [self accessibilityObject]; + if (_authenticationPolicy && accessibilityObject) { + if (floor(NSFoundationVersionNumber) > floor(iOS_7_1_or_10_9_2)) { // iOS 8+ or OS X 10.10+ + CFErrorRef securityError = NULL; + SecAccessControlRef accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibilityObject, (SecAccessControlCreateFlags)_authenticationPolicy, &securityError); + if (securityError) { + NSError *e = (__bridge NSError *)securityError; + NSLog(@"error: [%@] %@", @(e.code), e.localizedDescription); + if (error) { + *error = e; + CFRelease(accessControl); + return nil; + } + } + if (!accessControl) { + NSString *message = NSLocalizedString(@"Unexpected error has occurred.", nil); + NSError *e = [self.class unexpectedError:message]; + if (error) { + *error = e; + } + return nil; + } + attributes[(__bridge __strong id)kSecAttrAccessControl] = (__bridge_transfer id)accessControl; + } else { +#if TARGET_OS_IOS + NSLog(@"%@", @"Unavailable 'Touch ID integration' on iOS versions prior to 8.0."); +#else + NSLog(@"%@", @"Unavailable 'Touch ID integration' on OS X versions prior to 10.10."); +#endif + } + } else { + if (floor(NSFoundationVersionNumber) <= floor(iOS_7_1_or_10_9_2) && _accessibility == UICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly) { +#if TARGET_OS_IOS + NSLog(@"%@", @"Unavailable 'UICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly' attribute on iOS versions prior to 8.0."); +#else + NSLog(@"%@", @"Unavailable 'UICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly' attribute on OS X versions prior to 10.10."); +#endif + } else { + if (accessibilityObject) { + attributes[(__bridge __strong id)kSecAttrAccessible] = (__bridge id)accessibilityObject; + } + } + } + + if (floor(NSFoundationVersionNumber) > floor(993.00)) { // iOS 7+ + attributes[(__bridge __strong id)kSecAttrSynchronizable] = @(_synchronizable); + } + + return attributes; +} + +#pragma mark - + +- (CFTypeRef)itemClassObject +{ + switch (_itemClass) { + case UICKeyChainStoreItemClassGenericPassword: + return kSecClassGenericPassword; + case UICKeyChainStoreItemClassInternetPassword: + return kSecClassInternetPassword; + default: + return nil; + } +} + +- (CFTypeRef)protocolTypeObject +{ + switch (_protocolType) { + case UICKeyChainStoreProtocolTypeFTP: + return kSecAttrProtocolFTP; + case UICKeyChainStoreProtocolTypeFTPAccount: + return kSecAttrProtocolFTPAccount; + case UICKeyChainStoreProtocolTypeHTTP: + return kSecAttrProtocolHTTP; + case UICKeyChainStoreProtocolTypeIRC: + return kSecAttrProtocolIRC; + case UICKeyChainStoreProtocolTypeNNTP: + return kSecAttrProtocolNNTP; + case UICKeyChainStoreProtocolTypePOP3: + return kSecAttrProtocolPOP3; + case UICKeyChainStoreProtocolTypeSMTP: + return kSecAttrProtocolSMTP; + case UICKeyChainStoreProtocolTypeSOCKS: + return kSecAttrProtocolSOCKS; + case UICKeyChainStoreProtocolTypeIMAP: + return kSecAttrProtocolIMAP; + case UICKeyChainStoreProtocolTypeLDAP: + return kSecAttrProtocolLDAP; + case UICKeyChainStoreProtocolTypeAppleTalk: + return kSecAttrProtocolAppleTalk; + case UICKeyChainStoreProtocolTypeAFP: + return kSecAttrProtocolAFP; + case UICKeyChainStoreProtocolTypeTelnet: + return kSecAttrProtocolTelnet; + case UICKeyChainStoreProtocolTypeSSH: + return kSecAttrProtocolSSH; + case UICKeyChainStoreProtocolTypeFTPS: + return kSecAttrProtocolFTPS; + case UICKeyChainStoreProtocolTypeHTTPS: + return kSecAttrProtocolHTTPS; + case UICKeyChainStoreProtocolTypeHTTPProxy: + return kSecAttrProtocolHTTPProxy; + case UICKeyChainStoreProtocolTypeHTTPSProxy: + return kSecAttrProtocolHTTPSProxy; + case UICKeyChainStoreProtocolTypeFTPProxy: + return kSecAttrProtocolFTPProxy; + case UICKeyChainStoreProtocolTypeSMB: + return kSecAttrProtocolSMB; + case UICKeyChainStoreProtocolTypeRTSP: + return kSecAttrProtocolRTSP; + case UICKeyChainStoreProtocolTypeRTSPProxy: + return kSecAttrProtocolRTSPProxy; + case UICKeyChainStoreProtocolTypeDAAP: + return kSecAttrProtocolDAAP; + case UICKeyChainStoreProtocolTypeEPPC: + return kSecAttrProtocolEPPC; + case UICKeyChainStoreProtocolTypeNNTPS: + return kSecAttrProtocolNNTPS; + case UICKeyChainStoreProtocolTypeLDAPS: + return kSecAttrProtocolLDAPS; + case UICKeyChainStoreProtocolTypeTelnetS: + return kSecAttrProtocolTelnetS; + case UICKeyChainStoreProtocolTypeIRCS: + return kSecAttrProtocolIRCS; + case UICKeyChainStoreProtocolTypePOP3S: + return kSecAttrProtocolPOP3S; + default: + return nil; + } +} + +- (CFTypeRef)authenticationTypeObject +{ + switch (_authenticationType) { + case UICKeyChainStoreAuthenticationTypeNTLM: + return kSecAttrAuthenticationTypeNTLM; + case UICKeyChainStoreAuthenticationTypeMSN: + return kSecAttrAuthenticationTypeMSN; + case UICKeyChainStoreAuthenticationTypeDPA: + return kSecAttrAuthenticationTypeDPA; + case UICKeyChainStoreAuthenticationTypeRPA: + return kSecAttrAuthenticationTypeRPA; + case UICKeyChainStoreAuthenticationTypeHTTPBasic: + return kSecAttrAuthenticationTypeHTTPBasic; + case UICKeyChainStoreAuthenticationTypeHTTPDigest: + return kSecAttrAuthenticationTypeHTTPDigest; + case UICKeyChainStoreAuthenticationTypeHTMLForm: + return kSecAttrAuthenticationTypeHTMLForm; + case UICKeyChainStoreAuthenticationTypeDefault: + return kSecAttrAuthenticationTypeDefault; + default: + return nil; + } +} + +- (CFTypeRef)accessibilityObject +{ + switch (_accessibility) { + case UICKeyChainStoreAccessibilityWhenUnlocked: + return kSecAttrAccessibleWhenUnlocked; + case UICKeyChainStoreAccessibilityAfterFirstUnlock: + return kSecAttrAccessibleAfterFirstUnlock; + case UICKeyChainStoreAccessibilityAlways: + return kSecAttrAccessibleAlways; + case UICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly: + return kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly; + case UICKeyChainStoreAccessibilityWhenUnlockedThisDeviceOnly: + return kSecAttrAccessibleWhenUnlockedThisDeviceOnly; + case UICKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly: + return kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly; + case UICKeyChainStoreAccessibilityAlwaysThisDeviceOnly: + return kSecAttrAccessibleAlwaysThisDeviceOnly; + default: + return nil; + } +} + ++ (NSError *)argumentError:(NSString *)message +{ + NSError *error = [NSError errorWithDomain:UICKeyChainStoreErrorDomain code:UICKeyChainStoreErrorInvalidArguments userInfo:@{NSLocalizedDescriptionKey: message}]; + NSLog(@"error: [%@] %@", @(error.code), error.localizedDescription); + return error; +} + ++ (NSError *)conversionError:(NSString *)message +{ + NSError *error = [NSError errorWithDomain:UICKeyChainStoreErrorDomain code:-67594 userInfo:@{NSLocalizedDescriptionKey: message}]; + NSLog(@"error: [%@] %@", @(error.code), error.localizedDescription); + return error; +} + ++ (NSError *)securityError:(OSStatus)status +{ + NSString *message = @"Security error has occurred."; +#if TARGET_OS_MAC && !TARGET_OS_IPHONE + CFStringRef description = SecCopyErrorMessageString(status, NULL); + if (description) { + message = (__bridge_transfer NSString *)description; + } +#endif + NSError *error = [NSError errorWithDomain:UICKeyChainStoreErrorDomain code:status userInfo:@{NSLocalizedDescriptionKey: message}]; + NSLog(@"OSStatus error: [%@] %@", @(error.code), error.localizedDescription); + return error; +} + ++ (NSError *)unexpectedError:(NSString *)message +{ + NSError *error = [NSError errorWithDomain:UICKeyChainStoreErrorDomain code:-99999 userInfo:@{NSLocalizedDescriptionKey: message}]; + NSLog(@"error: [%@] %@", @(error.code), error.localizedDescription); + return error; +} + +@end + +@implementation UICKeyChainStore (Deprecation) + +- (void)synchronize +{ + // Deprecated, calling this method is no longer required +} + +- (BOOL)synchronizeWithError:(NSError *__autoreleasing *)error +{ + // Deprecated, calling this method is no longer required + return true; +} + +@end diff --git a/Classes_cocos/UIViewController+Wallet.mm b/Classes_cocos/UIViewController+Wallet.mm index 06f8f4e..50b4fe6 100644 --- a/Classes_cocos/UIViewController+Wallet.mm +++ b/Classes_cocos/UIViewController+Wallet.mm @@ -13,12 +13,12 @@ #include "WalletEvent.h" #include "JcWallet.h" #import -#include "SSKeychain.h" +#include "DataManager.h" + @import GoogleSignIn; static NSString * const kClientID = @"53206975661-0d6q9pqljn84n9l63gm0to1ulap9cbk4.apps.googleusercontent.com"; -static NSString * const cebgWalletService = @"CEBG-wallet"; @implementation UIViewController (Wallet) @@ -35,20 +35,11 @@ static NSString * const cebgWalletService = @"CEBG-wallet"; } -(void)saveKey:(NSString *) account key:(NSString *) key { NSLog(@"saveKey::account:%@, key: %@", account, key); - [SSKeychain setPassword:key forService:cebgWalletService account:account]; - [SSKeychain setAccessibilityType:kSecAttrAccessibleWhenUnlocked]; + [[DataManager sharedInstanceWith: SynLock] saveKey: account key: key]; } -(NSString *)loadKey:(NSString *) account { NSLog(@"loadKey::account:%@", account); - NSError *error = nil; - NSString *password = [SSKeychain passwordForService:cebgWalletService account:account error:&error]; - if ([error code] == SSKeychainErrorNotFound) { - NSLog(@"password not found, account: %@", account); - return @""; - } else { - NSLog(@"password for %@ is %@", account, password); - return password; - } + return [[DataManager sharedInstanceWith: SynLock] loadKey: account]; } -(void)scanQRCode:(NSString *)funid title:(NSString *) title{ diff --git a/Unity-iPhone.xcodeproj/project.pbxproj b/Unity-iPhone.xcodeproj/project.pbxproj index f183a05..6167b38 100644 --- a/Unity-iPhone.xcodeproj/project.pbxproj +++ b/Unity-iPhone.xcodeproj/project.pbxproj @@ -81,7 +81,8 @@ D5538BA5287E9908000BDFB6 /* WalletEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D5538BA3287E9908000BDFB6 /* WalletEvent.cpp */; }; D589C9BB28B62D93002CAA34 /* cacert.pem in Resources */ = {isa = PBXBuildFile; fileRef = D589C9B928B62D93002CAA34 /* cacert.pem */; }; D59AB424292DBACE00714392 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D59AB423292DBACE00714392 /* CloudKit.framework */; }; - D59AB427292DD91D00714392 /* SSKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = D59AB426292DD91D00714392 /* SSKeychain.m */; }; + D59AB42F292E250500714392 /* UICKeyChainStore.m in Sources */ = {isa = PBXBuildFile; fileRef = D59AB42E292E250500714392 /* UICKeyChainStore.m */; }; + D59AB433292E26CE00714392 /* DataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D59AB432292E26CE00714392 /* DataManager.m */; }; D5AB1D3328BF782300AA6AFA /* QRToggleTorchButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D5AB1D2928BF782200AA6AFA /* QRToggleTorchButton.m */; }; D5AB1D3428BF782300AA6AFA /* QRCameraSwitchButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D5AB1D2B28BF782200AA6AFA /* QRCameraSwitchButton.m */; }; D5AB1D3528BF782300AA6AFA /* QRCodeReaderViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D5AB1D2D28BF782200AA6AFA /* QRCodeReaderViewController.m */; }; @@ -366,8 +367,10 @@ D589C9B928B62D93002CAA34 /* cacert.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = cacert.pem; sourceTree = ""; }; D59AB422292DBABA00714392 /* Unity-iPhone.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = "Unity-iPhone.entitlements"; path = "Unity-iPhone/Unity-iPhone.entitlements"; sourceTree = ""; }; D59AB423292DBACE00714392 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; }; - D59AB425292DD8E500714392 /* SSKeychain.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SSKeychain.h; sourceTree = ""; }; - D59AB426292DD91D00714392 /* SSKeychain.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SSKeychain.m; sourceTree = ""; }; + D59AB42C292E24DD00714392 /* UICKeyChainStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UICKeyChainStore.h; sourceTree = ""; }; + D59AB42E292E250500714392 /* UICKeyChainStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UICKeyChainStore.m; sourceTree = ""; }; + D59AB431292E26B600714392 /* DataManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataManager.h; sourceTree = ""; }; + D59AB432292E26CE00714392 /* DataManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DataManager.m; sourceTree = ""; }; D5AB1D2828BF782200AA6AFA /* QRCodeReaderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QRCodeReaderView.h; sourceTree = ""; }; D5AB1D2928BF782200AA6AFA /* QRToggleTorchButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QRToggleTorchButton.m; sourceTree = ""; }; D5AB1D2A28BF782200AA6AFA /* QRCodeReaderDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QRCodeReaderDelegate.h; sourceTree = ""; }; @@ -899,8 +902,10 @@ D5F2D104287C12DD003C2B62 /* JcWallet.mm */, D5538BA4287E9908000BDFB6 /* WalletEvent.h */, D5538BA3287E9908000BDFB6 /* WalletEvent.cpp */, - D59AB425292DD8E500714392 /* SSKeychain.h */, - D59AB426292DD91D00714392 /* SSKeychain.m */, + D59AB42C292E24DD00714392 /* UICKeyChainStore.h */, + D59AB42E292E250500714392 /* UICKeyChainStore.m */, + D59AB431292E26B600714392 /* DataManager.h */, + D59AB432292E26CE00714392 /* DataManager.m */, ); path = Classes_cocos; sourceTree = ""; @@ -1212,6 +1217,7 @@ D5F2CF75287BEC0D003C2B62 /* Il2CppCompilerCalculateTypeValues_21Table.cpp in Sources */, D5F2CF43287BEC0D003C2B62 /* Bulk_Generics_2.cpp in Sources */, D5F2CF6F287BEC0D003C2B62 /* Il2CppCompilerCalculateTypeValues_4Table.cpp in Sources */, + D59AB433292E26CE00714392 /* DataManager.m in Sources */, 8A142DC61636943E00DD87CA /* Keyboard.mm in Sources */, 8A0FED491649699200E9727D /* EAGLContextHelper.mm in Sources */, D5F2CF57287BEC0D003C2B62 /* Bulk_System.Xml_0.cpp in Sources */, @@ -1254,6 +1260,7 @@ D5F2CF8A287BEC0D003C2B62 /* Bulk_UnityEngine.CoreModule_0.cpp in Sources */, 4E090A341F27885B0077B28D /* StoreReview.m in Sources */, 8AC74A9519B47FEF00019D38 /* AVCapture.mm in Sources */, + D59AB42F292E250500714392 /* UICKeyChainStore.m in Sources */, D5F2CF90287BEC0D003C2B62 /* Il2CppCompilerCalculateTypeValues_6Table.cpp in Sources */, D5F2CFA8287BEC0D003C2B62 /* Il2CppCompilerCalculateTypeValues_13Table.cpp in Sources */, D5F2CF5C287BEC0D003C2B62 /* Bulk_Generics_7.cpp in Sources */, @@ -1279,7 +1286,6 @@ D5F2D106287C12DD003C2B62 /* JcWallet.mm in Sources */, D5F2CF8B287BEC0D003C2B62 /* Bulk_System.Diagnostics.StackTrace_0.cpp in Sources */, D5F2CF63287BEC0D003C2B62 /* Il2CppCompilerCalculateTypeValues_10Table.cpp in Sources */, - D59AB427292DD91D00714392 /* SSKeychain.m in Sources */, D5F2CF88287BEC0D003C2B62 /* Bulk_UnityEngine.UIModule_0.cpp in Sources */, D5F2CF5E287BEC0D003C2B62 /* GenericMethods3.cpp in Sources */, D5F2CF72287BEC0D003C2B62 /* Bulk_mscorlib_2.cpp in Sources */, diff --git a/Unity-iPhone.xcworkspace/xcuserdata/zhl.xcuserdatad/UserInterfaceState.xcuserstate b/Unity-iPhone.xcworkspace/xcuserdata/zhl.xcuserdatad/UserInterfaceState.xcuserstate index 9d8d3afd86078d0eb6f38fa42a9033a1510df877..e1fd2324983221916ccf572a94024e7a01120900 100644 GIT binary patch literal 136060 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

K(hj(y*cW&iHxru+J;c7rJLIDv zMR0$y?k~0`I*P4JeIoF#*v5EYYztb^5ATfK!s#H?Rkp64*VWH;?TQ(@nyu?9*07$9 zxWTU9v7a9}gju`(h@Ew{v#yu;ldD`0Lfx_=f44lm!CQD&w*nMG{%*dbZncrQo6Ozp zpj&fV(wa7OXAX<`lD+7ZJZm5^WDaIU!3nYPH%D5 z2uDY8I*RkoxG36UH*q~kqz|d2F_~%1U>0s5ZW$|(Ep8j%BVU}3;&c>uEeLgg9J}jo z{_b|yy)eZnNg3YfBh25uDfZRf{M}{g9!(5-=u0J-hh^`;Gse6I{ey#k;HcD?A87J)Y$`UgQ;CBR8+} z7VnZDH`XJJs`y5F)Wogzs7C`LF-H$`^w4(?-$xIbdrZgo(c^Rw>goIFsf(U<>B=a4 zA3f#nDR)n~du~L>J-_1shd9bHe!`vhG(%4_^t{Rq^q!E7T)ctY334asJfSefD1rP5 z;mDdGYl5r^?jpf=kCI$k@le``C9MS^Ma>kAC~~V<5WiGnC>)`mzaKM{Bv+DLNpdC0m9&aAtY;H4Cb`q3A34qm z^qKT4XF1PB{@_op1fjnA?3)kW_3h3iHe$ZM{{*3auThptxQ%{t_p3<+EzoU0-S%?_ z{W@ZXerD*`mjMjIE%b8>{pKQfztyZ|12Xs9#!hzQ4*H$p0>5(^{r0=TZSDjizaKNy zzXba0ufP7yX+;}+L;YiL!~J9N-u`LmvHuvxW5)hdn9V}IU>Ww@U$*|T`CXWy{(JbA z@6bnoS^Dd&|8;H!p#cFIufX!@WJMMCTyaT@Bd=MHa*T8qNtAX7x^FVhp@ECswq2%YV zTfgHnl>9nxQjk*Eck+jnry^m56G0=)kZkwKI!`u7vVN20PL?})0#ljJC(L3g@+Qlg zENil?$$CxR$9{g`SN;n^gYqKFpm)fJOoNJ09Gwo*>7e@PbC5m%ukQaG{*T{vAhv;^QZimP^q%0p&j#|`3*F$tY zMAt)_(hIqV*!hr=j7H`mdL5$IAs@34cRIw*hiqmmc0R;?4zc$k_CDl95E>fdDYBA{ z=gEm35B&f+hU#u;TcR=7&@OZ%o}S1vRBuCN7&@70%wQICScLwD>Tl>;HlV+u-yp}( z{pe`uDbDa47rBLf55333AT%s9FY+?4BIhvoIjlUD@SP8ovRqj-|Q!jCY z2RsTw!vivq2{Q~g!|+#ljoi4I;crqAxrav(NfTrquK(fsAKo5)4|li2eM`fKWB%?xR!D9eZFFHL`GdP{4B`O;e8y=mT?7EKHZ=q=6n zlV<+3WPCGe-k)aoX?CBskTtAFH)&h2<1{-?v*WZQ=qgQDX&2B{+TTHFL~iop-|rD` z^B(yr!v~Z@KO-tr75f~~j*fJp8}ZoX2;GcGBb_nGHDVgmnaOOHvXSpO#%c64;ud$f z&p$!P@8k@Pw6~G=Hu7n*k_Y)l$~3YT4QY%_BkgNs6rG4A4mUS45#5cnyODM_Ql^nI zjFe&IPWJFE-*JHBoZx3pA>YWe{1=4Mb5a3&O7DPorF&Ppcctqf-HoKXjr2)OWjf|g zpTk_%vXx!9lk~mlA>I4Z?IzuB(l7D{*U?G39i`vHO^?#as4V2b&PKh-JLID%B`Aga t8fAB*s!*5axT{e*8r2%R8{Z-LzyB}eWB>2J=H2rD{_Fq$&!O?1{tp(8LoNUS literal 160142 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 diff --git a/Unity-iPhone.xcworkspace/xcuserdata/zhl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Unity-iPhone.xcworkspace/xcuserdata/zhl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 7911574..b9600b9 100644 --- a/Unity-iPhone.xcworkspace/xcuserdata/zhl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/Unity-iPhone.xcworkspace/xcuserdata/zhl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -14,8 +14,8 @@ filePath = "Classes_cocos/UIViewController+Wallet.mm" startingColumnNumber = "9" endingColumnNumber = "9" - startingLineNumber = "134" - endingLineNumber = "134" + startingLineNumber = "133" + endingLineNumber = "133" landmarkName = "-refreshTokenID:funid:" landmarkType = "7"> @@ -30,8 +30,8 @@ filePath = "Classes_cocos/UIViewController+Wallet.mm" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "140" - endingLineNumber = "140" + startingLineNumber = "131" + endingLineNumber = "131" landmarkName = "-refreshTokenID:funid:" landmarkType = "7"> @@ -46,8 +46,8 @@ filePath = "Classes_cocos/UIViewController+Wallet.mm" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "142" - endingLineNumber = "142" + startingLineNumber = "133" + endingLineNumber = "133" landmarkName = "-refreshTokenID:funid:" landmarkType = "7"> @@ -78,8 +78,8 @@ filePath = "Classes_cocos/UIViewController+Wallet.mm" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "141" - endingLineNumber = "141" + startingLineNumber = "132" + endingLineNumber = "132" landmarkName = "-refreshTokenID:funid:" landmarkType = "7"> @@ -94,8 +94,8 @@ filePath = "Classes_cocos/UIViewController+Wallet.mm" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "147" - endingLineNumber = "147" + startingLineNumber = "138" + endingLineNumber = "138" landmarkName = "-signWithGoogle:" landmarkType = "7"> @@ -116,5 +116,21 @@ landmarkType = "7"> + + + + diff --git a/Unity-iPhone/Unity-iPhone.entitlements b/Unity-iPhone/Unity-iPhone.entitlements index 264bbd1..d41b41f 100644 --- a/Unity-iPhone/Unity-iPhone.entitlements +++ b/Unity-iPhone/Unity-iPhone.entitlements @@ -23,5 +23,9 @@ com.apple.developer.ubiquity-kvstore-identifier $(TeamIdentifierPrefix)$(CFBundleIdentifier) + keychain-access-groups + + $(AppIdentifierPrefix)com.jc.tebg +