diff --git a/SFHFKeychainUtils.podspec b/SFHFKeychainUtils.podspec new file mode 100644 index 0000000..5b150ca --- /dev/null +++ b/SFHFKeychainUtils.podspec @@ -0,0 +1,40 @@ +Pod::Spec.new do |s| + s.name = 'SFHFKeychainUtils' + s.version = '0.0.2' + s.platform = :ios + s.summary = 'SciFiHiFi Utilities for manipulating the keychain.' + s.homepage = 'https://github.com/ldandersen/scifihifi-iphone/tree/master/security' + s.author = { 'Buzz Andersen' => 'buzz@scifihifi.com' } + s.source = { :git => 'https://github.com/ldandersen/scifihifi-iphone.git', :tag => '0.0.2' } + s.source_files = 'security' + s.framework = 'Security' + s.requires_arc = false + + s.license = {:type => 'MIT', :text => <<-TXT + Created by Buzz Andersen on 10/20/08. + Based partly on code by Jonathan Wight, Jon Crosby, and Mike Malone. + Copyright 2008 Sci-Fi Hi-Fi. All rights reserved. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + TXT + } +end diff --git a/security/SFHFKeychainUtils.h b/security/SFHFKeychainUtils.h index 9ccff0f..3856330 100644 --- a/security/SFHFKeychainUtils.h +++ b/security/SFHFKeychainUtils.h @@ -30,12 +30,27 @@ #import -@interface SFHFKeychainUtils : NSObject { - -} +@interface SFHFKeychainUtils : NSObject -+ (NSString *) getPasswordForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error; -+ (BOOL) storeUsername: (NSString *) username andPassword: (NSString *) password forServiceName: (NSString *) serviceName updateExisting: (BOOL) updateExisting error: (NSError **) error; -+ (BOOL) deleteItemForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error; ++ (NSString *) getPasswordForUsername: (NSString *) username + andServiceName: (NSString *) serviceName + error: (NSError **) error; + ++ (BOOL) storeUsername: (NSString *) username + andPassword: (NSString *) password + forServiceName: (NSString *) serviceName + updateExisting: (BOOL) updateExisting + error: (NSError **) error; + ++ (BOOL) storeUsername: (NSString *) username + andPassword: (NSString *) password + forServiceName: (NSString *) serviceName + updateExisting: (BOOL) updateExisting + accessibility: (CFTypeRef) accessibility // restrict accessiblitiy - see kSecAttrAccessible + error: (NSError **) error; + ++ (BOOL) deleteItemForUsername: (NSString *) username + andServiceName: (NSString *) serviceName + error: (NSError **) error; @end \ No newline at end of file diff --git a/security/SFHFKeychainUtils.m b/security/SFHFKeychainUtils.m index 0017b83..2cc3b97 100644 --- a/security/SFHFKeychainUtils.m +++ b/security/SFHFKeychainUtils.m @@ -42,7 +42,10 @@ @implementation SFHFKeychainUtils #if __IPHONE_OS_VERSION_MIN_REQUIRED < 30000 && TARGET_IPHONE_SIMULATOR -+ (NSString *) getPasswordForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error { ++ (NSString *) getPasswordForUsername: (NSString *) username + andServiceName: (NSString *) serviceName + error: (NSError **) error +{ if (!username || !serviceName) { *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil]; return nil; @@ -96,7 +99,12 @@ + (NSString *) getPasswordForUsername: (NSString *) username andServiceName: (NS return passwordString; } -+ (void) storeUsername: (NSString *) username andPassword: (NSString *) password forServiceName: (NSString *) serviceName updateExisting: (BOOL) updateExisting error: (NSError **) error { ++ (void) storeUsername: (NSString *) username + andPassword: (NSString *) password + forServiceName: (NSString *) serviceName + updateExisting: (BOOL) updateExisting + error: (NSError **) error +{ if (!username || !password || !serviceName) { *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil]; return; @@ -136,7 +144,10 @@ + (void) storeUsername: (NSString *) username andPassword: (NSString *) password } } -+ (void) deleteItemForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error { ++ (void) deleteItemForUsername: (NSString *) username + andServiceName: (NSString *) serviceName + error: (NSError **) error +{ if (!username || !serviceName) { *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: 2000 userInfo: nil]; return; @@ -163,7 +174,10 @@ + (void) deleteItemForUsername: (NSString *) username andServiceName: (NSString } } -+ (SecKeychainItemRef) getKeychainItemReferenceForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error { ++ (SecKeychainItemRef) getKeychainItemReferenceForUsername: (NSString *) username + andServiceName: (NSString *) serviceName + error: (NSError **) error +{ if (!username || !serviceName) { *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil]; return nil; @@ -195,7 +209,10 @@ + (SecKeychainItemRef) getKeychainItemReferenceForUsername: (NSString *) usernam #else -+ (NSString *) getPasswordForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error { ++ (NSString *) getPasswordForUsername: (NSString *) username + andServiceName: (NSString *) serviceName + error: (NSError **) error +{ if (!username || !serviceName) { if (error != nil) { *error = [NSError errorWithDomain: SFHFKeychainUtilsErrorDomain code: -2000 userInfo: nil]; @@ -286,7 +303,26 @@ + (NSString *) getPasswordForUsername: (NSString *) username andServiceName: (NS return [password autorelease]; } -+ (BOOL) storeUsername: (NSString *) username andPassword: (NSString *) password forServiceName: (NSString *) serviceName updateExisting: (BOOL) updateExisting error: (NSError **) error ++ (BOOL) storeUsername: (NSString *) username + andPassword: (NSString *) password + forServiceName: (NSString *) serviceName + updateExisting: (BOOL) updateExisting + error: (NSError **) error +{ + return [self storeUsername:username + andPassword:password + forServiceName:serviceName + updateExisting:updateExisting + accessibility:nil + error:error]; +} + ++ (BOOL) storeUsername: (NSString *) username + andPassword: (NSString *) password + forServiceName: (NSString *) serviceName + updateExisting: (BOOL) updateExisting + accessibility: (CFTypeRef) accessibility // restrict accessiblitiy - see kSecAttrAccessible + error: (NSError **) error { if (!username || !password || !serviceName) { @@ -301,7 +337,7 @@ + (BOOL) storeUsername: (NSString *) username andPassword: (NSString *) password NSError *getError = nil; NSString *existingPassword = [SFHFKeychainUtils getPasswordForUsername: username andServiceName: serviceName error:&getError]; - if ([getError code] == -1999) + if ([getError code] == -1999 || (existingPassword && [existingPassword length] == 0)) { // There is an existing entry without a password properly stored (possibly as a result of the previous incorrect version of this code. // Delete the existing item before moving on entering a correct one. @@ -309,6 +345,8 @@ + (BOOL) storeUsername: (NSString *) username andPassword: (NSString *) password getError = nil; [self deleteItemForUsername: username andServiceName: serviceName error: &getError]; + + existingPassword = nil; if ([getError code] != noErr) { @@ -355,6 +393,12 @@ + (BOOL) storeUsername: (NSString *) username andPassword: (NSString *) password serviceName, username, nil] autorelease]; + + if (accessibility != nil) + { + keys = [keys arrayByAddingObject:kSecAttrAccessible]; + objects = [objects arrayByAddingObject:accessibility]; + } NSDictionary *query = [[[NSDictionary alloc] initWithObjects: objects forKeys: keys] autorelease]; @@ -398,7 +442,9 @@ + (BOOL) storeUsername: (NSString *) username andPassword: (NSString *) password return YES; } -+ (BOOL) deleteItemForUsername: (NSString *) username andServiceName: (NSString *) serviceName error: (NSError **) error ++ (BOOL) deleteItemForUsername: (NSString *) username + andServiceName: (NSString *) serviceName + error: (NSError **) error { if (!username || !serviceName) {