Skip to content

Commit

Permalink
Version 0.1.3
Browse files Browse the repository at this point in the history
* Added ARC support
* Added ARC tests
  • Loading branch information
soffes committed May 8, 2012
1 parent 0b0dbf2 commit ca7ebbc
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 13 deletions.
7 changes: 6 additions & 1 deletion Changelog.markdown
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# SSKeychain Changelog

### Version 0.1.3

[Released October 18, 2011](https://github.com/samsoffes/sskeychain/tree/0.1.2)

* Added ARC support

### Version 0.1.2

[Released October 18, 2011](https://github.com/samsoffes/sskeychain/tree/0.1.2)

* Added VERSION file
* Added documentation
* Added string constants for keys in returned dictionaries
* Renamed `SSKeychainErrorDomain` to `kSSKeychainErrorDomain`
Expand Down
4 changes: 3 additions & 1 deletion Readme.markdown
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SSKeychain

SSKeychain is a simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system Keychain on Mac OS X and iOS.
SSKeychain is a simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system Keychain on Mac OS X and iOS. SSKeychain works in ARC and non-ARC projects.

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).

Expand All @@ -9,6 +9,8 @@ This was originally inspired by EMKeychain and SDKeychain (both of which are now
1. Add `Security.framework` to your target
2. Add `SSKeychain.h` and `SSKeychain.m` to your project.

You don't need to do anything regarding ARC. SSKeychain will detect if you're not using ARC and add the required memory management code.

Note: Currently SSKeychain does not support Mac OS 10.6.

## Working with the keychain
Expand Down
66 changes: 55 additions & 11 deletions SSKeychain.m
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,26 @@ + (NSArray *)accountsForService:(NSString *)service {

+ (NSArray *)accountsForService:(NSString *)service error:(NSError **)error {
OSStatus status = SSKeychainErrorBadArguments;
CFArrayRef result = NULL;
NSMutableDictionary *query = [self _queryForService:service account:nil];
[query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes];
[query setObject:(id)kSecMatchLimitAll forKey:(id)kSecMatchLimit];
status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&result);

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
}


Expand All @@ -68,7 +79,15 @@ + (NSString *)passwordForService:(NSString *)service account:(NSString *)account

+ (NSString *)passwordForService:(NSString *)service account:(NSString *)account error:(NSError **)error {
NSData *data = [self passwordDataForService:service account:account error:error];
return ([data length]) ? [[[NSString alloc] initWithData:(NSData *)data encoding:NSUTF8StringEncoding] autorelease] : nil;
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;
}


Expand All @@ -79,19 +98,36 @@ + (NSData *)passwordDataForService:(NSString *)service account:(NSString *)accou

+ (NSData *)passwordDataForService:(NSString *)service account:(NSString *)account error:(NSError **)error {
OSStatus status = SSKeychainErrorBadArguments;
NSData *result = nil;
if (service && account) {
NSMutableDictionary *query = [self _queryForService:service account:account];
[query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
[query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
status = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&result);
if (!service || !account) {
if (error) {
*error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil];
}
return nil;
}

NSMutableDictionary *query = [self _queryForService:service account:account];
[query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
[query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
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;
}
return [result autorelease];

#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 {
Expand All @@ -103,7 +139,11 @@ + (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account
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];
Expand Down Expand Up @@ -144,7 +184,11 @@ + (BOOL)setPasswordData:(NSData *)password forService:(NSString *)service accoun
}
#endif

status = SecItemAdd((CFDictionaryRef)query, NULL);
#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];
Expand Down
104 changes: 104 additions & 0 deletions Tests/SSKeychain.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
objects = {

/* Begin PBXBuildFile section */
B2059B5D1559058C003D2FAC /* SSKeychainTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B2A5FACE143AC25C000F6011 /* SSKeychainTests.m */; };
B2059B5E1559058C003D2FAC /* SSKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = B25737E1143AC2EC003FACED /* SSKeychain.m */; };
B2059B601559058C003D2FAC /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B25737E4143AC308003FACED /* Security.framework */; };
B2059B611559058C003D2FAC /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2A5FAB1143AC134000F6011 /* SenTestingKit.framework */; };
B2059B621559058C003D2FAC /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2A5FA93143AC133000F6011 /* Cocoa.framework */; };
B25737E2143AC2EC003FACED /* SSKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = B25737E1143AC2EC003FACED /* SSKeychain.m */; };
B25737E5143AC308003FACED /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B25737E4143AC308003FACED /* Security.framework */; };
B2A5FAB2143AC134000F6011 /* SenTestingKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2A5FAB1143AC134000F6011 /* SenTestingKit.framework */; };
Expand All @@ -15,6 +20,8 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
B2059B681559058C003D2FAC /* SSKeychainTestsARC.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SSKeychainTestsARC.octest; sourceTree = BUILT_PRODUCTS_DIR; };
B2059B691559058C003D2FAC /* SSKeychainTestsARC-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "SSKeychainTestsARC-Info.plist"; path = "/Users/samsoffes/Code/sskeychain/Tests/SSKeychainTestsARC-Info.plist"; sourceTree = "<absolute>"; };
B25737E0143AC2EC003FACED /* SSKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SSKeychain.h; path = ../SSKeychain.h; sourceTree = "<group>"; };
B25737E1143AC2EC003FACED /* SSKeychain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SSKeychain.m; path = ../SSKeychain.m; sourceTree = "<group>"; };
B25737E4143AC308003FACED /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
Expand All @@ -29,6 +36,16 @@
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
B2059B5F1559058C003D2FAC /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
B2059B601559058C003D2FAC /* Security.framework in Frameworks */,
B2059B611559058C003D2FAC /* SenTestingKit.framework in Frameworks */,
B2059B621559058C003D2FAC /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B2A5FAAC143AC134000F6011 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
Expand Down Expand Up @@ -65,6 +82,7 @@
isa = PBXGroup;
children = (
B2A5FAB0143AC134000F6011 /* SSKeychainTests.octest */,
B2059B681559058C003D2FAC /* SSKeychainTestsARC.octest */,
);
name = Products;
sourceTree = "<group>";
Expand Down Expand Up @@ -95,13 +113,32 @@
children = (
B2A5FACE143AC25C000F6011 /* SSKeychainTests.m */,
B2A5FACC143AC25C000F6011 /* SSKeychainTests-Info.plist */,
B2059B691559058C003D2FAC /* SSKeychainTestsARC-Info.plist */,
);
path = SSKeychainTests;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
B2059B5B1559058C003D2FAC /* SSKeychainTestsARC */ = {
isa = PBXNativeTarget;
buildConfigurationList = B2059B651559058C003D2FAC /* Build configuration list for PBXNativeTarget "SSKeychainTestsARC" */;
buildPhases = (
B2059B5C1559058C003D2FAC /* Sources */,
B2059B5F1559058C003D2FAC /* Frameworks */,
B2059B631559058C003D2FAC /* Resources */,
B2059B641559058C003D2FAC /* ShellScript */,
);
buildRules = (
);
dependencies = (
);
name = SSKeychainTestsARC;
productName = SSKeychainTests;
productReference = B2059B681559058C003D2FAC /* SSKeychainTestsARC.octest */;
productType = "com.apple.product-type.bundle";
};
B2A5FAAF143AC134000F6011 /* SSKeychainTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = B2A5FAC4143AC134000F6011 /* Build configuration list for PBXNativeTarget "SSKeychainTests" */;
Expand Down Expand Up @@ -142,11 +179,19 @@
projectRoot = "";
targets = (
B2A5FAAF143AC134000F6011 /* SSKeychainTests */,
B2059B5B1559058C003D2FAC /* SSKeychainTestsARC */,
);
};
/* End PBXProject section */

/* Begin PBXResourcesBuildPhase section */
B2059B631559058C003D2FAC /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
B2A5FAAD143AC134000F6011 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
Expand All @@ -157,6 +202,19 @@
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
B2059B641559058C003D2FAC /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n";
};
B2A5FAAE143AC134000F6011 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand All @@ -173,6 +231,15 @@
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
B2059B5C1559058C003D2FAC /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B2059B5D1559058C003D2FAC /* SSKeychainTests.m in Sources */,
B2059B5E1559058C003D2FAC /* SSKeychain.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B2A5FAAB143AC134000F6011 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
Expand All @@ -185,6 +252,32 @@
/* End PBXSourcesBuildPhase section */

/* Begin XCBuildConfiguration section */
B2059B661559058C003D2FAC /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
INFOPLIST_FILE = "SSKeychainTestsARC-Info.plist";
PRODUCT_NAME = SSKeychainTestsARC;
RUN_CLANG_STATIC_ANALYZER = YES;
TEST_HOST = "$(BUNDLE_LOADER)";
WRAPPER_EXTENSION = octest;
};
name = Debug;
};
B2059B671559058C003D2FAC /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
INFOPLIST_FILE = "SSKeychainTestsARC-Info.plist";
PRODUCT_NAME = SSKeychainTestsARC;
RUN_CLANG_STATIC_ANALYZER = YES;
TEST_HOST = "$(BUNDLE_LOADER)";
WRAPPER_EXTENSION = octest;
};
name = Release;
};
B2A5FABF143AC134000F6011 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
Expand Down Expand Up @@ -236,6 +329,7 @@
FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
INFOPLIST_FILE = "SSKeychainTests-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
RUN_CLANG_STATIC_ANALYZER = YES;
TEST_HOST = "$(BUNDLE_LOADER)";
WRAPPER_EXTENSION = octest;
};
Expand All @@ -247,6 +341,7 @@
FRAMEWORK_SEARCH_PATHS = "$(DEVELOPER_LIBRARY_DIR)/Frameworks";
INFOPLIST_FILE = "SSKeychainTests-Info.plist";
PRODUCT_NAME = "$(TARGET_NAME)";
RUN_CLANG_STATIC_ANALYZER = YES;
TEST_HOST = "$(BUNDLE_LOADER)";
WRAPPER_EXTENSION = octest;
};
Expand All @@ -255,6 +350,15 @@
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
B2059B651559058C003D2FAC /* Build configuration list for PBXNativeTarget "SSKeychainTestsARC" */ = {
isa = XCConfigurationList;
buildConfigurations = (
B2059B661559058C003D2FAC /* Debug */,
B2059B671559058C003D2FAC /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
B2A5FA89143AC133000F6011 /* Build configuration list for PBXProject "SSKeychain" */ = {
isa = XCConfigurationList;
buildConfigurations = (
Expand Down
22 changes: 22 additions & 0 deletions Tests/SSKeychainTestsARC-Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>com.samsoffes.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

0 comments on commit ca7ebbc

Please sign in to comment.