Created
October 22, 2012 21:28
-
-
Save AquaGeek/3934520 to your computer and use it in GitHub Desktop.
Keychain
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| - (BOOL)checkKeychainForAuthCredentials | |
| { | |
| NSMutableDictionary *keychainQuery = [self keychainSearchDictionary]; | |
| // Fire off the query | |
| OSStatus keychainErr = noErr; | |
| CFDictionaryRef outDictionary; | |
| keychainErr = SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&outDictionary); | |
| if (keychainErr == noErr && outDictionary != NULL) | |
| { | |
| // Query the keychain again for the password data | |
| [keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; | |
| [keychainQuery removeObjectForKey:(__bridge id)kSecReturnAttributes]; | |
| CFDataRef passwordData = NULL; | |
| keychainErr = SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&passwordData); | |
| if (keychainErr == noErr) | |
| { | |
| NSString *username = [((__bridge NSDictionary *)outDictionary) objectForKey:(__bridge id)kSecAttrAccount]; | |
| // Convert the password to an NSString and add it to the return dictionary | |
| NSString *password = [[NSString alloc] initWithBytes:[(__bridge NSData *)passwordData bytes] | |
| length:[(__bridge NSData *)passwordData length] | |
| encoding:NSUTF8StringEncoding]; | |
| NSLog(@"Username: %@ || Password: %@", username, password); | |
| // TODO: Validate the credentials? | |
| } | |
| else if (keychainErr == errSecItemNotFound) | |
| { | |
| // TODO: Anything? | |
| } | |
| } | |
| else if (keychainErr == errSecItemNotFound) | |
| { | |
| // TODO: Anything? | |
| } | |
| return NO; | |
| } | |
| - (BOOL)saveAuthCredentialsToKeychain:(NSDictionary *)credentials | |
| { | |
| NSMutableDictionary *keychainQuery = [self keychainSearchDictionary]; | |
| // Fire off the query | |
| OSErr keychainErr = noErr; | |
| // Try to find an existing item | |
| CFDictionaryRef outDictionary; | |
| keychainErr = SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&outDictionary); | |
| NSString *username = [credentials objectForKey:@"username"]; | |
| NSData *passwordData = [[credentials objectForKey:@"password"] dataUsingEncoding:NSUTF8StringEncoding]; | |
| if (keychainErr == errSecSuccess) | |
| { | |
| // Update the item (via the response we got back from the call to SecItemCopyMatching) | |
| NSDictionary *updatedCredentials = @{ (__bridge id)kSecAttrAccount : username, (__bridge id)kSecValueData : passwordData }; | |
| keychainErr = SecItemUpdate(outDictionary, (__bridge CFDictionaryRef)updatedCredentials); | |
| return (keychainErr == noErr); | |
| } | |
| else | |
| { | |
| // Create the item | |
| [keychainQuery setObject:username forKey:(__bridge id)kSecAttrAccount]; | |
| [keychainQuery setObject:passwordData forKey:(__bridge id)kSecValueData]; | |
| keychainErr = SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL); | |
| return (keychainErr == noErr); | |
| } | |
| } | |
| - (NSMutableDictionary *)keychainSearchDictionary | |
| { | |
| NSMutableDictionary *keychainQuery = [@{ } mutableCopy]; | |
| // We're looking for a generic password | |
| [keychainQuery setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; | |
| // For the Fly Delta app | |
| [keychainQuery setObject:@"My Awesome Service" forKey:(__bridge id)kSecAttrService]; | |
| // We only want the first match | |
| [keychainQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; | |
| // Return the attributes of the keychain item (if found) | |
| [keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes]; | |
| return keychainQuery; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment